Skip to content

Commit 76e21ad

Browse files
authored
Merge pull request #65569 from ahoppen/ahoppen/5.9/name-suggestions
[5.9][CodeComplete] Offer completions for the `names:` argument of a macro declaration
2 parents 0244445 + fbb9827 commit 76e21ad

File tree

9 files changed

+109
-35
lines changed

9 files changed

+109
-35
lines changed

include/swift/AST/MacroDeclaration.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,14 @@ enum class MacroIntroducedDeclNameKind {
9797
Prefixed,
9898
Suffixed,
9999
Arbitrary,
100+
101+
// NOTE: When adding a new name kind, also add it to
102+
// `getAllMacroIntroducedDeclNameKinds`.
100103
};
101104

105+
/// Returns an enumeratable list of all macro introduced decl name kinds.
106+
std::vector<MacroIntroducedDeclNameKind> getAllMacroIntroducedDeclNameKinds();
107+
102108
/// Whether a macro-introduced name of this kind requires an argument.
103109
bool macroIntroducedNameRequiresArgument(MacroIntroducedDeclNameKind kind);
104110

include/swift/IDE/CompletionLookup.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
449449
CodeCompletionKeywordKind KeyKind = CodeCompletionKeywordKind::None,
450450
CodeCompletionFlair flair = {});
451451

452-
void addDeclAttrParamKeyword(StringRef Name, StringRef Annotation,
453-
bool NeedSpecify);
452+
void addDeclAttrParamKeyword(StringRef Name, ArrayRef<StringRef> Parameters,
453+
StringRef Annotation, bool NeedSpecify);
454454

455455
void addDeclAttrKeyword(StringRef Name, StringRef Annotation);
456456

@@ -586,7 +586,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
586586
void getAttributeDeclCompletions(bool IsInSil, Optional<DeclKind> DK);
587587

588588
void getAttributeDeclParamCompletions(CustomSyntaxAttributeKind AttrKind,
589-
int ParamIndex);
589+
int ParamIndex, bool HasLabel);
590590

591591
void getTypeAttributeKeywordCompletions();
592592

include/swift/Parse/IDEInspectionCallbacks.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,10 @@ class CodeCompletionCallbacks {
194194

195195
/// Complete the parameters in attribute, for instance, version specifier for
196196
/// @available.
197-
virtual void completeDeclAttrParam(CustomSyntaxAttributeKind DK, int Index){};
197+
/// If `HasLabel` is `true`, then the argument already has a label specified,
198+
/// e.g. we're completing after `names: ` in a macro declaration.
199+
virtual void completeDeclAttrParam(CustomSyntaxAttributeKind DK, int Index,
200+
bool HasLabel){};
198201

199202
/// Complete 'async' and 'throws' at effects specifier position.
200203
virtual void completeEffectsSpecifier(bool hasAsync, bool hasThrows) {};

lib/AST/Decl.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10137,6 +10137,17 @@ StringRef swift::getMacroRoleString(MacroRole role) {
1013710137
}
1013810138
}
1013910139

10140+
std::vector<MacroIntroducedDeclNameKind>
10141+
swift::getAllMacroIntroducedDeclNameKinds() {
10142+
return {
10143+
MacroIntroducedDeclNameKind::Named,
10144+
MacroIntroducedDeclNameKind::Overloaded,
10145+
MacroIntroducedDeclNameKind::Prefixed,
10146+
MacroIntroducedDeclNameKind::Suffixed,
10147+
MacroIntroducedDeclNameKind::Arbitrary,
10148+
};
10149+
}
10150+
1014010151
bool swift::macroIntroducedNameRequiresArgument(
1014110152
MacroIntroducedDeclNameKind kind
1014210153
) {

lib/IDE/CodeCompletion.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks,
127127
CodeCompletionCallbacks::PrecedenceGroupCompletionKind SyntxKind;
128128

129129
int AttrParamIndex;
130+
bool AttrParamHasLabel;
130131
bool IsInSil = false;
131132
bool HasSpace = false;
132133
bool ShouldCompleteCallPatternAfterParen = true;
@@ -270,7 +271,8 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks,
270271
void completeCaseStmtKeyword() override;
271272
void completeCaseStmtBeginning(CodeCompletionExpr *E) override;
272273
void completeDeclAttrBeginning(bool Sil, bool isIndependent) override;
273-
void completeDeclAttrParam(CustomSyntaxAttributeKind DK, int Index) override;
274+
void completeDeclAttrParam(CustomSyntaxAttributeKind DK, int Index,
275+
bool HasLabel) override;
274276
void completeEffectsSpecifier(bool hasAsync, bool hasThrows) override;
275277
void completeInPrecedenceGroup(
276278
CodeCompletionCallbacks::PrecedenceGroupCompletionKind SK) override;
@@ -457,10 +459,11 @@ void CodeCompletionCallbacksImpl::completeTypeSimpleBeginning() {
457459
}
458460

459461
void CodeCompletionCallbacksImpl::completeDeclAttrParam(
460-
CustomSyntaxAttributeKind DK, int Index) {
462+
CustomSyntaxAttributeKind DK, int Index, bool HasLabel) {
461463
Kind = CompletionKind::AttributeDeclParen;
462464
AttrKind = DK;
463465
AttrParamIndex = Index;
466+
AttrParamHasLabel = HasLabel;
464467
CurDeclContext = P.CurDeclContext;
465468
}
466469

@@ -1844,7 +1847,8 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
18441847
break;
18451848
}
18461849
case CompletionKind::AttributeDeclParen: {
1847-
Lookup.getAttributeDeclParamCompletions(AttrKind, AttrParamIndex);
1850+
Lookup.getAttributeDeclParamCompletions(AttrKind, AttrParamIndex,
1851+
AttrParamHasLabel);
18481852
break;
18491853
}
18501854
case CompletionKind::PoundAvailablePlatform: {

lib/IDE/CodeCompletionResultBuilder.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,17 @@ class CodeCompletionResultBuilder {
345345
addChunkWithTextNoCopy(CodeCompletionString::Chunk::ChunkKind::Equal, "=");
346346
}
347347

348-
void addDeclAttrParamKeyword(StringRef Name, StringRef Annotation,
349-
bool NeedSpecify) {
348+
void addDeclAttrParamKeyword(StringRef Name, ArrayRef<StringRef> Parameters,
349+
StringRef Annotation, bool NeedSpecify) {
350350
addChunkWithText(CodeCompletionString::Chunk::ChunkKind::
351351
DeclAttrParamKeyword, Name);
352+
if (!Parameters.empty()) {
353+
addLeftParen();
354+
for (auto Parameter : Parameters) {
355+
addSimpleNamedParameter(Parameter);
356+
}
357+
addRightParen();
358+
}
352359
if (NeedSpecify)
353360
addChunkWithText(CodeCompletionString::Chunk::ChunkKind::
354361
DeclAttrParamColon, ": ");

lib/IDE/CompletionLookup.cpp

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,11 +1850,12 @@ void CompletionLookup::addKeyword(StringRef Name, StringRef TypeAnnotation,
18501850
}
18511851

18521852
void CompletionLookup::addDeclAttrParamKeyword(StringRef Name,
1853+
ArrayRef<StringRef> Parameters,
18531854
StringRef Annotation,
18541855
bool NeedSpecify) {
18551856
CodeCompletionResultBuilder Builder(Sink, CodeCompletionResultKind::Keyword,
18561857
SemanticContextKind::None);
1857-
Builder.addDeclAttrParamKeyword(Name, Annotation, NeedSpecify);
1858+
Builder.addDeclAttrParamKeyword(Name, Parameters, Annotation, NeedSpecify);
18581859
}
18591860

18601861
void CompletionLookup::addDeclAttrKeyword(StringRef Name,
@@ -3012,23 +3013,27 @@ void CompletionLookup::getAttributeDeclCompletions(bool IsInSil,
30123013
}
30133014

30143015
void CompletionLookup::getAttributeDeclParamCompletions(
3015-
CustomSyntaxAttributeKind AttrKind, int ParamIndex) {
3016+
CustomSyntaxAttributeKind AttrKind, int ParamIndex, bool HasLabel) {
30163017
switch (AttrKind) {
30173018
case CustomSyntaxAttributeKind::Available:
30183019
if (ParamIndex == 0) {
3019-
addDeclAttrParamKeyword("*", "Platform", false);
3020+
addDeclAttrParamKeyword("*", /*Parameters=*/{}, "Platform", false);
30203021

30213022
#define AVAILABILITY_PLATFORM(X, PrettyName) \
3022-
addDeclAttrParamKeyword(swift::platformString(PlatformKind::X), "Platform", \
3023-
false);
3023+
addDeclAttrParamKeyword(swift::platformString(PlatformKind::X), \
3024+
/*Parameters=*/{}, "Platform", false);
30243025
#include "swift/AST/PlatformKinds.def"
30253026

30263027
} else {
3027-
addDeclAttrParamKeyword("unavailable", "", false);
3028-
addDeclAttrParamKeyword("message", "Specify message", true);
3029-
addDeclAttrParamKeyword("renamed", "Specify replacing name", true);
3030-
addDeclAttrParamKeyword("introduced", "Specify version number", true);
3031-
addDeclAttrParamKeyword("deprecated", "Specify version number", true);
3028+
addDeclAttrParamKeyword("unavailable", /*Parameters=*/{}, "", false);
3029+
addDeclAttrParamKeyword("message", /*Parameters=*/{}, "Specify message",
3030+
true);
3031+
addDeclAttrParamKeyword("renamed", /*Parameters=*/{},
3032+
"Specify replacing name", true);
3033+
addDeclAttrParamKeyword("introduced", /*Parameters=*/{},
3034+
"Specify version number", true);
3035+
addDeclAttrParamKeyword("deprecated", /*Parameters=*/{},
3036+
"Specify version number", true);
30323037
}
30333038
break;
30343039
case CustomSyntaxAttributeKind::FreestandingMacro:
@@ -3043,12 +3048,27 @@ void CompletionLookup::getAttributeDeclParamCompletions(
30433048
isRoleSupported &= isAttachedMacro(role);
30443049
}
30453050
if (isRoleSupported) {
3046-
addDeclAttrParamKeyword(getMacroRoleString(role), "", false);
3051+
addDeclAttrParamKeyword(getMacroRoleString(role), /*Parameters=*/{},
3052+
/*Annotation=*/"", /*NeedsSpecify=*/false);
30473053
}
30483054
}
30493055
break;
30503056
case 1:
3051-
addDeclAttrParamKeyword("names", "Specify declared names", true);
3057+
if (HasLabel) {
3058+
for (auto kind : getAllMacroIntroducedDeclNameKinds()) {
3059+
auto name = getMacroIntroducedDeclNameString(kind);
3060+
SmallVector<StringRef, 1> Parameters;
3061+
if (macroIntroducedNameRequiresArgument(kind)) {
3062+
Parameters = {"name"};
3063+
}
3064+
addDeclAttrParamKeyword(name, Parameters, /*Annotation=*/"",
3065+
/*NeedsSpecify=*/false);
3066+
}
3067+
} else {
3068+
addDeclAttrParamKeyword("names", /*Parameters=*/{},
3069+
"Specify declared names",
3070+
/*NeedsSpecify=*/true);
3071+
}
30523072
break;
30533073
}
30543074
break;
@@ -3126,7 +3146,8 @@ void CompletionLookup::getPrecedenceGroupCompletions(
31263146
void CompletionLookup::getPoundAvailablePlatformCompletions() {
31273147

31283148
// The platform names should be identical to those in @available.
3129-
getAttributeDeclParamCompletions(CustomSyntaxAttributeKind::Available, 0);
3149+
getAttributeDeclParamCompletions(CustomSyntaxAttributeKind::Available, 0,
3150+
/*HasLabel=*/false);
31303151
}
31313152

31323153
void CompletionLookup::getSelfTypeCompletionInDeclContext(

lib/Parse/ParseDecl.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,8 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
508508
.highlight(SourceRange(ArgumentLoc));
509509
if (Tok.is(tok::code_complete) && CodeCompletionCallbacks) {
510510
CodeCompletionCallbacks->completeDeclAttrParam(
511-
CustomSyntaxAttributeKind::Available, ParamIndex);
511+
CustomSyntaxAttributeKind::Available, ParamIndex,
512+
/*HasLabel=*/false);
512513
consumeToken(tok::code_complete);
513514
} else {
514515
consumeIf(tok::identifier);
@@ -941,7 +942,7 @@ bool Parser::parseAvailability(
941942
!(Tok.isAnyOperator() && Tok.getText() == "*")) {
942943
if (Tok.is(tok::code_complete) && CodeCompletionCallbacks) {
943944
CodeCompletionCallbacks->completeDeclAttrParam(
944-
CustomSyntaxAttributeKind::Available, 0);
945+
CustomSyntaxAttributeKind::Available, 0, /*HasLabel=*/false);
945946
consumeToken(tok::code_complete);
946947
}
947948
diagnose(Tok.getLoc(), diag::attr_availability_platform, AttrName)
@@ -2185,6 +2186,14 @@ Optional<MacroRole> getMacroRole(StringRef roleName) {
21852186
.Default(None);
21862187
}
21872188

2189+
static CustomSyntaxAttributeKind getCustomSyntaxAttributeKind(bool isAttached) {
2190+
if (isAttached) {
2191+
return CustomSyntaxAttributeKind::AttachedMacro;
2192+
} else {
2193+
return CustomSyntaxAttributeKind::FreestandingMacro;
2194+
}
2195+
}
2196+
21882197
ParserResult<MacroRoleAttr>
21892198
Parser::parseMacroRoleAttribute(
21902199
MacroSyntax syntax, SourceLoc AtLoc, SourceLoc Loc)
@@ -2221,20 +2230,18 @@ Parser::parseMacroRoleAttribute(
22212230
[&] {
22222231
ParserStatus status;
22232232

2224-
if (Tok.is(tok::code_complete)) {
2225-
consumeIf(tok::code_complete);
2233+
if (consumeIf(tok::code_complete)) {
22262234
status.setHasCodeCompletionAndIsError();
2227-
CustomSyntaxAttributeKind attributeKind =
2228-
isAttached ? CustomSyntaxAttributeKind::AttachedMacro
2229-
: CustomSyntaxAttributeKind::FreestandingMacro;
22302235
if (!sawRole) {
22312236
sawRole = true;
22322237
if (this->CodeCompletionCallbacks) {
2233-
this->CodeCompletionCallbacks->completeDeclAttrParam(attributeKind, 0);
2238+
this->CodeCompletionCallbacks->completeDeclAttrParam(
2239+
getCustomSyntaxAttributeKind(isAttached), 0, /*HasLabel=*/false);
22342240
}
22352241
} else if (!sawNames) {
22362242
if (this->CodeCompletionCallbacks) {
2237-
this->CodeCompletionCallbacks->completeDeclAttrParam(attributeKind, 1);
2243+
this->CodeCompletionCallbacks->completeDeclAttrParam(
2244+
getCustomSyntaxAttributeKind(isAttached), 1, /*HasLabel=*/false);
22382245
}
22392246
}
22402247
}
@@ -2309,10 +2316,15 @@ Parser::parseMacroRoleAttribute(
23092316
// Parse the introduced name kind.
23102317
Identifier introducedNameKind;
23112318
SourceLoc introducedNameKindLoc;
2312-
if (parseIdentifier(
2313-
introducedNameKind, introducedNameKindLoc,
2314-
diag::macro_attribute_unknown_argument_form,
2315-
/*diagnoseDollarPrefix=*/true)) {
2319+
if (consumeIf(tok::code_complete)) {
2320+
status.setHasCodeCompletionAndIsError();
2321+
if (this->CodeCompletionCallbacks) {
2322+
this->CodeCompletionCallbacks->completeDeclAttrParam(
2323+
getCustomSyntaxAttributeKind(isAttached), 1, /*HasLabel=*/true);
2324+
}
2325+
} else if (parseIdentifier(introducedNameKind, introducedNameKindLoc,
2326+
diag::macro_attribute_unknown_argument_form,
2327+
/*diagnoseDollarPrefix=*/true)) {
23162328
status.setIsParseError();
23172329
return status;
23182330
}

test/IDE/complete_macro_attribute.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,13 @@ macro FreestandingDeclarationMacro
2424

2525
// NAMES_POSITION: Begin completions, 1 item
2626
// NAMES_POSITION-DAG: Keyword/None: names: [#Specify declared names#]; name=names
27+
28+
@attached(member, names: #^NAMES_ARGUMENT^#)
29+
30+
// NAMES_ARGUMENT: Begin completions, 5 items
31+
// NAMES_ARGUMENT-DAG: Keyword/None: named({#(name)#}); name=named()
32+
// NAMES_ARGUMENT-DAG: Keyword/None: overloaded; name=overloaded
33+
// NAMES_ARGUMENT-DAG: Keyword/None: prefixed({#(name)#}); name=prefixed()
34+
// NAMES_ARGUMENT-DAG: Keyword/None: suffixed({#(name)#}); name=suffixed()
35+
// NAMES_ARGUMENT-DAG: Keyword/None: arbitrary; name=arbitrary
36+

0 commit comments

Comments
 (0)