Class: Steep::Locator::Ruby

Inherits:
Object show all
Includes:
NodeHelper
Defined in:
lib/steep/locator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from NodeHelper

#clone_node, #deconstruct_case_node, #deconstruct_case_node!, #deconstruct_if_node, #deconstruct_if_node!, #deconstruct_resbody_node, #deconstruct_resbody_node!, #deconstruct_rescue_node, #deconstruct_rescue_node!, #deconstruct_send_node, #deconstruct_send_node!, #deconstruct_sendish_and_block_nodes, #deconstruct_when_node, #deconstruct_when_node!, #deconstruct_whileish_node, #deconstruct_whileish_node!, #each_child_node, #each_descendant_node, #private_send?, #test_case_node, #test_if_node, #test_resbody_node, #test_rescue_node, #test_send_node, #test_when_node, #test_whileish_node, #value_node?

Constructor Details

#initialize(source) ⇒ Ruby

Returns a new instance of Ruby.



81
82
83
# File 'lib/steep/locator.rb', line 81

def initialize(source)
  @source = source
end

Instance Attribute Details

#sourceObject (readonly)

Returns the value of attribute source.



79
80
81
# File 'lib/steep/locator.rb', line 79

def source
  @source
end

Instance Method Details

#find(line, column) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/steep/locator.rb', line 85

def find(line, column)
  position = source.buffer.loc_to_pos([line, column])

  if nodes = source.find_heredoc_nodes(line, column, position)
    heredoc_node, *parent_nodes = nodes
    heredoc_node or raise
    each_child_node(heredoc_node) do |child_node|
      if result = find_ruby_node_in(position, child_node, nodes)
        return ruby_result_from_node(result, position)
      end
    end
    return NodeResult.new(heredoc_node, parent_nodes)
  end

  if source.node && node = find_ruby_node_in(position, source.node, [])
    ruby_result_from_node(node, position)
  else
    comment = source.comments.find { _1.location.expression.begin_pos <= position && position <= _1.location.expression.end_pos }
    if comment
      CommentResult.new(comment, nil)
    end
  end
end

#find_ruby_node_in(position, node, parents) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/steep/locator.rb', line 139

def find_ruby_node_in(position, node, parents)
  return unless node

  range = node.location.expression&.to_range

  return unless range

  if range.begin <= position && position <= range.end
    parents.unshift(node)
    each_child_node(node) do |child|
      if result = find_ruby_node_in(position, child, parents)
        return result
      end
    end

    parents.shift
    return NodeResult.new(node, parents)
  end
end

#ruby_result_from_node(node, position) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/steep/locator.rb', line 109

def ruby_result_from_node(node, position)
  case node.node.type
  when :assertion
    TypeAssertionResult.new(node.node.children[1], node)
  when :tapp
    application = node.node.children[1] #: AST::Node::TypeApplication
    TypeApplicationResult.new(application, node)
  else
    comment = source.comments.find do
      _1.location.expression.begin_pos <= position && position <= _1.location.expression.end_pos
    end

    if block_node = source.find_block_node([node.node, *node.parents])
      source.each_block_annotation(block_node) do |annotation|
        if location = annotation.location
          if location.start_pos <= position && position <= location.end_pos
            return AnnotationResult.new(annotation, node, block_node)
          end
        end
      end
    end

    if comment
      return CommentResult.new(comment, NodeResult.new(node.node, node.parents))
    end

    node
  end
end