Skip to content

Commit 63e7c93

Browse files
authored
Merge pull request swiftlang#74890 from hamishknight/attr-etc
[Completion] Update type attribute completions
2 parents fc012fd + ec597c8 commit 63e7c93

15 files changed

+163
-70
lines changed

include/swift/AST/Attr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3058,6 +3058,10 @@ class alignas(1 << AttrAlignInBits) TypeAttribute
30583058
/// Return the name (like "autoclosure") for an attribute ID.
30593059
static const char *getAttrName(TypeAttrKind kind);
30603060

3061+
/// Returns whether the given attribute is considered "user inaccessible",
3062+
/// which affects e.g whether it shows up in code completion.
3063+
static bool isUserInaccessible(TypeAttrKind DK);
3064+
30613065
static TypeAttribute *createSimple(const ASTContext &context,
30623066
TypeAttrKind kind,
30633067
SourceLoc atLoc,

include/swift/AST/TypeAttr.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,9 @@
5353
// Type attributes
5454
SIMPLE_TYPE_ATTR(autoclosure, Autoclosure)
5555
TYPE_ATTR(convention, Convention)
56-
SIMPLE_TYPE_ATTR(noescape, NoEscape)
5756
SIMPLE_TYPE_ATTR(escaping, Escaping)
5857
TYPE_ATTR(differentiable, Differentiable)
5958
SIMPLE_TYPE_ATTR(noDerivative, NoDerivative)
60-
SIMPLE_TYPE_ATTR(async, Async)
6159
SIMPLE_TYPE_ATTR(Sendable, Sendable)
6260
SIMPLE_TYPE_ATTR(retroactive, Retroactive)
6361
SIMPLE_TYPE_ATTR(unchecked, Unchecked)
@@ -68,10 +66,11 @@ TYPE_ATTR(_opaqueReturnTypeOf, OpaqueReturnTypeOf)
6866
TYPE_ATTR(isolated, Isolated)
6967

7068
// SIL-specific attributes
69+
SIMPLE_SIL_TYPE_ATTR(async, Async)
7170
SIMPLE_SIL_TYPE_ATTR(block_storage, BlockStorage)
7271
SIMPLE_SIL_TYPE_ATTR(box, Box)
7372
SIMPLE_SIL_TYPE_ATTR(dynamic_self, DynamicSelf)
74-
#define REF_STORAGE(Name, name, ...) SIMPLE_TYPE_ATTR(sil_##name, SIL##Name)
73+
#define REF_STORAGE(Name, name, ...) SIMPLE_SIL_TYPE_ATTR(sil_##name, SIL##Name)
7574
#include "swift/AST/ReferenceStorage.def"
7675
SIMPLE_SIL_TYPE_ATTR(error, Error)
7776
SIMPLE_SIL_TYPE_ATTR(error_indirect, ErrorIndirect)
@@ -84,6 +83,7 @@ SIMPLE_SIL_TYPE_ATTR(inout_aliasable, InoutAliasable)
8483
SIMPLE_SIL_TYPE_ATTR(in_guaranteed, InGuaranteed)
8584
SIMPLE_SIL_TYPE_ATTR(in_cxx, InCXX)
8685
SIMPLE_SIL_TYPE_ATTR(in_constant, InConstant)
86+
SIMPLE_SIL_TYPE_ATTR(noescape, NoEscape)
8787
SIMPLE_SIL_TYPE_ATTR(pack_owned, PackOwned)
8888
SIMPLE_SIL_TYPE_ATTR(pack_guaranteed, PackGuaranteed)
8989
SIMPLE_SIL_TYPE_ATTR(pack_inout, PackInout)

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: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,44 +1256,10 @@ class Parser {
12561256
return isLifetimeDependenceToken();
12571257
}
12581258

1259-
struct ParsedTypeAttributeList {
1260-
ParamDecl::Specifier Specifier = ParamDecl::Specifier::Default;
1261-
SourceLoc SpecifierLoc;
1262-
SourceLoc IsolatedLoc;
1263-
SourceLoc ConstLoc;
1264-
SourceLoc SendingLoc;
1265-
SmallVector<TypeOrCustomAttr> Attributes;
1266-
SmallVector<LifetimeDependenceSpecifier> lifetimeDependenceSpecifiers;
1267-
1268-
/// Main entry point for parsing.
1269-
///
1270-
/// Inline we just have the fast path of failing to match. We call slowParse
1271-
/// that contains the outline of more complex implementation. This is HOT
1272-
/// code!
1273-
ParserStatus parse(Parser &P) {
1274-
auto &Tok = P.Tok;
1275-
if (Tok.is(tok::at_sign) || P.isParameterSpecifier())
1276-
return slowParse(P);
1277-
return makeParserSuccess();
1278-
}
1279-
1280-
TypeRepr *applyAttributesToType(Parser &P, TypeRepr *Type) const;
1281-
1282-
private:
1283-
/// An out of line implementation of the more complicated cases. This
1284-
/// ensures on the inlined fast path we handle the case of not matching.
1285-
ParserStatus slowParse(Parser &P);
1286-
};
1287-
12881259
bool parseConventionAttributeInternal(SourceLoc atLoc, SourceLoc attrLoc,
12891260
ConventionTypeAttr *&result,
12901261
bool justChecking);
12911262

1292-
ParserStatus parseTypeAttribute(TypeOrCustomAttr &result, SourceLoc AtLoc,
1293-
SourceLoc AtEndLoc,
1294-
PatternBindingInitializer *&initContext,
1295-
bool justChecking = false);
1296-
12971263
ParserStatus parseLifetimeDependenceSpecifiers(
12981264
SmallVectorImpl<LifetimeDependenceSpecifier> &specifierList);
12991265

@@ -1432,6 +1398,8 @@ class Parser {
14321398

14331399
/// Whether the type is for a closure attribute.
14341400
CustomAttribute,
1401+
/// A type in an inheritance clause.
1402+
InheritanceClause,
14351403
};
14361404

14371405
ParserResult<TypeRepr> parseTypeScalar(
@@ -1488,6 +1456,43 @@ class Parser {
14881456
/// Parse a dotted type, e.g. 'Foo<X>.Y.Z', 'P.Type', '[X].Y'.
14891457
ParserResult<TypeRepr> parseTypeDotted(ParserResult<TypeRepr> Base);
14901458

1459+
struct ParsedTypeAttributeList {
1460+
ParseTypeReason ParseReason;
1461+
ParamDecl::Specifier Specifier = ParamDecl::Specifier::Default;
1462+
SourceLoc SpecifierLoc;
1463+
SourceLoc IsolatedLoc;
1464+
SourceLoc ConstLoc;
1465+
SourceLoc SendingLoc;
1466+
SmallVector<TypeOrCustomAttr> Attributes;
1467+
SmallVector<LifetimeDependenceSpecifier> lifetimeDependenceSpecifiers;
1468+
1469+
ParsedTypeAttributeList(ParseTypeReason reason) : ParseReason(reason) {}
1470+
1471+
/// Main entry point for parsing.
1472+
///
1473+
/// Inline we just have the fast path of failing to match. We call slowParse
1474+
/// that contains the outline of more complex implementation. This is HOT
1475+
/// code!
1476+
ParserStatus parse(Parser &P) {
1477+
auto &Tok = P.Tok;
1478+
if (Tok.is(tok::at_sign) || P.isParameterSpecifier())
1479+
return slowParse(P);
1480+
return makeParserSuccess();
1481+
}
1482+
1483+
TypeRepr *applyAttributesToType(Parser &P, TypeRepr *Type) const;
1484+
1485+
private:
1486+
/// An out of line implementation of the more complicated cases. This
1487+
/// ensures on the inlined fast path we handle the case of not matching.
1488+
ParserStatus slowParse(Parser &P);
1489+
};
1490+
1491+
ParserStatus parseTypeAttribute(TypeOrCustomAttr &result, SourceLoc AtLoc,
1492+
SourceLoc AtEndLoc, ParseTypeReason reason,
1493+
PatternBindingInitializer *&initContext,
1494+
bool justChecking = false);
1495+
14911496
ParserResult<TypeRepr> parseOldStyleProtocolComposition();
14921497
ParserResult<TypeRepr> parseAnyType();
14931498
ParserResult<TypeRepr> parseSILBoxType(GenericParamList *generics,

lib/AST/Attr.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,24 @@ const char *TypeAttribute::getAttrName(TypeAttrKind kind) {
146146
llvm_unreachable("unknown type attribute kind");
147147
}
148148

149+
bool TypeAttribute::isUserInaccessible(TypeAttrKind DK) {
150+
// Currently we can base this off whether it is underscored or for SIL.
151+
// TODO: We could introduce a similar options scheme to DECL_ATTR if we ever
152+
// need a user-inaccessible non-underscored attribute.
153+
switch (DK) {
154+
// SIL attributes are always considered user-inaccessible.
155+
#define SIL_TYPE_ATTR(SPELLING, C) \
156+
case TypeAttrKind::C: \
157+
return true;
158+
// For non-SIL attributes, check whether the spelling is underscored.
159+
#define TYPE_ATTR(SPELLING, C) \
160+
case TypeAttrKind::C: \
161+
return StringRef(#SPELLING).starts_with("_");
162+
#include "swift/AST/TypeAttr.def"
163+
}
164+
llvm_unreachable("unhandled case in switch!");
165+
}
166+
149167
TypeAttribute *TypeAttribute::createSimple(const ASTContext &context,
150168
TypeAttrKind kind,
151169
SourceLoc atLoc,

lib/IDE/CodeCompletion.cpp

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

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

659+
void CodeCompletionCallbacksImpl::completeTypeAttrInheritanceBeginning() {
660+
CurDeclContext = P.CurDeclContext;
661+
Kind = CompletionKind::TypeAttrInheritanceBeginning;
662+
}
663+
658664
bool swift::ide::isDynamicLookup(Type T) {
659665
return T->getRValueType()->isAnyObject();
660666
}
@@ -983,6 +989,7 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
983989
case CompletionKind::PrecedenceGroup:
984990
case CompletionKind::StmtLabel:
985991
case CompletionKind::TypeAttrBeginning:
992+
case CompletionKind::TypeAttrInheritanceBeginning:
986993
case CompletionKind::OptionalBinding:
987994
case CompletionKind::WithoutConstraintType:
988995
break;
@@ -1931,14 +1938,14 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
19311938
Lookup.getStmtLabelCompletions(Loc, ParentStmtKind == StmtKind::Continue);
19321939
break;
19331940
}
1934-
case CompletionKind::TypeAttrBeginning: {
1935-
Lookup.getTypeAttributeKeywordCompletions();
1941+
case CompletionKind::TypeAttrBeginning:
1942+
case CompletionKind::TypeAttrInheritanceBeginning: {
1943+
Lookup.getTypeAttributeKeywordCompletions(Kind);
19361944

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

lib/IDE/CompletionLookup.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3132,18 +3132,39 @@ void CompletionLookup::getAttributeDeclParamCompletions(
31323132
}
31333133
}
31343134

3135-
void CompletionLookup::getTypeAttributeKeywordCompletions() {
3136-
auto addTypeAttr = [&](StringRef Name) {
3135+
void CompletionLookup::getTypeAttributeKeywordCompletions(
3136+
CompletionKind completionKind) {
3137+
auto addTypeAttr = [&](TypeAttrKind Kind, StringRef Name) {
3138+
if (completionKind != CompletionKind::TypeAttrInheritanceBeginning) {
3139+
switch (Kind) {
3140+
case TypeAttrKind::Retroactive:
3141+
case TypeAttrKind::Preconcurrency:
3142+
case TypeAttrKind::Unchecked:
3143+
// These attributes are only available in inheritance clasuses.
3144+
return;
3145+
default:
3146+
break;
3147+
}
3148+
}
31373149
CodeCompletionResultBuilder Builder = makeResultBuilder(
31383150
CodeCompletionResultKind::Keyword, SemanticContextKind::None);
31393151
Builder.addAttributeKeyword(Name, "Type Attribute");
31403152
};
3141-
addTypeAttr("autoclosure");
3142-
addTypeAttr("convention(swift)");
3143-
addTypeAttr("convention(block)");
3144-
addTypeAttr("convention(c)");
3145-
addTypeAttr("convention(thin)");
3146-
addTypeAttr("escaping");
3153+
3154+
// Add simple user-accessible attributes.
3155+
#define SIL_TYPE_ATTR(SPELLING, C)
3156+
#define SIMPLE_SIL_TYPE_ATTR(SPELLING, C)
3157+
#define SIMPLE_TYPE_ATTR(SPELLING, C) \
3158+
if (!TypeAttribute::isUserInaccessible(TypeAttrKind::C)) \
3159+
addTypeAttr(TypeAttrKind::C, #SPELLING);
3160+
#include "swift/AST/TypeAttr.def"
3161+
3162+
// Add non-simple cases.
3163+
addTypeAttr(TypeAttrKind::Convention, "convention(swift)");
3164+
addTypeAttr(TypeAttrKind::Convention, "convention(block)");
3165+
addTypeAttr(TypeAttrKind::Convention, "convention(c)");
3166+
addTypeAttr(TypeAttrKind::Convention, "convention(thin)");
3167+
addTypeAttr(TypeAttrKind::Isolated, "isolated(any)");
31473168
}
31483169

31493170
void CompletionLookup::collectPrecedenceGroups() {

lib/Parse/ParseDecl.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4483,7 +4483,8 @@ bool Parser::canParseTypeAttribute() {
44834483
TypeOrCustomAttr result; // ignored
44844484
PatternBindingInitializer *initContext = nullptr;
44854485
return !parseTypeAttribute(result, /*atLoc=*/SourceLoc(),
4486-
/*atEndLoc=*/SourceLoc(), initContext,
4486+
/*atEndLoc=*/SourceLoc(),
4487+
ParseTypeReason::Unspecified, initContext,
44874488
/*justChecking*/ true)
44884489
.isError();
44894490
}
@@ -4684,6 +4685,7 @@ bool Parser::parseUUIDString(UUID &uuid, Diag<> diagnostic, bool justChecking) {
46844685
/// no need to actually record the attribute
46854686
ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result,
46864687
SourceLoc AtLoc, SourceLoc AtEndLoc,
4688+
ParseTypeReason reason,
46874689
PatternBindingInitializer *&initContext,
46884690
bool justChecking) {
46894691
if (AtEndLoc != Tok.getLoc()) {
@@ -4699,7 +4701,14 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result,
46994701
if (Tok.is(tok::code_complete)) {
47004702
if (!justChecking) {
47014703
if (CodeCompletionCallbacks) {
4702-
CodeCompletionCallbacks->completeTypeAttrBeginning();
4704+
switch (reason) {
4705+
case ParseTypeReason::InheritanceClause:
4706+
CodeCompletionCallbacks->completeTypeAttrInheritanceBeginning();
4707+
break;
4708+
default:
4709+
CodeCompletionCallbacks->completeTypeAttrBeginning();
4710+
break;
4711+
}
47034712
}
47044713
}
47054714
consumeToken(tok::code_complete);
@@ -5525,7 +5534,8 @@ ParserStatus Parser::ParsedTypeAttributeList::slowParse(Parser &P) {
55255534
TypeOrCustomAttr result;
55265535
SourceLoc AtEndLoc = Tok.getRange().getEnd();
55275536
SourceLoc AtLoc = P.consumeToken();
5528-
status |= P.parseTypeAttribute(result, AtLoc, AtEndLoc, initContext);
5537+
status |=
5538+
P.parseTypeAttribute(result, AtLoc, AtEndLoc, ParseReason, initContext);
55295539
if (status.isError())
55305540
return status;
55315541
if (result)
@@ -6806,7 +6816,8 @@ ParserStatus Parser::parseInheritance(
68066816
continue;
68076817
}
68086818

6809-
auto ParsedTypeResult = parseType();
6819+
auto ParsedTypeResult =
6820+
parseType(diag::expected_type, ParseTypeReason::InheritanceClause);
68106821
Status |= ParsedTypeResult;
68116822

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

0 commit comments

Comments
 (0)