Class: Ast::Merge::ConflictResolverBase Abstract
- Inherits:
-
Object
- Object
- Ast::Merge::ConflictResolverBase
- Defined in:
- lib/ast/merge/conflict_resolver_base.rb
Overview
Subclass and implement resolve_node_pair, resolve_batch, or resolve_boundary
Base class for conflict resolvers across all *-merge gems.
Provides common functionality for resolving conflicts between template
and destination content during merge operations. Supports three resolution
strategies that can be selected based on the needs of each file format:
:node- Per-node resolution (resolve individual node pairs):batch- Batch resolution (resolve entire file using signature maps):boundary- Boundary resolution (resolve sections/ranges of content)
Direct Known Subclasses
Constant Summary collapse
- DECISION_DESTINATION =
Use destination version (customization preserved)
:destination- DECISION_TEMPLATE =
Use template version (update applied)
:template- DECISION_ADDED =
Content was added from template (template-only)
:added- DECISION_FROZEN =
Content preserved from frozen block
:frozen- DECISION_IDENTICAL =
Content was identical (no conflict)
:identical- DECISION_KEPT_DEST =
Content was kept from destination (signature match, dest preferred)
:kept_destination- DECISION_KEPT_TEMPLATE =
Content was kept from template (signature match, template preferred)
:kept_template- DECISION_APPENDED =
Content was appended from destination (dest-only)
:appended- DECISION_FREEZE_BLOCK =
Content preserved from freeze block marker
:freeze_block- DECISION_RECURSIVE =
Content requires recursive merge (container types)
:recursive- DECISION_REPLACED =
Content was replaced (signature match with different content)
:replaced
Instance Attribute Summary collapse
-
#add_template_only_nodes ⇒ Boolean
readonly
Whether to add template-only nodes (batch strategy).
-
#dest_analysis ⇒ Object
readonly
Destination file analysis.
-
#match_refiner ⇒ Object?
readonly
Match refiner for fuzzy matching.
-
#preference ⇒ Symbol, Hash
readonly
Merge preference.
-
#recursive ⇒ Boolean, Integer
readonly
Whether to merge nested structures recursively - true: unlimited depth (default) - false: disabled - Integer > 0: max depth.
-
#remove_template_missing_nodes ⇒ Boolean
readonly
Whether to remove destination nodes not in template (batch strategy).
-
#strategy ⇒ Symbol
readonly
Resolution strategy (:node, :batch, or :boundary).
-
#template_analysis ⇒ Object
readonly
Template file analysis.
Instance Method Summary collapse
-
#default_preference ⇒ Symbol
Get the default preference (used as fallback).
-
#freeze_node?(node) ⇒ Boolean
Check if a node is a freeze node using duck typing.
-
#initialize(strategy:, preference:, template_analysis:, dest_analysis:, add_template_only_nodes: false, remove_template_missing_nodes: false, recursive: true, match_refiner: nil, **options) ⇒ ConflictResolverBase
constructor
Initialize the conflict resolver.
-
#per_type_preference? ⇒ Boolean
Check if Hash-based per-type preferences are configured.
-
#preference_for_node(node) ⇒ Symbol
Get the preference for a specific node.
-
#resolve(*args, **kwargs) ⇒ Object
Resolve conflicts using the configured strategy.
Constructor Details
#initialize(strategy:, preference:, template_analysis:, dest_analysis:, add_template_only_nodes: false, remove_template_missing_nodes: false, recursive: true, match_refiner: nil, **options) ⇒ ConflictResolverBase
Initialize the conflict resolver
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 152 def initialize(strategy:, preference:, template_analysis:, dest_analysis:, add_template_only_nodes: false, remove_template_missing_nodes: false, recursive: true, match_refiner: nil, **) unless %i[node batch boundary].include?(strategy) raise ArgumentError, "Invalid strategy: #{strategy}. Must be :node, :batch, or :boundary" end validate_preference!(preference) validate_recursive!(recursive) @strategy = strategy @preference = preference @template_analysis = template_analysis @dest_analysis = dest_analysis @add_template_only_nodes = add_template_only_nodes @remove_template_missing_nodes = remove_template_missing_nodes @recursive = recursive @match_refiner = match_refiner # **options captured for forward compatibility - subclasses may use additional options end |
Instance Attribute Details
#add_template_only_nodes ⇒ Boolean (readonly)
Returns Whether to add template-only nodes (batch strategy).
119 120 121 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 119 def add_template_only_nodes @add_template_only_nodes end |
#dest_analysis ⇒ Object (readonly)
Returns Destination file analysis.
116 117 118 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 116 def dest_analysis @dest_analysis end |
#match_refiner ⇒ Object? (readonly)
Returns Match refiner for fuzzy matching.
131 132 133 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 131 def match_refiner @match_refiner end |
#preference ⇒ Symbol, Hash (readonly)
Returns Merge preference.
As Symbol: :destination or :template (applies to all nodes)
As Hash: Maps node types/merge_types to preferences
@example { default: :destination, lint_gem: :template }.
110 111 112 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 110 def preference @preference end |
#recursive ⇒ Boolean, Integer (readonly)
Returns Whether to merge nested structures recursively
- true: unlimited depth (default)
- false: disabled
- Integer > 0: max depth.
128 129 130 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 128 def recursive @recursive end |
#remove_template_missing_nodes ⇒ Boolean (readonly)
Returns Whether to remove destination nodes not in template (batch strategy).
122 123 124 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 122 def remove_template_missing_nodes @remove_template_missing_nodes end |
#strategy ⇒ Symbol (readonly)
Returns Resolution strategy (:node, :batch, or :boundary).
104 105 106 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 104 def strategy @strategy end |
#template_analysis ⇒ Object (readonly)
Returns Template file analysis.
113 114 115 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 113 def template_analysis @template_analysis end |
Instance Method Details
#default_preference ⇒ Symbol
Get the default preference (used as fallback).
228 229 230 231 232 233 234 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 228 def default_preference if @preference.is_a?(Hash) @preference.fetch(:default, :destination) else @preference end end |
#freeze_node?(node) ⇒ Boolean
Check if a node is a freeze node using duck typing
194 195 196 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 194 def freeze_node?(node) node.respond_to?(:freeze_node?) && node.freeze_node? end |
#per_type_preference? ⇒ Boolean
Check if Hash-based per-type preferences are configured.
239 240 241 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 239 def per_type_preference? @preference.is_a?(Hash) end |
#preference_for_node(node) ⇒ Symbol
Get the preference for a specific node.
When preference is a Hash, looks up the preference for the node’s
merge_type (if wrapped with NodeTyping) or falls back to :default.
213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 213 def preference_for_node(node) return default_preference unless @preference.is_a?(Hash) return default_preference unless node # Check if node has a merge_type (from NodeTyping) merge_type = NodeTyping.merge_type_for(node) return @preference.fetch(merge_type) { default_preference } if merge_type # Fall back to default default_preference end |
#resolve(*args, **kwargs) ⇒ Object
Resolve conflicts using the configured strategy
For :node strategy, this delegates to resolve_node_pair
For :batch strategy, this delegates to resolve_batch
For :boundary strategy, this delegates to resolve_boundary
179 180 181 182 183 184 185 186 187 188 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 179 def resolve(*args, **kwargs) case @strategy when :node resolve_node_pair(*args, **kwargs) when :batch resolve_batch(*args) when :boundary resolve_boundary(*args) end end |