Skip to content

Commit d6cb6be

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 72ce3f9 commit d6cb6be

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
@@ -292,3 +292,23 @@ func expandMacro() {
292292
// CHECK-NEXT: <#code#>
293293
// CHECK-NEXT: }
294294
}
295+
296+
@Foo(<#Int#>)
297+
func testDeclAttr1() {}
298+
// CHECK: @Foo(<#Int#>)
299+
// CHECK-NEXT: func testDeclAttr1() {}
300+
301+
@Foo(<#T##() -> ()#>)
302+
func testDeclAttr2() {}
303+
// CHECK: @Foo({
304+
// CHECK-NEXT: <#code#>
305+
// CHECK-NEXT: })
306+
// CHECK-NEXT: func testDeclAttr2() {}
307+
308+
func testTypeAttr1(x: @Foo(<#Int#>) String) {}
309+
// CHECK: func testTypeAttr1(x: @Foo(<#Int#>) String) {}
310+
311+
func testTypeAttr2(x: @Foo(<#T##() -> ()#>) Int) {}
312+
// CHECK: func testTypeAttr2(x: @Foo({
313+
// CHECK-NEXT: <#code#>
314+
// 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)