Class: Prism::Merge::FreezeNode

Inherits:
Ast::Merge::FreezeNodeBase
  • Object
show all
Defined in:
lib/prism/merge/freeze_node.rb

Overview

Wrapper to represent freeze blocks as first-class nodes. A freeze block is a section marked with freeze/unfreeze comment markers that should be preserved from the destination during merges.

Inherits from Ast::Merge::FreezeNodeBase for shared functionality including the Location struct, InvalidStructureError, and configurable marker patterns.

Uses the :hash_comment pattern type by default for Ruby source files.

While freeze blocks are delineated by comment markers, they are conceptually different from CommentNode and do not inherit from it because:

  • FreezeNodeBase is a structural directive that contains code and/or comments
  • CommentNode represents pure documentation with no structural significance
  • FreezeNodeBase can contain Ruby code nodes (methods, constants, etc.)
  • CommentNode only contains comments
  • Their signatures need different semantics for merge matching

Freeze blocks can contain other nodes (methods, classes, etc.) and those nodes remain as separate entities within the block for analysis purposes, but the entire freeze block is treated as an atomic unit during merging.

Examples:

Freeze block with mixed content

# prism-merge:freeze
# Custom documentation
CUSTOM_CONFIG = { key: "secret" }
def custom_method
  # ...
end
# prism-merge:unfreeze

Defined Under Namespace

Classes: LocationWithOffsets

Constant Summary collapse

InvalidStructureError =

Inherit InvalidStructureError from base class

Ast::Merge::FreezeNodeBase::InvalidStructureError
Location =

Inherit Location from base class (used when no offset info available)

Ast::Merge::FreezeNodeBase::Location

Instance Method Summary collapse

Constructor Details

#initialize(start_line:, end_line:, analysis:, nodes: [], overlapping_nodes: nil, start_marker: nil, end_marker: nil, pattern_type: Ast::Merge::FreezeNodeBase::DEFAULT_PATTERN) ⇒ FreezeNode

Returns a new instance of FreezeNode.

Parameters:

  • start_line (Integer)

    Line number of freeze marker

  • end_line (Integer)

    Line number of unfreeze marker

  • analysis (FileAnalysis)

    The file analysis containing this block

  • nodes (Array<Prism::Node>) (defaults to: [])

    Nodes fully contained within the freeze block

  • overlapping_nodes (Array<Prism::Node>) (defaults to: nil)

    All nodes that overlap with freeze block (for validation)

  • start_marker (String, nil) (defaults to: nil)

    The freeze start marker text

  • end_marker (String, nil) (defaults to: nil)

    The freeze end marker text

  • pattern_type (Symbol) (defaults to: Ast::Merge::FreezeNodeBase::DEFAULT_PATTERN)

    Pattern type for marker matching (defaults to :hash_comment)



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/prism/merge/freeze_node.rb', line 67

def initialize(start_line:, end_line:, analysis:, nodes: [], overlapping_nodes: nil, start_marker: nil,
               end_marker: nil, pattern_type: Ast::Merge::FreezeNodeBase::DEFAULT_PATTERN)
  super(
    start_line: start_line,
    end_line: end_line,
    analysis: analysis,
    nodes: nodes,
    overlapping_nodes: overlapping_nodes || nodes,
    start_marker: start_marker,
    end_marker: end_marker,
    pattern_type: pattern_type
  )

  # Validate structure
  validate_structure!
end

Instance Method Details

#inspectString

String representation for debugging

Returns:

  • (String)


115
116
117
# File 'lib/prism/merge/freeze_node.rb', line 115

def inspect
  "#<Prism::Merge::FreezeNode lines=#{@start_line}..#{@end_line} nodes=#{@nodes.length}>"
end

#locationLocationWithOffsets

Returns a location with real byte offsets so TopLevelMergeRunner's already_output? works correctly (it compares byte ranges).

Returns:



87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/prism/merge/freeze_node.rb', line 87

def location
  @location ||= begin
    lines = @analysis&.lines
    if lines
      # Byte offset of first char of start_line (sum of all prior line bytes)
      so = lines.take(@start_line - 1).sum(&:bytesize)
      # Byte offset past end of end_line (sum through end_line)
      eo = lines.take(@end_line).sum(&:bytesize)
      LocationWithOffsets.new(@start_line, @end_line, so, eo)
    else
      Location.new(@start_line, @end_line)
    end
  end
end

#signatureArray

Returns a stable signature for this freeze block Signature includes the normalized content to detect changes

Returns:

  • (Array)

    Signature array



105
106
107
108
109
110
111
# File 'lib/prism/merge/freeze_node.rb', line 105

def signature
  normalized = (@start_line..@end_line).map do |ln|
    @analysis.normalized_line(ln)
  end.compact.join("\n")

  [:FreezeNode, normalized]
end