mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Implement function-declaration in lib/Syntax
https://bugs.swift.org/browse/SR-4043
This commit is contained in:
@@ -18,7 +18,6 @@
|
|||||||
#ifndef SWIFT_SYNTAX_DECLSYNTAX_H
|
#ifndef SWIFT_SYNTAX_DECLSYNTAX_H
|
||||||
#define SWIFT_SYNTAX_DECLSYNTAX_H
|
#define SWIFT_SYNTAX_DECLSYNTAX_H
|
||||||
|
|
||||||
#include "swift/Syntax/GenericSyntax.h"
|
|
||||||
#include "swift/Syntax/References.h"
|
#include "swift/Syntax/References.h"
|
||||||
#include "swift/Syntax/RawSyntax.h"
|
#include "swift/Syntax/RawSyntax.h"
|
||||||
#include "swift/Syntax/Syntax.h"
|
#include "swift/Syntax/Syntax.h"
|
||||||
@@ -35,6 +34,15 @@ namespace syntax {
|
|||||||
|
|
||||||
class ExprSyntax;
|
class ExprSyntax;
|
||||||
class ExprSyntaxData;
|
class ExprSyntaxData;
|
||||||
|
class CodeBlockStmtSyntax;
|
||||||
|
class CodeBlockStmtSyntaxData;
|
||||||
|
class TypeAttributesSyntax;
|
||||||
|
class TypeAttributesSyntaxData;
|
||||||
|
class DeclModifierListSyntax;
|
||||||
|
class GenericWhereClauseSyntax;
|
||||||
|
class GenericWhereClauseSyntaxData;
|
||||||
|
class GenericParameterListSyntax;
|
||||||
|
class GenericParameterListSyntaxData;
|
||||||
|
|
||||||
#pragma mark declaration-modifier Data
|
#pragma mark declaration-modifier Data
|
||||||
|
|
||||||
@@ -154,6 +162,7 @@ class DeclModifierListSyntax final :
|
|||||||
friend struct SyntaxFactory;
|
friend struct SyntaxFactory;
|
||||||
friend class Syntax;
|
friend class Syntax;
|
||||||
friend class SyntaxData;
|
friend class SyntaxData;
|
||||||
|
friend class FunctionDeclSyntax;
|
||||||
|
|
||||||
using DataType = DeclModifierListSyntaxData;
|
using DataType = DeclModifierListSyntaxData;
|
||||||
static constexpr SyntaxKind Kind = SyntaxKind::DeclModifierList;
|
static constexpr SyntaxKind Kind = SyntaxKind::DeclModifierList;
|
||||||
@@ -770,6 +779,115 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#pragma mark - function-declaration Data
|
||||||
|
|
||||||
|
class FunctionDeclSyntaxData final : public SyntaxData {
|
||||||
|
friend struct SyntaxFactory;
|
||||||
|
friend class SyntaxData;
|
||||||
|
friend class FunctionDeclSyntax;
|
||||||
|
|
||||||
|
RC<TypeAttributesSyntaxData> CachedAttributes;
|
||||||
|
RC<DeclModifierListSyntaxData> CachedModifiers;
|
||||||
|
RC<GenericParameterClauseSyntaxData> CachedGenericParams;
|
||||||
|
RC<FunctionSignatureSyntaxData> CachedSignature;
|
||||||
|
RC<GenericWhereClauseSyntaxData> CachedGenericWhereClause;
|
||||||
|
RC<CodeBlockStmtSyntaxData> CachedBody;
|
||||||
|
|
||||||
|
FunctionDeclSyntaxData(const RC<RawSyntax> Raw,
|
||||||
|
const SyntaxData *Parent = nullptr,
|
||||||
|
const CursorIndex IndexInParent = 0);
|
||||||
|
|
||||||
|
static RC<FunctionDeclSyntaxData> make(const RC<RawSyntax> Raw,
|
||||||
|
const SyntaxData *Parent = nullptr,
|
||||||
|
const CursorIndex IndexInParent = 0);
|
||||||
|
static RC<FunctionDeclSyntaxData> makeBlank();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static bool classof(const SyntaxData *SD) {
|
||||||
|
return SD->getKind() == SyntaxKind::FunctionDecl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma mark - function-declaration API
|
||||||
|
|
||||||
|
class FunctionDeclSyntax final : public Syntax {
|
||||||
|
friend struct SyntaxFactory;
|
||||||
|
friend class Syntax;
|
||||||
|
friend class SyntaxData;
|
||||||
|
friend class FunctionDeclSyntaxData;
|
||||||
|
|
||||||
|
enum class Cursor : CursorIndex {
|
||||||
|
Attributes,
|
||||||
|
Modifiers,
|
||||||
|
FuncKeyword,
|
||||||
|
Identifier,
|
||||||
|
GenericParameterClause,
|
||||||
|
Signature,
|
||||||
|
GenericWhereClause,
|
||||||
|
Body
|
||||||
|
};
|
||||||
|
|
||||||
|
using DataType = FunctionDeclSyntaxData;
|
||||||
|
|
||||||
|
FunctionDeclSyntax(const RC<SyntaxData> Root, const DataType *Data)
|
||||||
|
: Syntax(Root, Data) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Get the attributes of this function declaration.
|
||||||
|
TypeAttributesSyntax getAttributes() const;
|
||||||
|
|
||||||
|
/// Return a FunctionDeclSyntax with the given attributes.
|
||||||
|
FunctionDeclSyntax withAttributes(TypeAttributesSyntax NewAttributes) const;
|
||||||
|
|
||||||
|
/// Get the modifiers of this function declaration.
|
||||||
|
DeclModifierListSyntax getModifiers() const;
|
||||||
|
|
||||||
|
/// Return a FunctionDeclSyntax with the given modifiers.
|
||||||
|
FunctionDeclSyntax withModifiers(DeclModifierListSyntax NewModifiers) const;
|
||||||
|
|
||||||
|
/// Return the 'func' keyword of tis function declaration.
|
||||||
|
RC<TokenSyntax> getFuncKeyword() const;
|
||||||
|
|
||||||
|
/// Return a FunctionDeclSyntax with the given 'func' keyword.
|
||||||
|
FunctionDeclSyntax withFuncKeyword(RC<TokenSyntax> NewFuncKeyword) const;
|
||||||
|
|
||||||
|
/// Return the identifier of the function declaration.
|
||||||
|
RC<TokenSyntax> getIdentifier() const;
|
||||||
|
|
||||||
|
/// Return a FunctionDeclSyntax with the given identifier.
|
||||||
|
FunctionDeclSyntax withIdentifier(RC<TokenSyntax> NewIdentifier) const;
|
||||||
|
|
||||||
|
/// Return the generic parameter clause of the function declaration, if
|
||||||
|
/// there is one. Otherwise, return llvm::None.
|
||||||
|
llvm::Optional<GenericParameterClauseSyntax>
|
||||||
|
getGenericParameterClause() const;
|
||||||
|
|
||||||
|
/// Return a FunctionDeclSyntax with the given generic parameter clause.
|
||||||
|
/// To remove the generic parameters, pass in llvm::None.
|
||||||
|
FunctionDeclSyntax withGenericParameterClause(
|
||||||
|
llvm::Optional<GenericParameterClauseSyntax> NewGenericParams) const;
|
||||||
|
|
||||||
|
/// Return the signature of the function declaration.
|
||||||
|
FunctionSignatureSyntax getSignature() const;
|
||||||
|
|
||||||
|
/// Return a FunctionDeclSyntax with the given function signature.
|
||||||
|
FunctionDeclSyntax withSignature(FunctionSignatureSyntax NewSignature) const;
|
||||||
|
|
||||||
|
/// Return the body of the function declaration, if there is one.
|
||||||
|
///
|
||||||
|
/// As an example, function declarations in protocols have no body.
|
||||||
|
llvm::Optional<CodeBlockStmtSyntax> getBody() const;
|
||||||
|
|
||||||
|
/// Return a FunctionDeclSyntax with the given body. To remove the body,
|
||||||
|
/// pass in llvm::None.
|
||||||
|
FunctionDeclSyntax
|
||||||
|
withBody(llvm::Optional<CodeBlockStmtSyntax> NewBody) const;
|
||||||
|
|
||||||
|
static bool classof(const Syntax *S) {
|
||||||
|
return S->getKind() == SyntaxKind::FunctionDecl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace syntax
|
} // end namespace syntax
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|
||||||
|
|||||||
@@ -277,9 +277,9 @@ class GenericParameterClauseSyntaxData final : public SyntaxData {
|
|||||||
|
|
||||||
RC<GenericParameterListSyntaxData> CachedGenericParameterList;
|
RC<GenericParameterListSyntaxData> CachedGenericParameterList;
|
||||||
|
|
||||||
GenericParameterClauseSyntaxData(RC<RawSyntax> Raw,
|
GenericParameterClauseSyntaxData(const RC<RawSyntax> Raw,
|
||||||
const SyntaxData *Parent = nullptr,
|
const SyntaxData *Parent = nullptr,
|
||||||
CursorIndex IndexInParent = 0);
|
const CursorIndex IndexInParent = 0);
|
||||||
static RC<GenericParameterClauseSyntaxData>
|
static RC<GenericParameterClauseSyntaxData>
|
||||||
make(RC<RawSyntax> Raw,
|
make(RC<RawSyntax> Raw,
|
||||||
const SyntaxData *Parent = nullptr,
|
const SyntaxData *Parent = nullptr,
|
||||||
@@ -299,6 +299,8 @@ class GenericParameterClauseSyntax final : public Syntax {
|
|||||||
friend struct SyntaxFactory;
|
friend struct SyntaxFactory;
|
||||||
friend class GenericParameterClauseSyntaxData;
|
friend class GenericParameterClauseSyntaxData;
|
||||||
friend class GenericParameterClauseBuilder;
|
friend class GenericParameterClauseBuilder;
|
||||||
|
friend class FunctionDeclSyntax;
|
||||||
|
|
||||||
enum class Cursor : CursorIndex {
|
enum class Cursor : CursorIndex {
|
||||||
LeftAngleBracketToken,
|
LeftAngleBracketToken,
|
||||||
GenericParameterList,
|
GenericParameterList,
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "swift/Syntax/References.h"
|
#include "swift/Syntax/References.h"
|
||||||
#include "swift/Syntax/DeclSyntax.h"
|
#include "swift/Syntax/DeclSyntax.h"
|
||||||
|
#include "swift/Syntax/GenericSyntax.h"
|
||||||
#include "swift/Syntax/ExprSyntax.h"
|
#include "swift/Syntax/ExprSyntax.h"
|
||||||
#include "swift/Syntax/StmtSyntax.h"
|
#include "swift/Syntax/StmtSyntax.h"
|
||||||
#include "swift/Syntax/Syntax.h"
|
#include "swift/Syntax/Syntax.h"
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ class CodeBlockStmtSyntax : public StmtSyntax {
|
|||||||
};
|
};
|
||||||
friend struct SyntaxFactory;
|
friend struct SyntaxFactory;
|
||||||
friend class CodeBlockStmtSyntaxData;
|
friend class CodeBlockStmtSyntaxData;
|
||||||
|
friend class FunctionDeclSyntax;
|
||||||
|
|
||||||
CodeBlockStmtSyntax(const RC<SyntaxData> Root, CodeBlockStmtSyntaxData *Data);
|
CodeBlockStmtSyntax(const RC<SyntaxData> Root, CodeBlockStmtSyntaxData *Data);
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,19 @@ struct SyntaxFactory {
|
|||||||
/// Make an empty list of declaration members.
|
/// Make an empty list of declaration members.
|
||||||
static DeclMembersSyntax makeBlankDeclMembers();
|
static DeclMembersSyntax makeBlankDeclMembers();
|
||||||
|
|
||||||
|
/// Make a function declaration with the specified elements.
|
||||||
|
static FunctionDeclSyntax
|
||||||
|
makeFunctionDecl(TypeAttributesSyntax Attributes,
|
||||||
|
DeclModifierListSyntax Modifiers,
|
||||||
|
RC<TokenSyntax> FuncKeyword,
|
||||||
|
RC<TokenSyntax> Identifier,
|
||||||
|
llvm::Optional<GenericParameterClauseSyntax> GenericParams,
|
||||||
|
FunctionSignatureSyntax Signature,
|
||||||
|
llvm::Optional<CodeBlockStmtSyntax> Body);
|
||||||
|
|
||||||
|
/// Make a function declaration with all missing elements.
|
||||||
|
static FunctionDeclSyntax makeBlankFunctionDecl();
|
||||||
|
|
||||||
#pragma mark - function-parameter
|
#pragma mark - function-parameter
|
||||||
|
|
||||||
/// Make a function parameter with the given elements.
|
/// Make a function parameter with the given elements.
|
||||||
@@ -233,6 +246,19 @@ struct SyntaxFactory {
|
|||||||
|
|
||||||
#pragma mark - Tokens
|
#pragma mark - Tokens
|
||||||
|
|
||||||
|
/// Make a 'static' keyword with the specified leading and trailing trivia.
|
||||||
|
static RC<TokenSyntax> makeStaticKeyword(const Trivia &LeadingTrivia,
|
||||||
|
const Trivia &TrailingTrivia);
|
||||||
|
|
||||||
|
|
||||||
|
/// Make a 'public' keyword with the specified leading and trailing trivia.
|
||||||
|
static RC<TokenSyntax> makePublicKeyword(const Trivia &LeadingTrivia,
|
||||||
|
const Trivia &TrailingTrivia);
|
||||||
|
|
||||||
|
/// Make a 'func' keyword with the specified leading and trailing trivia.
|
||||||
|
static RC<TokenSyntax> makeFuncKeyword(const Trivia &LeadingTrivia,
|
||||||
|
const Trivia &TrailingTrivia);
|
||||||
|
|
||||||
/// Make a 'fallthrough' keyword with the specified leading and
|
/// Make a 'fallthrough' keyword with the specified leading and
|
||||||
/// trailing trivia.
|
/// trailing trivia.
|
||||||
static RC<TokenSyntax> makeFallthroughKeyword(const Trivia &LeadingTrivia,
|
static RC<TokenSyntax> makeFallthroughKeyword(const Trivia &LeadingTrivia,
|
||||||
|
|||||||
@@ -40,8 +40,9 @@ ABSTRACT_SYNTAX(DeclSyntax, Syntax)
|
|||||||
SYNTAX(UnknownDecl, DeclSyntax)
|
SYNTAX(UnknownDecl, DeclSyntax)
|
||||||
SYNTAX(StructDecl, DeclSyntax)
|
SYNTAX(StructDecl, DeclSyntax)
|
||||||
SYNTAX(TypeAliasDecl, DeclSyntax)
|
SYNTAX(TypeAliasDecl, DeclSyntax)
|
||||||
|
SYNTAX(FunctionDecl, DeclSyntax)
|
||||||
|
|
||||||
SYNTAX_RANGE(Decl, MissingDecl, TypeAliasDecl)
|
SYNTAX_RANGE(Decl, MissingDecl, FunctionDecl)
|
||||||
|
|
||||||
SYNTAX(DeclMembers, Syntax)
|
SYNTAX(DeclMembers, Syntax)
|
||||||
SYNTAX(GenericParameter, Syntax)
|
SYNTAX(GenericParameter, Syntax)
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ class TypeAttributesSyntax final : public Syntax {
|
|||||||
friend class TypeAttributesSyntaxData;
|
friend class TypeAttributesSyntaxData;
|
||||||
friend class SyntaxData;
|
friend class SyntaxData;
|
||||||
friend class FunctionSignatureSyntax;
|
friend class FunctionSignatureSyntax;
|
||||||
|
friend class FunctionDeclSyntax;
|
||||||
|
|
||||||
using DataType = TypeAttributesSyntaxData;
|
using DataType = TypeAttributesSyntaxData;
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,11 @@
|
|||||||
|
|
||||||
#include "swift/Syntax/DeclSyntax.h"
|
#include "swift/Syntax/DeclSyntax.h"
|
||||||
#include "swift/Syntax/ExprSyntax.h"
|
#include "swift/Syntax/ExprSyntax.h"
|
||||||
|
#include "swift/Syntax/GenericSyntax.h"
|
||||||
#include "swift/Syntax/RawSyntax.h"
|
#include "swift/Syntax/RawSyntax.h"
|
||||||
|
#include "swift/Syntax/StmtSyntax.h"
|
||||||
#include "swift/Syntax/SyntaxFactory.h"
|
#include "swift/Syntax/SyntaxFactory.h"
|
||||||
|
#include "swift/Syntax/TypeSyntax.h"
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
using namespace swift::syntax;
|
using namespace swift::syntax;
|
||||||
@@ -817,3 +820,206 @@ withReturnTypeSyntax(TypeSyntax NewReturnTypeSyntax) const {
|
|||||||
return Data->replaceChild<FunctionSignatureSyntax>(
|
return Data->replaceChild<FunctionSignatureSyntax>(
|
||||||
NewReturnTypeSyntax.getRaw(), Cursor::ReturnType);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -149,9 +149,9 @@ GenericParameterClauseSyntaxData(RC<RawSyntax> Raw,
|
|||||||
}
|
}
|
||||||
|
|
||||||
RC<GenericParameterClauseSyntaxData>
|
RC<GenericParameterClauseSyntaxData>
|
||||||
GenericParameterClauseSyntaxData::make(RC<RawSyntax> Raw,
|
GenericParameterClauseSyntaxData::make(const RC<RawSyntax> Raw,
|
||||||
const SyntaxData *Parent,
|
const SyntaxData *Parent,
|
||||||
CursorIndex IndexInParent) {
|
const CursorIndex IndexInParent) {
|
||||||
return RC<GenericParameterClauseSyntaxData> {
|
return RC<GenericParameterClauseSyntaxData> {
|
||||||
new GenericParameterClauseSyntaxData {
|
new GenericParameterClauseSyntaxData {
|
||||||
Raw, Parent, IndexInParent,
|
Raw, Parent, IndexInParent,
|
||||||
@@ -173,7 +173,7 @@ GenericParameterClauseSyntaxData::makeBlank() {
|
|||||||
#pragma mark - generic-parameter-clause API
|
#pragma mark - generic-parameter-clause API
|
||||||
|
|
||||||
GenericParameterClauseSyntax::
|
GenericParameterClauseSyntax::
|
||||||
GenericParameterClauseSyntax(RC<SyntaxData> Root,
|
GenericParameterClauseSyntax(const RC<SyntaxData> Root,
|
||||||
const GenericParameterClauseSyntaxData *Data)
|
const GenericParameterClauseSyntaxData *Data)
|
||||||
: Syntax(Root, Data) {}
|
: Syntax(Root, Data) {}
|
||||||
|
|
||||||
|
|||||||
@@ -455,6 +455,30 @@ FunctionCallExprSyntax SyntaxFactory::makeBlankFunctionCallExpr() {
|
|||||||
|
|
||||||
#pragma mark - Tokens
|
#pragma mark - Tokens
|
||||||
|
|
||||||
|
RC<TokenSyntax>
|
||||||
|
SyntaxFactory::makeStaticKeyword(const Trivia &LeadingTrivia,
|
||||||
|
const Trivia &TrailingTrivia) {
|
||||||
|
return TokenSyntax::make(tok::kw_static, "static",
|
||||||
|
SourcePresence::Present,
|
||||||
|
LeadingTrivia, TrailingTrivia);
|
||||||
|
}
|
||||||
|
|
||||||
|
RC<TokenSyntax>
|
||||||
|
SyntaxFactory::makePublicKeyword(const Trivia &LeadingTrivia,
|
||||||
|
const Trivia &TrailingTrivia) {
|
||||||
|
return TokenSyntax::make(tok::kw_public, "public",
|
||||||
|
SourcePresence::Present,
|
||||||
|
LeadingTrivia, TrailingTrivia);
|
||||||
|
}
|
||||||
|
|
||||||
|
RC<TokenSyntax>
|
||||||
|
SyntaxFactory::makeFuncKeyword(const Trivia &LeadingTrivia,
|
||||||
|
const Trivia &TrailingTrivia) {
|
||||||
|
return TokenSyntax::make(tok::kw_func, "func",
|
||||||
|
SourcePresence::Present,
|
||||||
|
LeadingTrivia, TrailingTrivia);
|
||||||
|
}
|
||||||
|
|
||||||
RC<TokenSyntax>
|
RC<TokenSyntax>
|
||||||
SyntaxFactory::makeFallthroughKeyword(const Trivia &LeadingTrivia,
|
SyntaxFactory::makeFallthroughKeyword(const Trivia &LeadingTrivia,
|
||||||
const Trivia &TrailingTrivia) {
|
const Trivia &TrailingTrivia) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "swift/Syntax/SyntaxFactory.h"
|
#include "swift/Syntax/SyntaxFactory.h"
|
||||||
#include "swift/Syntax/DeclSyntax.h"
|
#include "swift/Syntax/DeclSyntax.h"
|
||||||
#include "swift/Syntax/ExprSyntax.h"
|
#include "swift/Syntax/ExprSyntax.h"
|
||||||
|
#include "swift/Syntax/StmtSyntax.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
@@ -465,5 +466,109 @@ TEST(DeclSyntaxTests, FunctionSignatureWithAPIs) {
|
|||||||
|
|
||||||
#pragma mark - function-declaration
|
#pragma mark - function-declaration
|
||||||
|
|
||||||
// TODO: Nodes
|
DeclModifierListSyntax getCannedModifiers() {
|
||||||
// TODO: Tests
|
auto PublicID = SyntaxFactory::makePublicKeyword({}, Trivia::spaces(1));
|
||||||
|
auto NoLParen = TokenSyntax::missingToken(tok::l_paren, "(");
|
||||||
|
auto NoArgument = TokenSyntax::missingToken(tok::identifier, "");
|
||||||
|
auto NoRParen = TokenSyntax::missingToken(tok::r_paren, ")");
|
||||||
|
auto Public = SyntaxFactory::makeDeclModifier(PublicID, NoLParen, NoArgument,
|
||||||
|
NoRParen);
|
||||||
|
|
||||||
|
auto StaticKW = SyntaxFactory::makeStaticKeyword({}, Trivia::spaces(1));
|
||||||
|
auto Static = SyntaxFactory::makeDeclModifier(StaticKW, NoLParen, NoArgument,
|
||||||
|
NoRParen);
|
||||||
|
|
||||||
|
return SyntaxFactory::makeBlankDeclModifierList()
|
||||||
|
.appending(Public)
|
||||||
|
.appending(Static)
|
||||||
|
.castTo<DeclModifierListSyntax>();
|
||||||
|
}
|
||||||
|
|
||||||
|
GenericParameterClauseSyntax getCannedGenericParams() {
|
||||||
|
GenericParameterClauseBuilder GB;
|
||||||
|
|
||||||
|
auto LAngle = SyntaxFactory::makeLeftAngleToken({}, {});
|
||||||
|
auto RAngle = SyntaxFactory::makeLeftAngleToken({}, Trivia::spaces(1));
|
||||||
|
|
||||||
|
auto T = SyntaxFactory::makeGenericParameter("T", {}, {});
|
||||||
|
auto U = SyntaxFactory::makeGenericParameter("U", {}, {});
|
||||||
|
|
||||||
|
auto Comma = SyntaxFactory::makeCommaToken({}, Trivia::spaces(1));
|
||||||
|
|
||||||
|
GB.addParameter(llvm::None, T);
|
||||||
|
GB.addParameter(Comma, U);
|
||||||
|
GB.useLeftAngleBracket(LAngle);
|
||||||
|
GB.useLeftAngleBracket(RAngle);
|
||||||
|
|
||||||
|
return GB.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeBlockStmtSyntax getCannedBody() {
|
||||||
|
auto NoSign = TokenSyntax::missingToken(tok::oper_prefix, "-");
|
||||||
|
auto OneDigits = SyntaxFactory::makeIntegerLiteralToken("1", {}, {});
|
||||||
|
auto One = SyntaxFactory::makeIntegerLiteralExpr(NoSign, OneDigits);
|
||||||
|
auto ReturnKW =
|
||||||
|
SyntaxFactory::makeReturnKeyword(Trivia::newlines(1) + Trivia::spaces(1),
|
||||||
|
{});
|
||||||
|
auto Return = SyntaxFactory::makeReturnStmt(ReturnKW, One);
|
||||||
|
|
||||||
|
auto Stmts = SyntaxFactory::makeBlankStmtList()
|
||||||
|
.appending(Return)
|
||||||
|
.castTo<StmtListSyntax>();
|
||||||
|
|
||||||
|
auto LBrace = SyntaxFactory::makeLeftBrace({}, {});
|
||||||
|
auto RBrace = SyntaxFactory::makeRightBrace(Trivia::newlines(1), {});
|
||||||
|
|
||||||
|
return SyntaxFactory::makeCodeBlock(LBrace, Stmts, RBrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionDeclSyntax getCannedFunctionDecl() {
|
||||||
|
auto NoAttributes = SyntaxFactory::makeBlankTypeAttributes();
|
||||||
|
auto Foo = SyntaxFactory::makeIdentifier("foo", {}, {});
|
||||||
|
auto FuncKW = SyntaxFactory::makeFuncKeyword({}, Trivia::spaces(1));
|
||||||
|
auto Modifiers = getCannedModifiers();
|
||||||
|
auto GenericParams = getCannedGenericParams();
|
||||||
|
auto Signature = getCannedFunctionSignature();
|
||||||
|
auto Body = getCannedBody();
|
||||||
|
|
||||||
|
return SyntaxFactory::makeFunctionDecl(NoAttributes, Modifiers, FuncKW, Foo,
|
||||||
|
GenericParams, Signature, Body);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DeclSyntaxTests, FunctionDeclMakeAPIs) {
|
||||||
|
{
|
||||||
|
SmallString<1> Scratch;
|
||||||
|
llvm::raw_svector_ostream OS(Scratch);
|
||||||
|
SyntaxFactory::makeBlankFunctionDecl().print(OS);
|
||||||
|
ASSERT_EQ(OS.str().str(), "");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SmallString<64> Scratch;
|
||||||
|
llvm::raw_svector_ostream OS(Scratch);
|
||||||
|
getCannedFunctionDecl().print(OS);
|
||||||
|
ASSERT_EQ(OS.str().str(),
|
||||||
|
"public static func foo(x: Int, y: Int) throws -> Int {\n"
|
||||||
|
" return 1\n"
|
||||||
|
"}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DeclSyntaxTests, FunctionDeclGetAPIs) {
|
||||||
|
{
|
||||||
|
SmallString<1> Scratch;
|
||||||
|
llvm::raw_svector_ostream OS(Scratch);
|
||||||
|
SyntaxFactory::makeBlankFunctionDecl().print(OS);
|
||||||
|
ASSERT_EQ(OS.str().str(), "");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DeclSyntaxTests, FunctionDeclWithAPIs) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DeclSyntaxTests, FunctionDeclBuilderAPIs) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user