Class: Maccro::Rule
- Inherits:
-
Object
- Object
- Maccro::Rule
- Defined in:
- lib/maccro/rule.rb
Instance Attribute Summary collapse
-
#after ⇒ Object
readonly
Returns the value of attribute after.
-
#before ⇒ Object
readonly
Returns the value of attribute before.
-
#matcher ⇒ Object
readonly
Returns the value of attribute matcher.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#safe_reference ⇒ Object
readonly
Returns the value of attribute safe_reference.
-
#under ⇒ Object
readonly
Returns the value of attribute under.
Class Method Summary collapse
Instance Method Summary collapse
-
#after_code(replace_pairs) ⇒ Object
name => snippet.
- #dig_match(matches, ast) ⇒ Object
- #dig_prune(matches, ast) ⇒ Object
-
#initialize(name, before, after, under: nil, safe_reference: false) ⇒ Rule
constructor
A new instance of Rule.
- #match(ast) ⇒ Object
Constructor Details
#initialize(name, before, after, under: nil, safe_reference: false) ⇒ Rule
Returns a new instance of Rule.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/maccro/rule.rb', line 9 def initialize(name, before, after, under: nil, safe_reference: false) @name = name @before = before @after = after @under = under @safe_reference = safe_reference # TODO: check all placeholder in @after exist in @before # (placeholders in @before are not required to exist in @after, because it may be removed) # TODO: check $TARGET exists in under just once # TODO: implement a matcher in @before matches in multi times @matcher = DSL.matcher(before) @pruner = under && DSL.matcher(under) || nil end |
Instance Attribute Details
#after ⇒ Object (readonly)
Returns the value of attribute after.
7 8 9 |
# File 'lib/maccro/rule.rb', line 7 def after @after end |
#before ⇒ Object (readonly)
Returns the value of attribute before.
7 8 9 |
# File 'lib/maccro/rule.rb', line 7 def before @before end |
#matcher ⇒ Object (readonly)
Returns the value of attribute matcher.
7 8 9 |
# File 'lib/maccro/rule.rb', line 7 def matcher @matcher end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
7 8 9 |
# File 'lib/maccro/rule.rb', line 7 def name @name end |
#safe_reference ⇒ Object (readonly)
Returns the value of attribute safe_reference.
7 8 9 |
# File 'lib/maccro/rule.rb', line 7 def safe_reference @safe_reference end |
#under ⇒ Object (readonly)
Returns the value of attribute under.
7 8 9 |
# File 'lib/maccro/rule.rb', line 7 def under @under end |
Class Method Details
.find_placeholder_code_ranges(ast, name) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/maccro/rule.rb', line 72 def self.find_placeholder_code_ranges(ast, name) return [] unless ast.is_a? RubyVM::AbstractSyntaxTree::Node if ast.type == :VCALL && ast.children.first.to_s == name return [CodeRange.from_node(ast)] end ranges = [] ast.children.each do |c| rs = find_placeholder_code_ranges(c, name) ranges.concat(rs) unless rs.empty? end ranges.sort end |
Instance Method Details
#after_code(replace_pairs) ⇒ Object
name => snippet
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/maccro/rule.rb', line 87 def after_code(replace_pairs) # name => snippet code = @after.dup ast = CodeUtil.parse_to_ast(@after) code_range_to_name = {} replace_pairs.each_key do |name| self.class.find_placeholder_code_ranges(ast, name).each do |r| code_range_to_name[r] = name end end # reverse is not to break code position for unprocessed code ranges code_range_to_name.keys.sort.reverse.each do |code_range| name = code_range_to_name[code_range] snippet = replace_pairs[name] range = CodeUtil.code_range_to_range(@after.dup, code_range) code[range] = snippet end code end |
#dig_match(matches, ast) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/maccro/rule.rb', line 56 def dig_match(matches, ast) if @matcher.match?(ast) placeholders = {} @matcher.capture(ast, placeholders) matches << Match.new(rule: self, placeholders: placeholders, range: ast.to_code_range) elsif ast.respond_to?(:children) ast.children.each do |c| dig_match(matches, c) end elsif ast.respond_to?(:each) ast.each do |i| dig_match(matches, i) end end end |
#dig_prune(matches, ast) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/maccro/rule.rb', line 40 def dig_prune(matches, ast) if @pruner.match?(ast) placeholders = {} @pruner.capture(ast, placeholders) dig_match(matches, placeholders[:__target__]) elsif ast.respond_to?(:children) ast.children.each do |c| dig_prune(matches, c) end elsif ast.respond_to?(:each) ast.each do |i| dig_prune(matches, i) end end end |