Files
swift-mirror/include/swift/Syntax/DeclSyntax.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

387 lines
12 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/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 {
#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;
};
} // end namespace syntax
} // end namespace swift
#endif // SWIFT_SYNTAX_DECLSYNTAX_H