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
94
95
# File 'lib/synvert/core/node_ext.rb', line 82

def arguments
  case self.type
  when :def, :block
    ArgumentsNode.new self.children[1]
  when :defs
    ArgumentsNode.new self.children[2]
  when :send
    self.children[2..-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:



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

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:



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

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:



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

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:



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

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:



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

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.



280
281
282
# File 'lib/synvert/core/node_ext.rb', line 280

def indent
  self.loc.expression.column
end

#keyParser::AST::Node

Get key node of hash :pair node.

Returns:

Raises:



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

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:



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

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

#left_valueArray<Parser::AST::Node>

Return the left value.

Returns:

Raises:



219
220
221
222
223
224
225
226
227
228
# File 'lib/synvert/core/node_ext.rb', line 219

def left_value
  case self.type
  when :masgn
    self.children[0].children
  when :lvasgn, :ivasgn
    self.children[0]
  else
    raise Synvert::Core::MethodNotSupported.new "left_value 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.



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'lib/synvert/core/node_ext.rb', line 301

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, :arg, :blockarg
    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:



288
289
290
291
292
293
294
295
# File 'lib/synvert/core/node_ext.rb', line 288

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:



326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'lib/synvert/core/node_ext.rb', line 326

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

#right_valueArray<Parser::AST::Node>

Return the right value.

Returns:

Raises:



234
235
236
237
238
239
240
241
242
243
# File 'lib/synvert/core/node_ext.rb', line 234

def right_value
  case self.type
  when :masgn
    self.children[1].children
  when :lvasgn, :ivasgn
    self.children[1]
  else
    raise Synvert::Core::MethodNotSupported.new "right_value is not handled for #{self.inspect}"
  end
end

#to_sourceString

Get the source code of current node.

Returns:

  • (String)

    source code.



271
272
273
274
275
# File 'lib/synvert/core/node_ext.rb', line 271

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

#to_valueObject

Return the exact value.

Returns:

  • (Object)

    exact value.

Raises:



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/synvert/core/node_ext.rb', line 249

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:



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

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:



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

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