mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This mostly wraps up the first cut of function-declaration. https://bugs.swift.org/browse/SR-4043
1036 lines
38 KiB
C++
1036 lines
38 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/ExprSyntax.h"
|
|
#include "swift/Syntax/GenericSyntax.h"
|
|
#include "swift/Syntax/RawSyntax.h"
|
|
#include "swift/Syntax/StmtSyntax.h"
|
|
#include "swift/Syntax/SyntaxFactory.h"
|
|
#include "swift/Syntax/TypeSyntax.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 - declaration-modifier Data
|
|
|
|
DeclModifierSyntaxData::
|
|
DeclModifierSyntaxData(const RC<RawSyntax> Raw,
|
|
const SyntaxData *Parent,
|
|
const CursorIndex IndexInParent)
|
|
: SyntaxData(Raw, Parent, IndexInParent) {
|
|
assert(Raw->Kind == SyntaxKind::DeclModifier);
|
|
assert(Raw->Layout.size() == 4);
|
|
#ifndef NDEBUG
|
|
auto Name =
|
|
cast<TokenSyntax>(Raw->getChild(DeclModifierSyntax::Cursor::Name));
|
|
auto Kind = Name->getTokenKind();
|
|
assert(Kind == tok::kw_class ||
|
|
Kind == tok::kw_static ||
|
|
Kind == tok::identifier ||
|
|
Kind == tok::kw_public ||
|
|
Kind == tok::kw_private ||
|
|
Kind == tok::kw_fileprivate ||
|
|
Kind == tok::kw_internal);
|
|
#endif
|
|
syntax_assert_child_token_text(Raw, DeclModifierSyntax::Cursor::LeftParen,
|
|
tok::l_paren, "(");
|
|
syntax_assert_child_token(Raw, DeclModifierSyntax::Cursor::Argument,
|
|
tok::identifier);
|
|
syntax_assert_child_token_text(Raw, DeclModifierSyntax::Cursor::RightParen,
|
|
tok::r_paren, ")");
|
|
}
|
|
|
|
RC<DeclModifierSyntaxData>
|
|
DeclModifierSyntaxData::make(const RC<RawSyntax> Raw,
|
|
const SyntaxData *Parent,
|
|
const CursorIndex IndexInParent) {
|
|
return RC<DeclModifierSyntaxData>{
|
|
new DeclModifierSyntaxData {
|
|
Raw, Parent, IndexInParent
|
|
}
|
|
};
|
|
}
|
|
|
|
RC<DeclModifierSyntaxData> DeclModifierSyntaxData::makeBlank() {
|
|
auto Raw = RawSyntax::make(SyntaxKind::DeclModifier,
|
|
{
|
|
TokenSyntax::missingToken(tok::identifier, ""),
|
|
TokenSyntax::missingToken(tok::l_paren, "("),
|
|
TokenSyntax::missingToken(tok::identifier, ""),
|
|
TokenSyntax::missingToken(tok::r_paren, ")"),
|
|
},
|
|
SourcePresence::Present);
|
|
return make(Raw);
|
|
}
|
|
|
|
#pragma mark - declaration-modifier API
|
|
|
|
RC<TokenSyntax> DeclModifierSyntax::getName() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::Name));
|
|
}
|
|
|
|
DeclModifierSyntax DeclModifierSyntax::withName(RC<TokenSyntax> NewName) const {
|
|
assert(NewName->getTokenKind() == tok::identifier);
|
|
return Data->replaceChild<DeclModifierSyntax>(NewName, Cursor::Name);
|
|
}
|
|
|
|
RC<TokenSyntax> DeclModifierSyntax::getLeftParenToken() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::LeftParen));
|
|
}
|
|
|
|
DeclModifierSyntax
|
|
DeclModifierSyntax::withLeftParenToken(RC<TokenSyntax> NewLeftParen) const {
|
|
syntax_assert_token_is(NewLeftParen, tok::l_paren, "(");
|
|
return Data->replaceChild<DeclModifierSyntax>(NewLeftParen,
|
|
Cursor::LeftParen);
|
|
}
|
|
|
|
RC<TokenSyntax> DeclModifierSyntax::getArgument() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::Argument));
|
|
}
|
|
|
|
DeclModifierSyntax
|
|
DeclModifierSyntax::withArgument(RC<TokenSyntax> NewArgument) const {
|
|
assert(NewArgument->getTokenKind() == tok::identifier);
|
|
return Data->replaceChild<DeclModifierSyntax>(NewArgument, Cursor::Argument);
|
|
}
|
|
|
|
RC<TokenSyntax> DeclModifierSyntax::getRightParenToken() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::RightParen));
|
|
}
|
|
|
|
DeclModifierSyntax
|
|
DeclModifierSyntax::withRightParenToken(RC<TokenSyntax> NewRightParen) const {
|
|
syntax_assert_token_is(NewRightParen, tok::r_paren, ")");
|
|
return Data->replaceChild<DeclModifierSyntax>(NewRightParen,
|
|
Cursor::RightParen);
|
|
}
|
|
|
|
#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() };
|
|
}
|
|
|
|
#pragma mark - function-parameter Data
|
|
|
|
FunctionParameterSyntaxData::FunctionParameterSyntaxData(RC<RawSyntax> Raw,
|
|
const SyntaxData *Parent,
|
|
CursorIndex IndexInParent)
|
|
: SyntaxData(Raw, Parent, IndexInParent) {
|
|
assert(Raw->Layout.size() == 8);
|
|
syntax_assert_child_token(Raw, FunctionParameterSyntax::Cursor::ExternalName,
|
|
tok::identifier);
|
|
syntax_assert_child_token(Raw, FunctionParameterSyntax::Cursor::LocalName,
|
|
tok::identifier);
|
|
syntax_assert_child_token_text(Raw, FunctionParameterSyntax::Cursor::Colon,
|
|
tok::colon, ":");
|
|
assert(Raw->getChild(FunctionParameterSyntax::Cursor::Type)->isType());
|
|
syntax_assert_child_token_text(Raw, FunctionParameterSyntax::Cursor::Ellipsis,
|
|
tok::identifier, "...");
|
|
syntax_assert_child_token_text(Raw,
|
|
FunctionParameterSyntax::Cursor::DefaultEqual,
|
|
tok::equal, "=");
|
|
assert(Raw->getChild(
|
|
FunctionParameterSyntax::Cursor::DefaultExpression)->isExpr());
|
|
syntax_assert_child_token_text(Raw,
|
|
FunctionParameterSyntax::Cursor::TrailingComma,
|
|
tok::comma, ",");
|
|
}
|
|
|
|
RC<FunctionParameterSyntaxData>
|
|
FunctionParameterSyntaxData::make(RC<RawSyntax> Raw, const SyntaxData *Parent,
|
|
CursorIndex IndexInParent) {
|
|
return RC<FunctionParameterSyntaxData> {
|
|
new FunctionParameterSyntaxData {
|
|
Raw, Parent, IndexInParent
|
|
}
|
|
};
|
|
}
|
|
|
|
RC<FunctionParameterSyntaxData> FunctionParameterSyntaxData::makeBlank() {
|
|
auto Raw = RawSyntax::make(SyntaxKind::FunctionParameter,
|
|
{
|
|
TokenSyntax::missingToken(tok::identifier, ""),
|
|
TokenSyntax::missingToken(tok::identifier, ""),
|
|
TokenSyntax::missingToken(tok::colon, ":"),
|
|
RawSyntax::missing(SyntaxKind::MissingType),
|
|
TokenSyntax::missingToken(tok::identifier, "..."),
|
|
TokenSyntax::missingToken(tok::equal, "="),
|
|
RawSyntax::missing(SyntaxKind::MissingExpr),
|
|
TokenSyntax::missingToken(tok::comma, ","),
|
|
},
|
|
SourcePresence::Present);
|
|
return make(Raw);
|
|
}
|
|
|
|
|
|
#pragma mark - function-parameter API
|
|
|
|
RC<TokenSyntax> FunctionParameterSyntax::getExternalName() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::ExternalName));
|
|
}
|
|
|
|
FunctionParameterSyntax FunctionParameterSyntax::
|
|
withExternalName(RC<TokenSyntax> NewExternalName) const {
|
|
assert(NewExternalName->getTokenKind() == tok::identifier);
|
|
return Data->replaceChild<FunctionParameterSyntax>(NewExternalName,
|
|
Cursor::ExternalName);
|
|
}
|
|
|
|
RC<TokenSyntax> FunctionParameterSyntax::getLocalName() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::LocalName));
|
|
}
|
|
|
|
FunctionParameterSyntax FunctionParameterSyntax::
|
|
withLocalName(RC<TokenSyntax> NewLocalName) const {
|
|
assert(NewLocalName->getTokenKind() == tok::identifier);
|
|
return Data->replaceChild<FunctionParameterSyntax>(NewLocalName,
|
|
Cursor::LocalName);
|
|
}
|
|
|
|
RC<TokenSyntax> FunctionParameterSyntax::getColonToken() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::Colon));
|
|
}
|
|
|
|
FunctionParameterSyntax FunctionParameterSyntax::
|
|
withColonToken(RC<TokenSyntax> NewColonToken) const {
|
|
syntax_assert_token_is(NewColonToken, tok::colon, ":");
|
|
return Data->replaceChild<FunctionParameterSyntax>(NewColonToken,
|
|
Cursor::Colon);
|
|
}
|
|
|
|
llvm::Optional<TypeSyntax> FunctionParameterSyntax::getTypeSyntax() const {
|
|
auto RawType = getRaw()->getChild(Cursor::Type);
|
|
if (RawType->isMissing()) {
|
|
return llvm::None;
|
|
}
|
|
|
|
auto *MyData = getUnsafeData<FunctionParameterSyntax>();
|
|
|
|
if (MyData->CachedTypeSyntax) {
|
|
return TypeSyntax { Root, MyData->CachedTypeSyntax.get() };
|
|
}
|
|
|
|
auto &ChildPtr = *reinterpret_cast<std::atomic<uintptr_t>*>(
|
|
&MyData->CachedTypeSyntax);
|
|
|
|
SyntaxData::realizeSyntaxNode<TypeSyntax>(ChildPtr, RawType, MyData,
|
|
cursorIndex(Cursor::Type));
|
|
|
|
return TypeSyntax { Root, MyData->CachedTypeSyntax.get() };
|
|
}
|
|
|
|
FunctionParameterSyntax FunctionParameterSyntax::
|
|
withTypeSyntax(llvm::Optional<TypeSyntax> NewType) const {
|
|
if (!NewType.hasValue()) {
|
|
auto RawType = RawSyntax::missing(SyntaxKind::MissingType);
|
|
return Data->replaceChild<FunctionParameterSyntax>(RawType, Cursor::Type);
|
|
}
|
|
|
|
return Data->replaceChild<FunctionParameterSyntax>(
|
|
NewType.getValue().getRaw(), Cursor::Type);
|
|
}
|
|
|
|
RC<TokenSyntax> FunctionParameterSyntax::getEqualToken() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::DefaultEqual));
|
|
}
|
|
|
|
FunctionParameterSyntax FunctionParameterSyntax::
|
|
withEqualToken(RC<TokenSyntax> NewEqualToken) const {
|
|
assert(NewEqualToken->getTokenKind() == tok::equal);
|
|
return Data->replaceChild<FunctionParameterSyntax>(NewEqualToken,
|
|
Cursor::DefaultEqual);
|
|
}
|
|
|
|
llvm::Optional<ExprSyntax> FunctionParameterSyntax::getDefaultValue() const {
|
|
auto RawExpr = getRaw()->getChild(Cursor::DefaultExpression);
|
|
if (RawExpr->isMissing()) {
|
|
return llvm::None;
|
|
}
|
|
|
|
auto *MyData = getUnsafeData<FunctionParameterSyntax>();
|
|
|
|
if (MyData->CachedTypeSyntax) {
|
|
return ExprSyntax { Root, MyData->CachedDefaultValue.get() };
|
|
}
|
|
|
|
auto &ChildPtr = *reinterpret_cast<std::atomic<uintptr_t>*>(
|
|
&MyData->CachedDefaultValue);
|
|
|
|
SyntaxData::realizeSyntaxNode<TypeSyntax>(ChildPtr, RawExpr, MyData,
|
|
cursorIndex(Cursor::DefaultExpression));
|
|
|
|
return ExprSyntax { Root, MyData->CachedDefaultValue.get() };
|
|
}
|
|
|
|
FunctionParameterSyntax FunctionParameterSyntax::
|
|
withDefaultValue(llvm::Optional<ExprSyntax> NewDefaultValue) const {
|
|
if (!NewDefaultValue.hasValue()) {
|
|
auto RawType = RawSyntax::missing(SyntaxKind::MissingExpr);
|
|
return Data->replaceChild<FunctionParameterSyntax>(RawType,
|
|
Cursor::DefaultExpression);
|
|
}
|
|
|
|
return Data->replaceChild<FunctionParameterSyntax>(
|
|
NewDefaultValue.getValue().getRaw(), Cursor::DefaultExpression);
|
|
}
|
|
|
|
RC<TokenSyntax> FunctionParameterSyntax::getTrailingComma() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::TrailingComma));
|
|
}
|
|
|
|
FunctionParameterSyntax FunctionParameterSyntax::
|
|
withTrailingComma(RC<TokenSyntax> NewTrailingComma) const {
|
|
syntax_assert_token_is(NewTrailingComma, tok::comma, ",");
|
|
return Data->replaceChild<FunctionParameterSyntax>(NewTrailingComma,
|
|
Cursor::TrailingComma);
|
|
}
|
|
|
|
#pragma mark - function-signature Data
|
|
|
|
FunctionSignatureSyntaxData::
|
|
FunctionSignatureSyntaxData(const RC<RawSyntax> Raw,
|
|
const SyntaxData *Parent,
|
|
const CursorIndex IndexInParent)
|
|
: SyntaxData(Raw, Parent, IndexInParent) {
|
|
assert(Raw->Layout.size() == 7);
|
|
syntax_assert_child_token_text(Raw,
|
|
FunctionSignatureSyntax::Cursor::LeftParen,
|
|
tok::l_paren, "(");
|
|
|
|
assert(Raw->getChild(FunctionSignatureSyntax::Cursor::ParameterList)->Kind ==
|
|
SyntaxKind::FunctionParameterList);
|
|
|
|
syntax_assert_child_token_text(Raw,
|
|
FunctionSignatureSyntax::Cursor::RightParen,
|
|
tok::r_paren, ")");
|
|
#ifndef NDEBUG
|
|
auto ThrowsRethrows = cast<TokenSyntax>(
|
|
Raw->getChild(FunctionSignatureSyntax::Cursor::ThrowsOrRethrows));
|
|
assert(cast<TokenSyntax>(ThrowsRethrows)->getTokenKind() == tok::kw_throws ||
|
|
cast<TokenSyntax>(ThrowsRethrows)->getTokenKind() == tok::kw_rethrows);
|
|
#endif
|
|
syntax_assert_child_token_text(Raw, FunctionSignatureSyntax::Cursor::Arrow,
|
|
tok::arrow, "->");
|
|
syntax_assert_child_kind(Raw,
|
|
FunctionSignatureSyntax::Cursor::ReturnTypeAttributes,
|
|
SyntaxKind::TypeAttributes);
|
|
assert(Raw->getChild(FunctionSignatureSyntax::Cursor::ReturnType)->isType());
|
|
}
|
|
|
|
RC<FunctionSignatureSyntaxData>
|
|
FunctionSignatureSyntaxData::make(RC<RawSyntax> Raw, const SyntaxData *Parent,
|
|
CursorIndex IndexInParent) {
|
|
return RC<FunctionSignatureSyntaxData> {
|
|
new FunctionSignatureSyntaxData {
|
|
Raw, Parent, IndexInParent
|
|
}
|
|
};
|
|
}
|
|
|
|
RC<FunctionSignatureSyntaxData> FunctionSignatureSyntaxData::makeBlank() {
|
|
auto Raw = RawSyntax::make(SyntaxKind::FunctionSignature,
|
|
{
|
|
TokenSyntax::missingToken(tok::l_paren, "("),
|
|
RawSyntax::missing(SyntaxKind::FunctionParameterList),
|
|
TokenSyntax::missingToken(tok::r_paren, ")"),
|
|
TokenSyntax::missingToken(tok::kw_throws, "throws"),
|
|
TokenSyntax::missingToken(tok::arrow, "->"),
|
|
RawSyntax::missing(SyntaxKind::TypeAttributes),
|
|
RawSyntax::missing(SyntaxKind::MissingType),
|
|
},
|
|
SourcePresence::Present);
|
|
return make(Raw);
|
|
}
|
|
|
|
#pragma mark - function-signature API
|
|
|
|
RC<TokenSyntax> FunctionSignatureSyntax::getLeftParenToken() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::LeftParen));
|
|
}
|
|
|
|
FunctionSignatureSyntax FunctionSignatureSyntax::
|
|
withLeftParenToken(RC<TokenSyntax> NewLeftParen) const {
|
|
syntax_assert_token_is(NewLeftParen, tok::l_paren, "(");
|
|
return Data->replaceChild<FunctionSignatureSyntax>(NewLeftParen,
|
|
Cursor::LeftParen);
|
|
}
|
|
|
|
FunctionParameterListSyntax FunctionSignatureSyntax::getParameterList() const {
|
|
auto RawList = getRaw()->getChild(Cursor::ParameterList);
|
|
|
|
auto *MyData = getUnsafeData<FunctionSignatureSyntax>();
|
|
|
|
auto &ChildPtr = *reinterpret_cast<std::atomic<uintptr_t>*>(
|
|
&MyData->CachedParameterList);
|
|
|
|
SyntaxData::realizeSyntaxNode<FunctionParameterListSyntax>(ChildPtr, RawList,
|
|
MyData, cursorIndex(Cursor::ParameterList));
|
|
|
|
return FunctionParameterListSyntax {
|
|
Root,
|
|
MyData->CachedParameterList.get()
|
|
};
|
|
}
|
|
|
|
FunctionSignatureSyntax FunctionSignatureSyntax::
|
|
withParameterList(FunctionParameterListSyntax NewParameterList) const {
|
|
return Data->replaceChild<FunctionSignatureSyntax>(NewParameterList.getRaw(),
|
|
Cursor::ParameterList);
|
|
}
|
|
|
|
RC<TokenSyntax> FunctionSignatureSyntax::getRightParenToken() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::RightParen));
|
|
}
|
|
|
|
FunctionSignatureSyntax FunctionSignatureSyntax::
|
|
withRightParenToken(RC<TokenSyntax> NewRightParen) const {
|
|
syntax_assert_token_is(NewRightParen, tok::r_paren, ")");
|
|
return Data->replaceChild<FunctionSignatureSyntax>(NewRightParen,
|
|
Cursor::RightParen);
|
|
}
|
|
|
|
RC<TokenSyntax> FunctionSignatureSyntax::getThrowsToken() const {
|
|
auto Throw = cast<TokenSyntax>(getRaw()->getChild(Cursor::ThrowsOrRethrows));
|
|
if (Throw->getTokenKind() != tok::kw_throws) {
|
|
return TokenSyntax::missingToken(tok::kw_throws, "throws");
|
|
}
|
|
return Throw;
|
|
}
|
|
|
|
FunctionSignatureSyntax FunctionSignatureSyntax::
|
|
withThrowsToken(RC<TokenSyntax> NewThrowsToken) const {
|
|
syntax_assert_token_is(NewThrowsToken, tok::kw_throws, "throws");
|
|
return Data->replaceChild<FunctionSignatureSyntax>(NewThrowsToken,
|
|
Cursor::ThrowsOrRethrows);
|
|
}
|
|
|
|
RC<TokenSyntax> FunctionSignatureSyntax::getRethrowsToken() const {
|
|
auto Rethrow = cast<TokenSyntax>(
|
|
getRaw()->getChild(Cursor::ThrowsOrRethrows));
|
|
if (Rethrow->getTokenKind() != tok::kw_rethrows) {
|
|
return TokenSyntax::missingToken(tok::kw_rethrows, "rethrows");
|
|
}
|
|
return Rethrow;
|
|
}
|
|
|
|
FunctionSignatureSyntax FunctionSignatureSyntax::
|
|
withRethrowsToken(RC<TokenSyntax> NewRethrowsToken) const {
|
|
syntax_assert_token_is(NewRethrowsToken, tok::kw_rethrows, "rethrows");
|
|
return Data->replaceChild<FunctionSignatureSyntax>(NewRethrowsToken,
|
|
Cursor::ThrowsOrRethrows);
|
|
}
|
|
|
|
RC<TokenSyntax> FunctionSignatureSyntax::getArrowToken() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::Arrow));
|
|
}
|
|
|
|
FunctionSignatureSyntax FunctionSignatureSyntax::
|
|
withArrowToken(RC<TokenSyntax> NewArrowToken) const {
|
|
syntax_assert_token_is(NewArrowToken, tok::arrow, "->");
|
|
return Data->replaceChild<FunctionSignatureSyntax>(NewArrowToken,
|
|
Cursor::Arrow);
|
|
}
|
|
|
|
TypeAttributesSyntax FunctionSignatureSyntax::getReturnTypeAttributes() const {
|
|
auto RawAttrs = getRaw()->getChild(Cursor::ReturnTypeAttributes);
|
|
|
|
auto *MyData = getUnsafeData<FunctionSignatureSyntax>();
|
|
|
|
auto &ChildPtr = *reinterpret_cast<std::atomic<uintptr_t>*>(
|
|
&MyData->CachedReturnTypeAttributes);
|
|
|
|
SyntaxData::realizeSyntaxNode<TypeAttributesSyntax>(ChildPtr, RawAttrs,
|
|
MyData, cursorIndex(Cursor::ReturnTypeAttributes));
|
|
|
|
return TypeAttributesSyntax {
|
|
Root,
|
|
MyData->CachedReturnTypeAttributes.get()
|
|
};
|
|
}
|
|
|
|
FunctionSignatureSyntax FunctionSignatureSyntax::
|
|
withReturnTypeAttributes(TypeAttributesSyntax NewAttributes) const {
|
|
return Data->replaceChild<FunctionSignatureSyntax>(NewAttributes.getRaw(),
|
|
Cursor::ReturnTypeAttributes);
|
|
}
|
|
|
|
TypeSyntax FunctionSignatureSyntax::getReturnTypeSyntax() const {
|
|
auto RawType = getRaw()->getChild(Cursor::ReturnType);
|
|
|
|
auto *MyData = getUnsafeData<FunctionSignatureSyntax>();
|
|
|
|
auto &ChildPtr = *reinterpret_cast<std::atomic<uintptr_t>*>(
|
|
&MyData->CachedReturnTypeSyntax);
|
|
|
|
SyntaxData::realizeSyntaxNode<TypeSyntax>(ChildPtr, RawType,
|
|
MyData, cursorIndex(Cursor::ReturnType));
|
|
|
|
return TypeSyntax {
|
|
Root,
|
|
MyData->CachedReturnTypeSyntax.get()
|
|
};
|
|
}
|
|
|
|
FunctionSignatureSyntax FunctionSignatureSyntax::
|
|
withReturnTypeSyntax(TypeSyntax NewReturnTypeSyntax) const {
|
|
return Data->replaceChild<FunctionSignatureSyntax>(
|
|
NewReturnTypeSyntax.getRaw(), Cursor::ReturnType);
|
|
}
|
|
|
|
#pragma mark - function-declaration-data
|
|
|
|
FunctionDeclSyntaxData::
|
|
FunctionDeclSyntaxData(const RC<RawSyntax> Raw,
|
|
const SyntaxData *Parent,
|
|
const CursorIndex IndexInParent)
|
|
: SyntaxData(Raw, Parent, IndexInParent) {
|
|
assert(Raw->Kind == SyntaxKind::FunctionDecl);
|
|
assert(Raw->Layout.size() == 8);
|
|
syntax_assert_child_kind(Raw, FunctionDeclSyntax::Cursor::Attributes,
|
|
SyntaxKind::TypeAttributes);
|
|
syntax_assert_child_kind(Raw, FunctionDeclSyntax::Cursor::Modifiers,
|
|
SyntaxKind::DeclModifierList);
|
|
syntax_assert_child_token_text(Raw, FunctionDeclSyntax::Cursor::FuncKeyword,
|
|
tok::kw_func, "func");
|
|
syntax_assert_child_token(Raw, FunctionDeclSyntax::Cursor::Identifier,
|
|
tok::identifier);
|
|
syntax_assert_child_kind(Raw,
|
|
FunctionDeclSyntax::Cursor::GenericParameterClause,
|
|
SyntaxKind::GenericParameterClause);
|
|
syntax_assert_child_kind(Raw, FunctionDeclSyntax::Cursor::Signature,
|
|
SyntaxKind::FunctionSignature);
|
|
syntax_assert_child_kind(Raw, FunctionDeclSyntax::Cursor::GenericWhereClause,
|
|
SyntaxKind::GenericWhereClause);
|
|
syntax_assert_child_kind(Raw, FunctionDeclSyntax::Cursor::Body,
|
|
SyntaxKind::CodeBlockStmt);
|
|
}
|
|
|
|
RC<FunctionDeclSyntaxData> FunctionDeclSyntaxData::make(const RC<RawSyntax> Raw,
|
|
const SyntaxData *Parent,
|
|
const CursorIndex IndexInParent) {
|
|
return RC<FunctionDeclSyntaxData> {
|
|
new FunctionDeclSyntaxData {
|
|
Raw, Parent, IndexInParent
|
|
}
|
|
};
|
|
}
|
|
|
|
RC<FunctionDeclSyntaxData> FunctionDeclSyntaxData::makeBlank() {
|
|
auto Raw = RawSyntax::make(SyntaxKind::FunctionDecl,
|
|
{
|
|
RawSyntax::missing(SyntaxKind::TypeAttributes),
|
|
RawSyntax::missing(SyntaxKind::DeclModifierList),
|
|
TokenSyntax::missingToken(tok::kw_func, "func"),
|
|
TokenSyntax::missingToken(tok::identifier, ""),
|
|
RawSyntax::missing(SyntaxKind::GenericParameterClause),
|
|
RawSyntax::missing(SyntaxKind::FunctionSignature),
|
|
RawSyntax::missing(SyntaxKind::GenericWhereClause),
|
|
RawSyntax::missing(SyntaxKind::CodeBlockStmt),
|
|
},
|
|
SourcePresence::Present);
|
|
return make(Raw);
|
|
}
|
|
|
|
#pragma mark - function-declaration-API
|
|
|
|
TypeAttributesSyntax FunctionDeclSyntax::getAttributes() const {
|
|
auto RawAttrs = getRaw()->getChild(Cursor::Attributes);
|
|
|
|
auto *MyData = getUnsafeData<FunctionDeclSyntax>();
|
|
|
|
auto &ChildPtr = *reinterpret_cast<std::atomic<uintptr_t>*>(
|
|
&MyData->CachedAttributes);
|
|
|
|
SyntaxData::realizeSyntaxNode<ExprSyntax>(ChildPtr, RawAttrs, MyData,
|
|
cursorIndex(Cursor::Attributes));
|
|
|
|
return { Root, MyData->CachedAttributes.get() };
|
|
}
|
|
|
|
FunctionDeclSyntax
|
|
FunctionDeclSyntax::withAttributes(TypeAttributesSyntax NewAttributes) const {
|
|
return Data->replaceChild<FunctionDeclSyntax>(NewAttributes.getRaw(),
|
|
Cursor::Attributes);
|
|
}
|
|
|
|
DeclModifierListSyntax FunctionDeclSyntax::getModifiers() const {
|
|
auto RawModifiers = getRaw()->getChild(Cursor::Attributes);
|
|
|
|
auto *MyData = getUnsafeData<FunctionDeclSyntax>();
|
|
|
|
auto &ChildPtr = *reinterpret_cast<std::atomic<uintptr_t>*>(
|
|
&MyData->CachedModifiers);
|
|
|
|
SyntaxData::realizeSyntaxNode<DeclModifierListSyntax>(ChildPtr, RawModifiers,
|
|
MyData, cursorIndex(Cursor::Modifiers));
|
|
|
|
return { Root, MyData->CachedModifiers.get() };
|
|
}
|
|
|
|
FunctionDeclSyntax
|
|
FunctionDeclSyntax::withModifiers(DeclModifierListSyntax NewModifiers) const {
|
|
return Data->replaceChild<FunctionDeclSyntax>(NewModifiers.getRaw(),
|
|
Cursor::Modifiers);
|
|
}
|
|
|
|
RC<TokenSyntax> FunctionDeclSyntax::getFuncKeyword() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::FuncKeyword));
|
|
}
|
|
|
|
FunctionDeclSyntax
|
|
FunctionDeclSyntax::withFuncKeyword(RC<TokenSyntax> NewFuncKeyword) const {
|
|
syntax_assert_token_is(NewFuncKeyword, tok::kw_func, "func");
|
|
return Data->replaceChild<FunctionDeclSyntax>(NewFuncKeyword,
|
|
Cursor::FuncKeyword);
|
|
|
|
}
|
|
|
|
RC<TokenSyntax> FunctionDeclSyntax::getIdentifier() const {
|
|
return cast<TokenSyntax>(getRaw()->getChild(Cursor::Identifier));
|
|
}
|
|
|
|
FunctionDeclSyntax
|
|
FunctionDeclSyntax::withIdentifier(RC<TokenSyntax> NewIdentifier) const {
|
|
assert(NewIdentifier->getTokenKind() == tok::identifier);
|
|
return Data->replaceChild<FunctionDeclSyntax>(NewIdentifier,
|
|
Cursor::Identifier);
|
|
}
|
|
|
|
llvm::Optional<GenericParameterClauseSyntax>
|
|
FunctionDeclSyntax::getGenericParameterClause() const {
|
|
auto RawGenericParams = getRaw()->getChild(Cursor::Attributes);
|
|
if (RawGenericParams->isMissing()) {
|
|
return llvm::None;
|
|
}
|
|
|
|
auto *MyData = getUnsafeData<FunctionDeclSyntax>();
|
|
|
|
auto &ChildPtr = *reinterpret_cast<std::atomic<uintptr_t>*>(
|
|
&MyData->CachedGenericParams);
|
|
|
|
SyntaxData::realizeSyntaxNode<DeclModifierListSyntax>(ChildPtr,
|
|
RawGenericParams, MyData, cursorIndex(Cursor::GenericParameterClause));
|
|
|
|
GenericParameterClauseSyntax Params {
|
|
Root,
|
|
MyData->CachedGenericParams.get()
|
|
};
|
|
|
|
return Params;
|
|
}
|
|
|
|
FunctionDeclSyntax FunctionDeclSyntax::withGenericParameterClause(
|
|
llvm::Optional<GenericParameterClauseSyntax> NewGenericParams) const {
|
|
auto RawParams = NewGenericParams.hasValue()
|
|
? NewGenericParams->getRaw()
|
|
: SyntaxFactory::makeBlankGenericParameterClause().getRaw();
|
|
return Data->replaceChild<FunctionDeclSyntax>(RawParams,
|
|
Cursor::GenericParameterClause);
|
|
|
|
}
|
|
|
|
FunctionSignatureSyntax FunctionDeclSyntax::getSignature() const {
|
|
auto RawSig = getRaw()->getChild(Cursor::Attributes);
|
|
|
|
auto *MyData = getUnsafeData<FunctionDeclSyntax>();
|
|
|
|
auto &ChildPtr = *reinterpret_cast<std::atomic<uintptr_t>*>(
|
|
&MyData->CachedSignature);
|
|
|
|
SyntaxData::realizeSyntaxNode<FunctionSignatureSyntax>(ChildPtr, RawSig,
|
|
MyData, cursorIndex(Cursor::Signature));
|
|
|
|
return { Root, MyData->CachedSignature.get() };
|
|
}
|
|
|
|
FunctionDeclSyntax
|
|
FunctionDeclSyntax::withSignature(FunctionSignatureSyntax NewSignature) const {
|
|
return Data->replaceChild<FunctionDeclSyntax>(NewSignature.getRaw(),
|
|
Cursor::Signature);
|
|
}
|
|
|
|
llvm::Optional<CodeBlockStmtSyntax> FunctionDeclSyntax::getBody() const {
|
|
auto RawBody = getRaw()->getChild(Cursor::Body);
|
|
if (RawBody->isMissing()) {
|
|
return llvm::None;
|
|
}
|
|
|
|
auto *MyData = getUnsafeData<FunctionDeclSyntax>();
|
|
|
|
auto &ChildPtr = *reinterpret_cast<std::atomic<uintptr_t>*>(
|
|
&MyData->CachedBody);
|
|
|
|
SyntaxData::realizeSyntaxNode<CodeBlockStmtSyntax>(ChildPtr,
|
|
RawBody, MyData, cursorIndex(Cursor::Body));
|
|
|
|
CodeBlockStmtSyntax Body {
|
|
Root,
|
|
MyData->CachedBody.get()
|
|
};
|
|
|
|
return Body;
|
|
}
|
|
|
|
FunctionDeclSyntax FunctionDeclSyntax::
|
|
withBody(llvm::Optional<CodeBlockStmtSyntax> NewBody) const {
|
|
auto RawBody = NewBody.hasValue()
|
|
? NewBody->getRaw()
|
|
: SyntaxFactory::makeBlankCodeBlock().getRaw();
|
|
return Data->replaceChild<FunctionDeclSyntax>(RawBody,
|
|
Cursor::Body);
|
|
}
|