Class: Ast::Merge::ConflictResolverBase Abstract
- Inherits:
-
Object
- Object
- Ast::Merge::ConflictResolverBase
- Includes:
- UnresolvedSupport
- 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
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 156 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).
123 124 125 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 123 def add_template_only_nodes @add_template_only_nodes end |
#dest_analysis ⇒ Object (readonly)
Returns Destination file analysis.
120 121 122 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 120 def dest_analysis @dest_analysis end |
#match_refiner ⇒ Object? (readonly)
Returns Match refiner for fuzzy matching.
135 136 137 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 135 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 }.
114 115 116 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 114 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.
132 133 134 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 132 def recursive @recursive end |
#remove_template_missing_nodes ⇒ Boolean (readonly)
Returns Whether to remove destination nodes not in template (batch strategy).
126 127 128 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 126 def remove_template_missing_nodes @remove_template_missing_nodes end |
#strategy ⇒ Symbol (readonly)
Returns Resolution strategy (:node, :batch, or :boundary).
108 109 110 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 108 def strategy @strategy end |
#template_analysis ⇒ Object (readonly)
Returns Template file analysis.
117 118 119 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 117 def template_analysis @template_analysis end |
Instance Method Details
#default_preference ⇒ Symbol
Get the default preference (used as fallback).
233 234 235 236 237 238 239 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 233 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
199 200 201 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 199 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.
244 245 246 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 244 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.
218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 218 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
184 185 186 187 188 189 190 191 192 193 |
# File 'lib/ast/merge/conflict_resolver_base.rb', line 184 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 |