//===--- SyntaxFactory.h - Swift Syntax Builder Interface -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // This file defines the SyntaxFactory, one of the most important client-facing // types in lib/Syntax and likely to be very commonly used. // // Effectively a namespace, SyntaxFactory is never instantiated, but is *the* // one-stop shop for making new Syntax nodes. Putting all of these into a // collection of static methods provides a single point of API lookup for // clients' convenience and also allows the library to hide all of the // constructors for all Syntax nodes, as the SyntaxFactory is friend to all. // //===----------------------------------------------------------------------===// #ifndef SWIFT_SYNTAX_SyntaxFactory_H #define SWIFT_SYNTAX_SyntaxFactory_H #include "swift/Syntax/DeclSyntax.h" #include "swift/Syntax/GenericSyntax.h" #include "swift/Syntax/TokenSyntax.h" #include "swift/Syntax/TypeSyntax.h" #include "swift/Syntax/Trivia.h" #include "llvm/ADT/ArrayRef.h" #include namespace swift { namespace syntax { #define SYNTAX(Id, Parent) class Id##Syntax; #include "swift/Syntax/SyntaxKinds.def" class DeclSyntax; class ExprSyntax; class StmtSyntax; class UnknownSyntax; struct TokenSyntax; /// The Syntax builder - the one-stop shop for making new Syntax nodes. struct SyntaxFactory { /// Collect a list of tokens into a piece of "unknown" syntax. static UnknownSyntax makeUnknownSyntax(llvm::ArrayRef> Tokens); #pragma mark - Declarations #pragma mark - declaration-modifier /// Make a declaration modifier with the specified elements. static DeclModifierSyntax makeDeclModifier(RC Name, RC LeftParen, RC Argument, RC RightParen); /// Make a declaration modifier with all missing elements. static DeclModifierSyntax makeBlankDeclModifier(); /// Make a declaration modifier list with the specified modifiers. static DeclModifierListSyntax makeDeclModifierList(const std::vector &Modifiers); /// Make an empty declaration modifier list. static DeclModifierListSyntax makeBlankDeclModifierList(); #pragma mark - struct-declaration /// Make a struct declaration with the specified elements. static StructDeclSyntax makeStructDecl(RC StructToken, RC Identifier, Syntax GenericParameters, Syntax WhereClause, RC LeftBrace, Syntax DeclMembers, RC RightBrace); /// Make a struct declaration with all missing elements. static StructDeclSyntax makeBlankStructDecl(); /// Make a typealias declaration with the specified elements. static TypeAliasDeclSyntax makeTypealiasDecl(RC TypealiasToken, RC Identifier, GenericParameterClauseSyntax GenericParams, RC AssignmentToken, TypeSyntax Type); /// Make a typealias declaration with all missing elements. static TypeAliasDeclSyntax makeBlankTypealiasDecl(); /// Make an empty list of declaration members. static DeclMembersSyntax makeBlankDeclMembers(); /// Make a function declaration with the specified elements. static FunctionDeclSyntax makeFunctionDecl(TypeAttributesSyntax Attributes, DeclModifierListSyntax Modifiers, RC FuncKeyword, RC Identifier, llvm::Optional GenericParams, FunctionSignatureSyntax Signature, llvm::Optional GenericWhereClause, llvm::Optional Body); /// Make a function declaration with all missing elements. static FunctionDeclSyntax makeBlankFunctionDecl(); #pragma mark - function-parameter /// Make a function parameter with the given elements. static FunctionParameterSyntax makeFunctionParameter(RC ExternalName, RC LocalName, RC Colon, llvm::Optional ParameterTypeSyntax, RC Ellipsis, RC Equal, llvm::Optional DefaultValue, RC TrailingComma); /// Make a function parameter with all elements marked as missing. static FunctionParameterSyntax makeBlankFunctionParameter(); #pragma mark - function-parameter-list /// Make a function parameter list with the given parameters. static FunctionParameterListSyntax makeFunctionParameterList( std::vector Parameters); /// Make an empty function parameter list. static FunctionParameterListSyntax makeBlankFunctionParameterList(); #pragma mark - function-signature /// Make a function signature with the given elements. static FunctionSignatureSyntax makeFunctionSignature(RC LeftParen, FunctionParameterListSyntax ParameterList, RC RightParen, RC ThrowsOrRethrows, RC Arrow, TypeAttributesSyntax ReturnTypeAttributes, TypeSyntax ReturnTypeSyntax); /// Make a blank function signature. static FunctionSignatureSyntax makeBlankFunctionSignature(); //-/ Make a function declaration with the given elements. // TODO //-/ Make a blank function declaration. // TODO #pragma mark - Statements /// Make a code block with the specified elements. static CodeBlockStmtSyntax makeCodeBlock(RC LeftBraceToken, StmtListSyntax Elements, RC RightBraceToken); /// Make a code block with all missing elements. static CodeBlockStmtSyntax makeBlankCodeBlock(); /// Make a fallthrough statement with the give `fallthrough` keyword. static FallthroughStmtSyntax makeFallthroughStmt(RC FallthroughKeyword); /// Make a fallthrough statement with the `fallthrough` keyword /// marked as missing. static FallthroughStmtSyntax makeBlankFallthroughStmt(); /// Make a break statement with the give `break` keyword and /// destination label. static BreakStmtSyntax makeBreakStmt(RC BreakKeyword, RC Label); /// Make a break statement with the `break` keyword /// and destination label marked as missing. static BreakStmtSyntax makeBlankBreakStmtSyntax(); /// Make a continue statement with the given `continue` keyword and /// destination label. static ContinueStmtSyntax makeContinueStmt(RC ContinueKeyword, RC Label); /// Make a continue statement with the `continue` keyword /// and destination label marked as missing. static ContinueStmtSyntax makeBlankContinueStmtSyntax(); /// Make a return statement with the given `return` keyword and returned /// expression. static ReturnStmtSyntax makeReturnStmt(RC ReturnKeyword, ExprSyntax ReturnedExpression); /// Make a return statement with the `return` keyword and return expression /// marked as missing. static ReturnStmtSyntax makeBlankReturnStmt(); /// Make a statement list from a loosely connected list of statements. static StmtListSyntax makeStmtList(const std::vector &Statements); /// Make an empty statement list. static StmtListSyntax makeBlankStmtList(); #pragma mark - Expressions /// Make an integer literal with the given '+'/'-' sign and string of digits. static IntegerLiteralExprSyntax makeIntegerLiteralExpr(RC Sign, RC Digits); /// Make an integer literal with the sign and string of digits marked /// as missing. static IntegerLiteralExprSyntax makeBlankIntegerLiteralExpr(); /// Make a symbolic reference with the given identifier and optionally a /// generic argument clause. static SymbolicReferenceExprSyntax makeSymbolicReferenceExpr(RC Identifier, llvm::Optional GenericArgs); /// Make a symbolic reference expression with the identifier and /// generic argument clause marked as missing. static SymbolicReferenceExprSyntax makeBlankSymbolicReferenceExpr(); /// Make a function call argument with all elements marked as missing. static FunctionCallArgumentSyntax makeBlankFunctionCallArgument(); /// Make a function call argument based on an expression with the /// given elements. static FunctionCallArgumentSyntax makeFunctionCallArgument(RC Label, RC Colon, ExprSyntax ExpressionArgument, RC TrailingComma); /// Make a function call argument list with the given arguments. static FunctionCallArgumentListSyntax makeFunctionCallArgumentList( std::vector Arguments); /// Make a function call argument list with no arguments. static FunctionCallArgumentListSyntax makeBlankFunctionCallArgumentList(); /// Make a function call expression with the given elements. static FunctionCallExprSyntax makeFunctionCallExpr(ExprSyntax CalledExpr, RC LeftParen, FunctionCallArgumentListSyntax Arguments, RC RightParen); /// Make a function call expression with all elements marked as missing. static FunctionCallExprSyntax makeBlankFunctionCallExpr(); #pragma mark - Tokens /// Make a 'static' keyword with the specified leading and trailing trivia. static RC makeStaticKeyword(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a 'public' keyword with the specified leading and trailing trivia. static RC makePublicKeyword(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a 'func' keyword with the specified leading and trailing trivia. static RC makeFuncKeyword(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a 'fallthrough' keyword with the specified leading and /// trailing trivia. static RC makeFallthroughKeyword(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make an at-sign '@' token with the specified leading and /// trailing trivia. static RC makeAtSignToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a 'break' keyword with the specified leading and /// trailing trivia. static RC makeBreakKeyword(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a 'continue' keyword with the specified leading and /// trailing trivia. static RC makeContinueKeyword(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a 'return' keyword with the specified leading and /// trailing trivia. static RC makeReturnKeyword(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a left angle '<' token with the specified leading and /// trailing trivia. static RC makeLeftAngleToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a right angle '>' token with the specified leading and /// trailing trivia. static RC makeRightAngleToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a left parenthesis '(' token with the specified leading and /// trailing trivia. static RC makeLeftParenToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a right parenthesis ')' token with the specified leading and /// trailing trivia. static RC makeRightParenToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a left brace '{' token with the specified leading and /// trailing trivia. static RC makeLeftBraceToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a right brace '}' token with the specified leading and /// trailing trivia. static RC makeRightBraceToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a left square bracket '[' token with the specified leading and /// trailing trivia. static RC makeLeftSquareBracketToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a right square bracket ']' token with the specified leading and /// trailing trivia. static RC makeRightSquareBracketToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a postfix question '?' token with the specified trailing trivia. /// The leading trivia is assumed to be of zero width. static RC makeQuestionPostfixToken(const Trivia &TrailingTrivia); /// Make an exclamation '!' token with the specified trailing trivia. /// The leading trivia is assumed to be of zero width. static RC makeExclaimPostfixToken(const Trivia &TrailingTrivia); /// Make an identifier token with the specified leading and trailing trivia. static RC makeIdentifier(OwnedString Name, const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a comma ',' token with the specified leading and trailing trivia. static RC makeCommaToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a colon ':' token with the specified leading and trailing trivia. static RC makeColonToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a dot '.' token with the specified leading and trailing trivia. static RC makeDotToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a 'struct' keyword with the specified leading and trailing trivia. static RC makeStructKeyword(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a 'where' keyword with the specified leading and trailing trivia. static RC makeWhereKeyword(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a 'inout' keyword with the specified leading and trailing trivia. static RC makeInoutKeyword(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a 'throws' keyword with the specified leading and trailing trivia. static RC makeThrowsKeyword(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a 'rethrows' keyword with the specified leading and /// trailing trivia. static RC makeRethrowsKeyword(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a 'typealias' keyword with the specified leading and /// trailing trivia. static RC makeTypealiasKeyword(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make an equal '=' token with the specified leading and /// trailing trivia. static RC makeEqualToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make an arrow '->' token with the specified leading and trailing trivia. static RC makeArrow(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make an equality '==' binary operator with the specified leading and /// trailing trivia. static RC makeEqualityOperator(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make the terminal identifier token `Type` static RC makeTypeToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make the terminal identifier token `Protocol` static RC makeProtocolToken(const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a token representing the digits of an integer literal. /// /// Note: This is not a stand-in for the expression, which can contain /// a minus sign. static RC makeIntegerLiteralToken(OwnedString Digits, const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); #pragma mark - Operators /// Make a prefix operator with the given text. static RC makePrefixOperator(OwnedString Name, const Trivia &LeadingTrivia); #pragma mark - Types #pragma mark - type-attribute /// Make a type attribute with the specified elements. static TypeAttributeSyntax makeTypeAttribute(RC AtSignToken, RC Identifier, RC LeftParen, BalancedTokensSyntax BalancedTokens, RC RightParen); /// Make a type attribute with all elements marked as missing. static TypeAttributeSyntax makeBlankTypeAttribute(); #pragma mark - type-attributes /// Make a set of type attributes with all elements marked as missing. static TypeAttributesSyntax makeBlankTypeAttributes(); #pragma mark - balanced-tokens /// Make a list of balanced tokens. static BalancedTokensSyntax makeBalancedTokens(RawSyntax::LayoutList Tokens); /// Make an empty list of balanced tokens. static BalancedTokensSyntax makeBlankBalancedTokens(); #pragma mark - type-identifier /// Make a non-generic type identifier with some name. static TypeIdentifierSyntax makeTypeIdentifier(OwnedString Name, const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a generic type identifier. static TypeIdentifierSyntax makeTypeIdentifier(RC Identifier, GenericArgumentClauseSyntax GenericArgs); /// Make a bare "Any" type. static TypeIdentifierSyntax makeAnyTypeIdentifier(); /// Make a bare "Self" type. static TypeIdentifierSyntax makeSelfTypeIdentifier(); #pragma mark - tuple-type /// Make a bare "()" void tuple type static TupleTypeSyntax makeVoidTupleType(); /// Make a tuple type from a type element list and the provided left/right /// paren tokens. static TupleTypeSyntax makeTupleType(RC LParen, TupleTypeElementListSyntax Elements, RC RParen); /// Make a tuple type element of the form 'Name: ElementType' static TupleTypeElementSyntax makeTupleTypeElement(RC Name, RC Colon, TypeSyntax ElementType, llvm::Optional> MaybeComma = llvm::None); /// Make a tuple type element without a label. static TupleTypeElementSyntax makeTupleTypeElement(TypeSyntax ElementType, llvm::Optional> MaybeComma = llvm::None); /// Make a tuple type element list. static TupleTypeElementListSyntax makeTupleTypeElementList(std::vector ElementTypes); #pragma mark - optional-type /// Make an optional type, such as `Int?` static OptionalTypeSyntax makeOptionalType(TypeSyntax BaseType, const Trivia &TrailingTrivia); /// Make an optional type with all elements marked as missing. static OptionalTypeSyntax makeBlankOptionalType(); #pragma mark - implicitly-unwrapped-optional-type /// Make an implicitly unwrapped optional type, such as `Int!` static ImplicitlyUnwrappedOptionalTypeSyntax makeImplicitlyUnwrappedOptionalType(TypeSyntax BaseType, const Trivia &TrailingTrivia); static ImplicitlyUnwrappedOptionalTypeSyntax makeBlankImplicitlyUnwrappedOptionalType(); #pragma mark - metatype-type /// Make a metatype type, as in `T.Type` /// `Type` is a terminal token here, not a placeholder for something else. static MetatypeTypeSyntax makeMetatypeType(TypeSyntax BaseType, RC DotToken, RC TypeToken); /// Make a metatype type with all elements marked as missing. static MetatypeTypeSyntax makeBlankMetatypeType(); #pragma mark - array-type /// Make a sugared Array type, as in `[MyType]`. static ArrayTypeSyntax makeArrayType(RC LeftSquareBracket, TypeSyntax ElementType, RC RightSquareBracket); /// Make an array type with all elements marked as missing. static ArrayTypeSyntax makeBlankArrayType(); #pragma mark - dictionary-type /// Make a Dictionary type, as in `[Key : Value]`. static DictionaryTypeSyntax makeDictionaryType(RC LeftSquareBracket, TypeSyntax KeyType, RC Colon, TypeSyntax ValueType, RC RightSquareBracket); /// Make an a dictionary type with all elements marked as missing. static DictionaryTypeSyntax makeBlankDictionaryType(); #pragma mark - function-type-argument /// Make a function argument type syntax with the specified elements. static FunctionTypeArgumentSyntax makeFunctionTypeArgument(RC ExternalParameterName, RC LocalParameterName, TypeAttributesSyntax TypeAttributes, RC InoutKeyword, RC ColonToken, TypeSyntax ParameterTypeSyntax); /// Make a simple function type argument syntax with the given label and /// simple type name. static FunctionTypeArgumentSyntax makeFunctionTypeArgument(RC LocalParameterName, RC ColonToken, TypeSyntax ParameterType); /// Make a simple function type argument syntax with the given simple /// type name. static FunctionTypeArgumentSyntax makeFunctionTypeArgument(TypeSyntax TypeArgument); /// Make a function argument type syntax with all elements marked as missing. static FunctionTypeArgumentSyntax makeBlankFunctionArgumentType(); #pragma mark - function-type /// Make a function type, for example, `(Int, Int) throws -> Int` static FunctionTypeSyntax makeFunctionType(TypeAttributesSyntax TypeAttributes, RC LeftParen, FunctionParameterListSyntax ArgumentList, RC RightParen, RC ThrowsOrRethrows, RC Arrow, TypeSyntax ReturnType); /// Make a function type with all elements marked as missing. static FunctionTypeSyntax makeBlankFunctionType(); #pragma mark - tuple-type-element-list /// Make a list of type arguments with all elements marked as missing. static TupleTypeElementListSyntax makeBlankTupleTypeElementList(); #pragma mark - Generics /// Make an empty generic parameter clause. static GenericParameterClauseSyntax makeBlankGenericParameterClause(); /// Make an empty generic argument clause. static GenericArgumentClauseSyntax makeBlankGenericArgumentClause(); /// Make an empty generic where clause. static GenericWhereClauseSyntax makeBlankGenericWhereClause(); /// Make a same-type requirement with the specified elements. /// /// Any elements are allowed to be marked as missing. static SameTypeRequirementSyntax makeSameTypeRequirement(TypeIdentifierSyntax LeftTypeIdentifier, RC EqualityToken, TypeSyntax RightType); /// Make a list of generic requirements with the given loosely collected /// requirements/ static GenericRequirementListSyntax makeGenericRequirementList( std::vector &Requirements); /// Make an empty list of generic requirements. static GenericRequirementListSyntax makeBlankGenericRequirementList(); /// Make a same-type requirement with all elements marked as missing. static SameTypeRequirementSyntax makeBlankSameTypeRequirement(); /// Make an empty same-type-requirement with all missing elements. static SameTypeRequirementSyntax makeSameTypeRequirement(); /// Make a generic parameter with the specified name and trivia. static GenericParameterSyntax makeGenericParameter(OwnedString TypeName, const Trivia &LeadingTrivia, const Trivia &TrailingTrivia); /// Make a generic parameter with all elements marked as missing. static GenericParameterSyntax makeBlankGenericParameter(); }; } // end namespace syntax } // end namespace swift #endif // SWIFT_SYNTAX_SyntaxFactory_H