Skip to content

Commit 7522a3e

Browse files
committed
[SourceKit] Handle CustomAttrs arguments for placeholder expansion
Introduce a new ASTWalker option for walking CustomAttrs and use it for the placeholder scanner to ensure we can expand placeholders in attribute arguments.
1 parent 6095278 commit 7522a3e

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

include/swift/AST/ASTWalker.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,13 @@ class ASTWalker {
603603
/// params in AbstractFunctionDecl and NominalTypeDecl.
604604
virtual bool shouldWalkIntoGenericParams() { return false; }
605605

606+
/// Whether the walker should walk into any attached CustomAttrs.
607+
virtual bool shouldWalkIntoCustomAttrs() const {
608+
// Default to false currently since some walkers don't handle this case
609+
// well.
610+
return false;
611+
}
612+
606613
/// This method configures how the walker should walk the initializers of
607614
/// lazy variables. These initializers are semantically different from other
608615
/// initializers in their context and so sometimes should be visited as part

lib/AST/ASTWalker.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
120120
[[nodiscard]]
121121
bool visit(Decl *D) {
122122
SetParentRAII SetParent(Walker, D);
123+
if (visitDeclCommon(D))
124+
return true;
123125
return inherited::visit(D);
124126
}
125127

@@ -138,6 +140,40 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
138140
// Decls
139141
//===--------------------------------------------------------------------===//
140142

143+
[[nodiscard]]
144+
bool visitCustomAttr(CustomAttr *CA) {
145+
auto *newTypeExpr = doIt(CA->getTypeExpr());
146+
if (!newTypeExpr)
147+
return true;
148+
149+
ASSERT(newTypeExpr == CA->getTypeExpr() &&
150+
"Cannot change CustomAttr TypeExpr");
151+
152+
if (auto *args = CA->getArgs()) {
153+
auto *newArgs = doIt(args);
154+
if (!newArgs)
155+
return true;
156+
157+
CA->setArgs(newArgs);
158+
}
159+
return false;
160+
}
161+
162+
[[nodiscard]]
163+
bool visitDeclCommon(Decl *D) {
164+
if (Walker.shouldWalkIntoCustomAttrs()) {
165+
for (auto *attr : D->getAttrs()) {
166+
auto *CA = dyn_cast<CustomAttr>(attr);
167+
if (!CA)
168+
continue;
169+
170+
if (visitCustomAttr(CA))
171+
return true;
172+
}
173+
}
174+
return false;
175+
}
176+
141177
[[nodiscard]]
142178
bool visitGenericParamListIfNeeded(GenericContext *GC) {
143179
// Must check this first in case extensions have not been bound yet
@@ -2218,6 +2254,15 @@ bool Traversal::visitErrorTypeRepr(ErrorTypeRepr *T) {
22182254
}
22192255

22202256
bool Traversal::visitAttributedTypeRepr(AttributedTypeRepr *T) {
2257+
if (Walker.shouldWalkIntoCustomAttrs()) {
2258+
for (auto attr : T->getAttrs()) {
2259+
auto *CA = attr.dyn_cast<CustomAttr *>();
2260+
if (!CA)
2261+
continue;
2262+
if (visitCustomAttr(CA))
2263+
return true;
2264+
}
2265+
}
22212266
return doIt(T->getTypeRepr());
22222267
}
22232268

test/SourceKit/CodeExpand/code-expand.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,23 @@ struct ExpandDeclMacro {
315315
// CHECK-NEXT: <#code#>
316316
// CHECK-NEXT: }))
317317
}
318+
319+
@Foo(<#Int#>)
320+
func testDeclAttr1() {}
321+
// CHECK: @Foo(<#Int#>)
322+
// CHECK-NEXT: func testDeclAttr1() {}
323+
324+
@Foo(<#T##() -> ()#>)
325+
func testDeclAttr2() {}
326+
// CHECK: @Foo({
327+
// CHECK-NEXT: <#code#>
328+
// CHECK-NEXT: })
329+
// CHECK-NEXT: func testDeclAttr2() {}
330+
331+
func testTypeAttr1(x: @Foo(<#Int#>) String) {}
332+
// CHECK: func testTypeAttr1(x: @Foo(<#Int#>) String) {}
333+
334+
func testTypeAttr2(x: @Foo(<#T##() -> ()#>) Int) {}
335+
// CHECK: func testTypeAttr2(x: @Foo({
336+
// CHECK-NEXT: <#code#>
337+
// CHECK-NEXT: }) Int) {}

tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,6 +1592,10 @@ class PlaceholderExpansionScanner {
15921592
return MacroWalking::Arguments;
15931593
}
15941594

1595+
bool shouldWalkIntoCustomAttrs() const override {
1596+
return true;
1597+
}
1598+
15951599
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
15961600
if (isa<EditorPlaceholderExpr>(E) && E->getStartLoc() == PlaceholderLoc) {
15971601
Found = cast<EditorPlaceholderExpr>(E);

0 commit comments

Comments
 (0)