Class: Laser::Analysis::Sexp
- Inherits:
-
Array
- Object
- Array
- Laser::Analysis::Sexp
- Extended by:
- ModuleExtensions
- Includes:
- Laser::Analysis::SexpExtensions::ConstantExtraction, Laser::Analysis::SexpExtensions::SourceLocation, Laser::Analysis::SexpExtensions::TypeInference
- Defined in:
- lib/laser/analysis/sexp.rb
Overview
Replaces the ParseTree Sexps by adding a few handy-dandy methods.
Instance Attribute Summary (collapse)
-
- (Object) binding
Returns the value of attribute binding.
-
- (Object) errors
Returns the value of attribute errors.
-
- (Object) file_name
Returns the value of attribute file_name.
-
- (Object) file_source
Returns the value of attribute file_source.
-
- (Object) reachable
Returns the value of attribute reachable.
-
- (Object) scope
Returns the value of attribute scope.
Instance Method Summary (collapse)
- - (Object) add_error(error)
-
- (Object) all_errors
Returns all errors in this subtree, in DFS order.
- - (Object) all_subtrees
-
- (Array<Object>) children
The children of the node.
-
- (Object) deep_find
Same as #find for Enumerable, only recursively.
-
- (Object) dfs {|_self| ... }
Performs a DFS on the node, yielding each subnode (including the given node) in DFS order.
-
- (Object) dfs_enumerator
Returns an enumerator that iterates over each subnode of this node in DFS order.
-
- (Object) expanded_identifier
Returns the text of the identifier, assuming this node identifies something.
- - (Object) find_type(type)
-
- (Sexp) initialize(other, file_name = nil, file_source = nil)
constructor
Initializes the Sexp with the contents of the array returned by Ripper.
- - (Boolean) is_method_call?
-
- (Boolean) is_sexp?(sexp)
is the given object a sexp?.
- - (Object) lines
-
- (Object) method_call
Returns the MethodCall wrapping up all the method call information about this node.
-
- (Symbol) type
The type of the node.
Methods included from ModuleExtensions
attr_accessor_with_default, cattr_accessor, cattr_accessor_with_default, cattr_get_and_setter, cattr_reader, cattr_writer, opposite_method
Methods included from Laser::Analysis::SexpExtensions::TypeInference
Methods included from Laser::Analysis::SexpExtensions::SourceLocation
#backtrack_expecting!, #backtrack_searching, #forwardtrack_searching, #line_number, #source_begin, #source_end, #text_at
Methods included from Laser::Analysis::SexpExtensions::ConstantExtraction
Methods inherited from Array
#&, #*, #+, #-, #<<, #<=>, #==, [], #[], #[]=, #abbrev, #assoc, #at, #clear, #collect, #collect!, #combination, #compact, #compact!, #concat, #count, #cycle, #delete, #delete_at, #delete_if, #drop, #drop_while, #each, #each_index, #empty?, #eql?, #fetch, #fill, #find_index, #first, #flatten, #flatten!, #frozen?, #hash, #include?, #index, #insert, #inspect, #join, #keep_if, #last, #map, #map!, new, #pack, #permutation, #pop, #product, #push, #rassoc, #reject, #reject!, #repeated_combination, #repeated_permutation, #replace, #reverse, #reverse!, #reverse_each, #rindex, #rotate, #rotate!, #sample, #select, #select!, #shift, #shuffle, #shuffle!, #size, #slice, #slice!, #sort, #sort!, #sort_by!, #take, #take_while, #to_a, #to_ary, #to_s, #transpose, #uniq, #uniq!, #unshift, #values_at, #zip, #|
Constructor Details
- (Sexp) initialize(other, file_name = nil, file_source = nil)
Initializes the Sexp with the contents of the array returned by Ripper.
16 17 18 19 20 21 22 23 24 |
# File 'lib/laser/analysis/sexp.rb', line 16 def initialize(other, file_name=nil, file_source=nil) @reachable = true @expr_type = nil @errors = [] @file_name = file_name @file_source = file_source replace other replace_children! end |
Instance Attribute Details
- (Object) binding
Returns the value of attribute binding
10 11 12 |
# File 'lib/laser/analysis/sexp.rb', line 10 def binding @binding end |
- (Object) errors
Returns the value of attribute errors
10 11 12 |
# File 'lib/laser/analysis/sexp.rb', line 10 def errors @errors end |
- (Object) file_name
Returns the value of attribute file_name
10 11 12 |
# File 'lib/laser/analysis/sexp.rb', line 10 def file_name @file_name end |
- (Object) file_source
Returns the value of attribute file_source
10 11 12 |
# File 'lib/laser/analysis/sexp.rb', line 10 def file_source @file_source end |
- (Object) reachable
Returns the value of attribute reachable
11 12 13 |
# File 'lib/laser/analysis/sexp.rb', line 11 def reachable @reachable end |
- (Object) scope
Returns the value of attribute scope
10 11 12 |
# File 'lib/laser/analysis/sexp.rb', line 10 def scope @scope end |
Instance Method Details
- (Object) add_error(error)
36 37 38 |
# File 'lib/laser/analysis/sexp.rb', line 36 def add_error(error) errors << error unless errors.include?(error) end |
- (Object) all_errors
Returns all errors in this subtree, in DFS order. returns: [Error]
94 95 96 |
# File 'lib/laser/analysis/sexp.rb', line 94 def all_errors dfs_enumerator.map(&:errors).flatten end |
- (Object) all_subtrees
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/laser/analysis/sexp.rb', line 64 def all_subtrees to_visit = self.children.dup visited = Set.new while to_visit.any? todo = to_visit.shift next unless is_sexp?(todo) case todo[0] when Array to_visit.concat todo when ::Symbol to_visit.concat todo.children visited << todo end end visited end |
- (Array<Object>) children
The children of the node.
27 28 29 |
# File 'lib/laser/analysis/sexp.rb', line 27 def children @children ||= ((Array === self[0] ? self : self[1..-1]) || []) end |
- (Object) deep_find
Same as #find for Enumerable, only recursively. Useful for "jumping" past useless parser nodes.
57 58 59 60 61 62 |
# File 'lib/laser/analysis/sexp.rb', line 57 def deep_find ([self] + all_subtrees.to_a).each do |node| return node if yield(node) end nil end |
- (Object) dfs {|_self| ... }
Performs a DFS on the node, yielding each subnode (including the given node) in DFS order.
100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/laser/analysis/sexp.rb', line 100 def dfs yield self self.children.each do |child| next unless is_sexp?(child) case child[0] when Array child.each { |x| x.dfs { |y| yield y}} when ::Symbol child.dfs { |y| yield y } end end end |
- (Object) dfs_enumerator
Returns an enumerator that iterates over each subnode of this node in DFS order.
84 85 86 87 88 89 90 |
# File 'lib/laser/analysis/sexp.rb', line 84 def dfs_enumerator Enumerator.new do |g| dfs do |node| g.yield node end end end |
- (Object) expanded_identifier
Returns the text of the identifier, assuming this node identifies something.
126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/laser/analysis/sexp.rb', line 126 def case type when :@ident, :@const, :@gvar, :@cvar, :@ivar, :@kw, :@op self[1] when :var_ref, :var_field, :const_ref, :symbol self[1]. when :top_const_ref, :top_const_field "::#{self[1].}" when :const_path_ref, :const_path_field lhs, rhs = children "#{lhs.}::#{rhs.}" end end |
- (Object) find_type(type)
51 52 53 |
# File 'lib/laser/analysis/sexp.rb', line 51 def find_type(type) deep_find { |node| node.type == type } end |
- (Boolean) is_method_call?
140 141 142 143 |
# File 'lib/laser/analysis/sexp.rb', line 140 def is_method_call? [:command, :method_add_arg, :method_add_block, :vcall, :var_ref, :call, :fcall, :command_call, :binary, :unary, :super, :zsuper, :aref].include?(type) end |
- (Boolean) is_sexp?(sexp)
is the given object a sexp?
43 44 45 |
# File 'lib/laser/analysis/sexp.rb', line 43 def is_sexp?(sexp) Analysis::Sexp === sexp end |
- (Object) lines
47 48 49 |
# File 'lib/laser/analysis/sexp.rb', line 47 def lines @file_source.lines.to_a end |
- (Object) method_call
Returns the MethodCall wrapping up all the method call information about this node.
raises: TypeError return: MethodCall
150 151 152 153 154 155 156 |
# File 'lib/laser/analysis/sexp.rb', line 150 def method_call unless is_method_call? raise TypeError.new("Only method call nodes define #method_call. "+ "This node is of type #{type}.") end MethodCall.new(self) end |
- (Symbol) type
The type of the node.
32 33 34 |
# File 'lib/laser/analysis/sexp.rb', line 32 def type self[0] end |