class Solargraph::Arc::Walker
Public Class Methods
from_source(source)
click to toggle source
# File lib/solargraph/arc/walker.rb, line 24 def self.from_source(source) self.new(self.normalize_ast(source)) end
new(ast)
click to toggle source
# File lib/solargraph/arc/walker.rb, line 28 def initialize(ast) @ast = ast @hooks = Hash.new([]) end
normalize_ast(source)
click to toggle source
github.com/castwide/solargraph/issues/522
# File lib/solargraph/arc/walker.rb, line 14 def self.normalize_ast(source) ast = source.node if ast.is_a?(::Parser::AST::Node) ast else NodeParser.parse(source.code, source.filename) end end
Public Instance Methods
on(node_type, args=[], &block)
click to toggle source
# File lib/solargraph/arc/walker.rb, line 33 def on(node_type, args=[], &block) @hooks[node_type] << Hook.new(node_type, args, &block) end
walk()
click to toggle source
# File lib/solargraph/arc/walker.rb, line 37 def walk if @ast.is_a?(Array) @ast.each { |node| traverse(node) } else traverse(@ast) end end
Private Instance Methods
match_children(args, children)
click to toggle source
# File lib/solargraph/arc/walker.rb, line 78 def match_children(args, children) args.each_with_index.all? do |arg, i| if children[i].is_a?(::Parser::AST::Node) children[i].type == arg else children[i] == arg end end end
traverse(node)
click to toggle source
# File lib/solargraph/arc/walker.rb, line 47 def traverse(node) return unless node.is_a?(::Parser::AST::Node) @hooks[node.type].each do |hook| try_match(node, hook) end node.children.each {|child| traverse(child) } end
try_match(node, hook)
click to toggle source
# File lib/solargraph/arc/walker.rb, line 57 def try_match(node, hook) return unless node.type == hook.node_type return unless node.children matched = hook.args.empty? || if node.children.first.is_a?(::Parser::AST::Node) node.children.any? { |child| child.is_a?(::Parser::AST::Node) && match_children(hook.args[1..-1], child.children) } else match_children(hook.args, node.children) end if matched if hook.proc.arity == 1 hook.proc.call(node) elsif hook.proc.arity == 2 walker = Walker.new(node) hook.proc.call(node, walker) walker.walk end end end