diff options
author | Earlopain <[email protected]> | 2025-01-19 12:09:51 +0100 |
---|---|---|
committer | git <[email protected]> | 2025-01-20 18:03:13 +0000 |
commit | 769cccba56e3a1b7336d0cfadcfb9e0689e8f01f (patch) | |
tree | 831e24eb628230713d235a4d256aa0ca4639a6e0 | |
parent | c6c1e7a92a86154c4bec5d6ccac29adc37ce810d (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.rb | 15 |
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? |