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

367 lines
13 KiB
C++

//===--- DeclSyntax.cpp - Declaration Syntax Implementation ---------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "swift/Syntax/DeclSyntax.h"
#include "swift/Syntax/RawSyntax.h"
#include "swift/Syntax/SyntaxFactory.h"
using namespace swift;
using namespace swift::syntax;
#pragma mark - declaration Data
DeclSyntaxData::DeclSyntaxData(RC<RawSyntax> Raw,
const SyntaxData *Parent,
CursorIndex IndexInParent)
: SyntaxData(Raw, Parent, IndexInParent) {
assert(Raw->isDecl());
}
#pragma mark - declaration API
DeclSyntax::DeclSyntax(const RC<SyntaxData> Root, const DeclSyntaxData *Data)
: Syntax(Root, Data) {}
#pragma mark - unknown-statement Data
UnknownDeclSyntaxData::UnknownDeclSyntaxData(RC<RawSyntax> Raw,
const SyntaxData *Parent,
CursorIndex IndexInParent)
: UnknownSyntaxData(Raw, Parent, IndexInParent) {
assert(Raw->Kind == SyntaxKind::UnknownDecl);
}
RC<UnknownDeclSyntaxData>
UnknownDeclSyntaxData::make(RC<RawSyntax> Raw,
const SyntaxData *Parent,
CursorIndex IndexInParent) {
auto UnknownRaw = RawSyntax::make(SyntaxKind::UnknownDecl, Raw->Layout,
Raw->Presence);
return RC<UnknownDeclSyntaxData> {
new UnknownDeclSyntaxData {
Raw, Parent, IndexInParent
}
};
}
#pragma mark - unknown-statement API
UnknownDeclSyntax::UnknownDeclSyntax(const RC<SyntaxData> Root,
const UnknownDeclSyntaxData *Data)
: UnknownSyntax(Root, Data) {}
#pragma mark - declaration-members Data
DeclMembersSyntaxData::DeclMembersSyntaxData(RC<RawSyntax> Raw,
const SyntaxData *Parent,
CursorIndex IndexInParent)
: SyntaxData(Raw, Parent, IndexInParent) {
assert(Raw->Kind == SyntaxKind::DeclMembers);
}
RC<DeclMembersSyntaxData>
DeclMembersSyntaxData::make(RC<RawSyntax> Raw,
const SyntaxData *Parent,
CursorIndex IndexInParent) {
return RC<DeclMembersSyntaxData> {
new DeclMembersSyntaxData {
Raw, Parent, IndexInParent
}
};
}
RC<DeclMembersSyntaxData> DeclMembersSyntaxData::makeBlank() {
return make(RawSyntax::make(SyntaxKind::DeclMembers, {},
SourcePresence::Present));
}
#pragma mark - declaration-members API
DeclMembersSyntax::DeclMembersSyntax(const RC<SyntaxData> Root,
const DeclMembersSyntaxData *Data)
: Syntax(Root, Data) {}
#pragma mark - declaration-members Builder
DeclMembersSyntaxBuilder &
DeclMembersSyntaxBuilder::addMember(DeclSyntax Member) {
MembersLayout.push_back(Member.getRaw());
return *this;
}
DeclMembersSyntax DeclMembersSyntaxBuilder::build() const {
auto Raw = RawSyntax::make(SyntaxKind::DeclMembers, MembersLayout,
SourcePresence::Present);
auto Data = DeclMembersSyntaxData::make(Raw);
return DeclMembersSyntax { Data, Data.get() };
}
#pragma mark - struct-declaration Data
StructDeclSyntaxData::StructDeclSyntaxData(RC<RawSyntax> Raw,
const SyntaxData *Parent,
CursorIndex IndexInParent)
: DeclSyntaxData(Raw, Parent, IndexInParent) {
assert(Raw->Kind == SyntaxKind::StructDecl);
syntax_assert_child_token_text(Raw, StructDeclSyntax::Cursor::StructKeyword,
tok::kw_struct, "struct");
syntax_assert_child_token(Raw, StructDeclSyntax::Cursor::Identifier,
tok::identifier);
syntax_assert_child_kind(Raw,
StructDeclSyntax::Cursor::GenericParameterClause,
SyntaxKind::GenericParameterClause);
syntax_assert_child_kind(Raw, StructDeclSyntax::Cursor::GenericWhereClause,
SyntaxKind::GenericWhereClause);
syntax_assert_child_token_text(Raw, StructDeclSyntax::Cursor::LeftBrace,
tok::l_brace, "{");
syntax_assert_child_kind(Raw, StructDeclSyntax::Cursor::Members,
SyntaxKind::DeclMembers);
syntax_assert_child_token_text(Raw, StructDeclSyntax::Cursor::RightBrace,
tok::r_brace, "}");
}
RC<StructDeclSyntaxData> StructDeclSyntaxData::make(RC<RawSyntax> Raw,
const SyntaxData *Parent,
CursorIndex IndexInParent) {
return RC<StructDeclSyntaxData> {
new StructDeclSyntaxData { Raw, Parent, IndexInParent }
};
}
RC<StructDeclSyntaxData> StructDeclSyntaxData::makeBlank() {
return make(RawSyntax::make(SyntaxKind::StructDecl,
{
TokenSyntax::missingToken(tok::kw_struct, "struct"),
TokenSyntax::missingToken(tok::identifier, ""),
RawSyntax::missing(SyntaxKind::GenericParameterClause),
RawSyntax::missing(SyntaxKind::GenericWhereClause),
TokenSyntax::missingToken(tok::l_brace, "{"),
RawSyntax::missing(SyntaxKind::DeclMembers),
TokenSyntax::missingToken(tok::r_brace, "}"),
},
SourcePresence::Present));
}
#pragma mark - struct-declaration API
StructDeclSyntax::StructDeclSyntax(const RC<SyntaxData> Root,
const StructDeclSyntaxData *Data)
: DeclSyntax(Root, Data) {}
RC<TokenSyntax> StructDeclSyntax::getStructKeyword() const {
return cast<TokenSyntax>(getRaw()->getChild(Cursor::StructKeyword));
}
StructDeclSyntax
StructDeclSyntax::withStructKeyword(RC<TokenSyntax> NewStructKeyword)
const {
syntax_assert_token_is(NewStructKeyword, tok::kw_struct, "struct");
return Data->replaceChild<StructDeclSyntax>(NewStructKeyword,
Cursor::StructKeyword);
}
StructDeclSyntax
StructDeclSyntax::withLeftBrace(RC<TokenSyntax> NewLeftBrace) const {
syntax_assert_token_is(NewLeftBrace, tok::l_brace, "{");
return Data->replaceChild<StructDeclSyntax>(NewLeftBrace,
Cursor::LeftBrace);
}
RC<TokenSyntax> StructDeclSyntax::getLeftBraceToken() const {
return cast<TokenSyntax>(getRaw()->getChild(Cursor::LeftBrace));
}
StructDeclSyntax
StructDeclSyntax::withMembers(DeclMembersSyntax NewMembers) const {
return Data->replaceChild<StructDeclSyntax>(NewMembers.getRaw(),
Cursor::Members);
}
DeclMembersSyntax StructDeclSyntax::getMembers() const {
auto Raw = getRaw()->getChild(Cursor::Members);
auto MembersData = DeclMembersSyntaxData::make(Raw,
Data,
cursorIndex(Cursor::Members));
const_cast<StructDeclSyntaxData *>(getData())->CachedMembers = MembersData;
return DeclMembersSyntax { Root, MembersData.get() };
}
#pragma mark - struct-declaration Builder
StructDeclSyntaxBuilder::StructDeclSyntaxBuilder()
: StructLayout(SyntaxFactory::makeBlankStructDecl().getRaw()->Layout) {}
StructDeclSyntaxBuilder &
StructDeclSyntaxBuilder::useStructKeyword(RC<TokenSyntax> StructKeyword) {
syntax_assert_token_is(StructKeyword, tok::kw_struct, "struct");
auto Index = cursorIndex(StructDeclSyntax::Cursor::StructKeyword);
StructLayout[Index] = StructKeyword;
return *this;
}
StructDeclSyntaxBuilder &
StructDeclSyntaxBuilder::useIdentifier(RC<TokenSyntax> Identifier) {
assert(Identifier->getTokenKind() == tok::identifier);
auto Index = cursorIndex(StructDeclSyntax::Cursor::Identifier);
StructLayout[Index] = Identifier;
return *this;
}
StructDeclSyntaxBuilder &
StructDeclSyntaxBuilder::useLeftBrace(RC<TokenSyntax> LeftBrace) {
syntax_assert_token_is(LeftBrace, tok::l_brace, "{");
auto Index = cursorIndex(StructDeclSyntax::Cursor::LeftBrace);
StructLayout[Index] = LeftBrace;
return *this;
}
StructDeclSyntaxBuilder &
StructDeclSyntaxBuilder::useMembers(DeclMembersSyntax Members) {
auto Index = cursorIndex(StructDeclSyntax::Cursor::Members);
StructLayout[Index] = Members.getRaw();
return *this;
}
StructDeclSyntaxBuilder &
StructDeclSyntaxBuilder::useRightBrace(RC<TokenSyntax> RightBrace) {
syntax_assert_token_is(RightBrace, tok::r_brace, "}");
auto Index = cursorIndex(StructDeclSyntax::Cursor::RightBrace);
StructLayout[Index] = RightBrace;
return *this;
}
StructDeclSyntax StructDeclSyntaxBuilder::build() const {
auto Raw = RawSyntax::make(SyntaxKind::StructDecl, StructLayout,
SourcePresence::Present);
auto Data = StructDeclSyntaxData::make(Raw);
return StructDeclSyntax { Data, Data.get() };
}
#pragma mark - type-alias Data
TypeAliasDeclSyntaxData::TypeAliasDeclSyntaxData(RC<RawSyntax> Raw,
const SyntaxData *Parent,
CursorIndex IndexInParent)
: DeclSyntaxData(Raw, Parent, IndexInParent) {}
RC<TypeAliasDeclSyntaxData>
TypeAliasDeclSyntaxData::make(RC<RawSyntax> Raw,
const SyntaxData *Parent,
CursorIndex IndexInParent) {
return RC<TypeAliasDeclSyntaxData> {
new TypeAliasDeclSyntaxData { Raw, Parent, IndexInParent }
};
}
RC<TypeAliasDeclSyntaxData>
TypeAliasDeclSyntaxData::makeBlank() {
return make(RawSyntax::make(SyntaxKind::TypeAliasDecl,
{
TokenSyntax::missingToken(tok::kw_typealias, "typealias"),
TokenSyntax::missingToken(tok::identifier, ""),
RawSyntax::missing(SyntaxKind::GenericParameterClause),
TokenSyntax::missingToken(tok::equal, "="),
RawSyntax::missing(SyntaxKind::MissingType),
},
SourcePresence::Present));
}
#pragma mark - type-alias API
TypeAliasDeclSyntax::TypeAliasDeclSyntax(RC<SyntaxData> Root,
const TypeAliasDeclSyntaxData *Data)
: DeclSyntax(Root, Data) {}
TypeAliasDeclSyntax TypeAliasDeclSyntax::
withTypeAliasKeyword(RC<TokenSyntax> NewTypeAliasKeyword) const {
syntax_assert_token_is(NewTypeAliasKeyword, tok::kw_typealias, "typealias");
return Data->replaceChild<TypeAliasDeclSyntax>(NewTypeAliasKeyword,
Cursor::TypeAliasKeyword);
}
TypeAliasDeclSyntax
TypeAliasDeclSyntax::withIdentifier(RC<TokenSyntax> NewIdentifier) const {
assert(NewIdentifier->getTokenKind() == tok::identifier);
return Data->replaceChild<TypeAliasDeclSyntax>(NewIdentifier,
Cursor::Identifier);
}
TypeAliasDeclSyntax TypeAliasDeclSyntax::
withGenericParameterClause(GenericParameterClauseSyntax NewGenericParams)
const {
return Data->replaceChild<TypeAliasDeclSyntax>(NewGenericParams.getRaw(),
Cursor::GenericParameterClause);
}
TypeAliasDeclSyntax
TypeAliasDeclSyntax::withEqualToken(RC<TokenSyntax> NewEqualToken) const {
syntax_assert_token_is(NewEqualToken, tok::equal, "=");
return Data->replaceChild<TypeAliasDeclSyntax>(NewEqualToken,
Cursor::EqualToken);
}
TypeAliasDeclSyntax
TypeAliasDeclSyntax::withTypeSyntax(TypeSyntax NewType) const {
return Data->replaceChild<TypeAliasDeclSyntax>(NewType.getRaw(),
Cursor::Type);
}
#pragma mark - type-alias Builder
TypeAliasDeclSyntaxBuilder::TypeAliasDeclSyntaxBuilder()
: TypeAliasLayout(SyntaxFactory::makeBlankTypealiasDecl().getRaw()->Layout)
{}
TypeAliasDeclSyntaxBuilder &TypeAliasDeclSyntaxBuilder::
useTypeAliasKeyword(RC<TokenSyntax> TypeAliasKeyword) {
syntax_assert_token_is(TypeAliasKeyword, tok::kw_typealias, "typealias");
auto Index = cursorIndex(TypeAliasDeclSyntax::Cursor::TypeAliasKeyword);
TypeAliasLayout[Index] = TypeAliasKeyword;
return *this;
}
TypeAliasDeclSyntaxBuilder &
TypeAliasDeclSyntaxBuilder::useIdentifier(RC<TokenSyntax> Identifier) {
assert(Identifier->getTokenKind() == tok::identifier);
auto Index = cursorIndex(TypeAliasDeclSyntax::Cursor::Identifier);
TypeAliasLayout[Index] = Identifier;
return *this;
}
TypeAliasDeclSyntaxBuilder &TypeAliasDeclSyntaxBuilder::
useGenericParameterClause(GenericParameterClauseSyntax GenericParams) {
auto Index = cursorIndex(TypeAliasDeclSyntax::Cursor::GenericParameterClause);
TypeAliasLayout[Index] = GenericParams.getRaw();
return *this;
}
TypeAliasDeclSyntaxBuilder &
TypeAliasDeclSyntaxBuilder::useEqualToken(RC<TokenSyntax> EqualToken) {
auto Index = cursorIndex(TypeAliasDeclSyntax::Cursor::EqualToken);
TypeAliasLayout[Index] = EqualToken;
return *this;
}
TypeAliasDeclSyntaxBuilder &
TypeAliasDeclSyntaxBuilder::useType(TypeSyntax ReferentType) {
auto Index = cursorIndex(TypeAliasDeclSyntax::Cursor::Type);
TypeAliasLayout[Index] = ReferentType.getRaw();
return *this;
}
TypeAliasDeclSyntax TypeAliasDeclSyntaxBuilder::build() const {
auto Raw = RawSyntax::make(SyntaxKind::TypeAliasDecl, TypeAliasLayout,
SourcePresence::Present);
auto Data = TypeAliasDeclSyntaxData::make(Raw);
return { Data, Data.get() };
}