Skip to content

Commit 41d387f

Browse files
geoffw0Copilot
andcommitted
unified: Cover multi-segment constant string extraction
Exercise full literal expressions, including currently missing multiline and escaped values, and retain an extractor corpus case distinguishing constants from interpolation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent bddbb6a commit 41d387f

4 files changed

Lines changed: 181 additions & 11 deletions

File tree

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
let escaped = "a\nb\rc"
2+
let raw = #"\n"#
3+
let multiline = """
4+
aa|
5+
bb
6+
"""
7+
let interpolated = "a\(raw)b"
8+
9+
---
10+
11+
sourceFile
12+
endOfFileToken: endOfFile
13+
statements:
14+
codeBlockItem
15+
item:
16+
variableDecl
17+
attributes:
18+
modifiers:
19+
bindingSpecifier: let
20+
bindings:
21+
patternBinding
22+
initializer:
23+
initializerClause
24+
equal: =
25+
value:
26+
stringLiteralExpr
27+
closingQuote: "
28+
openingQuote: "
29+
segments:
30+
stringSegment
31+
content: stringSegment "a\\n"
32+
stringSegment
33+
content: stringSegment "b\\r"
34+
stringSegment
35+
content: stringSegment "c"
36+
pattern:
37+
identifierPattern
38+
identifier: identifier "escaped"
39+
codeBlockItem
40+
item:
41+
variableDecl
42+
attributes:
43+
modifiers:
44+
bindingSpecifier: let
45+
bindings:
46+
patternBinding
47+
initializer:
48+
initializerClause
49+
equal: =
50+
value:
51+
stringLiteralExpr
52+
closingPounds: rawStringPoundDelimiter "#"
53+
openingPounds: rawStringPoundDelimiter "#"
54+
closingQuote: "
55+
openingQuote: "
56+
segments:
57+
stringSegment
58+
content: stringSegment "\\n"
59+
pattern:
60+
identifierPattern
61+
identifier: identifier "raw"
62+
codeBlockItem
63+
item:
64+
variableDecl
65+
attributes:
66+
modifiers:
67+
bindingSpecifier: let
68+
bindings:
69+
patternBinding
70+
initializer:
71+
initializerClause
72+
equal: =
73+
value:
74+
stringLiteralExpr
75+
closingQuote: """
76+
openingQuote: """
77+
segments:
78+
stringSegment
79+
content: stringSegment "aa|\n"
80+
stringSegment
81+
content: stringSegment "bb"
82+
pattern:
83+
identifierPattern
84+
identifier: identifier "multiline"
85+
codeBlockItem
86+
item:
87+
variableDecl
88+
attributes:
89+
modifiers:
90+
bindingSpecifier: let
91+
bindings:
92+
patternBinding
93+
initializer:
94+
initializerClause
95+
equal: =
96+
value:
97+
stringLiteralExpr
98+
closingQuote: "
99+
openingQuote: "
100+
segments:
101+
stringSegment
102+
content: stringSegment "a"
103+
expressionSegment
104+
leftParen: (
105+
rightParen: )
106+
backslash: \
107+
expressions:
108+
labeledExpr
109+
expression:
110+
declReferenceExpr
111+
baseName: identifier "raw"
112+
stringSegment
113+
content: stringSegment "b"
114+
pattern:
115+
identifierPattern
116+
identifier: identifier "interpolated"
117+
118+
---
119+
120+
top_level source="⟨body⟩"
121+
body:
122+
block source="⟨stmt⟩\n⟨stmt⟩\n⟨stmt⟩\n⟨stmt⟩"
123+
stmt:
124+
variable_declaration source="⟨modifier⟩ ⟨pattern⟩ = ⟨value⟩"
125+
modifier: modifier "let" source="let"
126+
pattern: identifier "escaped" source="escaped"
127+
value:
128+
string_interpolation_expr source="\"⟨element⟩⟨element⟩⟨element⟩\""
129+
element:
130+
string_literal "a\\n" source="a\\n"
131+
string_literal "b\\r" source="b\\r"
132+
string_literal "c" source="c"
133+
variable_declaration source="⟨modifier⟩ ⟨pattern⟩ = ⟨value⟩"
134+
modifier: modifier "let" source="let"
135+
pattern: identifier "raw" source="raw"
136+
value: string_literal "#\"\\n\"#" source="#\"\\n\"#"
137+
variable_declaration source="⟨modifier⟩ ⟨pattern⟩ = ⟨value⟩"
138+
modifier: modifier "let" source="let"
139+
pattern: identifier "multiline" source="multiline"
140+
value:
141+
string_interpolation_expr source="\"\"\"\n ⟨element⟩ ⟨element⟩\n \"\"\""
142+
element:
143+
string_literal "aa|\n" source="aa|\n"
144+
string_literal "bb" source="bb"
145+
variable_declaration source="⟨modifier⟩ ⟨pattern⟩ = ⟨value⟩"
146+
modifier: modifier "let" source="let"
147+
pattern: identifier "interpolated" source="interpolated"
148+
value:
149+
string_interpolation_expr source="\"⟨element⟩⟨element⟩⟨element⟩\""
150+
element:
151+
string_literal "a" source="a"
152+
call_expr source="\\(⟨argument⟩)"
153+
callee: builtin_expr "interpolation" source=""
154+
argument:
155+
argument source="⟨value⟩"
156+
value: identifier "raw" source="raw"
157+
string_literal "b" source="b"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
let escaped = "a\nb\rc"
2+
let raw = #"\n"#
3+
let multiline = """
4+
aa|
5+
bb
6+
"""
7+
let interpolated = "a\(raw)b"
Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1-
| test.swift:1:13:1:14 | "" | |
2-
| test.swift:2:14:2:18 | "abc" | abc |
3-
| test.swift:4:24:4:28 | "\\\\n" | \\\\n |
4-
| test.swift:5:15:5:31 | "\\u{61}\\u{1F600}" | \\u{61}\\u{1F600} |
5-
| test.swift:6:11:6:21 | #"\\n\\"abc"# | #"\\n\\"abc"# |
6-
| test.swift:8:20:8:30 | #"abc#def"# | #"abc#def"# |
1+
| test.swift:1:5:1:9 | empty | |
2+
| test.swift:2:5:2:10 | simple | abc |
3+
| test.swift:3:5:3:11 | escaped | |
4+
| test.swift:4:5:4:20 | escapedBackslash | \\\\n |
5+
| test.swift:5:5:5:11 | unicode | \\u{61}\\u{1F600} |
6+
| test.swift:6:5:6:7 | raw | #"\\n\\"abc"# |
7+
| test.swift:7:5:7:14 | rawEscapes | |
8+
| test.swift:8:5:8:16 | hashesInside | #"abc#def"# |
9+
| test.swift:9:5:9:13 | multiline | |
10+
| test.swift:13:5:13:19 | multilineIndent | |
11+
| test.swift:17:5:17:22 | multilineEmptyLine | |
12+
| test.swift:22:5:22:25 | multilineContinuation | |
13+
| test.swift:26:5:26:16 | rawMultiline | |
14+
| test.swift:30:5:30:17 | interpolation | |
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import unified
22

3-
from StringLiteral literal
4-
where
5-
literal.getFile().getRelativePath() = "test.swift" and
6-
not literal.getParent() instanceof StringInterpolationExpr
7-
select literal, literal.getStringValue()
3+
from VariableDeclaration decl
4+
where decl.getFile().getRelativePath() = "test.swift"
5+
select decl.getPattern(), concat(decl.getValue().getStringValue())

0 commit comments

Comments
 (0)