Skip to content

[SyntaxParse] Introduce CodeCompletionTypeSyntax #27325

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 1 commit into from
Sep 24, 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
1 change: 1 addition & 0 deletions cmake/modules/SwiftHandleGybSources.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ function(handle_gyb_sources dependency_out_var_name sources_var_name arch)
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/AttributeNodes.py"
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/AvailabilityNodes.py"
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/CommonNodes.py"
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/CompletionOnlyNodes.py"
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/DeclNodes.py"
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/ExprNodes.py"
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/GenericNodes.py"
Expand Down
2 changes: 2 additions & 0 deletions include/swift/Parse/ASTGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ class ASTGen {
const SourceLoc Loc);
TypeRepr *generate(const syntax::ImplicitlyUnwrappedOptionalTypeSyntax &Type,
const SourceLoc Loc);
TypeRepr *generate(const syntax::CodeCompletionTypeSyntax &Type,
const SourceLoc Loc);
TypeRepr *generate(const syntax::UnknownTypeSyntax &Type,
const SourceLoc Loc);

Expand Down
10 changes: 8 additions & 2 deletions include/swift/Parse/CodeCompletionCallbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class CodeCompletionCallbacks {
/// completion. This declaration contained the code completion token.
Decl *ParsedDecl = nullptr;

TypeLoc ParsedTypeLoc;

/// True if code completion is done inside a raw value expression of an enum
/// case.
bool InEnumElementRawValue = false;
Expand Down Expand Up @@ -76,6 +78,10 @@ class CodeCompletionCallbacks {
ParsedDecl = D;
}

void setParsedTypeLoc(TypeLoc TyLoc) {
ParsedTypeLoc = TyLoc;
}

void setLeadingSequenceExprs(ArrayRef<Expr *> exprs) {
leadingSequenceExprs.assign(exprs.begin(), exprs.end());
}
Expand Down Expand Up @@ -159,10 +165,10 @@ class CodeCompletionCallbacks {
virtual void completeTypeSimpleBeginning() {};

/// Complete a given type-identifier after we have consumed the dot.
virtual void completeTypeIdentifierWithDot(IdentTypeRepr *ITR) {};
virtual void completeTypeIdentifierWithDot() {};

/// Complete a given type-identifier when there is no trailing dot.
virtual void completeTypeIdentifierWithoutDot(IdentTypeRepr *ITR) {};
virtual void completeTypeIdentifierWithoutDot() {};

/// Complete the beginning of a case statement at the top of switch stmt.
virtual void completeCaseStmtKeyword() {};
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Parse/ParsedSyntaxBuilders.h.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace swift {
class ParsedRawSyntaxRecorder;
class SyntaxParsingContext;

% for node in SYNTAX_NODES + SILONLY_NODES:
% for node in SYNTAX_NODES + PARSEONLY_NODES:
% if node.is_buildable():
% child_count = len(node.children)
class Parsed${node.name}Builder {
Expand Down
6 changes: 3 additions & 3 deletions include/swift/Parse/ParsedSyntaxNodes.h.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@ namespace swift {
% # Emit the non-collection classes first, then emit the collection classes
% # that reference these classes.

% for node in SYNTAX_NODES + SILONLY_NODES:
% for node in SYNTAX_NODES + PARSEONLY_NODES:
% if not node.is_syntax_collection():
class Parsed${node.name};
% end
% end

% for node in SYNTAX_NODES + SILONLY_NODES:
% for node in SYNTAX_NODES + PARSEONLY_NODES:
% if node.is_syntax_collection():
using Parsed${node.name} =
ParsedSyntaxCollection<syntax::SyntaxKind::${node.syntax_kind}>;
% end
% end

% for node in SYNTAX_NODES + SILONLY_NODES:
% for node in SYNTAX_NODES + PARSEONLY_NODES:
% if not node.is_syntax_collection():
% qualifier = "" if node.is_base() else "final"
% for line in dedented_lines(node.description):
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Parse/ParsedSyntaxRecorder.h.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class SyntaxParsingContext;

struct ParsedSyntaxRecorder {

% for node in SYNTAX_NODES + SILONLY_NODES:
% for node in SYNTAX_NODES + PARSEONLY_NODES:
% if node.children:
% child_params = []
% for child in node.children:
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Syntax/SyntaxBuilders.h.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace syntax {

class SyntaxArena;

% for node in SYNTAX_NODES + SILONLY_NODES:
% for node in SYNTAX_NODES + PARSEONLY_NODES:
% if node.is_buildable():
% child_count = len(node.children)
class ${node.name}Builder {
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Syntax/SyntaxFactory.h.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ struct SyntaxFactory {
static Syntax
makeBlankCollectionSyntax(SyntaxKind Kind);

% for node in SYNTAX_NODES + SILONLY_NODES:
% for node in SYNTAX_NODES + PARSEONLY_NODES:
% if node.children:
% child_params = []
% for child in node.children:
Expand Down
6 changes: 3 additions & 3 deletions include/swift/Syntax/SyntaxKind.h.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from gyb_syntax_support import *
from gyb_syntax_support.kinds import SYNTAX_BASE_KINDS
grouped_nodes = { kind: [] for kind in SYNTAX_BASE_KINDS }
for node in SYNTAX_NODES + SILONLY_NODES:
for node in SYNTAX_NODES + PARSEONLY_NODES:
grouped_nodes[node.base_kind].append(node)
# -*- mode: C++ -*-
# Ignore the following admonition; it applies to the resulting .h file only
Expand Down Expand Up @@ -93,7 +93,7 @@ struct WrapperTypeTraits<syntax::SyntaxKind> {
case syntax::SyntaxKind::${node.syntax_kind}:
return ${SYNTAX_NODE_SERIALIZATION_CODES[node.syntax_kind]};
% end
% for node in SILONLY_NODES:
% for node in PARSEONLY_NODES:
case syntax::SyntaxKind::${node.syntax_kind}:
% end
llvm_unreachable("unserializable syntax kind");
Expand Down Expand Up @@ -124,7 +124,7 @@ struct ScalarReferenceTraits<syntax::SyntaxKind> {
case syntax::SyntaxKind::${node.syntax_kind}:
return "\"${node.syntax_kind}\"";
% end
% for node in SILONLY_NODES:
% for node in PARSEONLY_NODES:
case syntax::SyntaxKind::${node.syntax_kind}:
% end
llvm_unreachable("unserializable syntax kind");
Expand Down
6 changes: 3 additions & 3 deletions include/swift/Syntax/SyntaxNodes.h.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,21 @@ namespace syntax {
% # Emit the non-collection classes first, then emit the collection classes
% # that reference these classes.

% for node in SYNTAX_NODES + SILONLY_NODES:
% for node in SYNTAX_NODES + PARSEONLY_NODES:
% if not node.is_syntax_collection():
class ${node.name};
% end
% end

% for node in SYNTAX_NODES + SILONLY_NODES:
% for node in SYNTAX_NODES + PARSEONLY_NODES:
% if node.is_syntax_collection():
using ${node.name} =
SyntaxCollection<SyntaxKind::${node.syntax_kind},
${node.collection_element_type}>;
% end
% end

% for node in SYNTAX_NODES + SILONLY_NODES:
% for node in SYNTAX_NODES + PARSEONLY_NODES:
% if not node.is_syntax_collection():
% qualifier = "" if node.is_base() else "final"
% for line in dedented_lines(node.description):
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Syntax/SyntaxVisitor.h.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace syntax {
struct SyntaxVisitor {
virtual ~SyntaxVisitor() {}

% for node in SYNTAX_NODES + SILONLY_NODES:
% for node in SYNTAX_NODES + PARSEONLY_NODES:
% if is_visitable(node):
virtual void visit(${node.name} node);
% end
Expand Down
18 changes: 4 additions & 14 deletions lib/IDE/CodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,6 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
CompletionKind Kind = CompletionKind::None;
Expr *ParsedExpr = nullptr;
SourceLoc DotLoc;
TypeLoc ParsedTypeLoc;
DeclContext *CurDeclContext = nullptr;
DeclAttrKind AttrKind;

Expand Down Expand Up @@ -1351,8 +1350,8 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {

void completeTypeDeclResultBeginning() override;
void completeTypeSimpleBeginning() override;
void completeTypeIdentifierWithDot(IdentTypeRepr *ITR) override;
void completeTypeIdentifierWithoutDot(IdentTypeRepr *ITR) override;
void completeTypeIdentifierWithDot() override;
void completeTypeIdentifierWithoutDot() override;

void completeCaseStmtKeyword() override;
void completeCaseStmtBeginning(CodeCompletionExpr *E) override;
Expand Down Expand Up @@ -4609,22 +4608,13 @@ void CodeCompletionCallbacksImpl::completeInPrecedenceGroup(SyntaxKind SK) {
CurDeclContext = P.CurDeclContext;
}

void CodeCompletionCallbacksImpl::completeTypeIdentifierWithDot(
IdentTypeRepr *ITR) {
if (!ITR) {
completeTypeSimpleBeginning();
return;
}
void CodeCompletionCallbacksImpl::completeTypeIdentifierWithDot() {
Kind = CompletionKind::TypeIdentifierWithDot;
ParsedTypeLoc = TypeLoc(ITR);
CurDeclContext = P.CurDeclContext;
}

void CodeCompletionCallbacksImpl::completeTypeIdentifierWithoutDot(
IdentTypeRepr *ITR) {
assert(ITR);
void CodeCompletionCallbacksImpl::completeTypeIdentifierWithoutDot() {
Kind = CompletionKind::TypeIdentifierWithoutDot;
ParsedTypeLoc = TypeLoc(ITR);
CurDeclContext = P.CurDeclContext;
}

Expand Down
41 changes: 27 additions & 14 deletions lib/Parse/ASTGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "swift/Parse/ASTGen.h"

#include "swift/Basic/SourceManager.h"
#include "swift/Parse/CodeCompletionCallbacks.h"
#include "swift/Parse/Parser.h"

using namespace swift;
Expand Down Expand Up @@ -123,6 +124,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 CompletionTy = Type.getAs<CodeCompletionTypeSyntax>())
TypeAST = generate(*CompletionTy, Loc);
else if (auto Unknown = Type.getAs<UnknownTypeSyntax>())
TypeAST = generate(*Unknown, Loc);

Expand Down Expand Up @@ -445,34 +448,44 @@ TypeRepr *ASTGen::generate(const ImplicitlyUnwrappedOptionalTypeSyntax &Type,
ImplicitlyUnwrappedOptionalTypeRepr(WrappedType, ExclamationLoc);
}

TypeRepr *ASTGen::generate(const CodeCompletionTypeSyntax &Type,
const SourceLoc Loc) {
auto base = Type.getBase();
if (!base)
return nullptr;

TypeRepr *parsedTyR = generate(*base, Loc);
if (parsedTyR) {
if (P.CodeCompletion)
P.CodeCompletion->setParsedTypeLoc(parsedTyR);
}
return parsedTyR;
}

TypeRepr *ASTGen::generate(const UnknownTypeSyntax &Type, const SourceLoc Loc) {
auto ChildrenCount = Type.getNumChildren();

// Recover from old-style protocol composition:
// `protocol` `<` protocols `>`
if (ChildrenCount >= 2) {
auto Protocol = Type.getChild(0)->getAs<TokenSyntax>();
auto keyword = Type.getChild(0)->getAs<TokenSyntax>();

if (Protocol && Protocol->getText() == "protocol") {
if (keyword && keyword->getText() == "protocol") {
auto keywordLoc = advanceLocBegin(Loc, *keyword);
auto LAngle = Type.getChild(1);

SmallVector<TypeSyntax, 4> Protocols;
for (unsigned i = 2; i < Type.getNumChildren(); i++)
if (auto PType = Type.getChild(i)->getAs<TypeSyntax>())
Protocols.push_back(*PType);

auto RAngle = Type.getChild(ChildrenCount - 1);

auto ProtocolLoc = advanceLocBegin(Loc, *Protocol);
auto LAngleLoc = advanceLocBegin(Loc, *LAngle);
auto RAngleLoc = advanceLocBegin(Loc, *RAngle);

SmallVector<TypeRepr *, 4> ProtocolTypes;
for (auto &&P : llvm::reverse(Protocols))
ProtocolTypes.push_back(generate(P, Loc));
std::reverse(std::begin(ProtocolTypes), std::end(ProtocolTypes));
SmallVector<TypeRepr *, 4> protocols;
for (unsigned i = 2; i < Type.getNumChildren(); i++) {
if (auto elem = Type.getChild(i)->getAs<TypeSyntax>())
if (auto proto = generate(*elem, Loc))
protocols.push_back(proto);
}

return CompositionTypeRepr::create(Context, ProtocolTypes, ProtocolLoc,
return CompositionTypeRepr::create(Context, protocols, keywordLoc,
{LAngleLoc, RAngleLoc});
}
}
Expand Down
Loading