Skip to content

[SyntaxParse] Re-apply associatedtype decl parsing #27416

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions include/swift/Parse/ASTGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Expr.h"
#include "swift/AST/TypeRepr.h"
#include "swift/Parse/PersistentParserState.h"
#include "swift/Syntax/SyntaxNodes.h"
#include "llvm/ADT/DenseMap.h"
Expand Down Expand Up @@ -46,6 +47,30 @@ class ASTGen {

SourceLoc generate(const syntax::TokenSyntax &Tok, const SourceLoc Loc);

SourceLoc generateIdentifierDeclName(const syntax::TokenSyntax &Tok,
const SourceLoc, Identifier &Identifier);

public:
//===--------------------------------------------------------------------===//
// Decls.

Decl *generate(const syntax::DeclSyntax &Decl, const SourceLoc Loc);
TypeDecl *generate(const syntax::AssociatedtypeDeclSyntax &Decl,
const SourceLoc Loc);

TrailingWhereClause *generate(const syntax::GenericWhereClauseSyntax &syntax,
const SourceLoc Loc);
MutableArrayRef<TypeLoc>
generate(const syntax::TypeInheritanceClauseSyntax &syntax,
const SourceLoc Loc, bool allowClassRequirement);

private:
DeclAttributes
generateDeclAttributes(const syntax::DeclSyntax &D,
const Optional<syntax::AttributeListSyntax> &attrs,
const Optional<syntax::ModifierListSyntax> &modifiers,
SourceLoc Loc, bool includeComments);

public:
//===--------------------------------------------------------------------===//
// Expressions.
Expand Down Expand Up @@ -100,6 +125,8 @@ class ASTGen {
const SourceLoc Loc);
TypeRepr *generate(const syntax::ImplicitlyUnwrappedOptionalTypeSyntax &Type,
const SourceLoc Loc);
TypeRepr *generate(const syntax::ClassRestrictionTypeSyntax &Type,
const SourceLoc Loc);
TypeRepr *generate(const syntax::CodeCompletionTypeSyntax &Type,
const SourceLoc Loc);
TypeRepr *generate(const syntax::UnknownTypeSyntax &Type,
Expand Down
7 changes: 4 additions & 3 deletions include/swift/Parse/LibSyntaxGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@ class LibSyntaxGenerator {
assert(Node.isDeferredToken());

auto Kind = Node.getTokenKind();
auto Range = Node.getDeferredTokenRangeWithTrivia();
auto Range = Node.getDeferredTokenRange();
auto LeadingTriviaPieces = Node.getDeferredLeadingTriviaPieces();
auto TrailingTriviaPieces = Node.getDeferredTrailingTriviaPieces();

auto Recorded = Recorder.recordToken(Kind, Range, LeadingTriviaPieces,
TrailingTriviaPieces);
auto Raw = static_cast<RawSyntax *>(Recorded.takeOpaqueNode());
RC<RawSyntax> Raw{static_cast<RawSyntax *>(Recorded.takeOpaqueNode())};
Raw->Release(); // -1 since it's transfer of ownership.
return make<TokenSyntax>(Raw);
}

Expand All @@ -55,7 +56,7 @@ class LibSyntaxGenerator {
auto Children = Node.getDeferredChildren();

auto Recorded = Recorder.recordRawSyntax(Kind, Children);
RC<RawSyntax> Raw {static_cast<RawSyntax *>(Recorded.takeOpaqueNode()) };
RC<RawSyntax> Raw{static_cast<RawSyntax *>(Recorded.takeOpaqueNode())};
Raw->Release(); // -1 since it's transfer of ownership.
return make<SyntaxNode>(Raw);
}
Expand Down
19 changes: 15 additions & 4 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -1004,12 +1004,23 @@ class Parser {
bool delayParsingDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
IterableDeclContext *IDC);

ParsedSyntaxResult<ParsedTypeInheritanceClauseSyntax>
parseTypeInheritanceClauseSyntax(bool allowClassRequirement,
bool allowAnyObject);

ParsedSyntaxResult<ParsedDeclSyntax>
parseDeclAssociatedTypeSyntax(ParseDeclOptions flags,
Optional<ParsedAttributeListSyntax> attrs,
Optional<ParsedModifierListSyntax> modifiers);

ParserResult<TypeDecl> parseDeclTypeAlias(ParseDeclOptions Flags,
DeclAttributes &Attributes);
DeclAttributes &Attributes,
SourceLoc leadingLoc);

ParserResult<TypeDecl> parseDeclAssociatedType(ParseDeclOptions Flags,
DeclAttributes &Attributes);

DeclAttributes &Attributes,
SourceLoc leadingLoc);

/// Parse a #if ... #endif directive.
/// Delegate callback function to parse elements in the blocks.
ParserResult<IfConfigDecl> parseIfConfig(
Expand Down Expand Up @@ -1091,7 +1102,7 @@ class Parser {

ParserResult<ImportDecl> parseDeclImport(ParseDeclOptions Flags,
DeclAttributes &Attributes);
ParserStatus parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
ParserStatus parseInheritance(MutableArrayRef<TypeLoc> &Inherited,
bool allowClassRequirement,
bool allowAnyObject);
ParserStatus parseDeclItem(bool &PreviousHadSemi,
Expand Down
31 changes: 21 additions & 10 deletions include/swift/Parse/SyntaxParsingContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,17 +279,9 @@ class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext {
}

/// Returns the topmost Syntax node.
template <typename SyntaxNode> SyntaxNode topNode() {
ParsedRawSyntaxNode &TopNode = getStorage().back();
if (TopNode.isRecorded()) {
OpaqueSyntaxNode OpaqueNode = TopNode.getOpaqueNode();
return getSyntaxCreator().getLibSyntaxNodeFor<SyntaxNode>(OpaqueNode);
}
return getSyntaxCreator().createNode<SyntaxNode>(TopNode.copyDeferred());
}
template <typename SyntaxNode> SyntaxNode topNode();

template <typename SyntaxNode>
llvm::Optional<SyntaxNode> popIf() {
template <typename SyntaxNode> llvm::Optional<SyntaxNode> popIf() {
auto &Storage = getStorage();
if (Storage.size() <= Offset)
return llvm::None;
Expand Down Expand Up @@ -376,5 +368,24 @@ class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext {
"Only meant for use in the debugger");
};

template <typename SyntaxNode>
inline SyntaxNode SyntaxParsingContext::topNode() {
ParsedRawSyntaxNode &TopNode = getStorage().back();
if (TopNode.isRecorded()) {
OpaqueSyntaxNode OpaqueNode = TopNode.getOpaqueNode();
return getSyntaxCreator().getLibSyntaxNodeFor<SyntaxNode>(OpaqueNode);
}
return getSyntaxCreator().createNode<SyntaxNode>(TopNode.copyDeferred());
}

template <> inline TokenSyntax SyntaxParsingContext::topNode<TokenSyntax>() {
ParsedRawSyntaxNode &TopNode = getStorage().back();
if (TopNode.isRecorded()) {
OpaqueSyntaxNode OpaqueNode = TopNode.getOpaqueNode();
return getSyntaxCreator().getLibSyntaxNodeFor<TokenSyntax>(OpaqueNode);
}
return getSyntaxCreator().createToken(TopNode.copyDeferred());
}

} // namespace swift
#endif // SWIFT_SYNTAX_PARSING_CONTEXT_H
2 changes: 1 addition & 1 deletion include/swift/Syntax/Syntax.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class Syntax {
SyntaxKind getKind() const;

/// Get the shared raw syntax.
RC<RawSyntax> getRaw() const;
const RC<RawSyntax> &getRaw() const;

/// Get an ID for this node that is stable across incremental parses
SyntaxNodeId getId() const { return getRaw()->getId(); }
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Syntax/SyntaxData.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ class SyntaxData final
CursorIndex IndexInParent = 0);

/// Returns the raw syntax node for this syntax node.
const RC<RawSyntax> getRaw() const {
const RC<RawSyntax> &getRaw() const {
return Raw;
}

Expand Down
143 changes: 137 additions & 6 deletions lib/Parse/ASTGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "swift/AST/TypeRepr.h"
#include "swift/Basic/SourceManager.h"

#include "DebuggerContextChange.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Parse/CodeCompletionCallbacks.h"
#include "swift/Parse/Parser.h"
Expand All @@ -25,6 +26,132 @@ SourceLoc ASTGen::generate(const TokenSyntax &Tok, const SourceLoc Loc) {
return advanceLocBegin(Loc, Tok);
}

SourceLoc ASTGen::generateIdentifierDeclName(const syntax::TokenSyntax &Tok,
const SourceLoc Loc,
Identifier &Id) {
StringRef text;
if (Tok.getText() == "Any")
// Special handle 'Any' because we don't want to accidantaly declare 'Any'
// type in any way.
text = "#Any";
else
text = Tok.getIdentifierText();

Id = Context.getIdentifier(text);
return advanceLocBegin(Loc, Tok);
}

Decl *ASTGen::generate(const DeclSyntax &D, const SourceLoc Loc) {
Decl *DeclAST = nullptr;

if (auto associatedTypeDecl = D.getAs<AssociatedtypeDeclSyntax>()) {
DeclAST = generate(*associatedTypeDecl, Loc);
} else {
llvm_unreachable("unsupported decl kind");
}

return DeclAST;
}

DeclAttributes
ASTGen::generateDeclAttributes(const DeclSyntax &D,
const Optional<AttributeListSyntax> &attrs,
const Optional<ModifierListSyntax> &modifiers,
SourceLoc Loc, bool includeComments) {
SourceLoc attrsLoc;
if (attrs) {
attrsLoc = advanceLocBegin(Loc, *attrs->getFirstToken());
} else if (modifiers) {
attrsLoc = advanceLocBegin(Loc, *modifiers->getFirstToken());
} else {
// We might have comment attributes.
attrsLoc = advanceLocBegin(Loc, *D.getFirstToken());
}
if (hasDeclAttributes(attrsLoc))
return getDeclAttributes(attrsLoc);
return DeclAttributes();
}

MutableArrayRef<TypeLoc>
ASTGen::generate(const TypeInheritanceClauseSyntax &clause, SourceLoc Loc,
bool allowClassRequirement) {
SmallVector<TypeLoc, 2> inherited;

bool hasClass = false;
for (const auto elem : clause.getInheritedTypeCollection()) {
const auto &tySyntax = elem.getTypeName();
if (tySyntax.is<ClassRestrictionTypeSyntax>()) {
// Accept 'class' only if it's allowed and it's the first one.
if (!allowClassRequirement || hasClass)
continue;
hasClass = true;
}
if (auto ty = generate(tySyntax, Loc))
inherited.emplace_back(ty);
}

return Context.AllocateCopy(inherited);
}

TypeDecl *ASTGen::generate(const AssociatedtypeDeclSyntax &D,
const SourceLoc Loc) {
if (!isa<ProtocolDecl>(P.CurDeclContext)) {
// This is already diagnosed in Parser.
return nullptr;
}

auto idToken = D.getIdentifier();
if (idToken.isMissing())
return nullptr;

auto keywordLoc = advanceLocBegin(Loc, D.getAssociatedtypeKeyword());
auto name = Context.getIdentifier(idToken.getIdentifierText());
auto nameLoc = advanceLocBegin(Loc, idToken);

DeclAttributes attrs =
generateDeclAttributes(D, D.getAttributes(), D.getModifiers(), Loc, true);

DebuggerContextChange DCC(P, name, DeclKind::AssociatedType);

ArrayRef<TypeLoc> inherited;
if (const auto inheritanceClause = D.getInheritanceClause())
inherited =
generate(*inheritanceClause, Loc, /*allowClassRequirement=*/true);

TypeRepr *defaultTy = nullptr;
if (const auto init = D.getInitializer())
defaultTy = generate(init->getValue(), Loc);

TrailingWhereClause *trailingWhere = nullptr;
if (auto whereClause = D.getGenericWhereClause())
trailingWhere = generate(*whereClause, Loc);

auto assocType = new (Context)
AssociatedTypeDecl(P.CurDeclContext, keywordLoc, name, nameLoc, defaultTy,
trailingWhere);
assocType->getAttrs() = attrs;
if (!inherited.empty())
assocType->setInherited(Context.AllocateCopy(inherited));
addToScope(assocType);
return assocType;
}

TrailingWhereClause *ASTGen::generate(const GenericWhereClauseSyntax &syntax,
const SourceLoc Loc) {
SourceLoc whereLoc = advanceLocBegin(Loc, syntax.getWhereKeyword());

SmallVector<RequirementRepr, 4> requirements;
requirements.reserve(syntax.getRequirementList().size());
for (auto elem : syntax.getRequirementList()) {
if (auto req = generate(elem, Loc))
requirements.push_back(*req);
}

if (requirements.empty())
return nullptr;
return TrailingWhereClause::create(Context, whereLoc, requirements);
}

Expr *ASTGen::generate(const IntegerLiteralExprSyntax &Expr,
const SourceLoc Loc) {
auto Digits = Expr.getDigits();
Expand Down Expand Up @@ -126,6 +253,8 @@ TypeRepr *ASTGen::generate(const TypeSyntax &Type, const SourceLoc Loc) {
TypeAST = generate(*Unwrapped, Loc);
else if (auto Attributed = Type.getAs<AttributedTypeSyntax>())
TypeAST = generate(*Attributed, Loc);
else if (auto ClassRestriction = Type.getAs<ClassRestrictionTypeSyntax>())
TypeAST = generate(*ClassRestriction, Loc);
else if (auto CompletionTy = Type.getAs<CodeCompletionTypeSyntax>())
TypeAST = generate(*CompletionTy, Loc);
else if (auto Unknown = Type.getAs<UnknownTypeSyntax>())
Expand Down Expand Up @@ -386,11 +515,6 @@ TypeRepr *ASTGen::generate(const SimpleTypeIdentifierSyntax &Type,
auto AnyLoc = advanceLocBegin(Loc, Type.getName());
return CompositionTypeRepr::createEmptyComposition(Context, AnyLoc);
}
if (Type.getName().getText() == "class") {
auto classLoc = advanceLocBegin(Loc, Type.getName());
return new (Context)
SimpleIdentTypeRepr(classLoc, Context.getIdentifier("AnyObject"));
}

return generateSimpleOrMemberIdentifier(Type, Loc);
}
Expand Down Expand Up @@ -450,6 +574,13 @@ TypeRepr *ASTGen::generate(const ImplicitlyUnwrappedOptionalTypeSyntax &Type,
ImplicitlyUnwrappedOptionalTypeRepr(WrappedType, ExclamationLoc);
}

TypeRepr *
ASTGen::generate(const ClassRestrictionTypeSyntax &Type, const SourceLoc Loc) {
auto classLoc = advanceLocBegin(Loc, Type);
return new (Context)
SimpleIdentTypeRepr(classLoc, Context.getIdentifier("AnyObject"));
}

TypeRepr *ASTGen::generate(const CodeCompletionTypeSyntax &Type,
const SourceLoc Loc) {
auto base = Type.getBase();
Expand Down Expand Up @@ -594,7 +725,7 @@ GenericParamList *ASTGen::generate(const GenericParameterClauseSyntax &clause,

if (auto inherited = elem.getInheritedType()) {
if (auto ty = generate(*inherited, Loc)) {
SmallVector<TypeLoc, 1> constraints = {generate(*inherited, Loc)};
SmallVector<TypeLoc, 1> constraints = {ty};
param->setInherited(Context.AllocateCopy(constraints));
}
}
Expand Down
Loading