Module: OffenseToCorrector::AstTools
- Included in:
- OffenseParser
- Defined in:
- lib/offense_to_corrector/ast_tools.rb
Instance Method Summary collapse
-
#ast_from(value) ⇒ Object
So why bother with the above then? If we end up into correctors and tree-rewrites we need that original processed source to be the basis of the AST, otherwise we get object ID mismatches.
- #atom?(value) ⇒ Boolean
-
#get_children(source_node) ⇒ Object
Descendants leaves out a lot of detail potentially.
-
#get_corrector(value) ⇒ Object
Not needed quite yet, but could very potentially be used to verify how accurate generated cops are.
-
#processed_source_from(string) ⇒ Object
To get an AST we need the processed source of a string.
-
#range_overlap?(a, b) ⇒ Boolean
See if a range overlaps another one, bidirectional.
-
#range_overlap_count(a, b) ⇒ Object
How much do two ranges overlap? Used to see how well a node matches with the associated underline.
-
#string_intersection(a, b) ⇒ Object
I may have to work on getting this one later to try and narrow the band of ‘AtomNode` def childless?(node) false # TODO end.
Instance Method Details
#ast_from(value) ⇒ Object
So why bother with the above then? If we end up into correctors and tree-rewrites we need that original processed source to be the basis of the AST, otherwise we get object ID mismatches.
46 47 48 49 50 51 52 53 |
# File 'lib/offense_to_corrector/ast_tools.rb', line 46 def ast_from(value) case value when RuboCop::ProcessedSource value.ast else processed_source_from(value).ast end end |
#atom?(value) ⇒ Boolean
3 4 5 |
# File 'lib/offense_to_corrector/ast_tools.rb', line 3 def atom?(value) !value.is_a?(RuboCop::AST::Node) end |
#get_children(source_node) ⇒ Object
Descendants leaves out a lot of detail potentially. There has to be a better way to deal with this, but not thinking of one right now.
63 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 |
# File 'lib/offense_to_corrector/ast_tools.rb', line 63 def get_children(source_node) recurse = -> parent do collected_children = [] parent.children.each do |child| next if child.nil? # If it's a regular parent carry on as you were unless atom?(child) # || childless?(child) collected_children.concat([child, *recurse[child]]) next end # Otherwise we want to find where that parent is in the source code, # and the range it exists in, to create an `AtomNode` source = child.to_s parent_begin = parent.location.expression.to_range.begin range_begin = source_node.source.index(source, parent_begin) range_end = range_begin + source.size range = range_begin..range_end collected_children << AtomNode.new(parent:, source:, range:) end collected_children end [source_node, *recurse[source_node]] end |
#get_corrector(value) ⇒ Object
Not needed quite yet, but could very potentially be used to verify how accurate generated cops are.
57 58 59 |
# File 'lib/offense_to_corrector/ast_tools.rb', line 57 def get_corrector(value) RuboCop::Cop::Corrector.new(value.buffer) end |
#processed_source_from(string) ⇒ Object
To get an AST we need the processed source of a string
39 40 41 |
# File 'lib/offense_to_corrector/ast_tools.rb', line 39 def processed_source_from(string) RuboCop::ProcessedSource.new(string, RUBY_VERSION.to_f) end |
#range_overlap?(a, b) ⇒ Boolean
See if a range overlaps another one, bidirectional
34 35 36 |
# File 'lib/offense_to_corrector/ast_tools.rb', line 34 def range_overlap?(a, b) a.cover?(b.begin) || b.cover?(a.begin) end |
#range_overlap_count(a, b) ⇒ Object
How much do two ranges overlap? Used to see how well a node matches with the associated underline
26 27 28 29 30 31 |
# File 'lib/offense_to_corrector/ast_tools.rb', line 26 def range_overlap_count(a, b) return [a.end, b.end].min - b.begin if a.cover?(b.begin) return [a.end, b.end].min - a.begin if b.cover?(a.begin) 0 end |
#string_intersection(a, b) ⇒ Object
I may have to work on getting this one later to try and narrow the band of ‘AtomNode` def childless?(node)
false # TODO
end
13 14 15 16 17 18 19 20 21 22 |
# File 'lib/offense_to_corrector/ast_tools.rb', line 13 def string_intersection(a, b) # Smaller string inside larger string target, search_string = a.size < b.size ? [a, b] : [b, a] last_char_index = target.size.downto(1).find do |i| search_string.include?(target[0..i]) end or return "" target[0..last_char_index] end |