Skip to content

Commit 9050690

Browse files
authored
Merge pull request #68603 from ahoppen/ahoppen/storage-attribute-completion
[CodeCompletion] Completion for `@storageRestrictions` attribute
2 parents 1c8f295 + 8550799 commit 9050690

File tree

7 files changed

+274
-44
lines changed

7 files changed

+274
-44
lines changed

include/swift/IDE/CompletionLookup.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
105105
TypeInDeclContext,
106106
ImportFromModule,
107107
GenericRequirement,
108+
109+
/// Look up stored properties within a type.
110+
StoredProperty,
108111
};
109112

110113
LookupKind Kind;
@@ -528,6 +531,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
528531
void getValueExprCompletions(Type ExprType, ValueDecl *VD = nullptr,
529532
bool IsDeclUnapplied = false);
530533

534+
/// Add completions for stored properties of \p D.
535+
void getStoredPropertyCompletions(const NominalTypeDecl *D);
536+
531537
void collectOperators(SmallVectorImpl<OperatorDecl *> &results);
532538

533539
void addPostfixBang(Type resultType);

include/swift/Parse/IDEInspectionCallbacks.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,25 @@ enum class CustomSyntaxAttributeKind {
3636
Available,
3737
FreestandingMacro,
3838
AttachedMacro,
39+
StorageRestrictions
40+
};
41+
42+
/// A bit of a hack. When completing inside the '@storageRestrictions'
43+
/// attribute, we use the \c ParamIndex field to communicate where inside the
44+
/// attribute we are performing the completion.
45+
enum class StorageRestrictionsCompletionKind : int {
46+
/// We are completing directly after the '(' and require a 'initializes' or
47+
/// 'accesses' label.
48+
Label,
49+
/// We are completing in a context that only allows arguments (ie. accessed or
50+
/// initialized variables) and doesn't permit an argument label.
51+
Argument,
52+
/// Completion in a context that allows either an argument or the
53+
/// 'initializes' label.
54+
ArgumentOrInitializesLabel,
55+
/// Completion in a context that allows either an argument or the
56+
/// 'accesses' label.
57+
ArgumentOrAccessesLabel
3958
};
4059

4160
/// Parser's interface to code completion.

lib/IDE/CompletionLookup.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,7 @@ bool CompletionLookup::isImplicitlyCurriedInstanceMethod(
13051305

13061306
switch (Kind) {
13071307
case LookupKind::ValueExpr:
1308+
case LookupKind::StoredProperty:
13081309
return ExprType->is<AnyMetatypeType>();
13091310
case LookupKind::ValueInDeclContext:
13101311
if (InsideStaticMethod)
@@ -2248,6 +2249,13 @@ void CompletionLookup::foundDecl(ValueDecl *D, DeclVisibilityKind Reason,
22482249
}
22492250

22502251
return;
2252+
case LookupKind::StoredProperty:
2253+
if (auto *VD = dyn_cast<VarDecl>(D)) {
2254+
if (VD->hasStorage()) {
2255+
addVarDeclRef(VD, Reason, dynamicLookupInfo);
2256+
}
2257+
return;
2258+
}
22512259
}
22522260
}
22532261

@@ -2463,6 +2471,17 @@ void CompletionLookup::getValueExprCompletions(Type ExprType, ValueDecl *VD,
24632471
/*includeProtocolExtensionMembers*/ true);
24642472
}
24652473

2474+
void CompletionLookup::getStoredPropertyCompletions(const NominalTypeDecl *D) {
2475+
Kind = LookupKind::StoredProperty;
2476+
NeedLeadingDot = false;
2477+
2478+
lookupVisibleMemberDecls(*this, D->getDeclaredInterfaceType(),
2479+
/*DotLoc=*/SourceLoc(), CurrDeclContext,
2480+
/*IncludeInstanceMembers*/ true,
2481+
/*includeDerivedRequirements*/ false,
2482+
/*includeProtocolExtensionMembers*/ false);
2483+
}
2484+
24662485
void CompletionLookup::collectOperators(
24672486
SmallVectorImpl<OperatorDecl *> &results) {
24682487
assert(CurrDeclContext);
@@ -3051,6 +3070,43 @@ void CompletionLookup::getAttributeDeclParamCompletions(
30513070
break;
30523071
}
30533072
break;
3073+
case CustomSyntaxAttributeKind::StorageRestrictions: {
3074+
bool suggestInitializesLabel = false;
3075+
bool suggestAccessesLabel = false;
3076+
bool suggestArgument = false;
3077+
switch (static_cast<StorageRestrictionsCompletionKind>(ParamIndex)) {
3078+
case StorageRestrictionsCompletionKind::Label:
3079+
suggestAccessesLabel = true;
3080+
suggestInitializesLabel = true;
3081+
break;
3082+
case StorageRestrictionsCompletionKind::Argument:
3083+
suggestArgument = true;
3084+
break;
3085+
case StorageRestrictionsCompletionKind::ArgumentOrInitializesLabel:
3086+
suggestArgument = true;
3087+
suggestInitializesLabel = true;
3088+
break;
3089+
case StorageRestrictionsCompletionKind::ArgumentOrAccessesLabel:
3090+
suggestArgument = true;
3091+
suggestAccessesLabel = true;
3092+
break;
3093+
}
3094+
if (suggestInitializesLabel) {
3095+
addDeclAttrParamKeyword(
3096+
"initializes", /*Parameters=*/{},
3097+
"Specify stored properties initialized by the accessor", true);
3098+
}
3099+
if (suggestAccessesLabel) {
3100+
addDeclAttrParamKeyword(
3101+
"accesses", /*Parameters=*/{},
3102+
"Specify stored properties accessed by the accessor", true);
3103+
}
3104+
if (suggestArgument) {
3105+
if (auto NT = dyn_cast<NominalTypeDecl>(CurrDeclContext)) {
3106+
getStoredPropertyCompletions(NT);
3107+
}
3108+
}
3109+
}
30543110
}
30553111
}
30563112

0 commit comments

Comments
 (0)