Skip to content

Commit c2957db

Browse files
authored
Merge pull request #64253 from bnbarham/add-freestanding-decl-expansion
[Refactoring] Allow expanding freestanding decl expansions
2 parents a1c0abf + 3e76a5e commit c2957db

File tree

3 files changed

+80
-8
lines changed

3 files changed

+80
-8
lines changed

lib/IDE/SourceEntityWalker.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,14 @@ ASTWalker::PreWalkAction SemaAnnotator::walkToDeclPreProper(Decl *D) {
212212
}
213213
return Action::SkipChildren();
214214
}
215+
} else if (auto *MD = dyn_cast<MacroExpansionDecl>(D)) {
216+
if (auto *macro =
217+
dyn_cast_or_null<MacroDecl>(MD->getMacroRef().getDecl())) {
218+
auto macroRefType = macro->getDeclaredInterfaceType();
219+
if (!passReference(macro, macroRefType, MD->getMacroNameLoc(),
220+
ReferenceMetaData(SemaReferenceKind::DeclRef, None)))
221+
return Action::Stop();
222+
}
215223
}
216224

217225
CharSourceRange Range = (Loc.isValid()) ? CharSourceRange(Loc, NameLen)

lib/Refactoring/Refactoring.cpp

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,28 @@ class ContextFinder : public SourceEntityWalker {
5959
}
6060
return Result;
6161
}
62+
6263
public:
6364
ContextFinder(SourceFile &SF, ASTNode TargetNode,
6465
std::function<bool(ASTNode)> IsContext =
6566
[](ASTNode N) { return true; }) :
6667
SF(SF), Ctx(SF.getASTContext()), SM(Ctx.SourceMgr),
6768
Target(TargetNode.getSourceRange()), IsContext(IsContext) {}
69+
6870
ContextFinder(SourceFile &SF, SourceLoc TargetLoc,
6971
std::function<bool(ASTNode)> IsContext =
7072
[](ASTNode N) { return true; }) :
7173
SF(SF), Ctx(SF.getASTContext()), SM(Ctx.SourceMgr),
7274
Target(TargetLoc), IsContext(IsContext) {
7375
assert(TargetLoc.isValid() && "Invalid loc to find");
74-
}
76+
}
77+
78+
// Only need expansions for the expands refactoring, but we
79+
// skip nodes that don't contain the passed location anyway.
80+
virtual MacroWalking getMacroWalkingBehavior() const override {
81+
return MacroWalking::ArgumentsAndExpansion;
82+
}
83+
7584
bool walkToDeclPre(Decl *D, CharSourceRange Range) override { return contains(D); }
7685
bool walkToStmtPre(Stmt *S) override { return contains(S); }
7786
bool walkToExprPre(Expr *E) override { return contains(E); }
@@ -8497,6 +8506,15 @@ static Optional<unsigned> getMacroExpansionBuffer(
84978506
return None;
84988507
}
84998508

8509+
/// Retrieve the macro expansion buffer for the given macro expansion
8510+
/// declaration.
8511+
static Optional<unsigned>
8512+
getMacroExpansionBuffer(SourceManager &sourceMgr,
8513+
MacroExpansionDecl *expansion) {
8514+
return evaluateOrDefault(expansion->getASTContext().evaluator,
8515+
ExpandMacroExpansionDeclRequest{expansion}, {});
8516+
}
8517+
85008518
/// Retrieve the macro expansion buffers for the given attached macro reference.
85018519
static llvm::SmallVector<unsigned, 2>
85028520
getMacroExpansionBuffers(MacroDecl *macro, const CustomAttr *attr, Decl *decl) {
@@ -8584,13 +8602,14 @@ getMacroExpansionBuffers(SourceManager &sourceMgr, ResolvedCursorInfoPtr Info) {
85848602
// FIXME: A resolved cursor should contain a slice up to its reference.
85858603
// We shouldn't need to find it again.
85868604
ContextFinder Finder(*Info->getSourceFile(), Info->getLoc(), [&](ASTNode N) {
8587-
if (N.getStartLoc() == Info->getLoc())
8588-
return true;
8589-
8590-
// TODO: Handle MacroExpansionDecl
85918605
if (auto *expr =
85928606
dyn_cast_or_null<MacroExpansionExpr>(N.dyn_cast<Expr *>())) {
8593-
return expr->getMacroNameLoc().getBaseNameLoc() == Info->getLoc();
8607+
return expr->getStartLoc() == Info->getLoc() ||
8608+
expr->getMacroNameLoc().getBaseNameLoc() == Info->getLoc();
8609+
} else if (auto *decl =
8610+
dyn_cast_or_null<MacroExpansionDecl>(N.dyn_cast<Decl *>())) {
8611+
return decl->getStartLoc() == Info->getLoc() ||
8612+
decl->getMacroNameLoc().getBaseNameLoc() == Info->getLoc();
85948613
}
85958614

85968615
return false;
@@ -8599,8 +8618,11 @@ getMacroExpansionBuffers(SourceManager &sourceMgr, ResolvedCursorInfoPtr Info) {
85998618

86008619
if (!Finder.getContexts().empty()) {
86018620
Optional<unsigned> bufferID;
8602-
if (auto *target = dyn_cast<MacroExpansionExpr>(
8603-
Finder.getContexts()[0].get<Expr *>())) {
8621+
if (auto *target = dyn_cast_or_null<MacroExpansionExpr>(
8622+
Finder.getContexts()[0].dyn_cast<Expr *>())) {
8623+
bufferID = getMacroExpansionBuffer(sourceMgr, target);
8624+
} else if (auto *target = dyn_cast_or_null<MacroExpansionDecl>(
8625+
Finder.getContexts()[0].dyn_cast<Decl *>())) {
86048626
bufferID = getMacroExpansionBuffer(sourceMgr, target);
86058627
}
86068628

test/SourceKit/Macros/macro_basic.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ macro Hashable() = #externalMacro(module: "MacroDefinition", type: "HashableMacr
5151
@Hashable
5252
struct S4 { }
5353

54+
@freestanding(declaration)
55+
macro anonymousTypes(_: () -> String) = #externalMacro(module: "MacroDefinition", type: "DefineAnonymousTypesMacro")
56+
57+
#anonymousTypes { "hello" }
58+
5459
// FIXME: Swift parser is not enabled on Linux CI yet.
5560
// REQUIRES: OS=macosx
5661

@@ -105,6 +110,43 @@ struct S4 { }
105110
// EXPAND: source.edit.kind.active:
106111
// EXPAND-NEXT: 4:7-4:24 (@__swiftmacro_9MacroUser13testStringify1a1bySi_SitF9stringifyfMf_.swift) "(a + b, "a + b")"
107112

113+
//##-- cursor-info on macro declaration
114+
// RUN: %sourcekitd-test -req=cursor -pos=57:1 -cursor-action -req-opts=retrieve_symbol_graph=1 %s -- ${COMPILER_ARGS[@]} -parse-as-library -enable-experimental-feature FreestandingMacros | %FileCheck -check-prefix=CURSOR_MACRO_DECL %s
115+
// RUN: %sourcekitd-test -req=cursor -pos=57:2 -cursor-action -req-opts=retrieve_symbol_graph=1 %s -- ${COMPILER_ARGS[@]} -parse-as-library -enable-experimental-feature FreestandingMacros | %FileCheck -check-prefix=CURSOR_MACRO_DECL %s
116+
// CURSOR_MACRO_DECL: source.lang.swift.ref.macro (55:7-55:21)
117+
// CURSOR_MACRO_DECL-LABEL: SYMBOL GRAPH BEGIN
118+
// CURSOR_MACRO_DECL: "identifier": {
119+
// CURSOR_MACRO_DECL-NEXT: "interfaceLanguage": "swift",
120+
// CURSOR_MACRO_DECL-NEXT: "precise": "s:9MacroUser14anonymousTypesyySSyXEcfm"
121+
// CURSOR_MACRO_DECL-NEXT: },
122+
// CURSOR_MACRO_DECL-NEXT: "kind": {
123+
// CURSOR_MACRO_DECL-NEXT: "displayName": "Macro",
124+
// CURSOR_MACRO_DECL-NEXT: "identifier": "swift.macro"
125+
// CURSOR_MACRO_DECL-NEXT: },
126+
// CURSOR_MACRO_DECL: SYMBOL GRAPH END
127+
// CURSOR_MACRO_DECL-LABEL: ACTIONS BEGIN
128+
// CURSOR_MACRO_DECL: source.refactoring.kind.expand.macro
129+
// CURSOR_MACRO_DECL-NEXT: Expand Macro
130+
// CURSOR_MACRO_DECL: ACTIONS END
131+
132+
//##-- Refactoring on macro declaration
133+
// RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=57:1 %s -- ${COMPILER_ARGS[@]} -parse-as-library -enable-experimental-feature FreestandingMacros | %FileCheck -check-prefix=EXPAND_MACRO_DECL %s
134+
// RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=57:2 %s -- ${COMPILER_ARGS[@]} -parse-as-library -enable-experimental-feature FreestandingMacros | %FileCheck -check-prefix=EXPAND_MACRO_DECL %s
135+
// EXPAND_MACRO_DECL: source.edit.kind.active:
136+
// EXPAND_MACRO_DECL-NEXT: 57:1-57:28 (@__swiftmacro_9MacroUser14anonymousTypesfMf0_.swift) "class $s9MacroUser14anonymousTypesfMf0_4namefMu_ {
137+
// EXPAND_MACRO_DECL-NEXT: func hello() -> String {
138+
// EXPAND_MACRO_DECL-NEXT: "hello"
139+
// EXPAND_MACRO_DECL-NEXT: }
140+
// EXPAND_MACRO_DECL-NEXT: }
141+
// EXPAND_MACRO_DECL-NEXT: enum $s9MacroUser14anonymousTypesfMf0_4namefMu0_ {
142+
// EXPAND_MACRO_DECL-NEXT: case apple
143+
// EXPAND_MACRO_DECL-NEXT: case banana
144+
// EXPAND_MACRO_DECL-EMPTY:
145+
// EXPAND_MACRO_DECL-NEXT: func hello() -> String {
146+
// EXPAND_MACRO_DECL-NEXT: "hello"
147+
// EXPAND_MACRO_DECL-NEXT: }
148+
// EXPAND_MACRO_DECL-NEXT: }"
149+
108150
//##-- cursor-info on attached macro
109151
// RUN: %sourcekitd-test -req=cursor -pos=21:1 -cursor-action -req-opts=retrieve_symbol_graph=1 %s -- ${COMPILER_ARGS[@]} | %FileCheck -check-prefix=CURSOR_ATTACHED %s
110152
// RUN: %sourcekitd-test -req=cursor -pos=21:2 -cursor-action -req-opts=retrieve_symbol_graph=1 %s -- ${COMPILER_ARGS[@]} | %FileCheck -check-prefix=CURSOR_ATTACHED %s

0 commit comments

Comments
 (0)