Module: Ast::Merge::Freezable

Included in:
FreezeNodeBase, NodeTyping::FrozenWrapper
Defined in:
lib/ast/merge/freezable.rb

Overview

Mixin module that provides freeze node behavior.

This module can be included in any class to make it behave as a frozen node for merge operations. It provides the core API that identifies a node as frozen and allows it to participate in freeze-aware merging.

The primary use cases are:

  1. Included by FreezeNodeBase for traditional freeze block nodes

  2. Included by NodeTyping::FrozenWrapper for wrapping AST nodes with freeze markers

## Critical: Understanding freeze_signature vs structural matching

The ‘freeze_signature` method returns a content-based signature that includes the full text of the frozen content. This is appropriate for:

  • FreezeNodeBase: Explicit freeze blocks where the entire content is opaque and should be matched by content identity

However, for FrozenWrapper, using freeze_signature would cause matching problems because the wrapper contains an AST node (like a ‘gem` call) where we want to match by the node’s structural identity, not its full content.

For example, in a gemspec:

  • Template: ‘# token:freezengem “example”, “~> 1.0”`

  • Destination: ‘# token:freezengem “example”, “~> 2.0”` (different version)

If we used freeze_signature for both, they would NOT match (different content), causing duplication. Instead, FileAnalyzable#generate_signature unwraps FrozenWrapper nodes and uses the underlying node’s signature (gem name), so they DO match and merge correctly.

Examples:

Checking if something is freezable

if node.is_a?(Ast::Merge::Freezable)
  # Node will be preserved during merge
end

Including in a custom class

class MyFrozenNode
  include Ast::Merge::Freezable

  def slice
    @content
  end
end

See Also:

Instance Method Summary collapse

Instance Method Details

#freeze_node?Boolean

Check if this is a freeze node. Always returns true for classes that include this module.

Returns:

  • (Boolean)

    true



57
58
59
# File 'lib/ast/merge/freezable.rb', line 57

def freeze_node?
  true
end

#freeze_signatureArray

Returns a stable signature for this freeze node. The signature uses the content to allow matching freeze blocks between template and destination.

Subclasses can override this for custom signature behavior.

Returns:

  • (Array)

    Signature array in the form [:FreezeNode, content]



68
69
70
# File 'lib/ast/merge/freezable.rb', line 68

def freeze_signature
  [:FreezeNode, slice&.strip]
end

#sliceString

This method is abstract.

Returns the content of this freeze node. Must be implemented by including classes.

Returns:

  • (String)

    The frozen content

Raises:

  • (NotImplementedError)


77
78
79
# File 'lib/ast/merge/freezable.rb', line 77

def slice
  raise NotImplementedError, "#{self.class} must implement #slice"
end