summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEarlopain <[email protected]>2025-01-19 12:09:51 +0100
committergit <[email protected]>2025-01-20 18:03:13 +0000
commit769cccba56e3a1b7336d0cfadcfb9e0689e8f01f (patch)
tree831e24eb628230713d235a4d256aa0ca4639a6e0
parentc6c1e7a92a86154c4bec5d6ccac29adc37ce810d (diff)
[ruby/prism] Fix parser translator scope issues for implicit hash values
`builder.pair_label` is no good since it makes use of variables that the parser gem encountered. Since the prism translator doesn't keep proper track of that information, the following code interprets the implicit value as a local variable, even though it is not in scope: ```rb def foo bar = 123 end { bar: } ``` https://github.com/ruby/prism/commit/bbeb5b083a
-rw-r--r--lib/prism/translation/parser/compiler.rb15
1 files changed, 9 insertions, 6 deletions
diff --git a/lib/prism/translation/parser/compiler.rb b/lib/prism/translation/parser/compiler.rb
index a7e29d9dfc..c145cfa52c 100644
--- a/lib/prism/translation/parser/compiler.rb
+++ b/lib/prism/translation/parser/compiler.rb
@@ -128,14 +128,17 @@ module Prism
builder.pair_quoted(token(key.opening_loc), [builder.string_internal([key.unescaped, srange(key.value_loc)])], token(key.closing_loc), visit(node.value))
end
elsif node.value.is_a?(ImplicitNode)
- if (value = node.value.value).is_a?(LocalVariableReadNode)
- builder.pair_keyword(
- [key.unescaped, srange(key)],
- builder.ident([value.name, srange(key.value_loc)]).updated(:lvar)
- )
+ value = node.value.value
+
+ implicit_value = if value.is_a?(CallNode)
+ builder.call_method(nil, nil, [value.name, srange(value.message_loc)])
+ elsif value.is_a?(ConstantReadNode)
+ builder.const([value.name, srange(key.value_loc)])
else
- builder.pair_label([key.unescaped, srange(key.location)])
+ builder.ident([value.name, srange(key.value_loc)]).updated(:lvar)
end
+
+ builder.pair_keyword([key.unescaped, srange(key)], implicit_value)
elsif node.operator_loc
builder.pair(visit(key), token(node.operator_loc), visit(node.value))
elsif key.is_a?(SymbolNode) && key.opening_loc.nil?