Class: Sexp

Inherits:
Object
  • Object
show all
Defined in:
lib/code_analyzer/sexp.rb

Instance Method Summary collapse

Instance Method Details

#allArray

Get all arguments.

s(:args_add_block,
  s(:args_add,
    s(:args_add, s(:args_new), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "hello", s(1, 6))))),
    s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "world", s(1, 15))))
  ), false
)
    => [
         s(:args_add, s(:args_new), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "hello", s(1, 6))))),
         s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "world", s(1, 15))))
       ]

Returns:

  • (Array)

    all arguments



325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
# File 'lib/code_analyzer/sexp.rb', line 325

def all
  nodes = []
  case sexp_type
  when :args_add_block, :array
    if :args_new == self[1].sexp_type
      nodes << self[2]
    else
      node = self[1]
      while true
        if %i[args_add args_add_star].include? node.sexp_type
          nodes.unshift node[2]
          node = node[1]
        elsif :args_new == node.sexp_type
          break
        end
      end
    end
  when :args_add
    nodes.unshift self[2]
  end
  nodes
end

#all_conditionsArray

Get all condition nodes.

s(:binary,
  s(:binary,
    s(:var_ref, s(:@ident, "user", s(1, 0))),
    :==,
    s(:var_ref, s(:@ident, "current_user", s(1, 8)))
  ),
  :"&&",
  s(:call,
    s(:var_ref, s(:@ident, "user", s(1, 24))),
    :".",
    s(:@ident, "valid?", s(1, 29))
  )
)
    => [
         s(:binary,
           s(:var_ref, s(:@ident, "user", s(1, 0))),
           :==,
           s(:var_ref, s(:@ident, "current_user", s(1, 8)))
         ),
         s(:call,
           s(:var_ref, s(:@ident, "user", s(1, 24))),
             :".",
             s(:@ident, "valid?", s(1, 29))
         )
       ]

Returns:

  • (Array)

    all condition nodes



391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
# File 'lib/code_analyzer/sexp.rb', line 391

def all_conditions
  nodes = []
  if :binary == sexp_type && %w[&& || and or].include?(self[2].to_s)
    if :binary == self[1].sexp_type &&
       %w[&& || and or].include?(self[1][2].to_s)
      nodes += self[1].all_conditions
    else
      nodes << self[1]
    end
    if :binary == self[3].sexp_type &&
       %w[&& || and or].include?(self[3][2].to_s)
      nodes += self[3].all_conditions
    else
      nodes << self[3]
    end
  else
    self
  end
end

#argumentSexp

Get only argument for binary.

s(:binary,
  s(:var_ref, s(:@ident, "user", s(1, 0))),
  :==,
  s(:var_ref, s(:@ident, "current_user", s(1, 8)))
)
    => s(:var_ref, s(:@ident, "current_user", s(1, 8)))

Returns:

  • (Sexp)

    argument node



307
308
309
# File 'lib/code_analyzer/sexp.rb', line 307

def argument
  self[3] if :binary == sexp_type
end

#argumentsSexp

Get arguments node.

s(:command,
  s(:@ident, "resources", s(1, 0)),
  s(:args_add_block,
    s(:args_add, s(:args_new),
      s(:symbol_literal, s(:symbol, s(:@ident, "posts", s(1, 11))))
    ), false
  )
)
    => s(:args_add_block,
         s(:args_add, s(:args_new),
           s(:symbol_literal, s(:symbol, s(:@ident, "posts", s(1, 11))))
         ), false
       )

Returns:

  • (Sexp)

    arguments node



280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/code_analyzer/sexp.rb', line 280

def arguments
  case sexp_type
  when :command
    self[2]
  when :command_call
    self[4]
  when :method_add_arg
    self[2].arguments
  when :method_add_block
    self[1].arguments
  when :arg_paren
    self[1]
  when :array
    self
  end
end

#array_sizeInteger

Get the array size.

s(:array,
  s(:args_add,
    s(:args_add, s(:args_new), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "first_name", s(1, 2))))),
    s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "last_name", s(1, 16))))
  )
)
    => 2

Returns:

  • (Integer)

    array size



730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
# File 'lib/code_analyzer/sexp.rb', line 730

def array_size
  if :array == sexp_type
    first_node = self[1]
    array_size = 0
    if first_node
      while true
        array_size += 1
        first_node =
          s(:args_new) == first_node[1] ? first_node[2] : first_node[1]
        if :args_add != first_node.sexp_type
          if :array == first_node.sexp_type
            array_size += first_node.array_size
          end
          break
        end
      end
    end
    array_size
  end
end

#array_valuesArray

Get the array values.

s(:array,
  s(:args_add,
    s(:args_add, s(:args_new), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "first_name", s(1, 2))))),
    s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "last_name", s(1, 16))))
  )
)
    => [
         s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "first_name", s(1, 2)))),
         s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "last_name", s(1, 16))))
       ]

Returns:

  • (Array)

    array values



765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
# File 'lib/code_analyzer/sexp.rb', line 765

def array_values
  case sexp_type
  when :array
    if nil == self[1] ||
       %i[words_new qwords_new symbols_new qsymbols_new].include?(
         self[1].sexp_type
       )
      []
    elsif %i[words_add qwords_add symbols_add qsymbols_add].include? self[1]
                                                                  .sexp_type
      self[1].array_values
    else
      arguments.all
    end
  when :words_add, :qwords_add, :symbols_add, :qsymbols_add
    values = []
    node = self
    while true
      if %i[words_add qwords_add symbols_add qsymbols_add].include? node
                                                                 .sexp_type
        values.unshift node[2]
        node = node[1]
      elsif %i[words_new qwords_new symbols_new qsymbols_new].include? node
                                                                    .sexp_type
        break
      end
    end
    values
  else
    []
  end
end

#base_classSexp

Get the base class of the class node.

s(:class,
  s(:const_ref, s(:@const, "User", s(1, 6))),
  s(:const_path_ref, s(:var_ref, s(:@const, "ActiveRecord", s(1, 13))), s(:@const, "Base", s(1, 27))),
  s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil)
)
    => s(:const_path_ref, s(:var_ref, s(:@const, "ActiveRecord", s(1, 13))), s(:@const, "Base", s(1, 27))),

Returns:

  • (Sexp)

    base class of class node



206
207
208
# File 'lib/code_analyzer/sexp.rb', line 206

def base_class
  self[2] if :class == sexp_type
end

#blank?Boolean

false

Returns:

  • (Boolean)


887
888
889
# File 'lib/code_analyzer/sexp.rb', line 887

def blank?
  false
end

#block_nodeSexp

Get block node.

s(:method_add_block,
  s(:command,
    s(:@ident, "resources", s(1, 0)),
    s(:args_add_block, s(:args_add, s(:args_new), s(:symbol_literal, s(:symbol, s(:@ident, "posts", s(1, 11))))), false)
  ),
  s(:do_block, nil,
    s(:stmts_add, s(:stmts_add, s(:stmts_new), s(:void_stmt)),
      s(:command,
      s(:@ident, "resources", s(1, 21)),
      s(:args_add_block, s(:args_add, s(:args_new), s(:symbol_literal, s(:symbol, s(:@ident, "comments", s(1, 32))))), false))
    )
  )
)
    => s(:do_block, nil,
         s(:stmts_add, s(:stmts_add, s(:stmts_new), s(:void_stmt)),
           s(:command,
           s(:@ident, "resources", s(1, 21)),
           s(:args_add_block, s(:args_add, s(:args_new), s(:symbol_literal, s(:symbol, s(:@ident, "comments", s(1, 32))))), false))
         )
       )

Returns:

  • (Sexp)

    body node



495
496
497
498
499
500
# File 'lib/code_analyzer/sexp.rb', line 495

def block_node
  case sexp_type
  when :method_add_block
    self[2]
  end
end

#bodySexp

Get body node.

s(:class,
  s(:const_ref, s(:@const, "User", s(1, 6))),
  nil,
  s(:bodystmt,
    s(:stmts_add, s(:stmts_new),
      s(:def,
        s(:@ident, "login", s(1, 16)),
        s(:params, nil, nil, nil, nil, nil),
        s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil)
      )
    ), nil, nil, nil
  )
)
    => s(:bodystmt,
         s(:stmts_add, s(:stmts_new),
           s(:def,
             s(:@ident, "login", s(1, 16)),
             s(:params, nil, nil, nil, nil, nil),
             s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil)
           )
         ), nil, nil, nil
       )

Returns:

  • (Sexp)

    body node



458
459
460
461
462
463
464
465
466
467
468
469
# File 'lib/code_analyzer/sexp.rb', line 458

def body
  case sexp_type
  when :else
    self[1]
  when :module, :if, :elsif, :unless, :if_mod, :unless_mod, :ifop
    self[2]
  when :class, :def
    self[3]
  when :defs
    self[5]
  end
end

#check(visitor) ⇒ Object

check current node.

Parameters:



8
9
10
# File 'lib/code_analyzer/sexp.rb', line 8

def check(visitor)
  visitor.check_node(self)
end

#childrenArray

return child nodes of a sexp node.

Returns:

  • (Array)

    child nodes.



39
40
41
# File 'lib/code_analyzer/sexp.rb', line 39

def children
  find_all { |sexp| Sexp === sexp }
end

#class_nameSexp

Get the class name of the class node.

s(:class,
  s(:const_ref, s(:@const, "User", s(1, 6))),
  nil,
  s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil)
)
    => s(:const_ref, s(:@const, "User", s(1, 6))),

Returns:

  • (Sexp)

    class name node



192
193
194
# File 'lib/code_analyzer/sexp.rb', line 192

def class_name
  self[1] if :class == sexp_type
end

#conditional_statementSexp

Get the conditional statement of if node.

s(:if,
  s(:var_ref, s(:@kw, "true", s(1, 3))),
  s(:stmts_add, s(:stmts_new), s(:void_stmt)),
  nil
)
    => s(:var_ref, s(:@kw, "true", s(1, 3))),

Returns:

  • (Sexp)

    conditional statement of if node



358
359
360
# File 'lib/code_analyzer/sexp.rb', line 358

def conditional_statement
  self[1] if %i[if unless elsif ifop if_mod unless_mod].include? sexp_type
end

#const?Boolean

check if the self node is a const.

Returns:

  • (Boolean)


873
874
875
876
877
878
879
# File 'lib/code_analyzer/sexp.rb', line 873

def const?
  :@const == self.sexp_type ||
    (
      %i[var_ref vcall].include?(self.sexp_type) &&
        :@const == self[1].sexp_type
    )
end

#exception_classesObject

Get expcetion class of rescue node.

s(:rescue,
  s(
    s(:var_ref,
      s(:@const, "CustomException", s(1, 17))
    )
  ),
  nil,
  s(:stmts_add, s(:stmts_new), s(:void_stmt)),
  nil
)
    => s(s(:var_ref, s(:@const, "CustomException", s(1, 17))))


571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
# File 'lib/code_analyzer/sexp.rb', line 571

def exception_classes
  if :rescue == sexp_type
    return [] unless self[1]
    if :mrhs_add == self[1].sexp_type
      exceptions = Array.new(self[1][2])
      arg_nodes = self[1][1][1]
      while :args_add == arg_nodes.sexp_type
        exceptions.unshift arg_nodes[2]
        arg_nodes = arg_nodes[1]
      end
      exceptions
    else
      self[1]
    end
  end
end

#exception_variableObject

Get exception variable of rescue node.

s(:rescue,
  nil,
  s(:var_field, s(:@ident, "e", s(1, 20))),
  s(:stmts_add, s(:stmts_new), s(:void_stmt)),
  nil
)
    => s(:var_field, s(:@ident, "e", s(1, 20)))


597
598
599
# File 'lib/code_analyzer/sexp.rb', line 597

def exception_variable
  self[2] if :rescue == sexp_type
end

#grep_node(options) ⇒ Object

grep all the recursive child nodes with conditions, and yield the first match node.

options is the grep conditions, like

sexp_type: :call,
receiver: s(:const, Post),
message: [:find, :new]

the condition key is one of :sexp_type, :receiver, :message, and to_s, the condition value can be Symbol, Array or Sexp.

Parameters:

  • options (Hash)

    grep conditions



127
128
129
130
131
132
133
134
# File 'lib/code_analyzer/sexp.rb', line 127

def grep_node(options)
  result = CodeAnalyzer::Nil.new
  grep_nodes(options) do |node|
    result = node
    break
  end
  result
end

#grep_nodes(options) ⇒ Object

grep all the recursive child nodes with conditions, and yield each match node.

options is the grep conditions, like

sexp_type: :call,
receiver: "Post",
message: ["find", "new"]
to_s: "devise"

the condition key is one of :sexp_type, :receiver, :message, :to_s, the condition value can be Symbol, Array or Sexp.

Parameters:

  • options (Hash)

    grep conditions



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/code_analyzer/sexp.rb', line 64

def grep_nodes(options)
  sexp_type = options[:sexp_type]
  receiver = options[:receiver]
  message = options[:message]
  to_s = options[:to_s]
  self.recursive_children do |child|
    if (
       !sexp_type ||
         (
           if sexp_type.is_a?(Array)
             sexp_type.include?(child.sexp_type)
           else
             sexp_type == child.sexp_type
           end
         )
     ) &&
       (
         !receiver ||
           (
             if receiver.is_a?(Array)
               receiver.include?(child.receiver.to_s)
             else
               receiver == child.receiver.to_s
             end
           )
       ) &&
       (
         !message ||
           (
             if message.is_a?(Array)
               message.include?(child.message.to_s)
             else
               message == child.message.to_s
             end
           )
       ) &&
       (
         !to_s ||
           (
             if to_s.is_a?(Array)
               to_s.include?(child.to_s)
             else
               to_s == child.to_s
             end
           )
       )
      yield child
    end
  end
end

#grep_nodes_count(options) ⇒ Integer

grep all the recursive child nodes with conditions, and get the count of match nodes.

Parameters:

  • options (Hash)

    grep conditions

Returns:

  • (Integer)

    the count of metch nodes



140
141
142
143
144
# File 'lib/code_analyzer/sexp.rb', line 140

def grep_nodes_count(options)
  count = 0
  grep_nodes(options) { |node| count += 1 }
  count
end

#hash_keysArray

Get the hash keys.

s(:hash,
  s(:assoclist_from_args,
    s(
      s(:assoc_new, s(:@label, "first_name:", s(1, 1)), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Richard", s(1, 14))))),
      s(:assoc_new, s(:@label, "last_name:", s(1, 24)), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Huang", s(1, 36)))))
    )
  )
)
    => ["first_name", "last_name"]

Returns:

  • (Array)

    hash keys



669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
# File 'lib/code_analyzer/sexp.rb', line 669

def hash_keys
  pair_nodes =
    case sexp_type
    when :bare_assoc_hash
      self[1]
    when :hash
      self[1][1]
    else

    end
  if pair_nodes
    keys = []
    pair_nodes.size.times { |i| keys << pair_nodes[i][1].to_s }
    keys
  end
end

#hash_sizeInteger

Get hash size.

s(:hash,
  s(:assoclist_from_args,
    s(
      s(:assoc_new, s(:@label, "first_name:", s(1, 1)), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Richard", s(1, 14))))),
      s(:assoc_new, s(:@label, "last_name:", s(1, 24)), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Huang", s(1, 36)))))
    )
  )
)
    => 2

Returns:

  • (Integer)

    hash size



645
646
647
648
649
650
651
652
653
654
# File 'lib/code_analyzer/sexp.rb', line 645

def hash_size
  case sexp_type
  when :hash
    self[1].hash_size
  when :assoclist_from_args
    self[1].size
  when :bare_assoc_hash
    self[1].size
  end
end

#hash_value(key) ⇒ Sexp

Get hash value node.

s(:hash,
  s(:assoclist_from_args,
    s(
      s(:assoc_new, s(:@label, "first_name:", s(1, 1)), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Richard", s(1, 14))))),
      s(:assoc_new, s(:@label, "last_name:", s(1, 24)), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Huang", s(1, 36)))))
    )
  )
)
    => s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Richard", s(1, 14))))

Returns:

  • (Sexp)

    hash value node



614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
# File 'lib/code_analyzer/sexp.rb', line 614

def hash_value(key)
  pair_nodes =
    case sexp_type
    when :bare_assoc_hash
      self[1]
    when :hash
      self[1][1]
    else

    end
  if pair_nodes
    pair_nodes.size.times do |i|
      return pair_nodes[i][2] if key == pair_nodes[i][1].to_s
    end
  end
  CodeAnalyzer::Nil.new
end

#hash_valuesArray

Get the hash values.

s(:hash,
  s(:assoclist_from_args,
    s(
      s(:assoc_new, s(:@label, "first_name:", s(1, 1)), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Richard", s(1, 14))))),
      s(:assoc_new, s(:@label, "last_name:", s(1, 24)), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Huang", s(1, 36)))))
    )
  )
)
    => [
         s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Richard", s(1, 14)))),
         s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Huang", s(1, 36))))
       ]

Returns:

  • (Array)

    hash values



702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
# File 'lib/code_analyzer/sexp.rb', line 702

def hash_values
  pair_nodes =
    case sexp_type
    when :bare_assoc_hash
      self[1]
    when :hash
      self[1][1]
    else

    end
  if pair_nodes
    values = []
    pair_nodes.size.times { |i| values << pair_nodes[i][2] }
    values
  end
end

#left_valueSymbol

Get the left value of the assign node.

s(:assign,
  s(:var_field, s(:@ident, "user", s(1, 0))),
  s(:var_ref, s(:@ident, "current_user", s(1, 7)))
)
    => s(:var_field, s(:@ident, "user", s(1, 0))),

Returns:

  • (Symbol)

    left value of lasgn or iasgn node



219
220
221
# File 'lib/code_analyzer/sexp.rb', line 219

def left_value
  self[1] if :assign == sexp_type
end

#line_numberObject

return the line number of a sexp node.

s(:@ident, "test", s(2, 12)
  => 2


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/code_analyzer/sexp.rb', line 16

def line_number
  case sexp_type
  when :def, :defs, :command, :command_call, :call, :fcall, :method_add_arg, :method_add_block,
       :var_ref, :vcall, :const_ref, :const_path_ref, :class, :module, :if, :unless,
       :elsif, :ifop, :if_mod, :unless_mod, :binary, :alias, :symbol_literal, :symbol,
       :aref, :hash, :assoc_new, :string_literal, :massign, :var_field
    self[1].line_number
  when :assoclist_from_args, :bare_assoc_hash
    self[1][0].line_number
  when :string_add, :opassign
    self[2].line_number
  when :array
    array_values.first.line_number
  when :mlhs_add
    self.last.line_number
  else
    self.last.first if self.last.is_a? Array
  end
end

#messageSymbol

Get the message node.

s(:command,
  s(:@ident, "has_many", s(1, 0)),
  s(:args_add_block,
    s(:args_add, s(:args_new),
      s(:symbol_literal, s(:symbol, s(:@ident, "projects", s(1, 10))))
    ),
    false
  )
)
    => s(:@ident, "has_many", s(1, 0)),

Returns:

  • (Symbol)

    message node



250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/code_analyzer/sexp.rb', line 250

def message
  case sexp_type
  when :command, :fcall
    self[1]
  when :binary
    self[2]
  when :command_call, :field, :call
    self[3]
  when :method_add_arg, :method_add_block
    self[1].message
  end
end

#method_nameSexp

Get the method name of def node.

s(:def,
  s(:@ident, "show", s(1, 4)),
  s(:params, nil, nil, nil, nil, nil),
  s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil)
)
    => s(:@ident, "show", s(1, 4)),

Returns:

  • (Sexp)

    method name node



421
422
423
424
425
426
427
428
429
430
# File 'lib/code_analyzer/sexp.rb', line 421

def method_name
  case sexp_type
  when :def
    self[1]
  when :defs
    self[3]
  else

  end
end

#module_nameSexp

Get the module name of the module node.

s(:module,
  s(:const_ref, s(:@const, "Admin", s(1, 7))),
  s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil)
)
    => s(:const_ref, s(:@const, "Admin", s(1, 7))),

Returns:

  • (Sexp)

    module name node



178
179
180
# File 'lib/code_analyzer/sexp.rb', line 178

def module_name
  self[1] if :module == sexp_type
end

#new_methodObject

new method for alias node.

s(:alias,
  s(:symbol_literal, s(:@ident, "new", s(1, 6))),
  s(:symbol_literal, s(:@ident, "old", s(1, 10)))
)
    => s(:symbol_literal, s(:@ident, "new", s(1, 6))),


816
817
818
# File 'lib/code_analyzer/sexp.rb', line 816

def new_method
  self[1]
end

#old_methodObject

old method for alias node.

s(:alias,
  s(:symbol_literal, s(:@ident, "new", s(1, 6))),
  s(:symbol_literal, s(:@ident, "old", s(1, 10)))
)
    => s(:symbol_literal, s(:@ident, "old", s(1, 10))),


805
806
807
# File 'lib/code_analyzer/sexp.rb', line 805

def old_method
  self[2]
end

#present?Boolean

true

Returns:

  • (Boolean)


882
883
884
# File 'lib/code_analyzer/sexp.rb', line 882

def present?
  true
end

#receiverSexp

Get receiver node.

s(:call,
  s(:var_ref,
    s(:@ident, "user", s(1, 0))
  ),
  :".",
  s(:@ident, "name", s(1, 5))
)
    => s(:var_ref,
         s(:@ident, "user", s(1, 0))
       )

Returns:

  • (Sexp)

    receiver node



160
161
162
163
164
165
166
167
# File 'lib/code_analyzer/sexp.rb', line 160

def receiver
  case sexp_type
  when :assign, :field, :call, :binary, :command_call
    self[1]
  when :method_add_arg, :method_add_block
    self[1].receiver
  end
end

#recursive_childrenObject

recursively find all child nodes, and yeild each child node.



44
45
46
47
48
49
# File 'lib/code_analyzer/sexp.rb', line 44

def recursive_children
  children.each do |child|
    yield child
    child.recursive_children { |c| yield c }
  end
end

#remove_line_and_columnObject

remove the line and column info from sexp.



892
893
894
895
896
897
898
899
900
901
902
903
904
# File 'lib/code_analyzer/sexp.rb', line 892

def remove_line_and_column
  node = self.clone
  last_node = node.last
  if Sexp === last_node && last_node.size == 2 &&
     last_node.first.is_a?(Integer) &&
     last_node.last.is_a?(Integer)
    node.delete_at(-1)
  end
  node.sexp_body.each_with_index do |child, index|
    node[index + 1] = child.remove_line_and_column if Sexp === child
  end
  node
end

#right_valueSexp

Get the right value of assign node.

s(:assign,
  s(:var_field, s(:@ident, "user", s(1, 0))),
  s(:var_ref, s(:@ident, "current_user", s(1, 7)))
)
    => s(:var_ref, s(:@ident, "current_user", s(1, 7)))

Returns:

  • (Sexp)

    right value of assign node



232
233
234
# File 'lib/code_analyzer/sexp.rb', line 232

def right_value
  self[2] if :assign == sexp_type
end

#statementsArray

Get all statements nodes.

s(:bodystmt,
  s(:stmts_add,
    s(:stmts_add, s(:stmts_new),
      s(:def,
        s(:@ident, "login?", s(1, 16)),
        s(:params, nil, nil, nil, nil, nil),
        s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil)
      )
    ),
    s(:def,
      s(:@ident, "admin?", s(1, 33)),
      s(:params, nil, nil, nil, nil, nil),
      s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil)
    )
  ), nil, nil, nil
)
    => [
         s(:def,
           s(:@ident, "login?", s(1, 16)),
           s(:params, nil, nil, nil, nil, nil),
           s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil)
         ),
         s(:def,
           s(:@ident, "admin?", s(1, 33)),
           s(:params, nil, nil, nil, nil, nil),
           s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil)
         )
       ]

Returns:

  • (Array)

    all statements



534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
# File 'lib/code_analyzer/sexp.rb', line 534

def statements
  stmts = []
  node =
    case sexp_type
    when :do_block, :brace_block
      self[2][1]
    when :bodystmt
      self[1]
    else

    end
  if node
    while true
      if :stmts_add == node.sexp_type && s(:void_stmt) != node[2]
        stmts.unshift node[2]
        node = node[1]
      else
        break
      end
    end
  end
  stmts
end

#to_objectObject

To object.

s(:array,
  s(:args_add,
    s(:args_add, s(:args_new), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "first_name", s(1, 2))))),
    s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "last_name", s(1, 16))))
  )
)
    => ["first_name", "last_name"]

Returns:

  • (Object)


831
832
833
834
835
836
837
838
# File 'lib/code_analyzer/sexp.rb', line 831

def to_object
  case sexp_type
  when :array
    array_values.map(&:to_s)
  else
    to_s
  end
end

#to_sString

to_s.

Returns:

  • (String)

    to_s



843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
# File 'lib/code_analyzer/sexp.rb', line 843

def to_s
  case sexp_type
  when :string_literal, :xstring_literal, :string_content, :const_ref,
       :symbol_literal, :symbol, :args_add_block, :var_ref, :vcall, :var_field,
       :@ident, :@tstring_content, :@const, :@ivar, :@kw, :@gvar, :@cvar, :@period
    self[1].to_s
  when :string_add
    s(:string_content) == self[1] ? self[2].to_s : self[1].to_s
  when :args_add
    s(:args_new) == self[1] ? self[2].to_s : self[1].to_s
  when :qwords_add
    self[2].to_s
  when :word_add
    self[2].to_s
  when :const_path_ref
    "#{self[1]}::#{self[2]}"
  when :@label
    self[1].to_s[0..-2]
  when :aref
    "#{self[1]}[#{self[2]}]"
  when :call, :field
    "#{self.receiver}.#{self.message}"
  when :top_const_ref
    "::#{self[1]}"
  else
    ''
  end
end