Skip to content

Commit 8909446

Browse files
committed
TomlParserVisitor: strip quotes from quoted-key identifier name
`Toml.Identifier.name` previously held the verbatim source for both bare and quoted simple keys, so `"foo"` and `foo` produced different `name` values even though the TOML spec treats them as the same key. Consumers that matched on `getName()` had to strip quotes themselves at every site. The class already has a separate `source` field for round-trip fidelity; populate `name` with the unquoted form for simple keys while keeping `source` as-is so the printer still emits the original. Dotted keys are out of scope for this change. Without a dedicated multi-segment AST type the parser cannot tell `site."google.com"` (two segments, the second containing a literal dot) apart from `site.google.com` (three segments) once both are flattened into a single `name` string, so quoted segments inside a dotted key remain unstripped for now.
1 parent c4774bb commit 8909446

2 files changed

Lines changed: 45 additions & 8 deletions

File tree

rewrite-toml/src/main/java/org/openrewrite/toml/internal/TomlParserVisitor.java

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,16 @@ public Toml.Identifier visitKey(TomlParser.KeyContext ctx) {
134134

135135
@Override
136136
public Toml.Identifier visitSimpleKey(TomlParser.SimpleKeyContext ctx) {
137-
return convert(ctx, (c, prefix) -> new Toml.Identifier(
138-
randomId(),
139-
prefix,
140-
Markers.EMPTY,
141-
c.getText(),
142-
c.getText()
143-
));
137+
return convert(ctx, (c, prefix) -> {
138+
String source = c.getText();
139+
return new Toml.Identifier(
140+
randomId(),
141+
prefix,
142+
Markers.EMPTY,
143+
source,
144+
unquoteSimpleKey(source)
145+
);
146+
});
144147
}
145148

146149
@Override
@@ -162,6 +165,27 @@ public Toml.Identifier visitDottedKey(TomlParser.DottedKeyContext ctx) {
162165
);
163166
}
164167

168+
/**
169+
* Strip surrounding quotes from a TOML key's source text. Per the TOML spec
170+
* a quoted key (basic-string {@code "foo"} or literal-string {@code 'foo'})
171+
* names the same key as the unquoted form when only ASCII-identifier
172+
* characters are involved; the quotes are purely syntactic. For escape
173+
* processing parity with {@link Toml.Literal} string values we currently
174+
* only strip the outer quote characters and do not unescape interior
175+
* sequences — escaped key names are exceedingly rare in practice.
176+
*/
177+
private static String unquoteSimpleKey(String source) {
178+
if (source.length() < 2) {
179+
return source;
180+
}
181+
char first = source.charAt(0);
182+
char last = source.charAt(source.length() - 1);
183+
if ((first == '"' && last == '"') || (first == '\'' && last == '\'')) {
184+
return source.substring(1, source.length() - 1);
185+
}
186+
return source;
187+
}
188+
165189
@Override
166190
public Toml.KeyValue visitKeyValue(TomlParser.KeyValueContext ctx) {
167191
return convert(ctx, (c, prefix) -> new Toml.KeyValue(

rewrite-toml/src/test/java/org/openrewrite/toml/TomlParserTest.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,20 @@ void quotedKeys() {
310310
"ʎǝʞ" = "value"
311311
'key2' = "value"
312312
'quoted "value"' = "value"
313-
"""
313+
""",
314+
spec -> spec.afterRecipe(doc -> {
315+
// Quoted-key identifier exposes the unquoted form as `name` and the
316+
// verbatim source (with quotes) as `source`. The printer uses
317+
// `source` so round-tripping preserves the original syntax.
318+
assertThat(doc.getValues()).hasSize(5);
319+
Toml.Identifier ipKey = (Toml.Identifier) ((Toml.KeyValue) doc.getValues().get(0)).getKey();
320+
assertThat(ipKey.getName()).isEqualTo("127.0.0.1");
321+
assertThat(ipKey.getSource()).isEqualTo("\"127.0.0.1\"");
322+
323+
Toml.Identifier literalKey = (Toml.Identifier) ((Toml.KeyValue) doc.getValues().get(3)).getKey();
324+
assertThat(literalKey.getName()).isEqualTo("key2");
325+
assertThat(literalKey.getSource()).isEqualTo("'key2'");
326+
})
314327
)
315328
);
316329
}

0 commit comments

Comments
 (0)