Skip to content

Commit 6098a3c

Browse files
committed
[CodeCompletion] Support completion for macro roles and the 'names:' argument label
rdar://108163121
1 parent becbdc8 commit 6098a3c

File tree

8 files changed

+104
-13
lines changed

8 files changed

+104
-13
lines changed

include/swift/AST/MacroDeclaration.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,13 @@ enum class MacroRole: uint32_t {
5858
/// A freestanding macro that expands to expressions, statements and
5959
/// declarations in a code block.
6060
CodeItem = 0x80,
61+
62+
// NOTE: When adding a new macro role, also add it to `getAllMacroRoles`.
6163
};
6264

65+
/// Returns an enumeratable list of all macro roles.
66+
std::vector<MacroRole> getAllMacroRoles();
67+
6368
/// The contexts in which a particular macro declaration can be used.
6469
using MacroRoles = OptionSet<MacroRole>;
6570

include/swift/IDE/CompletionLookup.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
585585

586586
void getAttributeDeclCompletions(bool IsInSil, Optional<DeclKind> DK);
587587

588-
void getAttributeDeclParamCompletions(DeclAttrKind AttrKind, int ParamIndex);
588+
void getAttributeDeclParamCompletions(CustomSyntaxAttributeKind AttrKind,
589+
int ParamIndex);
589590

590591
void getTypeAttributeKeywordCompletions();
591592

include/swift/Parse/IDEInspectionCallbacks.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ enum class ObjCSelectorContext {
2929
SetterSelector
3030
};
3131

32+
/// Attributes that have syntax which can't be modelled using a function call.
33+
/// This can't be \c DeclAttrKind because '@freestandig' and '@attached' have
34+
/// the same attribute kind but take different macro roles as arguemnts.
35+
enum class CustomSyntaxAttributeKind {
36+
Available,
37+
FreestandingMacro,
38+
AttachedMacro,
39+
};
40+
3241
/// Parser's interface to code completion.
3342
class CodeCompletionCallbacks {
3443
protected:
@@ -185,7 +194,7 @@ class CodeCompletionCallbacks {
185194

186195
/// Complete the parameters in attribute, for instance, version specifier for
187196
/// @available.
188-
virtual void completeDeclAttrParam(DeclAttrKind DK, int Index) {};
197+
virtual void completeDeclAttrParam(CustomSyntaxAttributeKind DK, int Index){};
189198

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

lib/AST/Decl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10091,6 +10091,14 @@ BuiltinTupleDecl::BuiltinTupleDecl(Identifier Name, DeclContext *Parent)
1009110091
: NominalTypeDecl(DeclKind::BuiltinTuple, Parent, Name, SourceLoc(),
1009210092
ArrayRef<InheritedEntry>(), nullptr) {}
1009310093

10094+
std::vector<MacroRole> swift::getAllMacroRoles() {
10095+
return {
10096+
MacroRole::Expression, MacroRole::Declaration, MacroRole::Accessor,
10097+
MacroRole::MemberAttribute, MacroRole::Member, MacroRole::Peer,
10098+
MacroRole::Conformance, MacroRole::CodeItem,
10099+
};
10100+
}
10101+
1009410102
StringRef swift::getMacroRoleString(MacroRole role) {
1009510103
switch (role) {
1009610104
case MacroRole::Expression:

lib/IDE/CodeCompletion.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks,
113113
SourceLoc DotLoc;
114114
TypeLoc ParsedTypeLoc;
115115
DeclContext *CurDeclContext = nullptr;
116-
DeclAttrKind AttrKind;
116+
CustomSyntaxAttributeKind AttrKind;
117117

118118
/// When the code completion token occurs in a custom attribute, the attribute
119119
/// it occurs in. Used so we can complete inside the attribute even if it's
@@ -270,7 +270,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks,
270270
void completeCaseStmtKeyword() override;
271271
void completeCaseStmtBeginning(CodeCompletionExpr *E) override;
272272
void completeDeclAttrBeginning(bool Sil, bool isIndependent) override;
273-
void completeDeclAttrParam(DeclAttrKind DK, int Index) override;
273+
void completeDeclAttrParam(CustomSyntaxAttributeKind DK, int Index) override;
274274
void completeEffectsSpecifier(bool hasAsync, bool hasThrows) override;
275275
void completeInPrecedenceGroup(
276276
CodeCompletionCallbacks::PrecedenceGroupCompletionKind SK) override;
@@ -456,8 +456,8 @@ void CodeCompletionCallbacksImpl::completeTypeSimpleBeginning() {
456456
CurDeclContext = P.CurDeclContext;
457457
}
458458

459-
void CodeCompletionCallbacksImpl::completeDeclAttrParam(DeclAttrKind DK,
460-
int Index) {
459+
void CodeCompletionCallbacksImpl::completeDeclAttrParam(
460+
CustomSyntaxAttributeKind DK, int Index) {
461461
Kind = CompletionKind::AttributeDeclParen;
462462
AttrKind = DK;
463463
AttrParamIndex = Index;

lib/IDE/CompletionLookup.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3004,9 +3004,10 @@ void CompletionLookup::getAttributeDeclCompletions(bool IsInSil,
30043004
#include "swift/AST/Attr.def"
30053005
}
30063006

3007-
void CompletionLookup::getAttributeDeclParamCompletions(DeclAttrKind AttrKind,
3008-
int ParamIndex) {
3009-
if (AttrKind == DAK_Available) {
3007+
void CompletionLookup::getAttributeDeclParamCompletions(
3008+
CustomSyntaxAttributeKind AttrKind, int ParamIndex) {
3009+
switch (AttrKind) {
3010+
case CustomSyntaxAttributeKind::Available:
30103011
if (ParamIndex == 0) {
30113012
addDeclAttrParamKeyword("*", "Platform", false);
30123013

@@ -3022,6 +3023,28 @@ void CompletionLookup::getAttributeDeclParamCompletions(DeclAttrKind AttrKind,
30223023
addDeclAttrParamKeyword("introduced", "Specify version number", true);
30233024
addDeclAttrParamKeyword("deprecated", "Specify version number", true);
30243025
}
3026+
break;
3027+
case CustomSyntaxAttributeKind::FreestandingMacro:
3028+
case CustomSyntaxAttributeKind::AttachedMacro:
3029+
switch (ParamIndex) {
3030+
case 0:
3031+
for (auto role : getAllMacroRoles()) {
3032+
bool isRoleSupported = isMacroSupported(role, Ctx);
3033+
if (AttrKind == CustomSyntaxAttributeKind::FreestandingMacro) {
3034+
isRoleSupported &= isFreestandingMacro(role);
3035+
} else if (AttrKind == CustomSyntaxAttributeKind::AttachedMacro) {
3036+
isRoleSupported &= isAttachedMacro(role);
3037+
}
3038+
if (isRoleSupported) {
3039+
addDeclAttrParamKeyword(getMacroRoleString(role), "", false);
3040+
}
3041+
}
3042+
break;
3043+
case 1:
3044+
addDeclAttrParamKeyword("names", "Specify declared names", true);
3045+
break;
3046+
}
3047+
break;
30253048
}
30263049
}
30273050

@@ -3096,7 +3119,7 @@ void CompletionLookup::getPrecedenceGroupCompletions(
30963119
void CompletionLookup::getPoundAvailablePlatformCompletions() {
30973120

30983121
// The platform names should be identical to those in @available.
3099-
getAttributeDeclParamCompletions(DAK_Available, 0);
3122+
getAttributeDeclParamCompletions(CustomSyntaxAttributeKind::Available, 0);
31003123
}
31013124

31023125
void CompletionLookup::getSelfTypeCompletionInDeclContext(

lib/Parse/ParseDecl.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -507,8 +507,8 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
507507
diagnose(ArgumentLoc, diag::attr_availability_expected_option, AttrName)
508508
.highlight(SourceRange(ArgumentLoc));
509509
if (Tok.is(tok::code_complete) && CodeCompletionCallbacks) {
510-
CodeCompletionCallbacks->completeDeclAttrParam(DAK_Available,
511-
ParamIndex);
510+
CodeCompletionCallbacks->completeDeclAttrParam(
511+
CustomSyntaxAttributeKind::Available, ParamIndex);
512512
consumeToken(tok::code_complete);
513513
} else {
514514
consumeIf(tok::identifier);
@@ -940,7 +940,8 @@ bool Parser::parseAvailability(
940940
if (!Tok.is(tok::identifier) &&
941941
!(Tok.isAnyOperator() && Tok.getText() == "*")) {
942942
if (Tok.is(tok::code_complete) && CodeCompletionCallbacks) {
943-
CodeCompletionCallbacks->completeDeclAttrParam(DAK_Available, 0);
943+
CodeCompletionCallbacks->completeDeclAttrParam(
944+
CustomSyntaxAttributeKind::Available, 0);
944945
consumeToken(tok::code_complete);
945946
}
946947
diagnose(Tok.getLoc(), diag::attr_availability_platform, AttrName)
@@ -2220,6 +2221,24 @@ Parser::parseMacroRoleAttribute(
22202221
[&] {
22212222
ParserStatus status;
22222223

2224+
if (Tok.is(tok::code_complete)) {
2225+
consumeIf(tok::code_complete);
2226+
status.setHasCodeCompletionAndIsError();
2227+
CustomSyntaxAttributeKind attributeKind =
2228+
isAttached ? CustomSyntaxAttributeKind::AttachedMacro
2229+
: CustomSyntaxAttributeKind::FreestandingMacro;
2230+
if (!sawRole) {
2231+
sawRole = true;
2232+
if (this->CodeCompletionCallbacks) {
2233+
this->CodeCompletionCallbacks->completeDeclAttrParam(attributeKind, 0);
2234+
}
2235+
} else if (!sawNames) {
2236+
if (this->CodeCompletionCallbacks) {
2237+
this->CodeCompletionCallbacks->completeDeclAttrParam(attributeKind, 1);
2238+
}
2239+
}
2240+
}
2241+
22232242
// Parse the argment label, if there is one.
22242243
Identifier fieldName;
22252244
SourceLoc fieldNameLoc;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-ide-test -batch-code-completion -source-filename %s -filecheck %raw-FileCheck -completion-output-dir %t/output
3+
4+
5+
@freestanding(#^FREESTANDING_ROLE^#)
6+
macro FreestandingMacro
7+
8+
// FREESTANDING_ROLE: Begin completions, 2 items
9+
// FREESTANDING_ROLE-DAG: Keyword/None: expression; name=expression
10+
// FREESTANDING_ROLE-DAG: Keyword/None: declaration; name=declaration
11+
12+
@attached(#^ATTACHED_ROLE^#)
13+
macro AttachedMacro
14+
15+
// ATTACHED_ROLE: Begin completions, 5 items
16+
// ATTACHED_ROLE-DAG: Keyword/None: accessor; name=accessor
17+
// ATTACHED_ROLE-DAG: Keyword/None: memberAttribute; name=memberAttribute
18+
// ATTACHED_ROLE-DAG: Keyword/None: member; name=member
19+
// ATTACHED_ROLE-DAG: Keyword/None: peer; name=peer
20+
// ATTACHED_ROLE-DAG: Keyword/None: conformance; name=conformance
21+
22+
@freestanding(declaration, #^NAMES_POSITION^#)
23+
macro FreestandingDeclarationMacro
24+
25+
// NAMES_POSITION: Begin completions, 1 item
26+
// NAMES_POSITION-DAG: Keyword/None: names: [#Specify declared names#]; name=names

0 commit comments

Comments
 (0)