Class: Ast::Merge::Navigable::InjectionPointFinder
- Inherits:
-
Object
- Object
- Ast::Merge::Navigable::InjectionPointFinder
- Defined in:
- lib/ast/merge/navigable/injection_point_finder.rb
Overview
Finds injection points in a document based on matching rules.
This is language-agnostic - the matching rules work on the unified
Statement interface regardless of the underlying parser.
Instance Attribute Summary collapse
-
#statements ⇒ Array<Statement>
readonly
The statement list to search.
Instance Method Summary collapse
-
#find(type: nil, text: nil, position:, boundary_type: nil, boundary_text: nil, boundary_matcher: nil, boundary_same_or_shallower: false) {|Statement| ... } ⇒ InjectionPoint?
Find an injection point based on matching criteria.
-
#find_all(type: nil, text: nil, position:, &block) ⇒ Array<InjectionPoint>
Find all injection points matching criteria.
-
#initialize(statements) ⇒ InjectionPointFinder
constructor
A new instance of InjectionPointFinder.
Constructor Details
#initialize(statements) ⇒ InjectionPointFinder
Returns a new instance of InjectionPointFinder.
30 31 32 |
# File 'lib/ast/merge/navigable/injection_point_finder.rb', line 30 def initialize(statements) @statements = statements end |
Instance Attribute Details
#statements ⇒ Array<Statement> (readonly)
Returns The statement list to search.
28 29 30 |
# File 'lib/ast/merge/navigable/injection_point_finder.rb', line 28 def statements @statements end |
Instance Method Details
#find(type: nil, text: nil, position:, boundary_type: nil, boundary_text: nil, boundary_matcher: nil, boundary_same_or_shallower: false) {|Statement| ... } ⇒ InjectionPoint?
Find an injection point based on matching criteria.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/ast/merge/navigable/injection_point_finder.rb', line 45 def find(type: nil, text: nil, position:, boundary_type: nil, boundary_text: nil, boundary_matcher: nil, boundary_same_or_shallower: false, &block) anchor = Statement.find_first(statements, type: type, text: text, &block) return unless anchor boundary = nil if position == :replace && (boundary_type || boundary_text || boundary_matcher || boundary_same_or_shallower) # Find boundary starting after anchor remaining = statements[(anchor.index + 1)..] if boundary_same_or_shallower # Find next node at same or shallower tree depth # This is language-agnostic: ends section at next sibling or ancestor's sibling anchor_depth = anchor.tree_depth boundary = remaining.find do |stmt| # Must match type if specified next false if boundary_type && stmt.type.to_s != boundary_type.to_s next false if boundary_text && !stmt.text_matches?(boundary_text) # Check tree depth stmt.same_or_shallower_than?(anchor_depth) end elsif boundary_matcher # Use custom matcher boundary = remaining.find { |stmt| boundary_matcher.call(stmt) } else boundary = Statement.find_first( remaining, type: boundary_type, text: boundary_text, ) end end InjectionPoint.new( anchor: anchor, position: position, boundary: boundary, match: {type: type, text: text}, ) end |
#find_all(type: nil, text: nil, position:, &block) ⇒ Array<InjectionPoint>
Find all injection points matching criteria.
89 90 91 92 93 94 |
# File 'lib/ast/merge/navigable/injection_point_finder.rb', line 89 def find_all(type: nil, text: nil, position:, &block) anchors = Statement.find_matching(statements, type: type, text: text, &block) anchors.map do |anchor| InjectionPoint.new(anchor: anchor, position: position) end end |