Class: Rucoa::Nodes::Base

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

Instance Method Summary collapse

Constructor Details

#initialize ⇒ Base

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

#ancestors ⇒ Array<Rucoa::Nodes::Base>

Returns:



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

def ancestors
  each_ancestor.to_a
end

#child_nodes ⇒ Array<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_nodes ⇒ Array<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_nesting ⇒ Array<String>

Examples:

return ["Bar::Foo", "Foo"] for class Foo::Bar::Baz

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

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

#namespace ⇒ String

Note:

namespace is a String representation of Module.nesting.

Examples:

returns namespace

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

returns "Object" when the node is not in a namespace

node = Rucoa::Source.new(
  content: "    foo\n  RUBY\n  uri: 'file:///path/to/example.rb'\n).root_node\nexpect(node.namespace).to eq('Object')\n",

Returns:

  • (String)


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

def namespace
  module_nesting.first || 'Object'
end

#next_sibling_nodes ⇒ Array<Rucoa::Nodes::Base>

Examples:

returns next siblings

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

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

#parent ⇒ Rucoa::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_nodes ⇒ Array<Rucoa::Nodes::Base>

Examples:

returns previous siblings

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

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