Class: Reek::AST::Node

Inherits:
Parser::AST::Node
  • Object
show all
Defined in:
lib/reek/ast/node.rb

Overview

Base class for AST nodes extended with utility methods. Contains some methods to ease the transition from Sexp to AST::Node.

Defined Under Namespace

Classes: NodeLookupRule

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type, children = [], options = {}) ⇒ Node

Returns a new instance of Node.



17
18
19
20
# File 'lib/reek/ast/node.rb', line 17

def initialize(type, children = [], options = {})
  @comments = options.fetch(:comments, [])
  super
end

Instance Attribute Details

#commentsObject (readonly, private)

Returns the value of attribute comments.



139
140
141
# File 'lib/reek/ast/node.rb', line 139

def comments
  @comments
end

Instance Method Details

#conditionObject

Method will be overridden by the code in the IfNode, CaseNode, and LogicOperatorBase sexp extensions.



112
# File 'lib/reek/ast/node.rb', line 112

def condition; end

#contains_nested_node?(target_type) ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/reek/ast/node.rb', line 74

def contains_nested_node?(target_type)
  each_node(target_type).any?
end

#each_node(target_types, ignoring = [], &blk) ⇒ Object

Carries out a depth-first traversal of this syntax tree, yielding every Sexp of the searched for type or types. The traversal stops at any node whose type is listed in ‘ignoring`.

If a type is searched for and listed in ignoring, it will be yielded but traversal will not continue to its children.

If the root’s type is ignored, traversal does not stop, unless the root is of a target type.

Takes a block as well.

Returns an array with all matching nodes.

Examples:

node.each_node(:send, [:mlhs]) do |call_node| .... end
node.each_node(:lvar).any? { |it| it.var_name == 'something' }
node.each_node([:block]).flat_map do |elem| ... end

Parameters:

  • target_types (Symbol, Array<Symbol>)

    the type or types to look for

  • ignoring (Array<Symbol>) (defaults to: [])

    types to ignore

  • blk

    block to execute for every hit. Gets passed in the matching element itself.



67
68
69
70
71
72
# File 'lib/reek/ast/node.rb', line 67

def each_node(target_types, ignoring = [], &blk)
  return enum_for(:each_node, target_types, ignoring) unless blk

  lookup_rule = NodeLookupRule.new(Array(target_types), ignoring)
  look_for(lookup_rule, &blk)
end

#each_sexpObject (private)



141
142
143
# File 'lib/reek/ast/node.rb', line 141

def each_sexp
  children.each { |elem| yield elem if elem.is_a? ::Parser::AST::Node }
end

#format_to_rubyObject



80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/reek/ast/node.rb', line 80

def format_to_ruby
  if location
    lines = location.expression.source.split("\n").map(&:strip)
    case lines.length
    when 1 then lines.first
    when 2 then lines.join('; ')
    else [lines.first, lines.last].join(' ... ')
    end
  else
    to_s
  end
end

#full_commentObject



22
23
24
# File 'lib/reek/ast/node.rb', line 22

def full_comment
  comments.map(&:text).join("\n")
end

#leading_commentObject



26
27
28
29
30
31
32
# File 'lib/reek/ast/node.rb', line 26

def leading_comment
  line = location.line
  comment_lines = comments.select do |comment|
    comment.location.line < line
  end
  comment_lines.map(&:text).join("\n")
end

#lengthObject

Provide length for statement counting. A sexp counts as one statement.



94
95
96
# File 'lib/reek/ast/node.rb', line 94

def length
  1
end

#lineObject



34
35
36
# File 'lib/reek/ast/node.rb', line 34

def line
  loc && loc.line
end

#nameObject



38
39
40
# File 'lib/reek/ast/node.rb', line 38

def name
  to_s
end

#sourceObject



107
108
109
# File 'lib/reek/ast/node.rb', line 107

def source
  loc.expression.source_buffer.name
end

#statementsObject

Most nodes represent only one statement (although they can have nested statements). The special type :begin exists primarily to contain more statements.

Returns:

  • Array of unique outer-level statements contained in this node



103
104
105
# File 'lib/reek/ast/node.rb', line 103

def statements
  [self]
end