module Solargraph::Parser::Rubyvm::NodeMethods

Protected Class Methods

synchronized_find_recipient_node(cursor) click to toggle source
# File lib/solargraph/parser/rubyvm/node_methods.rb, line 139
def synchronized_find_recipient_node cursor
  source = cursor.source
  position = cursor.position
  offset = cursor.offset
  tree = source.tree_at(position.line, position.column)
  tree.shift while tree.first && [:FCALL, :VCALL, :CALL].include?(tree.first.type) && !source.code_for(tree.first).strip.end_with?(')')
  tree.each do |node|
    if [:FCALL, :VCALL, :CALL].include?(node.type)
      args = node.children.find { |c| Parser.is_ast_node?(c) && [:ARRAY, :ZARRAY, :LIST].include?(c.type) }
      if args
        match = source.code[0..offset-1].match(/,[^\)]*\z/)
        rng = Solargraph::Range.from_node(args)
        if match
          rng = Solargraph::Range.new(rng.start, position)
        end
        return node if rng.contain?(position)
      elsif source.code[0..offset-1] =~ /\(\s*$/
        break  unless source.code_for(node).strip.end_with?(')')
        return node
      end
    end
  end
  nil
end
unsynchronized_find_recipient_node(cursor) click to toggle source
# File lib/solargraph/parser/rubyvm/node_methods.rb, line 164
def unsynchronized_find_recipient_node cursor
  source = cursor.source
  position = cursor.position
  offset = cursor.offset
  if source.code[0..offset-1] =~ /\([A-Zaz0-9_\s]*\z$/ #&& source.code[offset] == ')'
    tree = source.tree_at(position.line, position.column - 1)
    if tree.first && [:FCALL, :VCALL, :CALL].include?(tree.first.type)
      return tree.first
    else
      return nil
    end
  else
    match = source.code[0..offset-1].match(/[\(,][A-Zaz0-9_\s]*\z/)
    if match
      moved = Position.from_offset(source.code, offset - match[0].length)
      tree = source.tree_at(moved.line, moved.column)
      tree.shift if match[0].start_with?(',')
      tree.shift while tree.first && ![:FCALL, :VCALL, :CALL].include?(tree.first.type)
      if tree.first && [:FCALL, :VCALL, :CALL].include?(tree.first.type)
        return tree.first
      end
    end
    return nil
  end
end

Public Instance Methods

call_nodes_from(node) click to toggle source
# File lib/solargraph/parser/rubyvm/node_methods.rb, line 73
def call_nodes_from node
  return [] unless Parser.is_ast_node?(node)
  result = []
  if node.type == :ITER
    result.push node.children[0]
    node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
  elsif node.type == :MASGN
    # @todo We're treating a mass assignment as a call node, but the
    #   type checker still needs the logic to handle it.
    result.push node
  elsif [:CALL, :VCALL, :FCALL, :ATTRASGN, :OPCALL].include?(node.type)
    result.push node
    node.children.each { |child| result.concat call_nodes_from(child) }
  else
    node.children.each { |child| result.concat call_nodes_from(child) }
  end
  result
end
const_nodes_from(node) click to toggle source
# File lib/solargraph/parser/rubyvm/node_methods.rb, line 62
def const_nodes_from node
  return [] unless Parser.is_ast_node?(node)
  result = []
  if [:CONST, :COLON2, :COLON3].include?(node.type)
    result.push node
  else
    node.children.each { |child| result.concat const_nodes_from(child) }
  end
  result
end
convert_hash(node) click to toggle source
# File lib/solargraph/parser/rubyvm/node_methods.rb, line 92
def convert_hash node
  return {} unless node?(node) && node.type == :HASH
  return convert_hash(node.children[0].children[1]) if splatted_hash?(node)
  return {} unless node?(node.children[0])
  result = {}
  index = 0
  until index > node.children[0].children.length - 2
    k = node.children[0].children[index]
    return {} unless node?(k)
    v = node.children[0].children[index + 1]
    result[k.children[0]] = Solargraph::Parser.chain(v)
    index += 2
  end
  result
end
find_recipient_node(cursor) click to toggle source

@param cursor [Solargraph::Source::Cursor]

# File lib/solargraph/parser/rubyvm/node_methods.rb, line 128
def find_recipient_node cursor
  if cursor.source.synchronized?
    NodeMethods.synchronized_find_recipient_node cursor
  else
    NodeMethods.unsynchronized_find_recipient_node cursor
  end
end
infer_literal_node_type(node) click to toggle source

@param node [RubyVM::AbstractSyntaxTree::Node] @return [String, nil]

# File lib/solargraph/parser/rubyvm/node_methods.rb, line 32
def infer_literal_node_type node
  return nil unless Parser.is_ast_node?(node)
  case node.type
  when :LIT, :STR
    "::#{node.children.first.class.to_s}"
  when :DSTR
    "::String"
  when :ARRAY, :ZARRAY, :LIST, :ZLIST
    '::Array'
  when :HASH
    '::Hash'
  when :DOT2, :DOT3
    '::Range'
  when :TRUE, :FALSE
    '::Boolean'
  when :SCOPE
    infer_literal_node_type(node.children[2])
  end
end
node?(node) click to toggle source
# File lib/solargraph/parser/rubyvm/node_methods.rb, line 123
def node? node
  node.is_a?(RubyVM::AbstractSyntaxTree::Node)
end
pack_name(node) click to toggle source

@param node [RubyVM::AbstractSyntaxTree::Node] @return [Array<String>]

# File lib/solargraph/parser/rubyvm/node_methods.rb, line 15
def pack_name(node)
  parts = []
  if node.is_a?(RubyVM::AbstractSyntaxTree::Node)
    parts.push '' if node.type == :COLON3
    node.children.each { |n|
      if n.is_a?(RubyVM::AbstractSyntaxTree::Node)
        parts += pack_name(n)
      else
        parts.push n unless n.nil?
      end
    }
  end
  parts
end
returns_from(node) click to toggle source
# File lib/solargraph/parser/rubyvm/node_methods.rb, line 52
def returns_from node
  return [] unless Parser.is_ast_node?(node)
  if node.type == :SCOPE
    # node.children.select { |n| n.is_a?(RubyVM::AbstractSyntaxTree::Node) }.map { |n| DeepInference.get_return_nodes(n) }.flatten
    DeepInference.get_return_nodes(node.children[2])
  else
    DeepInference.get_return_nodes(node)
  end
end
splatted_call?(node) click to toggle source
# File lib/solargraph/parser/rubyvm/node_methods.rb, line 119
def splatted_call? node
  splatted_node?(node) && node.children[0].children[1].type != :HASH
end
splatted_hash?(node) click to toggle source
# File lib/solargraph/parser/rubyvm/node_methods.rb, line 108
def splatted_hash? node
  splatted_node?(node) && node.children[0].children[1].type == :HASH
end
splatted_node?(node) click to toggle source
# File lib/solargraph/parser/rubyvm/node_methods.rb, line 112
def splatted_node? node
  node?(node.children[0]) &&
    [:ARRAY, :LIST].include?(node.children[0].type) &&
    node.children[0].children[0].nil? &&
    node?(node.children[0].children[1])
end
unpack_name(node) click to toggle source

@param node [RubyVM::AbstractSyntaxTree::Node] @return [String]

# File lib/solargraph/parser/rubyvm/node_methods.rb, line 9
def unpack_name node
  pack_name(node).join('::')
end