Files
swift-mirror/include/swift/Syntax/SyntaxFactory.h
David Farler c958cd65eb [Syntax] Allow UnknownSyntax to have children
This will make it easier to incrementally implement syntax nodes,
while allowing us to embed nodes that we do know about inside ones
that we don't.

https://bugs.swift.org/browse/SR-4062
2017-02-28 14:30:57 -08:00

484 lines
20 KiB
C++

//===--- 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 <vector>
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<RC<TokenSyntax>> Tokens);
#pragma mark - Declarations
/// Make a struct declaration with the specified elements.
static StructDeclSyntax
makeStructDecl(RC<TokenSyntax> StructToken, RC<TokenSyntax> Identifier,
Syntax GenericParameters, Syntax WhereClause,
RC<TokenSyntax> LeftBrace, Syntax DeclMembers,
RC<TokenSyntax> RightBrace);
/// Make a struct declaration with all missing elements.
static StructDeclSyntax makeBlankStructDecl();
/// Make a typealias declaration with the specified elements.
static TypeAliasDeclSyntax
makeTypealiasDecl(RC<TokenSyntax> TypealiasToken, RC<TokenSyntax> Identifier,
GenericParameterClauseSyntax GenericParams,
RC<TokenSyntax> AssignmentToken, TypeSyntax Type);
/// Make a typealias declaration with all missing elements.
static TypeAliasDeclSyntax makeBlankTypealiasDecl();
/// Make an empty list of declaration members.
static DeclMembersSyntax makeBlankDeclMembers();
#pragma mark - Statements
/// Make a code block with the specified elements.
static CodeBlockStmtSyntax
makeCodeBlock(RC<TokenSyntax> LeftBraceToken,
StmtListSyntax Elements,
RC<TokenSyntax> 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<TokenSyntax> 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<TokenSyntax> BreakKeyword, RC<TokenSyntax> 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<TokenSyntax> ContinueKeyword, RC<TokenSyntax> 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<TokenSyntax> ReturnKeyword, ExprSyntax ReturnedExpression);
/// Make a return statement with the `return` keyword and return expression
/// marked as missing.
static ReturnStmtSyntax makeBlankReturnStmt();
#pragma mark - Expressions
/// Make an integer literal with the given '+'/'-' sign and string of digits.
static IntegerLiteralExprSyntax
makeIntegerLiteralExpr(RC<TokenSyntax> Sign, RC<TokenSyntax> 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<TokenSyntax> Identifier,
llvm::Optional<GenericArgumentClauseSyntax> 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<TokenSyntax> Label, RC<TokenSyntax> Colon,
ExprSyntax ExpressionArgument,
RC<TokenSyntax> TrailingComma);
/// Make a function call argument list with the given arguments.
static FunctionCallArgumentListSyntax
makeFunctionCallArgumentList(
std::vector<FunctionCallArgumentSyntax> 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<TokenSyntax> LeftParen,
FunctionCallArgumentListSyntax Arguments,
RC<TokenSyntax> RightParen);
/// Make a function call expression with all elements marked as missing.
static FunctionCallExprSyntax makeBlankFunctionCallExpr();
#pragma mark - Tokens
/// Make a 'fallthrough' keyword with the specified leading and
/// trailing trivia.
static RC<TokenSyntax> makeFallthroughKeyword(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make an at-sign '@' token with the specified leading and
/// trailing trivia.
static RC<TokenSyntax> makeAtSignToken(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a 'break' keyword with the specified leading and
/// trailing trivia.
static RC<TokenSyntax> makeBreakKeyword(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a 'continue' keyword with the specified leading and
/// trailing trivia.
static RC<TokenSyntax> makeContinueKeyword(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a 'return' keyword with the specified leading and
/// trailing trivia.
static RC<TokenSyntax> makeReturnKeyword(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a left angle '<' token with the specified leading and
/// trailing trivia.
static RC<TokenSyntax> makeLeftAngleToken(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a right angle '>' token with the specified leading and
/// trailing trivia.
static RC<TokenSyntax> makeRightAngleToken(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a left parenthesis '(' token with the specified leading and
/// trailing trivia.
static RC<TokenSyntax> makeLeftParenToken(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a right parenthesis ')' token with the specified leading and
/// trailing trivia.
static RC<TokenSyntax> makeRightParenToken(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a left square bracket '[' token with the specified leading and
/// trailing trivia.
static RC<TokenSyntax>
makeLeftSquareBracketToken(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a right square bracket ']' token with the specified leading and
/// trailing trivia.
static RC<TokenSyntax>
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<TokenSyntax>
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<TokenSyntax> makeExclaimPostfixToken(const Trivia &TrailingTrivia);
/// Make an identifier token with the specified leading and trailing trivia.
static RC<TokenSyntax> makeIdentifier(OwnedString Name,
const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a comma ',' token with the specified leading and trailing trivia.
static RC<TokenSyntax> makeCommaToken(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a colon ':' token with the specified leading and trailing trivia.
static RC<TokenSyntax> makeColonToken(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a dot '.' token with the specified leading and trailing trivia.
static RC<TokenSyntax> makeDotToken(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a 'struct' keyword with the specified leading and trailing trivia.
static RC<TokenSyntax> makeStructKeyword(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a 'where' keyword with the specified leading and trailing trivia.
static RC<TokenSyntax> makeWhereKeyword(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a 'inout' keyword with the specified leading and trailing trivia.
static RC<TokenSyntax> makeInoutKeyword(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a 'throws' keyword with the specified leading and trailing trivia.
static RC<TokenSyntax> makeThrowsKeyword(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a 'rethrows' keyword with the specified leading and
/// trailing trivia.
static RC<TokenSyntax> makeRethrowsKeyword(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make a 'typealias' keyword with the specified leading and
/// trailing trivia.
static RC<TokenSyntax> makeTypealiasKeyword(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make an equal '=' token with the specified leading and
/// trailing trivia.
static RC<TokenSyntax> makeEqualToken(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make an arrow '->' token with the specified leading and trailing trivia.
static RC<TokenSyntax> makeArrow(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make an equality '==' binary operator with the specified leading and
/// trailing trivia.
static RC<TokenSyntax> makeEqualityOperator(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make the terminal identifier token `Type`
static RC<TokenSyntax> makeTypeToken(const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
/// Make the terminal identifier token `Protocol`
static RC<TokenSyntax> 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<TokenSyntax> makeIntegerLiteralToken(OwnedString Digits,
const Trivia &LeadingTrivia,
const Trivia &TrailingTrivia);
#pragma mark - Operators
/// Make a prefix operator with the given text.
static RC<TokenSyntax> makePrefixOpereator(OwnedString Name,
const Trivia &LeadingTrivia);
#pragma mark - Types
#pragma mark - type-attribute
/// Make a type attribute with the specified elements.
static TypeAttributeSyntax
makeTypeAttribute(RC<TokenSyntax> AtSignToken,
RC<TokenSyntax> Identifier,
RC<TokenSyntax> LeftParen,
BalancedTokensSyntax BalancedTokens,
RC<TokenSyntax> 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();
/// Make a list of balanced tokens.
static BalancedTokensSyntax
makeBalancedTokens(RawSyntax::LayoutList Tokens);
/// Make an empty list of balanced tokens.
static BalancedTokensSyntax makeBlankBalancedTokens();
/// 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<TokenSyntax> Identifier,
GenericArgumentClauseSyntax GenericArgs);
/// Make a bare "Any" type.
static TypeIdentifierSyntax makeAnyTypeIdentifier();
/// Make a bare "Self" type.
static TypeIdentifierSyntax makeSelfTypeIdentifier();
/// Make a bare "()" void tuple type
static TupleTypeSyntax makeVoidTupleType();
/// Make a tuple type element of the form 'Name: ElementType'
static TupleTypeElementSyntax
makeTupleTypeElement(RC<TokenSyntax> Name, TypeSyntax ElementType);
/// Make a tuple type element without a label.
static TupleTypeElementSyntax makeTupleTypeElement(TypeSyntax ElementType);
/// 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();
/// Make an implicitly unwrapped optional type, such as `Int!`
static ImplicitlyUnwrappedOptionalTypeSyntax
makeImplicitlyUnwrappedOptionalType(TypeSyntax BaseType,
const Trivia &TrailingTrivia);
static ImplicitlyUnwrappedOptionalTypeSyntax
makeBlankImplicitlyUnwrappedOptionalType();
/// 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<TokenSyntax> DotToken,
RC<TokenSyntax> TypeToken);
/// Make a metatype type with all elements marked as missing.
static MetatypeTypeSyntax makeBlankMetatypeType();
/// Make a sugared Array type, as in `[MyType]`.
static ArrayTypeSyntax makeArrayType(RC<TokenSyntax> LeftSquareBracket,
TypeSyntax ElementType,
RC<TokenSyntax> RightSquareBracket);
/// Make an array type with all elements marked as missing.
static ArrayTypeSyntax makeBlankArrayType();
/// Make a Dictionary type, as in `[Key : Value]`.
static DictionaryTypeSyntax
makeDictionaryType(RC<TokenSyntax> LeftSquareBracket, TypeSyntax KeyType,
RC<TokenSyntax> Colon, TypeSyntax ValueType,
RC<TokenSyntax> RightSquareBracket);
/// Make an a dictionary type with all elements marked as missing.
static DictionaryTypeSyntax makeBlankDictionaryType();
/// Make a function argument type syntax with the specified elements.
static FunctionTypeArgumentSyntax
makeFunctionTypeArgument(RC<TokenSyntax> ExternalParameterName,
RC<TokenSyntax> LocalParameterName,
TypeAttributesSyntax TypeAttributes,
RC<TokenSyntax> InoutKeyword,
RC<TokenSyntax> ColonToken,
TypeSyntax ParameterTypeSyntax);
/// Make a simple function type argument syntax with the given label and
/// simple type name.
static FunctionTypeArgumentSyntax
makeFunctionTypeArgument(RC<TokenSyntax> LocalParameterName,
RC<TokenSyntax> 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();
/// Make a function type, for example, `(Int, Int) throws -> Int`
static FunctionTypeSyntax
makeFunctionType(TypeAttributesSyntax TypeAttributes,
RC<TokenSyntax> LeftParen,
TypeArgumentListSyntax ArgumentList,
RC<TokenSyntax> RightParen, RC<TokenSyntax> ThrowsOrRethrows,
RC<TokenSyntax> Arrow, TypeSyntax ReturnType);
/// Make a function type with all elements marked as missing.
static FunctionTypeSyntax makeBlankFunctionType();
/// Make a list of type arguments with all elements marked as missing.
static TypeArgumentListSyntax makeBlankTypeArgumentList();
#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<TokenSyntax> EqualityToken, TypeSyntax RightType);
/// 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