[prism] handle locals consistently
This commit is contained in:
parent
e3258dd627
commit
6241cfab74
@ -52,9 +52,21 @@ module Prism
|
|||||||
stack = [ISeq.new(RubyVM::InstructionSequence.compile(source).to_a)]
|
stack = [ISeq.new(RubyVM::InstructionSequence.compile(source).to_a)]
|
||||||
|
|
||||||
while (iseq = stack.pop)
|
while (iseq = stack.pop)
|
||||||
# For some reason, CRuby occasionally pushes this special local
|
names = [*iseq.local_table]
|
||||||
# variable when there are splat arguments. We get rid of that here.
|
names.map!.with_index do |name, index|
|
||||||
locals << (iseq.local_table - [:"#arg_rest"])
|
# When an anonymous local variable is present in the iseq's local
|
||||||
|
# table, it is represented as the stack offset from the top.
|
||||||
|
# However, when these are dumped to binary and read back in, they
|
||||||
|
# are replaced with the symbol :#arg_rest. To consistently handle
|
||||||
|
# this, we replace them here with their index.
|
||||||
|
if name == :"#arg_rest"
|
||||||
|
names.length - index + 1
|
||||||
|
else
|
||||||
|
name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
locals << names
|
||||||
iseq.each_child { |child| stack << child }
|
iseq.each_child { |child| stack << child }
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -69,8 +81,6 @@ module Prism
|
|||||||
# For the given source, parses with prism and returns a list of all of the
|
# For the given source, parses with prism and returns a list of all of the
|
||||||
# sets of local variables that were encountered.
|
# sets of local variables that were encountered.
|
||||||
def self.prism_locals(source)
|
def self.prism_locals(source)
|
||||||
check_to_debug = ENV["RUBY_ISEQ_DUMP_DEBUG"] == "to_binary"
|
|
||||||
|
|
||||||
locals = []
|
locals = []
|
||||||
stack = [Prism.parse(source).value]
|
stack = [Prism.parse(source).value]
|
||||||
|
|
||||||
@ -108,7 +118,7 @@ module Prism
|
|||||||
*params.keywords.select(&:value).map(&:name)
|
*params.keywords.select(&:value).map(&:name)
|
||||||
]
|
]
|
||||||
|
|
||||||
sorted << AnonymousLocal if params.keywords.any? && !check_to_debug
|
sorted << AnonymousLocal if params.keywords.any?
|
||||||
|
|
||||||
# Recurse down the parameter tree to find any destructured
|
# Recurse down the parameter tree to find any destructured
|
||||||
# parameters and add them after the other parameters.
|
# parameters and add them after the other parameters.
|
||||||
@ -131,17 +141,17 @@ module Prism
|
|||||||
|
|
||||||
names.map!.with_index do |name, index|
|
names.map!.with_index do |name, index|
|
||||||
if name == AnonymousLocal
|
if name == AnonymousLocal
|
||||||
names.length - index + 1 unless check_to_debug
|
names.length - index + 1
|
||||||
else
|
else
|
||||||
name
|
name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
locals << names.compact
|
locals << names
|
||||||
when ClassNode, ModuleNode, ProgramNode, SingletonClassNode
|
when ClassNode, ModuleNode, ProgramNode, SingletonClassNode
|
||||||
locals << node.locals
|
locals << node.locals
|
||||||
when ForNode
|
when ForNode
|
||||||
locals << (check_to_debug ? [] : [2])
|
locals << [2]
|
||||||
when PostExecutionNode
|
when PostExecutionNode
|
||||||
locals.push([], [])
|
locals.push([], [])
|
||||||
when InterpolatedRegularExpressionNode
|
when InterpolatedRegularExpressionNode
|
||||||
|
Loading…
x
Reference in New Issue
Block a user