Skip to content

Commit 3891080

Browse files
committed
[utils] add support for expected-expansion to update-verify-tests
`expected-expansion` can be a bit unergonomic to use, because it requires pointing out not only the line, but also the column (which is not always obvious), and the nested diagnostics have to refer to absolute lines that aren't present in the source file. This makes both creating and updating these test cases easier through automation.
1 parent 0979d34 commit 3891080

File tree

3 files changed

+482
-57
lines changed

3 files changed

+482
-57
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import SwiftSyntax
2+
import SwiftSyntaxBuilder
3+
import SwiftSyntaxMacros
4+
5+
public struct UnstringifyPeerMacro: PeerMacro {
6+
public static func expansion(
7+
of node: AttributeSyntax,
8+
providingPeersOf declaration: some DeclSyntaxProtocol,
9+
in context: some MacroExpansionContext
10+
) throws -> [DeclSyntax] {
11+
do {
12+
let argumentList = node.arguments!.as(LabeledExprListSyntax.self)!
13+
let arguments = [LabeledExprSyntax](argumentList)
14+
let arg = arguments.first!.expression.as(StringLiteralExprSyntax.self)!
15+
let content = arg.representedLiteralValue!
16+
return [DeclSyntax("\(raw: content)")]
17+
}
18+
}
19+
}
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
// REQUIRES: swift_swift_parser, executable_test
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: split-file %s %t
5+
6+
// Building this macro takes some time, so amortise the cost by using it for multiple sub tests
7+
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(UnstringifyMacroDefinition) -module-name=UnstringifyMacroDefinition \
8+
// RUN: %S/Inputs/unstringify-macro.swift -g -no-toolchain-stdlib-rpath
9+
10+
11+
12+
// RUN: not %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/single.swift 2>%t/output.txt
13+
// RUN: %update-verify-tests < %t/output.txt
14+
// RUN: %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/single.swift
15+
// RUN: %diff %t/single.swift %t/single.swift.expected
16+
17+
// RUN: not %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/multiple.swift 2>%t/output.txt
18+
// RUN: %update-verify-tests < %t/output.txt
19+
// RUN: %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/multiple.swift
20+
// RUN: %diff %t/multiple.swift %t/multiple.swift.expected
21+
22+
// RUN: not %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/existing.swift 2>%t/output.txt
23+
// RUN: %update-verify-tests < %t/output.txt
24+
// RUN: %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/existing.swift
25+
// RUN: %diff %t/existing.swift %t/existing.swift.expected
26+
27+
// RUN: not %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/gone.swift 2>%t/output.txt
28+
// RUN: %update-verify-tests < %t/output.txt
29+
// RUN: %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/gone.swift
30+
// RUN: %diff %t/gone.swift %t/gone.swift.expected
31+
32+
// RUN: not %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/wrong-location.swift 2>%t/output.txt
33+
// RUN: %update-verify-tests < %t/output.txt
34+
// RUN: %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/wrong-location.swift
35+
// RUN: %diff %t/wrong-location.swift %t/wrong-location.swift.expected
36+
37+
// RUN: not %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/nested.swift 2>%t/output.txt
38+
// RUN: %update-verify-tests < %t/output.txt
39+
// RUN: %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/nested.swift
40+
// RUN: %diff %t/nested.swift %t/nested.swift.expected
41+
42+
//--- single.swift
43+
@attached(peer, names: overloaded)
44+
macro unstringifyPeer(_ s: String) =
45+
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
46+
47+
@unstringifyPeer("""
48+
func foo(_ x: Int) {
49+
let a = x
50+
}
51+
""")
52+
func foo() {}
53+
54+
//--- single.swift.expected
55+
@attached(peer, names: overloaded)
56+
macro unstringifyPeer(_ s: String) =
57+
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
58+
59+
// expected-note@+1{{in expansion of macro 'unstringifyPeer' on global function 'foo()' here}}
60+
@unstringifyPeer("""
61+
func foo(_ x: Int) {
62+
let a = x
63+
}
64+
""")
65+
// expected-expansion@+3:14{{
66+
// expected-warning@2{{initialization of immutable value 'a' was never used; consider replacing with assignment to '_' or removing it}}
67+
// }}
68+
func foo() {}
69+
70+
//--- multiple.swift
71+
@attached(peer, names: overloaded)
72+
macro unstringifyPeer(_ s: String) =
73+
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
74+
75+
@unstringifyPeer("""
76+
func foo(_ x: Int) {
77+
a = 2
78+
b = x
79+
}
80+
""")
81+
func foo() {}
82+
83+
//--- multiple.swift.expected
84+
@attached(peer, names: overloaded)
85+
macro unstringifyPeer(_ s: String) =
86+
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
87+
88+
// expected-note@+1 4{{in expansion of macro 'unstringifyPeer' on global function 'foo()' here}}
89+
@unstringifyPeer("""
90+
func foo(_ x: Int) {
91+
a = 2
92+
b = x
93+
}
94+
""")
95+
// expected-expansion@+5:14{{
96+
// expected-note@1 2{{'x' declared here}}
97+
// expected-error@2{{cannot find 'a' in scope; did you mean 'x'?}}
98+
// expected-error@3{{cannot find 'b' in scope; did you mean 'x'?}}
99+
// }}
100+
func foo() {}
101+
102+
//--- existing.swift
103+
@attached(peer, names: overloaded)
104+
macro unstringifyPeer(_ s: String) =
105+
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
106+
107+
@unstringifyPeer("""
108+
func foo(_ x: Int) {
109+
a = 2
110+
b = x
111+
}
112+
""")
113+
//expected-expansion@+4:14{{
114+
// expected-note@1 {{'x' declared here}}
115+
// expected-error@3 {{cannot find 'b' in scope; did you mean 'x'?}}
116+
//}}
117+
func foo() {}
118+
119+
//--- existing.swift.expected
120+
@attached(peer, names: overloaded)
121+
macro unstringifyPeer(_ s: String) =
122+
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
123+
124+
// expected-note@+1 4{{in expansion of macro 'unstringifyPeer' on global function 'foo()' here}}
125+
@unstringifyPeer("""
126+
func foo(_ x: Int) {
127+
a = 2
128+
b = x
129+
}
130+
""")
131+
//expected-expansion@+5:14{{
132+
// expected-error@3 {{cannot find 'b' in scope; did you mean 'x'?}}
133+
// expected-note@1 2{{'x' declared here}}
134+
// expected-error@2 {{cannot find 'a' in scope; did you mean 'x'?}}
135+
//}}
136+
func foo() {}
137+
138+
//--- gone.swift
139+
//expected-expansion@+4:14{{
140+
// expected-note@1 {{'x' declared here}}
141+
// expected-error@3 {{cannot find 'b' in scope; did you mean 'x'?}}
142+
//}}
143+
func foo() {}
144+
145+
//--- gone.swift.expected
146+
func foo() {}
147+
148+
//--- wrong-location.swift
149+
@attached(peer, names: overloaded)
150+
macro unstringifyPeer(_ s: String) =
151+
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
152+
153+
// expected-expansion@2:14{{
154+
// expected-note@2 {{'x' declared here}}
155+
// expected-error@3 {{cannot find 'b' in scope; did you mean 'x'?}}
156+
// }}
157+
@unstringifyPeer("""
158+
func foo(_ x: Int) {
159+
a = 2
160+
b = x
161+
}
162+
""")
163+
func foo() {}
164+
165+
//--- wrong-location.swift.expected
166+
@attached(peer, names: overloaded)
167+
macro unstringifyPeer(_ s: String) =
168+
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
169+
170+
// expected-note@+1 4{{in expansion of macro 'unstringifyPeer' on global function 'foo()' here}}
171+
@unstringifyPeer("""
172+
func foo(_ x: Int) {
173+
a = 2
174+
b = x
175+
}
176+
""")
177+
// expected-expansion@+5:14{{
178+
// expected-note@1 2{{'x' declared here}}
179+
// expected-error@2{{cannot find 'a' in scope; did you mean 'x'?}}
180+
// expected-error@3{{cannot find 'b' in scope; did you mean 'x'?}}
181+
// }}
182+
func foo() {}
183+
184+
//--- nested.swift
185+
@attached(peer, names: overloaded)
186+
macro unstringifyPeer(_ s: String) =
187+
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
188+
// hack to make this seem non-recursive
189+
@attached(peer, names: overloaded)
190+
macro unstringifyPeer2(_ s: String) =
191+
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
192+
193+
@unstringifyPeer("""
194+
func bar(_ y: Int) {
195+
@unstringifyPeer2(\"""
196+
func foo(_ x: Int) {
197+
a = 2
198+
b = x
199+
}
200+
\""")
201+
func foo() {}
202+
foo(y)
203+
}
204+
""")
205+
func bar() {}
206+
207+
//--- nested.swift.expected
208+
@attached(peer, names: overloaded)
209+
macro unstringifyPeer(_ s: String) =
210+
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
211+
// hack to make this seem non-recursive
212+
@attached(peer, names: overloaded)
213+
macro unstringifyPeer2(_ s: String) =
214+
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
215+
216+
// expected-note@+1 7{{in expansion of macro 'unstringifyPeer' on global function 'bar()' here}}
217+
@unstringifyPeer("""
218+
func bar(_ y: Int) {
219+
@unstringifyPeer2(\"""
220+
func foo(_ x: Int) {
221+
a = 2
222+
b = x
223+
}
224+
\""")
225+
func foo() {}
226+
foo(y)
227+
}
228+
""")
229+
// expected-expansion@+10:14{{
230+
// expected-note@1 2{{did you mean 'y'?}}
231+
// expected-note@2 4{{in expansion of macro 'unstringifyPeer2' on local function 'foo()' here}}
232+
// expected-expansion@9:6{{
233+
// expected-note@1 2{{did you mean 'x'?}}
234+
// expected-error@2{{cannot find 'a' in scope}}
235+
// expected-error@3{{cannot find 'b' in scope}}
236+
// }}
237+
// expected-error@10{{argument passed to call that takes no arguments}}
238+
// }}
239+
func bar() {}
240+

0 commit comments

Comments
 (0)