Class: Parser::AST::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/synvert/core/node_ext.rb

Overview

Parser::AST::Node monkey patch.

Instance Method Summary collapse

Instance Method Details

#argumentsArray<Parser::AST::Node>

Get arguments node of :send, :block or :defined? node.

Returns:

Raises:



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/synvert/core/node_ext.rb', line 82

def arguments
  case self.type
  when :send
    self.children[2..-1]
  when :block
    ArgumentsNode.new self.children[1]
  when :defined?
    self.children
  else
    raise Synvert::Core::MethodNotSupported.new "arguments is not handled for #{self.inspect}"
  end
end

#bodyArray<Parser::AST::Node>

Get body node of :begin or :block node.

Returns:

Raises:



111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/synvert/core/node_ext.rb', line 111

def body
  case self.type
  when :begin
    self.children
  when :def, :block
    return [] if self.children[2].nil?
    :begin == self.children[2].type ? self.children[2].body : self.children[2..-1]
  when :defs
    return [] if self.children[3].nil?
    :begin == self.children[3].type ? self.children[3].body : self.children[3..-1]
  else
    raise Synvert::Core::MethodNotSupported.new "body is not handled for #{self.inspect}"
  end
end

#callerParser::AST::Node

Get caller node of :block node.

Returns:

Raises:



99
100
101
102
103
104
105
# File 'lib/synvert/core/node_ext.rb', line 99

def caller
  if :block == self.type
    self.children[0]
  else
    raise Synvert::Core::MethodNotSupported.new "caller is not handled for #{self.inspect}"
  end
end

#conditionParser::AST::Node

Get condition node of :if node.

Returns:

Raises:



130
131
132
133
134
135
136
# File 'lib/synvert/core/node_ext.rb', line 130

def condition
  if :if == self.type
    self.children[0]
  else
    raise Synvert::Core::MethodNotSupported.new "condition is not handled for #{self.inspect}"
  end
end

#has_key?(key) ⇒ Boolean

Test if hash node contains specified key.

Parameters:

  • key (Object)

    value.

Returns:

  • (Boolean)

    true if specified key exists.

Raises:



167
168
169
170
171
172
173
# File 'lib/synvert/core/node_ext.rb', line 167

def has_key?(key)
  if :hash == self.type
    self.children.any? { |pair_node| pair_node.key.to_value == key }
  else
    raise Synvert::Core::MethodNotSupported.new "has_key? is not handled for #{self.inspect}"
  end
end

#hash_value(key) ⇒ Parser::AST::Node

Get hash value node according to specified key.

Parameters:

  • key (Object)

    value.

Returns:

Raises:



180
181
182
183
184
185
186
187
# File 'lib/synvert/core/node_ext.rb', line 180

def hash_value(key)
  if :hash == self.type
    value_node = self.children.find { |pair_node| pair_node.key.to_value == key }
    value_node ? value_node.value : nil
  else
    raise Synvert::Core::MethodNotSupported.new "has_key? is not handled for #{self.inspect}"
  end
end

#indentInteger

Get the indent of current node.

Returns:

  • (Integer)

    indent.



248
249
250
# File 'lib/synvert/core/node_ext.rb', line 248

def indent
  self.loc.expression.column
end

#keyParser::AST::Node

Get key node of hash :pair node.

Returns:

Raises:



193
194
195
196
197
198
199
# File 'lib/synvert/core/node_ext.rb', line 193

def key
  if :pair == self.type
    self.children.first
  else
    raise Synvert::Core::MethodNotSupported.new "key is not handled for #{self.inspect}"
  end
end

#keysArray<Parser::AST::Node>

Get keys node of :hash node.

Returns:

Raises:



142
143
144
145
146
147
148
# File 'lib/synvert/core/node_ext.rb', line 142

def keys
  if :hash == self.type
    self.children.map { |child| child.children[0] }
  else
    raise Synvert::Core::MethodNotSupported.new "keys is not handled for #{self.inspect}"
  end
end

#match?(rules) ⇒ Boolean

Match current node with rules.

Parameters:

  • rules (Hash)

    rules to match.

Returns:

  • (Boolean)

    true if matches.



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/synvert/core/node_ext.rb', line 269

def match?(rules)
  flat_hash(rules).keys.all? do |multi_keys|
    if multi_keys.last == :any
      actual_values = actual_value(self, multi_keys[0...-1])
      expected = expected_value(rules, multi_keys)
      actual_values.any? { |actual| match_value?(actual, expected) }
    elsif multi_keys.last == :not
      actual = actual_value(self, multi_keys[0...-1])
      expected = expected_value(rules, multi_keys)
      !match_value?(actual, expected)
    else
      actual = actual_value(self, multi_keys)
      expected = expected_value(rules, multi_keys)
      match_value?(actual, expected)
    end
  end
end

#messageParser::AST::Node

Get message node of :send node.

Returns:

Raises:



70
71
72
73
74
75
76
# File 'lib/synvert/core/node_ext.rb', line 70

def message
  if :send == self.type
    self.children[1]
  else
    raise Synvert::Core::MethodNotSupported.new "message is not handled for #{self.inspect}"
  end
end

#nameParser::AST::Node

Get name node of :class, :module, :def and :defs node.

Returns:

Raises:



31
32
33
34
35
36
37
38
39
40
# File 'lib/synvert/core/node_ext.rb', line 31

def name
  case self.type
  when :class, :module, :def
    self.children[0]
  when :defs
    self.children[1]
  else
    raise Synvert::Core::MethodNotSupported.new "name is not handled for #{self.inspect}"
  end
end

#parent_classParser::AST::Node

Get parent_class node of :class node.

Returns:

Raises:



46
47
48
49
50
51
52
# File 'lib/synvert/core/node_ext.rb', line 46

def parent_class
  if :class == self.type
    self.children[1]
  else
    raise Synvert::Core::MethodNotSupported.new "parent_class is not handled for #{self.inspect}"
  end
end

#receiverParser::AST::Node

Get receiver node of :send node.

Returns:

Raises:



58
59
60
61
62
63
64
# File 'lib/synvert/core/node_ext.rb', line 58

def receiver
  if :send == self.type
    self.children[0]
  else
    raise Synvert::Core::MethodNotSupported.new "receiver is not handled for #{self.inspect}"
  end
end

#recursive_children {|child| ... } ⇒ Object

Recursively iterate all child nodes of current node.

Yields:

  • (child)

    Gives a child node.

Yield Parameters:



256
257
258
259
260
261
262
263
# File 'lib/synvert/core/node_ext.rb', line 256

def recursive_children
  self.children.each do |child|
    if Parser::AST::Node === child
      yield child
      child.recursive_children { |c| yield c }
    end
  end
end

#rewritten_source(code) ⇒ String

Get rewritten source code.

Examples:

node.rewritten_source("create({{arguments}})") #=> "create(:post)"

Parameters:

  • code (String)

    raw code.

Returns:

  • (String)

    rewritten code, replace string in block } in raw code.

Raises:



294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'lib/synvert/core/node_ext.rb', line 294

def rewritten_source(code)
  code.gsub(/{{(.*?)}}/m) do
    old_code = $1
    if self.respond_to? old_code.split(/\.|\[/).first
      evaluated = self.instance_eval old_code
      case evaluated
      when Parser::AST::Node
        evaluated.loc.expression.source
      when Array, ArgumentsNode
        if evaluated.size > 0
          source = evaluated.first.loc.expression.source_buffer.source
          source[evaluated.first.loc.expression.begin_pos...evaluated.last.loc.expression.end_pos]
        end
      when String, Symbol
        evaluated
      when NilClass
        'nil'
      else
        raise Synvert::Core::MethodNotSupported.new "rewritten_source is not handled for #{evaluated.inspect}"
      end
    else
      "{{#{old_code}}}"
    end
  end
end

#to_sourceString

Get the source code of current node.

Returns:

  • (String)

    source code.



239
240
241
242
243
# File 'lib/synvert/core/node_ext.rb', line 239

def to_source
  if self.loc.expression
    self.loc.expression.source
  end
end

#to_valueObject

Return the exact value.

Returns:

  • (Object)

    exact value.

Raises:



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/synvert/core/node_ext.rb', line 217

def to_value
  case self.type
  when :int, :str, :sym
    self.children.last
  when :true
    true
  when :false
    false
  when :array
    self.children.map(&:to_value)
  when :irange
    (self.children.first.to_value..self.children.last.to_value)
  when :begin
    self.children.first.to_value
  else
    raise Synvert::Core::MethodNotSupported.new "to_value is not handled for #{self.inspect}"
  end
end

#valueParser::AST::Node

Get value node of hash :pair node.

Returns:

Raises:



205
206
207
208
209
210
211
# File 'lib/synvert/core/node_ext.rb', line 205

def value
  if :pair == self.type
    self.children.last
  else
    raise Synvert::Core::MethodNotSupported.new "value is not handled for #{self.inspect}"
  end
end

#valuesArray<Parser::AST::Node>

Get values node of :hash node.

Returns:

Raises:



154
155
156
157
158
159
160
# File 'lib/synvert/core/node_ext.rb', line 154

def values
  if :hash == self.type
    self.children.map { |child| child.children[1] }
  else
    raise Synvert::Core::MethodNotSupported.new "keys is not handled for #{self.inspect}"
  end
end