Skip to content

Commit f023fd3

Browse files
authored
Merge pull request #65523 from ahoppen/ahoppen/5.9/macro-attribute-completions
[5.9] [CodeCompletion] Support completion for macro roles and the 'names:' argument label
2 parents 7d233e3 + 673f987 commit f023fd3

13 files changed

+246
-109
lines changed

include/swift/AST/DiagnosticsCommon.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ ERROR(unknown_attribute,none,
220220
NOTE(in_macro_expansion,none,
221221
"in expansion of macro %0 here", (DeclName))
222222
ERROR(macro_experimental,none,
223-
"%0 macros are an experimental feature that is not enabled (%1)",
223+
"%0 macros are an experimental feature that is not enabled %select{|(%1)}1",
224224
(StringRef, StringRef))
225225
ERROR(ambiguous_macro_reference,none,
226226
"ambiguous reference to macro %0", (DeclName))

include/swift/AST/MacroDeclaration.h

Lines changed: 8 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

@@ -83,6 +88,9 @@ bool isAttachedMacro(MacroRoles contexts);
8388

8489
MacroRoles getAttachedMacroRoles();
8590

91+
/// Checks if the macro is supported or guarded behind an experimental flag.
92+
bool isMacroSupported(MacroRole role, ASTContext &ctx);
93+
8694
enum class MacroIntroducedDeclNameKind {
8795
Named,
8896
Overloaded,

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) {};

include/swift/Parse/Parser.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,9 +1024,10 @@ class Parser {
10241024
PatternBindingInitializer *initContext);
10251025

10261026
/// Parse the optional modifiers before a declaration.
1027-
bool parseDeclModifierList(DeclAttributes &Attributes, SourceLoc &StaticLoc,
1028-
StaticSpellingKind &StaticSpelling,
1029-
bool isFromClangAttribute = false);
1027+
ParserStatus parseDeclModifierList(DeclAttributes &Attributes,
1028+
SourceLoc &StaticLoc,
1029+
StaticSpellingKind &StaticSpelling,
1030+
bool isFromClangAttribute = false);
10301031

10311032
/// Parse an availability attribute of the form
10321033
/// @available(*, introduced: 1.0, deprecated: 3.1).
@@ -1138,9 +1139,9 @@ class Parser {
11381139
ParserResult<CustomAttr> parseCustomAttribute(
11391140
SourceLoc atLoc, PatternBindingInitializer *&initContext);
11401141

1141-
bool parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
1142-
DeclAttrKind DK,
1143-
bool isFromClangAttribute = false);
1142+
ParserStatus parseNewDeclAttribute(DeclAttributes &Attributes,
1143+
SourceLoc AtLoc, DeclAttrKind DK,
1144+
bool isFromClangAttribute = false);
11441145

11451146
/// Parse a version tuple of the form x[.y[.z]]. Returns true if there was
11461147
/// an error parsing.

lib/AST/Decl.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10101,6 +10101,14 @@ BuiltinTupleDecl::BuiltinTupleDecl(Identifier Name, DeclContext *Parent)
1010110101
: NominalTypeDecl(DeclKind::BuiltinTuple, Parent, Name, SourceLoc(),
1010210102
ArrayRef<InheritedEntry>(), nullptr) {}
1010310103

10104+
std::vector<MacroRole> swift::getAllMacroRoles() {
10105+
return {
10106+
MacroRole::Expression, MacroRole::Declaration, MacroRole::Accessor,
10107+
MacroRole::MemberAttribute, MacroRole::Member, MacroRole::Peer,
10108+
MacroRole::Conformance, MacroRole::CodeItem,
10109+
};
10110+
}
10111+
1010410112
StringRef swift::getMacroRoleString(MacroRole role) {
1010510113
switch (role) {
1010610114
case MacroRole::Expression:
@@ -10192,6 +10200,21 @@ MacroRoles swift::getAttachedMacroRoles() {
1019210200
return attachedMacroRoles;
1019310201
}
1019410202

10203+
bool swift::isMacroSupported(MacroRole role, ASTContext &ctx) {
10204+
switch (role) {
10205+
case MacroRole::Expression:
10206+
case MacroRole::Declaration:
10207+
case MacroRole::Accessor:
10208+
case MacroRole::MemberAttribute:
10209+
case MacroRole::Member:
10210+
case MacroRole::Peer:
10211+
case MacroRole::Conformance:
10212+
return true;
10213+
case MacroRole::CodeItem:
10214+
return ctx.LangOpts.hasFeature(Feature::CodeItemMacros);
10215+
}
10216+
}
10217+
1019510218
void MissingDecl::forEachMacroExpandedDecl(MacroExpandedDeclCallback callback) {
1019610219
auto macroRef = unexpandedMacro.macroRef;
1019710220
auto *baseDecl = unexpandedMacro.baseDecl;

lib/ClangImporter/ImportDecl.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7682,9 +7682,11 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
76827682
} else {
76837683
SourceLoc staticLoc;
76847684
StaticSpellingKind staticSpelling;
7685-
hadError = parser.parseDeclModifierList(
7686-
MappedDecl->getAttrs(), staticLoc, staticSpelling,
7687-
/*isFromClangAttribute=*/true);
7685+
hadError = parser
7686+
.parseDeclModifierList(MappedDecl->getAttrs(), staticLoc,
7687+
staticSpelling,
7688+
/*isFromClangAttribute=*/true)
7689+
.isError();
76887690
}
76897691

76907692
if (hadError) {

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
@@ -3011,9 +3011,10 @@ void CompletionLookup::getAttributeDeclCompletions(bool IsInSil,
30113011
#include "swift/AST/Attr.def"
30123012
}
30133013

3014-
void CompletionLookup::getAttributeDeclParamCompletions(DeclAttrKind AttrKind,
3015-
int ParamIndex) {
3016-
if (AttrKind == DAK_Available) {
3014+
void CompletionLookup::getAttributeDeclParamCompletions(
3015+
CustomSyntaxAttributeKind AttrKind, int ParamIndex) {
3016+
switch (AttrKind) {
3017+
case CustomSyntaxAttributeKind::Available:
30173018
if (ParamIndex == 0) {
30183019
addDeclAttrParamKeyword("*", "Platform", false);
30193020

@@ -3029,6 +3030,28 @@ void CompletionLookup::getAttributeDeclParamCompletions(DeclAttrKind AttrKind,
30293030
addDeclAttrParamKeyword("introduced", "Specify version number", true);
30303031
addDeclAttrParamKeyword("deprecated", "Specify version number", true);
30313032
}
3033+
break;
3034+
case CustomSyntaxAttributeKind::FreestandingMacro:
3035+
case CustomSyntaxAttributeKind::AttachedMacro:
3036+
switch (ParamIndex) {
3037+
case 0:
3038+
for (auto role : getAllMacroRoles()) {
3039+
bool isRoleSupported = isMacroSupported(role, Ctx);
3040+
if (AttrKind == CustomSyntaxAttributeKind::FreestandingMacro) {
3041+
isRoleSupported &= isFreestandingMacro(role);
3042+
} else if (AttrKind == CustomSyntaxAttributeKind::AttachedMacro) {
3043+
isRoleSupported &= isAttachedMacro(role);
3044+
}
3045+
if (isRoleSupported) {
3046+
addDeclAttrParamKeyword(getMacroRoleString(role), "", false);
3047+
}
3048+
}
3049+
break;
3050+
case 1:
3051+
addDeclAttrParamKeyword("names", "Specify declared names", true);
3052+
break;
3053+
}
3054+
break;
30323055
}
30333056
}
30343057

@@ -3103,7 +3126,7 @@ void CompletionLookup::getPrecedenceGroupCompletions(
31033126
void CompletionLookup::getPoundAvailablePlatformCompletions() {
31043127

31053128
// The platform names should be identical to those in @available.
3106-
getAttributeDeclParamCompletions(DAK_Available, 0);
3129+
getAttributeDeclParamCompletions(CustomSyntaxAttributeKind::Available, 0);
31073130
}
31083131

31093132
void CompletionLookup::getSelfTypeCompletionInDeclContext(

0 commit comments

Comments
 (0)