From 9f077a6cd4ae9ea4f65d07508cebf98ba6ac198f Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Tue, 28 Jul 2026 12:14:12 +0200 Subject: [PATCH] Better compatibility for hash string-like symbol keys in parser translator There's some special handling in regards to empty symbols and those containing newlines that should apply here. Makes it produce the correct amount of sym/dsym nodes --- lib/prism/translation/parser/compiler.rb | 8 ++- snapshots/hashes.txt | 66 ++++++++++++++++++------ test/prism/fixtures/hashes.txt | 6 +++ 3 files changed, 64 insertions(+), 16 deletions(-) diff --git a/lib/prism/translation/parser/compiler.rb b/lib/prism/translation/parser/compiler.rb index 8e17b5b61e..87ae24d7d8 100644 --- a/lib/prism/translation/parser/compiler.rb +++ b/lib/prism/translation/parser/compiler.rb @@ -165,7 +165,13 @@ def visit_assoc_node(node) else parts = if key.is_a?(SymbolNode) - [builder.string_internal([key.unescaped, srange(key.value_loc)])] + if key.value.nil? + [] + elsif key.value.include?("\n") + string_nodes_from_line_continuations(key.unescaped, key.value, key.value_loc.start_offset, key.opening) + else + [builder.string_internal([key.unescaped, srange(key.value_loc)])] + end else visit_all(key.parts) end diff --git a/snapshots/hashes.txt b/snapshots/hashes.txt index 0890f13667..a65a7b0676 100644 --- a/snapshots/hashes.txt +++ b/snapshots/hashes.txt @@ -1,10 +1,10 @@ -@ ProgramNode (location: (1,0)-(28,9)) +@ ProgramNode (location: (1,0)-(33,10)) ├── flags: ∅ ├── locals: [:a] └── statements: - @ StatementsNode (location: (1,0)-(28,9)) + @ StatementsNode (location: (1,0)-(33,10)) ├── flags: ∅ - └── body: (length: 10) + └── body: (length: 12) ├── @ HashNode (location: (1,0)-(1,2)) │ ├── flags: newline, static_literal │ ├── opening_loc: (1,0)-(1,1) = "{" @@ -418,22 +418,58 @@ │ │ └── closing_loc: (25,19)-(25,20) = "}" │ ├── opening_loc: (23,4)-(23,6) = "do" │ └── closing_loc: (26,0)-(26,3) = "end" - └── @ HashNode (location: (28,0)-(28,9)) + ├── @ HashNode (location: (28,0)-(28,9)) + │ ├── flags: newline, static_literal + │ ├── opening_loc: (28,0)-(28,1) = "{" + │ ├── elements: (length: 1) + │ │ └── @ AssocNode (location: (28,2)-(28,7)) + │ │ ├── flags: static_literal + │ │ ├── key: + │ │ │ @ SymbolNode (location: (28,2)-(28,4)) + │ │ │ ├── flags: static_literal, forced_us_ascii_encoding + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (28,2)-(28,3) = "a" + │ │ │ ├── closing_loc: (28,3)-(28,4) = ":" + │ │ │ └── unescaped: "a" + │ │ ├── value: + │ │ │ @ IntegerNode (location: (28,5)-(28,7)) + │ │ │ ├── flags: static_literal, decimal + │ │ │ └── value: -1 + │ │ └── operator_loc: ∅ + │ └── closing_loc: (28,8)-(28,9) = "}" + ├── @ HashNode (location: (30,0)-(30,10)) + │ ├── flags: newline, static_literal + │ ├── opening_loc: (30,0)-(30,1) = "{" + │ ├── elements: (length: 1) + │ │ └── @ AssocNode (location: (30,2)-(30,9)) + │ │ ├── flags: static_literal + │ │ ├── key: + │ │ │ @ SymbolNode (location: (30,2)-(30,5)) + │ │ │ ├── flags: static_literal + │ │ │ ├── opening_loc: (30,2)-(30,3) = "\"" + │ │ │ ├── value_loc: ∅ + │ │ │ ├── closing_loc: (30,3)-(30,5) = "\":" + │ │ │ └── unescaped: "" + │ │ ├── value: + │ │ │ @ NilNode (location: (30,6)-(30,9)) + │ │ │ └── flags: static_literal + │ │ └── operator_loc: ∅ + │ └── closing_loc: (30,9)-(30,10) = "}" + └── @ HashNode (location: (32,0)-(33,10)) ├── flags: newline, static_literal - ├── opening_loc: (28,0)-(28,1) = "{" + ├── opening_loc: (32,0)-(32,1) = "{" ├── elements: (length: 1) - │ └── @ AssocNode (location: (28,2)-(28,7)) + │ └── @ AssocNode (location: (32,2)-(33,9)) │ ├── flags: static_literal │ ├── key: - │ │ @ SymbolNode (location: (28,2)-(28,4)) + │ │ @ SymbolNode (location: (32,2)-(33,5)) │ │ ├── flags: static_literal, forced_us_ascii_encoding - │ │ ├── opening_loc: ∅ - │ │ ├── value_loc: (28,2)-(28,3) = "a" - │ │ ├── closing_loc: (28,3)-(28,4) = ":" - │ │ └── unescaped: "a" + │ │ ├── opening_loc: (32,2)-(32,3) = "\"" + │ │ ├── value_loc: (32,3)-(33,3) = "foo\nbar" + │ │ ├── closing_loc: (33,3)-(33,5) = "\":" + │ │ └── unescaped: "foo\nbar" │ ├── value: - │ │ @ IntegerNode (location: (28,5)-(28,7)) - │ │ ├── flags: static_literal, decimal - │ │ └── value: -1 + │ │ @ NilNode (location: (33,6)-(33,9)) + │ │ └── flags: static_literal │ └── operator_loc: ∅ - └── closing_loc: (28,8)-(28,9) = "}" + └── closing_loc: (33,9)-(33,10) = "}" diff --git a/test/prism/fixtures/hashes.txt b/test/prism/fixtures/hashes.txt index 0afb8db496..c6abbf086c 100644 --- a/test/prism/fixtures/hashes.txt +++ b/test/prism/fixtures/hashes.txt @@ -26,3 +26,9 @@ tap do end { a: -1 } + +{ "": nil} + +{ "foo +bar": nil} +