Skip to content

Commit 03eb996

Browse files
committed
unified: Add AST mappings for string interpolation
1 parent 4228e6c commit 03eb996

3 files changed

Lines changed: 211 additions & 19 deletions

File tree

‎unified/extractor/src/languages/swift/swift.rs‎

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,27 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
173173
rule!((nilLiteralExpr) @@node => expr {
174174
tree!((builtin_expr #{node}))
175175
}),
176-
rule!((stringLiteralExpr) @@node => expr {
177-
tree!((string_literal #{node}))
178-
}),
176+
rule!((simpleStringLiteralExpr) @@node => (string_literal #{node})),
177+
// String literal with a single constant segment (for some reason not typed as simpleStringLiteralExpr)
178+
rule!(
179+
(stringLiteralExpr segments: (stringSegment) segments: _* @@rest) @@node
180+
where rest.is_empty()
181+
=>
182+
(string_literal #{node})
183+
),
184+
rule!(
185+
(stringLiteralExpr segments: _* @segments)
186+
=>
187+
(string_interpolation_expr element: {segments})
188+
),
189+
rule!((stringSegment content: @@content) => (string_literal #{content})),
190+
rule!(
191+
(expressionSegment expressions: _* @expressions)
192+
=>
193+
(call_expr
194+
callee: (builtin_expr "interpolation")
195+
argument: {expressions})
196+
),
179197
rule!((regexLiteralExpr) @@node => expr {
180198
tree!((regex_literal #{node}))
181199
}),

‎unified/extractor/tests/corpus/swift/literals/string-with-interpolation.output‎

Lines changed: 184 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010
// Plain string before and after interpolation
1111
"prefix \(value) suffix"
1212

13+
// Calls to custom DefaultStringInterpolation.appendInterpolation impls
14+
"foo \(x, y)"
15+
"foo \(x, y, z)"
16+
"foo \(arg: x)"
17+
"foo \(arg: x, arg2: y)"
18+
1319
---
1420

1521
sourceFile
@@ -110,6 +116,108 @@ sourceFile
110116
baseName: identifier "value"
111117
stringSegment
112118
content: stringSegment " suffix"
119+
codeBlockItem
120+
item:
121+
stringLiteralExpr
122+
closingQuote: "
123+
openingQuote: "
124+
segments:
125+
stringSegment
126+
content: stringSegment "foo "
127+
expressionSegment
128+
leftParen: (
129+
rightParen: )
130+
backslash: \
131+
expressions:
132+
labeledExpr
133+
expression:
134+
declReferenceExpr
135+
baseName: identifier "x"
136+
trailingComma: ,
137+
labeledExpr
138+
expression:
139+
declReferenceExpr
140+
baseName: identifier "y"
141+
stringSegment
142+
content: stringSegment
143+
codeBlockItem
144+
item:
145+
stringLiteralExpr
146+
closingQuote: "
147+
openingQuote: "
148+
segments:
149+
stringSegment
150+
content: stringSegment "foo "
151+
expressionSegment
152+
leftParen: (
153+
rightParen: )
154+
backslash: \
155+
expressions:
156+
labeledExpr
157+
expression:
158+
declReferenceExpr
159+
baseName: identifier "x"
160+
trailingComma: ,
161+
labeledExpr
162+
expression:
163+
declReferenceExpr
164+
baseName: identifier "y"
165+
trailingComma: ,
166+
labeledExpr
167+
expression:
168+
declReferenceExpr
169+
baseName: identifier "z"
170+
stringSegment
171+
content: stringSegment
172+
codeBlockItem
173+
item:
174+
stringLiteralExpr
175+
closingQuote: "
176+
openingQuote: "
177+
segments:
178+
stringSegment
179+
content: stringSegment "foo "
180+
expressionSegment
181+
leftParen: (
182+
rightParen: )
183+
backslash: \
184+
expressions:
185+
labeledExpr
186+
colon: :
187+
label: identifier "arg"
188+
expression:
189+
declReferenceExpr
190+
baseName: identifier "x"
191+
stringSegment
192+
content: stringSegment
193+
codeBlockItem
194+
item:
195+
stringLiteralExpr
196+
closingQuote: "
197+
openingQuote: "
198+
segments:
199+
stringSegment
200+
content: stringSegment "foo "
201+
expressionSegment
202+
leftParen: (
203+
rightParen: )
204+
backslash: \
205+
expressions:
206+
labeledExpr
207+
colon: :
208+
label: identifier "arg"
209+
expression:
210+
declReferenceExpr
211+
baseName: identifier "x"
212+
trailingComma: ,
213+
labeledExpr
214+
colon: :
215+
label: identifier "arg2"
216+
expression:
217+
declReferenceExpr
218+
baseName: identifier "y"
219+
stringSegment
220+
content: stringSegment
113221

114222
---
115223

@@ -120,33 +228,93 @@ top_level
120228
string_interpolation_expr
121229
element:
122230
string_literal "hello "
123-
name_expr
124-
identifier: identifier "name"
231+
call_expr
232+
callee: builtin_expr "interpolation"
233+
argument:
234+
argument
235+
value: identifier "name"
125236
string_literal
126237
string_interpolation_expr
127238
element:
128239
string_literal "hello "
129-
name_expr
130-
identifier: identifier "first"
240+
call_expr
241+
callee: builtin_expr "interpolation"
242+
argument:
243+
argument
244+
value: identifier "first"
131245
string_literal " "
132-
name_expr
133-
identifier: identifier "last"
246+
call_expr
247+
callee: builtin_expr "interpolation"
248+
argument:
249+
argument
250+
value: identifier "last"
134251
string_literal
135252
string_interpolation_expr
136253
element:
137254
string_literal "result: "
138-
binary_expr
139-
left:
140-
name_expr
141-
identifier: identifier "x"
142-
operator: infix_operator "+"
143-
right:
144-
name_expr
145-
identifier: identifier "y"
255+
call_expr
256+
callee: builtin_expr "interpolation"
257+
argument:
258+
argument
259+
value:
260+
binary_expr
261+
left: identifier "x"
262+
operator: infix_operator "+"
263+
right: identifier "y"
146264
string_literal
147265
string_interpolation_expr
148266
element:
149267
string_literal "prefix "
150-
name_expr
151-
identifier: identifier "value"
268+
call_expr
269+
callee: builtin_expr "interpolation"
270+
argument:
271+
argument
272+
value: identifier "value"
152273
string_literal " suffix"
274+
string_interpolation_expr
275+
element:
276+
string_literal "foo "
277+
call_expr
278+
callee: builtin_expr "interpolation"
279+
argument:
280+
argument
281+
value: identifier "x"
282+
argument
283+
value: identifier "y"
284+
string_literal
285+
string_interpolation_expr
286+
element:
287+
string_literal "foo "
288+
call_expr
289+
callee: builtin_expr "interpolation"
290+
argument:
291+
argument
292+
value: identifier "x"
293+
argument
294+
value: identifier "y"
295+
argument
296+
value: identifier "z"
297+
string_literal
298+
string_interpolation_expr
299+
element:
300+
string_literal "foo "
301+
call_expr
302+
callee: builtin_expr "interpolation"
303+
argument:
304+
argument
305+
name_node: identifier "arg"
306+
value: identifier "x"
307+
string_literal
308+
string_interpolation_expr
309+
element:
310+
string_literal "foo "
311+
call_expr
312+
callee: builtin_expr "interpolation"
313+
argument:
314+
argument
315+
name_node: identifier "arg"
316+
value: identifier "x"
317+
argument
318+
name_node: identifier "arg2"
319+
value: identifier "y"
320+
string_literal

‎unified/extractor/tests/corpus/swift/literals/string-with-interpolation.swift‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@
99

1010
// Plain string before and after interpolation
1111
"prefix \(value) suffix"
12+
13+
// Calls to custom DefaultStringInterpolation.appendInterpolation impls
14+
"foo \(x, y)"
15+
"foo \(x, y, z)"
16+
"foo \(arg: x)"
17+
"foo \(arg: x, arg2: y)"

0 commit comments

Comments
 (0)