Class: Rucoa::Nodes::Base

Inherits:
Parser::AST::Node
  • Object
show all
Defined in:
lib/rucoa/nodes/base.rb

Instance Method Summary collapse

Constructor Details

#initializeBase

Note:

Override.

Returns a new instance of Base.



7
8
9
10
11
12
13
14
15
# File 'lib/rucoa/nodes/base.rb', line 7

def initialize(...)
  # Necessary to assign before calling `super` because it may freeze itself depending on the case.
  @mutable_attributes = {}

  super
  children.each do |child|
    child.parent = self if child.is_a?(::Parser::AST::Node)
  end
end

Instance Method Details

#ancestorsArray<Rucoa::Nodes::Base>

Returns:



18
19
20
# File 'lib/rucoa/nodes/base.rb', line 18

def ancestors
  each_ancestor.to_a
end

#child_nodesArray<Rucoa::Nodes::Base>

Returns:



23
24
25
# File 'lib/rucoa/nodes/base.rb', line 23

def child_nodes
  each_child_node.to_a
end

#descendant_nodesArray<Rucoa::Nodes::Base>

Returns:



28
29
30
# File 'lib/rucoa/nodes/base.rb', line 28

def descendant_nodes
  each_descendant_node.to_a
end

#each_ancestor(*types, &block) ⇒ Rucoa::Nodes::Base, Enumerator

Parameters:

  • types (Array<Symbol>)

Returns:



35
36
37
38
39
40
41
42
43
# File 'lib/rucoa/nodes/base.rb', line 35

def each_ancestor(
  *types,
  &block
)
  return to_enum(__method__, *types) unless block

  visit_ancestors(types, &block)
  self
end

#each_child_node(*types, &block) ⇒ Rucoa::Nodes::Base, Enumerator

Parameters:

  • types (Array<Symbol>)

Returns:



48
49
50
51
52
53
54
55
56
# File 'lib/rucoa/nodes/base.rb', line 48

def each_child_node(
  *types,
  &block
)
  return to_enum(__method__, *types) unless block

  visit_child_node(types, &block)
  self
end

#each_descendant_node(*types, &block) ⇒ Rucoa::Nodes::Base, Enumerator

Parameters:

  • types (Array<Symbol>)

Returns:



61
62
63
64
65
66
67
68
69
# File 'lib/rucoa/nodes/base.rb', line 61

def each_descendant_node(
  *types,
  &block
)
  return to_enum(__method__, *types) unless block

  visit_descendant_nodes(types, &block)
  self
end

#include_position?(position) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


73
74
75
76
77
# File 'lib/rucoa/nodes/base.rb', line 73

def include_position?(position)
  return false unless location.expression

  Range.from_parser_range(location.expression).include?(position)
end

#module_nestingArray<String>

Examples:

return [“Bar::Foo”, “Foo”] for class Foo::Bar::Baz

node = Rucoa::Source.new(
  content: <<~RUBY,
    module Foo
      module Bar
        module Baz
        end
      end
    end
  RUBY
  uri: 'file:///path/to/foo/bar/baz.rb'
).node_at(
  Rucoa::Position.new(
    column: 4,
    line: 3
  )
)
expect(node.module_nesting).to eq(['Foo::Bar', 'Foo'])

Returns:

  • (Array<String>)


98
99
100
# File 'lib/rucoa/nodes/base.rb', line 98

def module_nesting
  each_ancestor(:class, :module).map(&:qualified_name)
end

#namespaceString

Note:

namespace is a String representation of ‘Module.nesting`.

Examples:

returns namespace

node = Rucoa::Source.new(
  content: <<~RUBY,
    module Foo
      class Bar
        def baz
        end
      end
    end
  RUBY
  uri: 'file:///path/to/foo/bar.rb'
).node_at(
  Rucoa::Position.new(
    column: 4,
    line: 3
  )
)
expect(node.namespace).to eq('Foo::Bar')

returns “Object” when the node is not in a namespace

node = Rucoa::Source.new(
  content: <<~RUBY,
    foo
  RUBY
  uri: 'file:///path/to/example.rb'
).root_node
expect(node.namespace).to eq('Object')

Returns:

  • (String)


130
131
132
# File 'lib/rucoa/nodes/base.rb', line 130

def namespace
  module_nesting.first || 'Object'
end

#next_sibling_nodesArray<Rucoa::Nodes::Base>

Examples:

returns next siblings

node = Rucoa::Source.new(
  content: <<~RUBY,
    def foo
      a
      b
      c
      d
      e
    end
  RUBY
  uri: 'file:///path/to/example.rb'
).node_at(
  Rucoa::Position.new(
    column: 2,
    line: 4
  )
)
expect(node.next_sibling_nodes.map(&:name)).to eq(%w[d e])

Returns:



154
155
156
157
158
# File 'lib/rucoa/nodes/base.rb', line 154

def next_sibling_nodes
  return [] unless parent

  parent.child_nodes[(sibling_node_index + 1)..]
end

#parentRucoa::Nodes::Base?

Returns:



161
162
163
# File 'lib/rucoa/nodes/base.rb', line 161

def parent
  @mutable_attributes[:parent]
end

#parent=(node) ⇒ Object

Parameters:



166
167
168
# File 'lib/rucoa/nodes/base.rb', line 166

def parent=(node)
  @mutable_attributes[:parent] = node
end

#previous_sibling_nodesArray<Rucoa::Nodes::Base>

Examples:

returns previous siblings

node = Rucoa::Source.new(
  content: <<~RUBY,
    def foo
      a
      b
      c
      d
      e
    end
  RUBY
  uri: 'file:///path/to/example.rb'
).node_at(
  Rucoa::Position.new(
    column: 2,
    line: 4
  )
)
expect(node.previous_sibling_nodes.map(&:name)).to eq(%w[a b])

Returns:



190
191
192
193
194
# File 'lib/rucoa/nodes/base.rb', line 190

def previous_sibling_nodes
  return [] unless parent

  parent.child_nodes[0...sibling_node_index]
end

#updated(type = nil, children = nil, properties = {}) ⇒ Rucoa::Nodes::Base

Note:

Override. Some nodes change their type depending on the context. For example, ‘const` node can be `casgn` node.

Returns:



200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/rucoa/nodes/base.rb', line 200

def updated(
  type = nil,
  children = nil,
  properties = {}
)
  properties[:location] ||= @location
  ParserBuilder.node_class_for(type || @type).new(
    type || @type,
    children || @children,
    properties
  )
end