Class: RSpec::Support::Source::Node

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/rspec/support/source/node.rb

Overview

A wrapper for Ripper AST node which is generated with ‘Ripper.sexp`.

Direct Known Subclasses

ExpressionSequenceNode

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ripper_sexp, parent = nil) ⇒ Node

Returns a new instance of Node.



17
18
19
20
# File 'lib/rspec/support/source/node.rb', line 17

def initialize(ripper_sexp, parent=nil)
  @sexp = ripper_sexp.freeze
  @parent = parent
end

Instance Attribute Details

#parentObject (readonly)

Returns the value of attribute parent.



11
12
13
# File 'lib/rspec/support/source/node.rb', line 11

def parent
  @parent
end

#sexpObject (readonly)

Returns the value of attribute sexp.



11
12
13
# File 'lib/rspec/support/source/node.rb', line 11

def sexp
  @sexp
end

Class Method Details

.sexp?(array) ⇒ Boolean

Returns:

  • (Boolean)


13
14
15
# File 'lib/rspec/support/source/node.rb', line 13

def self.sexp?(array)
  array.is_a?(Array) && array.first.is_a?(Symbol)
end

Instance Method Details

#argsObject



26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/rspec/support/source/node.rb', line 26

def args
  @args ||= raw_args.map do |raw_arg|
    if Node.sexp?(raw_arg)
      Node.new(raw_arg, self)
    elsif Location.location?(raw_arg)
      Location.new(*raw_arg)
    elsif raw_arg.is_a?(Array)
      ExpressionSequenceNode.new(raw_arg, self)
    else
      raw_arg
    end
  end.freeze
end

#childrenObject



40
41
42
# File 'lib/rspec/support/source/node.rb', line 40

def children
  @children ||= args.select { |arg| arg.is_a?(Node) }.freeze
end

#eachObject

We use a loop here (instead of recursion) to prevent SystemStackError



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/rspec/support/source/node.rb', line 49

def each
  return to_enum(__method__) unless block_given?

  node_queue = []
  node_queue << self

  while (current_node = node_queue.shift)
    yield current_node
    node_queue.concat(current_node.children)
  end
end

#each_ancestorObject



61
62
63
64
65
66
67
68
69
# File 'lib/rspec/support/source/node.rb', line 61

def each_ancestor
  return to_enum(__method__) unless block_given?

  current_node = self

  while (current_node = current_node.parent)
    yield current_node
  end
end

#inspectObject



71
72
73
# File 'lib/rspec/support/source/node.rb', line 71

def inspect
  "#<#{self.class} #{type}>"
end

#locationObject



44
45
46
# File 'lib/rspec/support/source/node.rb', line 44

def location
  @location ||= args.find { |arg| arg.is_a?(Location) }
end

#typeObject



22
23
24
# File 'lib/rspec/support/source/node.rb', line 22

def type
  sexp[0]
end