//===--- DeclSyntax.h - Declaration Syntax 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 interface for declaration-specific syntax nodes, // such as for structures, enumerations, type aliases, and constants. // //===----------------------------------------------------------------------===// #ifndef SWIFT_SYNTAX_DECLSYNTAX_H #define SWIFT_SYNTAX_DECLSYNTAX_H #include "swift/Syntax/GenericSyntax.h" #include "swift/Syntax/References.h" #include "swift/Syntax/RawSyntax.h" #include "swift/Syntax/Syntax.h" #include "swift/Syntax/SyntaxData.h" #include "swift/Syntax/TokenSyntax.h" #include "swift/Syntax/TypeSyntax.h" #include "llvm/ADT/BitVector.h" namespace swift { namespace syntax { #pragma mark declaration Data class DeclSyntaxData : public SyntaxData { protected: DeclSyntaxData(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); public: static bool classof(const SyntaxData *S) { return S->isDecl(); } }; #pragma mark declaration API class DeclSyntax : public Syntax { friend class Syntax; using DataType = DeclSyntaxData; protected: DeclSyntax(const RC Root, const DeclSyntaxData *Data); public: static bool classof(const SyntaxData *S) { return S->isDecl(); } }; #pragma mark - unknown-declaration Data class UnknownDeclSyntaxData : public DeclSyntaxData { UnknownDeclSyntaxData(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); public: static RC make(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static bool classof(const SyntaxData *S) { return S->getKind() == SyntaxKind::UnknownDecl; } }; #pragma mark - unknown-declaration API class UnknownDeclSyntax : public DeclSyntax { friend class SyntaxData; friend class UnknownStmtSyntaxData; friend class LegacyASTTransformer; using DataType = UnknownDeclSyntaxData; UnknownDeclSyntax(const RC Root, const UnknownDeclSyntaxData *Data); public: static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::UnknownDecl; } }; #pragma mark declaration-members Data class DeclMembersSyntaxData final : public SyntaxData { friend class SyntaxData; friend class DeclMembersSyntaxBuilder; friend struct SyntaxFactory; DeclMembersSyntaxData(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); public: static RC make(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static RC makeBlank(); static bool classof(const SyntaxData *S) { return S->getKind() == SyntaxKind::DeclMembers; } }; #pragma mark - #pragma mark declaration-members API class DeclMembersSyntax final : public Syntax { using DataType = DeclMembersSyntaxData; friend struct SyntaxFactory; friend class SyntaxData; friend class Syntax; friend class DeclMembersSyntaxBuilder; friend class StructDeclSyntax; DeclMembersSyntax(RC Root, const DeclMembersSyntaxData *Data); public: static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::DeclMembers; } }; #pragma mark - #pragma mark declaration-members Builder (TODO) class DeclMembersSyntaxBuilder final { RawSyntax::LayoutList MembersLayout; public: DeclMembersSyntaxBuilder &addMember(DeclSyntax Member); DeclMembersSyntax build() const; }; #pragma mark - #pragma mark struct-declaration Data class StructDeclSyntaxData final : public DeclSyntaxData { friend class SyntaxData; friend class StructDeclSyntax; friend class StructDeclSyntaxBuilder; friend struct SyntaxFactory; RC CachedWhereClause; RC CachedGenericParams; RC CachedMembers; StructDeclSyntaxData(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static RC make(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static RC makeBlank(); public: static bool classof(const SyntaxData *S) { return S->getKind() == SyntaxKind::StructDecl; } }; #pragma mark - struct-declaration API /// struct-declaration -> attributes? access-level-modifier? /// 'struct' struct-name /// generic-parameter-clause? type-inheritance-clause? /// generic-where-clause? /// '{' struct-members '}' /// struct-name -> identifier /// struct-members -> struct-member struct-members? /// struct-member -> declaration | compiler-control-statement class StructDeclSyntax final : public DeclSyntax { using DataType = StructDeclSyntaxData; friend struct SyntaxFactory; friend class Syntax; friend class SyntaxData; friend class StructDeclSyntaxData; friend class StructDeclSyntaxBuilder; enum class Cursor : CursorIndex { StructKeyword, Identifier, GenericParameterClause, GenericWhereClause, LeftBrace, Members, RightBrace, First = StructKeyword, Last = RightBrace, }; StructDeclSyntax(const RC Root, const StructDeclSyntaxData *Data); const StructDeclSyntaxData *getData() const { return cast(Data); } public: /// Return the 'struct' keyword attached to the declaration. RC getStructKeyword() const; /// Return a StructDeclSyntax with the given 'struct' keyword. StructDeclSyntax withStructKeyword(RC NewStructKeyword) const; /// Return the identifier of the struct. RC getIdentifier() const; /// Return a StructDeclSyntax with the given identifier. StructDeclSyntax withIdentifier(RC NewIdentifier) const; /// Return the generic parameter clause of the struct declaration. GenericParameterClauseSyntax getGenericParameterClause() const; /// Return a StructDeclSyntax with the given generic parameter clause. StructDeclSyntax withGenericParameterClause(GenericParameterClauseSyntax NewGenericParams) const; /// Return the where clause of the struct declaration. GenericWhereClauseSyntax getGenericWhereClause() const; /// Return a StructDeclSyntax with the given generic where clause. StructDeclSyntax withWhereClause(GenericWhereClauseSyntax NewWhereClause) const; /// Return the left brace '{' token of the struct declaration. RC getLeftBraceToken() const; /// Return a StructDeclSyntax with the given left brace '{' token. StructDeclSyntax withLeftBrace(RC NewLeftBrace) const; /// Return the members' syntax of the struct. DeclMembersSyntax getMembers() const; /// Return a StructDeclSyntax with the given new members. StructDeclSyntax withMembers(DeclMembersSyntax NewMembers) const; /// Return the right brace '}' token of the struct declaration. RC getRightBraceToken() const; /// Return a StructDeclSyntax with the given right brace '}' token. StructDeclSyntax withRightBrace(RC NewRightBrace) const; static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::StructDecl; } }; #pragma mark - struct-declaration Builder class StructDeclSyntaxBuilder final { RawSyntax::LayoutList StructLayout; public: StructDeclSyntaxBuilder(); StructDeclSyntaxBuilder &useStructKeyword(RC StructKeyword); StructDeclSyntaxBuilder &useIdentifier(RC Identifier); StructDeclSyntaxBuilder &useLeftBrace(RC LeftBrace); StructDeclSyntaxBuilder & useGenericParameterClause(GenericParameterClauseSyntax GenericParams); StructDeclSyntaxBuilder & useGenericWhereClause(GenericWhereClauseSyntax GenericWhereClause); StructDeclSyntaxBuilder &useMembers(DeclMembersSyntax Members); StructDeclSyntaxBuilder &useRightBrace(RC RightBrace); StructDeclSyntax build() const; }; #pragma mark - #pragma mark - type-alias Data class TypeAliasDeclSyntaxData final : public DeclSyntaxData { friend class SyntaxData; friend struct SyntaxFactory; friend class TypeAliasDeclSyntaxBuilder; TypeAliasDeclSyntaxData(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static RC make(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static RC makeBlank(); public: static bool classof(const SyntaxData *S) { return S->getKind() == SyntaxKind::TypeAliasDecl; } }; #pragma mark - #pragma mark - type-alias API class TypeAliasDeclSyntax final : public DeclSyntax { friend struct SyntaxFactory; friend class SyntaxData; friend class TypeAliasDeclSyntaxData; friend class TypeAliasDeclSyntaxBuilder; using DataType = TypeAliasDeclSyntaxData; enum Cursor : CursorIndex { TypeAliasKeyword, Identifier, GenericParameterClause, EqualToken, Type }; TypeAliasDeclSyntax(RC Root, const TypeAliasDeclSyntaxData *Data); public: /// Return the 'typealias' keyword for the declaration. RC getTypealiasKeyword() const { return cast(getRaw()->getChild(Cursor::TypeAliasKeyword)); } /// Return a TypeAliasDeclSyntax with the given 'typealias' keyword. TypeAliasDeclSyntax withTypeAliasKeyword(RC NewTypeAliasKeyword) const; /// Return the identifier for the declaration. RC getIdentifier() const; /// Return a TypeAliasDeclSyntax with the given identifier. TypeAliasDeclSyntax withIdentifier(RC NewIdentifier) const; /// Return the generic parameter clause of the declaration. GenericParameterClauseSyntax getGenericParameterClause() const; /// Return a TypeAliasDeclSyntax with the given generic parameter clause. TypeAliasDeclSyntax withGenericParameterClause( GenericParameterClauseSyntax NewGenericParams) const; /// Return the equal '=' token from the declaration. RC getEqualToken() const; /// Return a TypeAliasDeclSyntax with the given equal '=' token. TypeAliasDeclSyntax withEqualToken(RC NewEqualToken) const; /// Return the type syntax to which the type alias is assigned. TypeSyntax getTypeSyntax() const; /// Return a TypeAliasDeclSyntax with the given type assignment. TypeAliasDeclSyntax withTypeSyntax(TypeSyntax NewType) const; static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::TypeAliasDecl; } }; #pragma mark - type-alias Builder class TypeAliasDeclSyntaxBuilder final { RawSyntax::LayoutList TypeAliasLayout; public: TypeAliasDeclSyntaxBuilder(); TypeAliasDeclSyntaxBuilder & useTypeAliasKeyword(RC TypeAliasKeyword); TypeAliasDeclSyntaxBuilder &useIdentifier(RC Identifier); TypeAliasDeclSyntaxBuilder & useGenericParameterClause(GenericParameterClauseSyntax GenericParams); TypeAliasDeclSyntaxBuilder &useEqualToken(RC EqualToken); TypeAliasDeclSyntaxBuilder &useType(TypeSyntax ReferentType); TypeAliasDeclSyntax build() const; }; } // end namespace syntax } // end namespace swift #endif // SWIFT_SYNTAX_DECLSYNTAX_H