From d03e95d134a070c395d5bf904ba154d443de46e3 Mon Sep 17 00:00:00 2001 From: Fred Snyder Date: Tue, 11 Aug 2020 18:06:28 -0400 Subject: [PATCH] Treat for loops as closures (#349) --- .../parser/rubyvm/node_processors.rb | 1 + .../rubyvm/node_processors/args_node.rb | 44 ++++++++++++++----- spec/source_map/mapper_spec.rb | 12 +++++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/lib/solargraph/parser/rubyvm/node_processors.rb b/lib/solargraph/parser/rubyvm/node_processors.rb index 741a060ff..457b98bb2 100644 --- a/lib/solargraph/parser/rubyvm/node_processors.rb +++ b/lib/solargraph/parser/rubyvm/node_processors.rb @@ -54,6 +54,7 @@ module NodeProcessor register :KW_ARG, Rubyvm::NodeProcessors::KwArgNode register :ITER, Rubyvm::NodeProcessors::BlockNode register :LAMBDA, Rubyvm::NodeProcessors::BlockNode + register :FOR, Rubyvm::NodeProcessors::BlockNode register :OP_ASGN_OR, Rubyvm::NodeProcessors::OrasgnNode register :LIT, Rubyvm::NodeProcessors::LitNode end diff --git a/lib/solargraph/parser/rubyvm/node_processors/args_node.rb b/lib/solargraph/parser/rubyvm/node_processors/args_node.rb index 57c3c6c73..48903feb1 100644 --- a/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +++ b/lib/solargraph/parser/rubyvm/node_processors/args_node.rb @@ -7,16 +7,30 @@ module NodeProcessors class ArgsNode < Parser::NodeProcessor::Base def process if region.closure.is_a?(Pin::BaseMethod) || region.closure.is_a?(Pin::Block) - node.children[0].times do |i| - locals.push Solargraph::Pin::Parameter.new( - location: region.closure.location, - closure: region.closure, - comments: comments_for(node), - name: region.lvars[i].to_s, - presence: region.closure.location.range, - decl: :arg - ) - region.closure.parameters.push locals.last + if region.lvars[0].nil? + node.children[0].times do |i| + locals.push Solargraph::Pin::Parameter.new( + location: region.closure.location, + closure: region.closure, + comments: comments_for(node), + name: extract_name(node.children[i + 1]), + presence: region.closure.location.range, + decl: :arg + ) + region.closure.parameters.push locals.last + end + else + node.children[0].times do |i| + locals.push Solargraph::Pin::Parameter.new( + location: region.closure.location, + closure: region.closure, + comments: comments_for(node), + name: region.lvars[i].to_s, + presence: region.closure.location.range, + decl: :arg + ) + region.closure.parameters.push locals.last + end end # @todo Optional args, keyword args, etc. if node.children[6] @@ -55,6 +69,16 @@ def process end process_children end + + private + + def extract_name var + if Parser.is_ast_node?(var) + var.children[0].to_s + else + var.to_s + end + end end end end diff --git a/spec/source_map/mapper_spec.rb b/spec/source_map/mapper_spec.rb index 74d7a7130..3e02301b1 100644 --- a/spec/source_map/mapper_spec.rb +++ b/spec/source_map/mapper_spec.rb @@ -1457,4 +1457,16 @@ def bar; end bar = map.first_pin('Foo#bar') expect(bar).to be_explicit end + + it 'separates parameters from local variables' do + map = Solargraph::SourceMap.load_string(%( + def foo(bar) + for i in (bar.length - 1).downto(0) do + puts bar[i] + end + end + )) + pin = map.first_pin('#foo') + expect(pin.parameters.length).to eq(1) + end end