Files
swift-mirror/include/swift/Syntax/DeclSyntax.h

644 lines
20 KiB
C++

//===--- 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/SyntaxCollection.h"
#include "swift/Syntax/SyntaxData.h"
#include "swift/Syntax/TokenSyntax.h"
#include "swift/Syntax/TypeSyntax.h"
#include "swift/Syntax/UnknownSyntax.h"
#include "llvm/ADT/BitVector.h"
namespace swift {
namespace syntax {
class ExprSyntax;
class ExprSyntaxData;
#pragma mark declaration Data
class DeclSyntaxData : public SyntaxData {
protected:
DeclSyntaxData(RC<RawSyntax> 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<SyntaxData> Root, const DeclSyntaxData *Data);
public:
static bool classof(const SyntaxData *S) { return S->isDecl(); }
};
#pragma mark - unknown-declaration Data
class UnknownDeclSyntaxData : public UnknownSyntaxData {
UnknownDeclSyntaxData(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
CursorIndex IndexInParent = 0);
public:
static RC<UnknownDeclSyntaxData> make(RC<RawSyntax> 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 UnknownSyntax {
friend class SyntaxData;
friend class UnknownStmtSyntaxData;
friend class LegacyASTTransformer;
using DataType = UnknownDeclSyntaxData;
UnknownDeclSyntax(const RC<SyntaxData> 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<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
CursorIndex IndexInParent = 0);
public:
static RC<DeclMembersSyntaxData> make(RC<RawSyntax> Raw,
const SyntaxData *Parent = nullptr,
CursorIndex IndexInParent = 0);
static RC<DeclMembersSyntaxData> 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<SyntaxData> 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<GenericWhereClauseSyntaxData> CachedWhereClause;
RC<GenericParameterClauseSyntaxData> CachedGenericParams;
RC<DeclMembersSyntaxData> CachedMembers;
StructDeclSyntaxData(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
CursorIndex IndexInParent = 0);
static RC<StructDeclSyntaxData> make(RC<RawSyntax> Raw,
const SyntaxData *Parent = nullptr,
CursorIndex IndexInParent = 0);
static RC<StructDeclSyntaxData> 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<SyntaxData> Root, const StructDeclSyntaxData *Data);
const StructDeclSyntaxData *getData() const {
return cast<StructDeclSyntaxData>(Data);
}
public:
/// Return the 'struct' keyword attached to the declaration.
RC<TokenSyntax> getStructKeyword() const;
/// Return a StructDeclSyntax with the given 'struct' keyword.
StructDeclSyntax withStructKeyword(RC<TokenSyntax> NewStructKeyword) const;
/// Return the identifier of the struct.
RC<TokenSyntax> getIdentifier() const;
/// Return a StructDeclSyntax with the given identifier.
StructDeclSyntax withIdentifier(RC<TokenSyntax> 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<TokenSyntax> getLeftBraceToken() const;
/// Return a StructDeclSyntax with the given left brace '{' token.
StructDeclSyntax withLeftBrace(RC<TokenSyntax> 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<TokenSyntax> getRightBraceToken() const;
/// Return a StructDeclSyntax with the given right brace '}' token.
StructDeclSyntax withRightBrace(RC<TokenSyntax> 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<TokenSyntax> StructKeyword);
StructDeclSyntaxBuilder &useIdentifier(RC<TokenSyntax> Identifier);
StructDeclSyntaxBuilder &useLeftBrace(RC<TokenSyntax> LeftBrace);
StructDeclSyntaxBuilder &
useGenericParameterClause(GenericParameterClauseSyntax GenericParams);
StructDeclSyntaxBuilder &
useGenericWhereClause(GenericWhereClauseSyntax GenericWhereClause);
StructDeclSyntaxBuilder &useMembers(DeclMembersSyntax Members);
StructDeclSyntaxBuilder &useRightBrace(RC<TokenSyntax> 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<RawSyntax> Raw,
const SyntaxData *Parent = nullptr,
CursorIndex IndexInParent = 0);
static RC<TypeAliasDeclSyntaxData> make(RC<RawSyntax> Raw,
const SyntaxData *Parent = nullptr,
CursorIndex IndexInParent = 0);
static RC<TypeAliasDeclSyntaxData> 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<SyntaxData> Root, const TypeAliasDeclSyntaxData *Data);
public:
/// Return the 'typealias' keyword for the declaration.
RC<TokenSyntax> getTypealiasKeyword() const {
return cast<TokenSyntax>(getRaw()->getChild(Cursor::TypeAliasKeyword));
}
/// Return a TypeAliasDeclSyntax with the given 'typealias' keyword.
TypeAliasDeclSyntax
withTypeAliasKeyword(RC<TokenSyntax> NewTypeAliasKeyword) const;
/// Return the identifier for the declaration.
RC<TokenSyntax> getIdentifier() const;
/// Return a TypeAliasDeclSyntax with the given identifier.
TypeAliasDeclSyntax withIdentifier(RC<TokenSyntax> 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<TokenSyntax> getEqualToken() const;
/// Return a TypeAliasDeclSyntax with the given equal '=' token.
TypeAliasDeclSyntax
withEqualToken(RC<TokenSyntax> 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<TokenSyntax> TypeAliasKeyword);
TypeAliasDeclSyntaxBuilder &useIdentifier(RC<TokenSyntax> Identifier);
TypeAliasDeclSyntaxBuilder &
useGenericParameterClause(GenericParameterClauseSyntax GenericParams);
TypeAliasDeclSyntaxBuilder &useEqualToken(RC<TokenSyntax> EqualToken);
TypeAliasDeclSyntaxBuilder &useType(TypeSyntax ReferentType);
TypeAliasDeclSyntax build() const;
};
#pragma mark - function-parameter Data
class FunctionParameterSyntaxData final : public SyntaxData {
friend struct SyntaxFactory;
friend class Syntax;
friend class SyntaxData;
friend class FunctionParameterSyntax;
RC<TypeSyntaxData> CachedTypeSyntax;
RC<ExprSyntaxData> CachedDefaultValue;
FunctionParameterSyntaxData(RC<RawSyntax> Raw,
const SyntaxData *Parent = nullptr,
CursorIndex IndexInParent = 0);
static RC<FunctionParameterSyntaxData>
make(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
CursorIndex IndexInParent = 0);
static RC<FunctionParameterSyntaxData> makeBlank();
public:
static bool classof(const SyntaxData *SD) {
return SD->getKind() == SyntaxKind::FunctionParameter;
}
};
#pragma mark - function-parameter API
/// parameter ->
/// external-parameter-name? local-parameter-name ':'
/// type '...'? '='? expression? ','?
class FunctionParameterSyntax final : public Syntax {
friend struct SyntaxFactory;
friend class Syntax;
friend class SyntaxData;
friend class FunctionParameterSyntaxData;
enum class Cursor : CursorIndex {
ExternalName,
LocalName,
Colon,
Type,
Ellipsis,
DefaultEqual,
DefaultExpression,
TrailingComma,
};
public:
using DataType = FunctionParameterSyntaxData;
static constexpr SyntaxKind Kind = SyntaxKind::FunctionParameter;
FunctionParameterSyntax(const RC<SyntaxData> Root, const DataType *Data)
: Syntax(Root, Data) {}
/// Get the external name of the parameter, if there is one.
RC<TokenSyntax> getExternalName() const;
/// Return a FunctionParameterSyntax with the given external name.
FunctionParameterSyntax
withExternalName(RC<TokenSyntax> NewExternalName) const;
/// Return the local name of the parameter.
RC<TokenSyntax> getLocalName() const;
/// Return a FunctionParameterSyntax with the given local name.
FunctionParameterSyntax
withLocalName(RC<TokenSyntax> NewLocalName) const;
/// Return the colon ':' token between the local name and type of the
/// parameter.
RC<TokenSyntax> getColonToken() const;
/// Return a FunctionParameterSyntax with the given colon token between
/// the local name and type.
FunctionParameterSyntax
withColonToken(RC<TokenSyntax> NewColonToken) const;
/// Return the syntax for the type of this parameter.
llvm::Optional<TypeSyntax> getTypeSyntax() const;
/// Return a FunctionParameterSyntax with the given parameter type syntax.
FunctionParameterSyntax
withTypeSyntax(llvm::Optional<TypeSyntax> NewType) const;
/// Return the equal '=' token in between the parameter type and the default
/// value, if there is one.
RC<TokenSyntax> getEqualToken() const;
/// Return a FunctionParameterSyntax with the given equal '=' token in
/// between the parameter type and the default value.
FunctionParameterSyntax withEqualToken(RC<TokenSyntax> NewEqualToken) const;
/// Return the expresion for the default value of the parameter, if there
/// is one.
llvm::Optional<ExprSyntax> getDefaultValue() const;
/// Return a FunctionParameterSyntax with the given default value. To remove
/// the default value, pass llvm::None.
FunctionParameterSyntax
withDefaultValue(llvm::Optional<ExprSyntax> NewDefaultValue) const;
/// Return the trailing comma on the parameter, if there is one.
RC<TokenSyntax> getTrailingComma() const;
/// Return a FunctionParameterSyntax with the given trailing comma.
FunctionParameterSyntax
withTrailingComma(RC<TokenSyntax> NewTrailingComma) const;
static bool classof(const Syntax *S) {
return S->getKind() == SyntaxKind::FunctionParameter;
}
};
#pragma mark - function-parameter-list Data
using FunctionParameterListSyntaxData = SyntaxCollectionData<SyntaxKind::FunctionParameterList, FunctionParameterSyntax>;
#pragma mark - function-parameter-list API
/// parameter-list -> parameteter | parameter ',' parameter-list
class FunctionParameterListSyntax final : public
SyntaxCollection<SyntaxKind::FunctionParameterList, FunctionParameterSyntax> {
friend struct SyntaxFactory;
friend class Syntax;
friend class SyntaxData;
friend class FunctionSignatureSyntax;
using DataType = FunctionParameterListSyntaxData;
FunctionParameterListSyntax(const RC<SyntaxData> Root,
const DataType *Data)
: SyntaxCollection(Root, Data) {}
public:
static bool classof(const Syntax *S) {
return S->getKind() == SyntaxKind::FunctionParameterList;
}
};
#pragma mark - function-signature Data
class FunctionSignatureSyntaxData final : public SyntaxData {
friend struct SyntaxFactory;
friend class SyntaxData;
friend class FunctionSignatureSyntax;
RC<FunctionParameterListSyntaxData> CachedParameterList;
RC<TypeAttributesSyntaxData> CachedReturnTypeAttributes;
RC<TypeSyntaxData> CachedReturnTypeSyntax;
FunctionSignatureSyntaxData(const RC<RawSyntax> Raw,
const SyntaxData *Parent = nullptr,
const CursorIndex IndexInParent = 0);
static RC<FunctionSignatureSyntaxData>
make(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
CursorIndex IndexInParent = 0);
static RC<FunctionSignatureSyntaxData> makeBlank();
public:
static bool classof(const SyntaxData *SD) {
return SD->getKind() == SyntaxKind::FunctionSignature;
}
};
#pragma mark - function-signature API
/// function-signature ->
/// '(' parameter-list? ')' (throws | rethrows)? '->' attributes? type
class FunctionSignatureSyntax final : public Syntax {
friend struct SyntaxBuilder;
friend class Syntax;
friend class SyntaxData;
friend class FunctionSignatureSyntaxData;
enum class Cursor : CursorIndex {
LeftParen,
ParameterList,
RightParen,
ThrowsOrRethrows,
Arrow,
ReturnTypeAttributes,
ReturnType,
};
public:
using DataType = FunctionSignatureSyntaxData;
static constexpr SyntaxKind Kind = SyntaxKind::FunctionSignature;
FunctionSignatureSyntax(const RC<SyntaxData> Root, const DataType *Data)
: Syntax(Root, Data) {}
/// Return the left parenthesis '(' token enclosing the parameter list.
RC<TokenSyntax> getLeftParenToken() const;
/// Return a FunctionSignatureSyntax with the given left parentesis '(' token
/// enclosing the parameter list.
FunctionSignatureSyntax
withLeftParenToken(RC<TokenSyntax> NewLeftParen) const;
/// Return the parameter list for this signature.
FunctionParameterListSyntax getParameterList() const;
/// Return the parameter list for this signature.
FunctionSignatureSyntax
withParameterList(FunctionParameterListSyntax NewParameterList) const;
/// Return the right parenthesis ')' token enclosing the parameter list.
RC<TokenSyntax> getRightParenToken() const;
/// Return a FunctionSignatureSyntax with the given right parentesis ')' token
/// enclosing the parameter list.
FunctionSignatureSyntax
withRightParenToken(RC<TokenSyntax> NewRightParen) const;
/// Return the 'throws' token in this signature if it exists.
RC<TokenSyntax> getThrowsToken() const;
/// Return a FunctionSignatureSyntax with the given 'throws' token.
FunctionSignatureSyntax withThrowsToken(RC<TokenSyntax> NewThrowsToken) const;
/// Return the 'rethrows' token in this signature if it exists;
RC<TokenSyntax> getRethrowsToken() const;
/// Return a FunctionSignatureSyntax with the given 'rethrows' token.
FunctionSignatureSyntax
withRethrowsToken(RC<TokenSyntax> NewRethrowsToken) const;
/// Return the arrow '->' token for the signature.
RC<TokenSyntax> getArrowToken() const;
/// Return a FunctionSignatureSyntax with the given arrow token
FunctionSignatureSyntax withArrowToken(RC<TokenSyntax> NewArrowToken) const;
/// Return the return type attributes for the signature.
TypeAttributesSyntax getReturnTypeAttributes() const;
/// Return a FunctionSignatureSyntax with the given return type attributes.
FunctionSignatureSyntax
withReturnTypeAttributes(TypeAttributesSyntax NewReturnTypeAttributes) const;
/// Return the syntax for the return type of the signature.
TypeSyntax getReturnTypeSyntax() const;
/// Return a FunctionSignatureSyntax with the given return type.
FunctionSignatureSyntax withReturnTypeSyntax(TypeSyntax NewReturnType) const;
static bool classof(const Syntax *S) {
return S->getKind() == SyntaxKind::FunctionSignature;
}
};
} // end namespace syntax
} // end namespace swift
#endif // SWIFT_SYNTAX_DECLSYNTAX_H