Skip to content

Commit 1a9b6d0

Browse files
committed
[SyntaxParse] Introduce CodeCompletionTypeSyntax
To represent a type with code completion. type? '.'? <code-completion-token> This is "parser only" node which is not exposed to SwiftSyntax. Using this, defer to set the parsed type to code-completion callbacks.
1 parent 29bc645 commit 1a9b6d0

24 files changed

+185
-153
lines changed

cmake/modules/SwiftHandleGybSources.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ function(handle_gyb_sources dependency_out_var_name sources_var_name arch)
118118
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/AttributeNodes.py"
119119
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/AvailabilityNodes.py"
120120
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/CommonNodes.py"
121+
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/CompletionOnlyNodes.py"
121122
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/DeclNodes.py"
122123
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/ExprNodes.py"
123124
"${SWIFT_SOURCE_DIR}/utils/gyb_syntax_support/GenericNodes.py"

include/swift/Parse/ASTGen.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ class ASTGen {
9797
const SourceLoc Loc);
9898
TypeRepr *generate(const syntax::ImplicitlyUnwrappedOptionalTypeSyntax &Type,
9999
const SourceLoc Loc);
100+
TypeRepr *generate(const syntax::CodeCompletionTypeSyntax &Type,
101+
const SourceLoc Loc);
100102
TypeRepr *generate(const syntax::UnknownTypeSyntax &Type,
101103
const SourceLoc Loc);
102104

include/swift/Parse/CodeCompletionCallbacks.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class CodeCompletionCallbacks {
4040
/// completion. This declaration contained the code completion token.
4141
Decl *ParsedDecl = nullptr;
4242

43+
TypeLoc ParsedTypeLoc;
44+
4345
/// True if code completion is done inside a raw value expression of an enum
4446
/// case.
4547
bool InEnumElementRawValue = false;
@@ -76,6 +78,10 @@ class CodeCompletionCallbacks {
7678
ParsedDecl = D;
7779
}
7880

81+
void setParsedTypeLoc(TypeLoc TyLoc) {
82+
ParsedTypeLoc = TyLoc;
83+
}
84+
7985
void setLeadingSequenceExprs(ArrayRef<Expr *> exprs) {
8086
leadingSequenceExprs.assign(exprs.begin(), exprs.end());
8187
}
@@ -159,10 +165,10 @@ class CodeCompletionCallbacks {
159165
virtual void completeTypeSimpleBeginning() {};
160166

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

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

167173
/// Complete the beginning of a case statement at the top of switch stmt.
168174
virtual void completeCaseStmtKeyword() {};

include/swift/Parse/ParsedSyntaxBuilders.h.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace swift {
3030
class ParsedRawSyntaxRecorder;
3131
class SyntaxParsingContext;
3232

33-
% for node in SYNTAX_NODES + SILONLY_NODES:
33+
% for node in SYNTAX_NODES + PARSEONLY_NODES:
3434
% if node.is_buildable():
3535
% child_count = len(node.children)
3636
class Parsed${node.name}Builder {

include/swift/Parse/ParsedSyntaxNodes.h.gyb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,20 @@ namespace swift {
2828
% # Emit the non-collection classes first, then emit the collection classes
2929
% # that reference these classes.
3030

31-
% for node in SYNTAX_NODES + SILONLY_NODES:
31+
% for node in SYNTAX_NODES + PARSEONLY_NODES:
3232
% if not node.is_syntax_collection():
3333
class Parsed${node.name};
3434
% end
3535
% end
3636

37-
% for node in SYNTAX_NODES + SILONLY_NODES:
37+
% for node in SYNTAX_NODES + PARSEONLY_NODES:
3838
% if node.is_syntax_collection():
3939
using Parsed${node.name} =
4040
ParsedSyntaxCollection<syntax::SyntaxKind::${node.syntax_kind}>;
4141
% end
4242
% end
4343

44-
% for node in SYNTAX_NODES + SILONLY_NODES:
44+
% for node in SYNTAX_NODES + PARSEONLY_NODES:
4545
% if not node.is_syntax_collection():
4646
% qualifier = "" if node.is_base() else "final"
4747
% for line in dedented_lines(node.description):

include/swift/Parse/ParsedSyntaxRecorder.h.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class SyntaxParsingContext;
3131

3232
struct ParsedSyntaxRecorder {
3333

34-
% for node in SYNTAX_NODES + SILONLY_NODES:
34+
% for node in SYNTAX_NODES + PARSEONLY_NODES:
3535
% if node.children:
3636
% child_params = []
3737
% for child in node.children:

include/swift/Syntax/SyntaxBuilders.h.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace syntax {
2929

3030
class SyntaxArena;
3131

32-
% for node in SYNTAX_NODES + SILONLY_NODES:
32+
% for node in SYNTAX_NODES + PARSEONLY_NODES:
3333
% if node.is_buildable():
3434
% child_count = len(node.children)
3535
class ${node.name}Builder {

include/swift/Syntax/SyntaxFactory.h.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ struct SyntaxFactory {
7171
static Syntax
7272
makeBlankCollectionSyntax(SyntaxKind Kind);
7373

74-
% for node in SYNTAX_NODES + SILONLY_NODES:
74+
% for node in SYNTAX_NODES + PARSEONLY_NODES:
7575
% if node.children:
7676
% child_params = []
7777
% for child in node.children:

include/swift/Syntax/SyntaxKind.h.gyb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from gyb_syntax_support import *
33
from gyb_syntax_support.kinds import SYNTAX_BASE_KINDS
44
grouped_nodes = { kind: [] for kind in SYNTAX_BASE_KINDS }
5-
for node in SYNTAX_NODES + SILONLY_NODES:
5+
for node in SYNTAX_NODES + PARSEONLY_NODES:
66
grouped_nodes[node.base_kind].append(node)
77
# -*- mode: C++ -*-
88
# Ignore the following admonition; it applies to the resulting .h file only
@@ -93,7 +93,7 @@ struct WrapperTypeTraits<syntax::SyntaxKind> {
9393
case syntax::SyntaxKind::${node.syntax_kind}:
9494
return ${SYNTAX_NODE_SERIALIZATION_CODES[node.syntax_kind]};
9595
% end
96-
% for node in SILONLY_NODES:
96+
% for node in PARSEONLY_NODES:
9797
case syntax::SyntaxKind::${node.syntax_kind}:
9898
% end
9999
llvm_unreachable("unserializable syntax kind");
@@ -124,7 +124,7 @@ struct ScalarReferenceTraits<syntax::SyntaxKind> {
124124
case syntax::SyntaxKind::${node.syntax_kind}:
125125
return "\"${node.syntax_kind}\"";
126126
% end
127-
% for node in SILONLY_NODES:
127+
% for node in PARSEONLY_NODES:
128128
case syntax::SyntaxKind::${node.syntax_kind}:
129129
% end
130130
llvm_unreachable("unserializable syntax kind");

include/swift/Syntax/SyntaxNodes.h.gyb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,21 @@ namespace syntax {
3232
% # Emit the non-collection classes first, then emit the collection classes
3333
% # that reference these classes.
3434

35-
% for node in SYNTAX_NODES + SILONLY_NODES:
35+
% for node in SYNTAX_NODES + PARSEONLY_NODES:
3636
% if not node.is_syntax_collection():
3737
class ${node.name};
3838
% end
3939
% end
4040

41-
% for node in SYNTAX_NODES + SILONLY_NODES:
41+
% for node in SYNTAX_NODES + PARSEONLY_NODES:
4242
% if node.is_syntax_collection():
4343
using ${node.name} =
4444
SyntaxCollection<SyntaxKind::${node.syntax_kind},
4545
${node.collection_element_type}>;
4646
% end
4747
% end
4848

49-
% for node in SYNTAX_NODES + SILONLY_NODES:
49+
% for node in SYNTAX_NODES + PARSEONLY_NODES:
5050
% if not node.is_syntax_collection():
5151
% qualifier = "" if node.is_base() else "final"
5252
% for line in dedented_lines(node.description):

include/swift/Syntax/SyntaxVisitor.h.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace syntax {
3232
struct SyntaxVisitor {
3333
virtual ~SyntaxVisitor() {}
3434

35-
% for node in SYNTAX_NODES + SILONLY_NODES:
35+
% for node in SYNTAX_NODES + PARSEONLY_NODES:
3636
% if is_visitable(node):
3737
virtual void visit(${node.name} node);
3838
% end

lib/IDE/CodeCompletion.cpp

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,6 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
12171217
CompletionKind Kind = CompletionKind::None;
12181218
Expr *ParsedExpr = nullptr;
12191219
SourceLoc DotLoc;
1220-
TypeLoc ParsedTypeLoc;
12211220
DeclContext *CurDeclContext = nullptr;
12221221
DeclAttrKind AttrKind;
12231222

@@ -1351,8 +1350,8 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
13511350

13521351
void completeTypeDeclResultBeginning() override;
13531352
void completeTypeSimpleBeginning() override;
1354-
void completeTypeIdentifierWithDot(IdentTypeRepr *ITR) override;
1355-
void completeTypeIdentifierWithoutDot(IdentTypeRepr *ITR) override;
1353+
void completeTypeIdentifierWithDot() override;
1354+
void completeTypeIdentifierWithoutDot() override;
13561355

13571356
void completeCaseStmtKeyword() override;
13581357
void completeCaseStmtBeginning(CodeCompletionExpr *E) override;
@@ -4609,22 +4608,13 @@ void CodeCompletionCallbacksImpl::completeInPrecedenceGroup(SyntaxKind SK) {
46094608
CurDeclContext = P.CurDeclContext;
46104609
}
46114610

4612-
void CodeCompletionCallbacksImpl::completeTypeIdentifierWithDot(
4613-
IdentTypeRepr *ITR) {
4614-
if (!ITR) {
4615-
completeTypeSimpleBeginning();
4616-
return;
4617-
}
4611+
void CodeCompletionCallbacksImpl::completeTypeIdentifierWithDot() {
46184612
Kind = CompletionKind::TypeIdentifierWithDot;
4619-
ParsedTypeLoc = TypeLoc(ITR);
46204613
CurDeclContext = P.CurDeclContext;
46214614
}
46224615

4623-
void CodeCompletionCallbacksImpl::completeTypeIdentifierWithoutDot(
4624-
IdentTypeRepr *ITR) {
4625-
assert(ITR);
4616+
void CodeCompletionCallbacksImpl::completeTypeIdentifierWithoutDot() {
46264617
Kind = CompletionKind::TypeIdentifierWithoutDot;
4627-
ParsedTypeLoc = TypeLoc(ITR);
46284618
CurDeclContext = P.CurDeclContext;
46294619
}
46304620

lib/Parse/ASTGen.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "swift/Parse/ASTGen.h"
1414

1515
#include "swift/Basic/SourceManager.h"
16+
#include "swift/Parse/CodeCompletionCallbacks.h"
1617
#include "swift/Parse/Parser.h"
1718

1819
using namespace swift;
@@ -123,6 +124,8 @@ TypeRepr *ASTGen::generate(const TypeSyntax &Type, const SourceLoc Loc) {
123124
TypeAST = generate(*Unwrapped, Loc);
124125
else if (auto Attributed = Type.getAs<AttributedTypeSyntax>())
125126
TypeAST = generate(*Attributed, Loc);
127+
else if (auto CompletionTy = Type.getAs<CodeCompletionTypeSyntax>())
128+
TypeAST = generate(*CompletionTy, Loc);
126129
else if (auto Unknown = Type.getAs<UnknownTypeSyntax>())
127130
TypeAST = generate(*Unknown, Loc);
128131

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

451+
TypeRepr *ASTGen::generate(const CodeCompletionTypeSyntax &Type,
452+
const SourceLoc Loc) {
453+
auto base = Type.getBase();
454+
if (!base)
455+
return nullptr;
456+
457+
TypeRepr *parsedTyR = generate(*base, Loc);
458+
if (parsedTyR) {
459+
if (P.CodeCompletion)
460+
P.CodeCompletion->setParsedTypeLoc(parsedTyR);
461+
}
462+
return parsedTyR;
463+
}
464+
448465
TypeRepr *ASTGen::generate(const UnknownTypeSyntax &Type, const SourceLoc Loc) {
449466
auto ChildrenCount = Type.getNumChildren();
450467

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

456-
if (Protocol && Protocol->getText() == "protocol") {
473+
if (keyword && keyword->getText() == "protocol") {
474+
auto keywordLoc = advanceLocBegin(Loc, *keyword);
457475
auto LAngle = Type.getChild(1);
458-
459-
SmallVector<TypeSyntax, 4> Protocols;
460-
for (unsigned i = 2; i < Type.getNumChildren(); i++)
461-
if (auto PType = Type.getChild(i)->getAs<TypeSyntax>())
462-
Protocols.push_back(*PType);
463-
464476
auto RAngle = Type.getChild(ChildrenCount - 1);
465477

466-
auto ProtocolLoc = advanceLocBegin(Loc, *Protocol);
467478
auto LAngleLoc = advanceLocBegin(Loc, *LAngle);
468479
auto RAngleLoc = advanceLocBegin(Loc, *RAngle);
469480

470-
SmallVector<TypeRepr *, 4> ProtocolTypes;
471-
for (auto &&P : llvm::reverse(Protocols))
472-
ProtocolTypes.push_back(generate(P, Loc));
473-
std::reverse(std::begin(ProtocolTypes), std::end(ProtocolTypes));
481+
SmallVector<TypeRepr *, 4> protocols;
482+
for (unsigned i = 2; i < Type.getNumChildren(); i++) {
483+
if (auto elem = Type.getChild(i)->getAs<TypeSyntax>())
484+
if (auto proto = generate(*elem, Loc))
485+
protocols.push_back(proto);
486+
}
474487

475-
return CompositionTypeRepr::create(Context, ProtocolTypes, ProtocolLoc,
488+
return CompositionTypeRepr::create(Context, protocols, keywordLoc,
476489
{LAngleLoc, RAngleLoc});
477490
}
478491
}

0 commit comments

Comments
 (0)