Skip to content

Commit f8542d9

Browse files
committed
[Completion] Only complete @unchecked et al in inheritance clauses
Add a case for completing type attributes in inheritance clause position, and limit the completion of `@unchecked`, `@preconcurrency`, and `@retroactive` to that case.
1 parent 7e356f8 commit f8542d9

File tree

11 files changed

+97
-23
lines changed

11 files changed

+97
-23
lines changed

include/swift/IDE/CodeCompletionResult.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ enum class CompletionKind : uint8_t {
229229
StmtLabel,
230230
ForEachPatternBeginning,
231231
TypeAttrBeginning,
232+
TypeAttrInheritanceBeginning,
232233
OptionalBinding,
233234

234235
/// Completion after `~` in an inheritance clause.

include/swift/IDE/CompletionLookup.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
605605
void getAttributeDeclParamCompletions(CustomSyntaxAttributeKind AttrKind,
606606
int ParamIndex, bool HasLabel);
607607

608-
void getTypeAttributeKeywordCompletions();
608+
void getTypeAttributeKeywordCompletions(CompletionKind completionKind);
609609

610610
void collectPrecedenceGroups();
611611

include/swift/Parse/IDEInspectionCallbacks.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ class CodeCompletionCallbacks {
288288

289289
virtual void completeTypeAttrBeginning() {};
290290

291+
virtual void completeTypeAttrInheritanceBeginning() {};
292+
291293
virtual void completeOptionalBinding(){};
292294

293295
virtual void completeWithoutConstraintType(){};

include/swift/Parse/Parser.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1391,6 +1391,8 @@ class Parser {
13911391

13921392
/// Whether the type is for a closure attribute.
13931393
CustomAttribute,
1394+
/// A type in an inheritance clause.
1395+
InheritanceClause,
13941396
};
13951397

13961398
ParserResult<TypeRepr> parseTypeScalar(
@@ -1448,6 +1450,7 @@ class Parser {
14481450
ParserResult<TypeRepr> parseTypeDotted(ParserResult<TypeRepr> Base);
14491451

14501452
struct ParsedTypeAttributeList {
1453+
ParseTypeReason ParseReason;
14511454
ParamDecl::Specifier Specifier = ParamDecl::Specifier::Default;
14521455
SourceLoc SpecifierLoc;
14531456
SourceLoc IsolatedLoc;
@@ -1457,6 +1460,8 @@ class Parser {
14571460
SmallVector<TypeOrCustomAttr> Attributes;
14581461
SmallVector<LifetimeDependenceSpecifier> lifetimeDependenceSpecifiers;
14591462

1463+
ParsedTypeAttributeList(ParseTypeReason reason) : ParseReason(reason) {}
1464+
14601465
/// Main entry point for parsing.
14611466
///
14621467
/// Inline we just have the fast path of failing to match. We call slowParse
@@ -1478,7 +1483,7 @@ class Parser {
14781483
};
14791484

14801485
ParserStatus parseTypeAttribute(TypeOrCustomAttr &result, SourceLoc AtLoc,
1481-
SourceLoc AtEndLoc,
1486+
SourceLoc AtEndLoc, ParseTypeReason reason,
14821487
PatternBindingInitializer *&initContext,
14831488
bool justChecking = false);
14841489

lib/IDE/CodeCompletion.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks,
302302
void completeStmtLabel(StmtKind ParentKind) override;
303303
void completeForEachPatternBeginning(bool hasTry, bool hasAwait) override;
304304
void completeTypeAttrBeginning() override;
305+
void completeTypeAttrInheritanceBeginning() override;
305306
void completeOptionalBinding() override;
306307
void completeWithoutConstraintType() override;
307308

@@ -654,6 +655,11 @@ void CodeCompletionCallbacksImpl::completeTypeAttrBeginning() {
654655
Kind = CompletionKind::TypeAttrBeginning;
655656
}
656657

658+
void CodeCompletionCallbacksImpl::completeTypeAttrInheritanceBeginning() {
659+
CurDeclContext = P.CurDeclContext;
660+
Kind = CompletionKind::TypeAttrInheritanceBeginning;
661+
}
662+
657663
bool swift::ide::isDynamicLookup(Type T) {
658664
return T->getRValueType()->isAnyObject();
659665
}
@@ -982,6 +988,7 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
982988
case CompletionKind::PrecedenceGroup:
983989
case CompletionKind::StmtLabel:
984990
case CompletionKind::TypeAttrBeginning:
991+
case CompletionKind::TypeAttrInheritanceBeginning:
985992
case CompletionKind::OptionalBinding:
986993
case CompletionKind::WithoutConstraintType:
987994
break;
@@ -1930,14 +1937,14 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
19301937
Lookup.getStmtLabelCompletions(Loc, ParentStmtKind == StmtKind::Continue);
19311938
break;
19321939
}
1933-
case CompletionKind::TypeAttrBeginning: {
1934-
Lookup.getTypeAttributeKeywordCompletions();
1940+
case CompletionKind::TypeAttrBeginning:
1941+
case CompletionKind::TypeAttrInheritanceBeginning: {
1942+
Lookup.getTypeAttributeKeywordCompletions(Kind);
19351943

19361944
// Type names at attribute position after '@'.
19371945
Lookup.getTypeCompletionsInDeclContext(
19381946
P.Context.SourceMgr.getIDEInspectionTargetLoc());
19391947
break;
1940-
19411948
}
19421949
case CompletionKind::OptionalBinding: {
19431950
SourceLoc Loc = P.Context.SourceMgr.getIDEInspectionTargetLoc();

lib/IDE/CompletionLookup.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3131,8 +3131,20 @@ void CompletionLookup::getAttributeDeclParamCompletions(
31313131
}
31323132
}
31333133

3134-
void CompletionLookup::getTypeAttributeKeywordCompletions() {
3135-
auto addTypeAttr = [&](StringRef Name) {
3134+
void CompletionLookup::getTypeAttributeKeywordCompletions(
3135+
CompletionKind completionKind) {
3136+
auto addTypeAttr = [&](TypeAttrKind Kind, StringRef Name) {
3137+
if (completionKind != CompletionKind::TypeAttrInheritanceBeginning) {
3138+
switch (Kind) {
3139+
case TypeAttrKind::Retroactive:
3140+
case TypeAttrKind::Preconcurrency:
3141+
case TypeAttrKind::Unchecked:
3142+
// These attributes are only available in inheritance clasuses.
3143+
return;
3144+
default:
3145+
break;
3146+
}
3147+
}
31363148
CodeCompletionResultBuilder Builder = makeResultBuilder(
31373149
CodeCompletionResultKind::Keyword, SemanticContextKind::None);
31383150
Builder.addAttributeKeyword(Name, "Type Attribute");
@@ -3141,17 +3153,17 @@ void CompletionLookup::getTypeAttributeKeywordCompletions() {
31413153
// Add simple user-accessible attributes.
31423154
#define SIL_TYPE_ATTR(SPELLING, C)
31433155
#define SIMPLE_SIL_TYPE_ATTR(SPELLING, C)
3144-
#define SIMPLE_TYPE_ATTR(SPELLING, C) \
3145-
if (!TypeAttribute::isUserInaccessible(TypeAttrKind::C)) \
3146-
addTypeAttr(#SPELLING);
3156+
#define SIMPLE_TYPE_ATTR(SPELLING, C) \
3157+
if (!TypeAttribute::isUserInaccessible(TypeAttrKind::C)) \
3158+
addTypeAttr(TypeAttrKind::C, #SPELLING);
31473159
#include "swift/AST/TypeAttr.def"
31483160

31493161
// Add non-simple cases.
3150-
addTypeAttr("convention(swift)");
3151-
addTypeAttr("convention(block)");
3152-
addTypeAttr("convention(c)");
3153-
addTypeAttr("convention(thin)");
3154-
addTypeAttr("isolated(any)");
3162+
addTypeAttr(TypeAttrKind::Convention, "convention(swift)");
3163+
addTypeAttr(TypeAttrKind::Convention, "convention(block)");
3164+
addTypeAttr(TypeAttrKind::Convention, "convention(c)");
3165+
addTypeAttr(TypeAttrKind::Convention, "convention(thin)");
3166+
addTypeAttr(TypeAttrKind::Isolated, "isolated(any)");
31553167
}
31563168

31573169
void CompletionLookup::collectPrecedenceGroups() {

lib/Parse/ParseDecl.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4489,7 +4489,8 @@ bool Parser::canParseTypeAttribute() {
44894489
TypeOrCustomAttr result; // ignored
44904490
PatternBindingInitializer *initContext = nullptr;
44914491
return !parseTypeAttribute(result, /*atLoc=*/SourceLoc(),
4492-
/*atEndLoc=*/SourceLoc(), initContext,
4492+
/*atEndLoc=*/SourceLoc(),
4493+
ParseTypeReason::Unspecified, initContext,
44934494
/*justChecking*/ true)
44944495
.isError();
44954496
}
@@ -4690,6 +4691,7 @@ bool Parser::parseUUIDString(UUID &uuid, Diag<> diagnostic, bool justChecking) {
46904691
/// no need to actually record the attribute
46914692
ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result,
46924693
SourceLoc AtLoc, SourceLoc AtEndLoc,
4694+
ParseTypeReason reason,
46934695
PatternBindingInitializer *&initContext,
46944696
bool justChecking) {
46954697
if (AtEndLoc != Tok.getLoc()) {
@@ -4705,7 +4707,14 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result,
47054707
if (Tok.is(tok::code_complete)) {
47064708
if (!justChecking) {
47074709
if (CodeCompletionCallbacks) {
4708-
CodeCompletionCallbacks->completeTypeAttrBeginning();
4710+
switch (reason) {
4711+
case ParseTypeReason::InheritanceClause:
4712+
CodeCompletionCallbacks->completeTypeAttrInheritanceBeginning();
4713+
break;
4714+
default:
4715+
CodeCompletionCallbacks->completeTypeAttrBeginning();
4716+
break;
4717+
}
47094718
}
47104719
}
47114720
consumeToken(tok::code_complete);
@@ -5534,7 +5543,8 @@ ParserStatus Parser::ParsedTypeAttributeList::slowParse(Parser &P) {
55345543
TypeOrCustomAttr result;
55355544
SourceLoc AtEndLoc = Tok.getRange().getEnd();
55365545
SourceLoc AtLoc = P.consumeToken();
5537-
status |= P.parseTypeAttribute(result, AtLoc, AtEndLoc, initContext);
5546+
status |=
5547+
P.parseTypeAttribute(result, AtLoc, AtEndLoc, ParseReason, initContext);
55385548
if (status.isError())
55395549
return status;
55405550
if (result)
@@ -6803,7 +6813,8 @@ ParserStatus Parser::parseInheritance(
68036813
continue;
68046814
}
68056815

6806-
auto ParsedTypeResult = parseType();
6816+
auto ParsedTypeResult =
6817+
parseType(diag::expected_type, ParseTypeReason::InheritanceClause);
68076818
Status |= ParsedTypeResult;
68086819

68096820
// Record the type if its a single type.

lib/Parse/ParsePattern.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ SourceLoc Parser::tryCompleteFunctionParamTypeBeginning() {
177177
// Skip over any starting parameter specifiers.
178178
{
179179
CancellableBacktrackingScope backtrack(*this);
180-
ParsedTypeAttributeList attrs;
180+
ParsedTypeAttributeList attrs(ParseTypeReason::Unspecified);
181181
attrs.parse(*this);
182182
if (!Tok.is(tok::code_complete))
183183
return SourceLoc();

lib/Parse/ParseType.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,15 @@ ParserResult<TypeRepr> Parser::parseTypeScalar(
399399
ParserStatus status;
400400

401401
// Parse attributes.
402-
ParsedTypeAttributeList parsedAttributeList;
402+
ParsedTypeAttributeList parsedAttributeList(reason);
403403
status |= parsedAttributeList.parse(*this);
404404

405+
// If we have a completion, create an ErrorType.
406+
if (status.hasCodeCompletion()) {
407+
auto *ET = ErrorTypeRepr::create(Context, PreviousLoc);
408+
return makeParserCodeCompletionResult<TypeRepr>(ET);
409+
}
410+
405411
// Parse generic parameters in SIL mode.
406412
GenericParamList *generics = nullptr;
407413
SourceLoc substitutedLoc;

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1128,7 +1128,8 @@ bool SILParser::parseSILType(SILType &Result,
11281128
}
11291129

11301130
// Parse attributes.
1131-
Parser::ParsedTypeAttributeList parsedAttrs;
1131+
Parser::ParsedTypeAttributeList parsedAttrs(
1132+
Parser::ParseTypeReason::Unspecified);
11321133
parsedAttrs.parse(P);
11331134

11341135
// Global functions are implicitly @convention(thin) if not specified otherwise.

test/IDE/complete_type_attribute.swift

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,45 @@
11
// RUN: %batch-code-completion
22

33
// TYPEATTR-NOT: myIntValue
4+
// TYPEATTR-NOT: Type Attribute
45
// TYPEATTR-DAG: Keyword/None: autoclosure[#Type Attribute#]; name=autoclosure
56
// TYPEATTR-DAG: Keyword/None: convention(swift)[#Type Attribute#]; name=convention(swift)
67
// TYPEATTR-DAG: Keyword/None: convention(block)[#Type Attribute#]; name=convention(block)
78
// TYPEATTR-DAG: Keyword/None: convention(c)[#Type Attribute#]; name=convention(c)
89
// TYPEATTR-DAG: Keyword/None: convention(thin)[#Type Attribute#]; name=convention(thin)
910
// TYPEATTR-DAG: Keyword/None: escaping[#Type Attribute#]; name=escaping
11+
// TYPEATTR-DAG: Keyword/None: isolated(any)[#Type Attribute#]; name=isolated(any)
12+
// TYPEATTR-DAG: Keyword/None: noDerivative[#Type Attribute#]; name=noDerivative
13+
// TYPEATTR-DAG: Keyword/None: Sendable[#Type Attribute#]; name=Sendable
14+
// TYPEATTR-NOT: Type Attribute
1015
// TYPEATTR-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
16+
// TYPEATTR-NOT: Type Attribute
1117
// TYPEATTR-NOT: myIntValue
1218

13-
struct MyStruct {}
19+
// TYPEATTR_INHERIT-DAG: Keyword/None: autoclosure[#Type Attribute#]; name=autoclosure
20+
// TYPEATTR_INHERIT-DAG: Keyword/None: convention(swift)[#Type Attribute#]; name=convention(swift)
21+
// TYPEATTR_INHERIT-DAG: Keyword/None: convention(block)[#Type Attribute#]; name=convention(block)
22+
// TYPEATTR_INHERIT-DAG: Keyword/None: convention(c)[#Type Attribute#]; name=convention(c)
23+
// TYPEATTR_INHERIT-DAG: Keyword/None: convention(thin)[#Type Attribute#]; name=convention(thin)
24+
// TYPEATTR_INHERIT-DAG: Keyword/None: escaping[#Type Attribute#]; name=escaping
25+
// TYPEATTR_INHERIT-DAG: Keyword/None: isolated(any)[#Type Attribute#]; name=isolated(any)
26+
// TYPEATTR_INHERIT-DAG: Keyword/None: noDerivative[#Type Attribute#]; name=noDerivative
27+
// TYPEATTR_INHERIT-DAG: Keyword/None: Sendable[#Type Attribute#]; name=Sendable
28+
//
29+
// TYPEATTR_INHERIT-DAG: Keyword/None: retroactive[#Type Attribute#]; name=retroactive
30+
// TYPEATTR_INHERIT-DAG: Keyword/None: unchecked[#Type Attribute#]; name=unchecked
31+
// TYPEATTR_INHERIT-DAG: Keyword/None: preconcurrency[#Type Attribute#]; name=preconcurrency
32+
33+
struct MyStruct : @#^STRUCT_INHERIT?check=TYPEATTR_INHERIT^# {}
34+
35+
class C : @#^CLASS_INHERIT?check=TYPEATTR_INHERIT^#,
36+
Array<@#^GENERIC_ARG_INHERIT?check=TYPEATTR^#>,
37+
@unchecked @#^CLASS_INHERIT2?check=TYPEATTR_INHERIT^# {}
38+
39+
extension C : @#^EXT_INHERIT1?check=TYPEATTR_INHERIT^# {}
40+
41+
protocol P : @#^PROTO_INHERIT?check=TYPEATTR_INHERIT^# {}
42+
extension C : P, @#^EXT_INHERIT2?check=TYPEATTR_INHERIT^# {}
1443

1544
var myIntValue: Int = 1
1645

0 commit comments

Comments
 (0)