Class: Prism::Merge::BeginNodeStructure

Inherits:
Object
  • Object
show all
Defined in:
lib/prism/merge/begin_node_structure.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(node) ⇒ BeginNodeStructure

Returns a new instance of BeginNodeStructure.



17
18
19
# File 'lib/prism/merge/begin_node_structure.rb', line 17

def initialize(node)
  @node = node
end

Instance Attribute Details

#nodeObject (readonly)

Returns the value of attribute node.



15
16
17
# File 'lib/prism/merge/begin_node_structure.rb', line 15

def node
  @node
end

Class Method Details

.rescue_signature(rescue_node) ⇒ Object



7
8
9
10
11
12
# File 'lib/prism/merge/begin_node_structure.rb', line 7

def rescue_signature(rescue_node)
  exceptions = Array(rescue_node.exceptions).map do |exception_node|
    exception_node.respond_to?(:slice) ? exception_node.slice : exception_node.to_s
  end
  Ruby::Merge::RescueSemantics.new.rescue_clause_signature(exceptions)
end

Instance Method Details

#boundary_linesObject



21
22
23
24
25
26
27
28
29
30
31
# File 'lib/prism/merge/begin_node_structure.rb', line 21

def boundary_lines
  return [node.location.start_line, node.location.end_line].uniq unless begin_node?

  [
    node.location.start_line,
    node.rescue_clause&.location&.start_line,
    node.else_clause&.location&.start_line,
    node.ensure_clause&.location&.start_line,
    node.location.end_line
  ].compact.uniq
end

#clause_nodes_by_typeObject



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

def clause_nodes_by_type
  return {} unless begin_node?

  rescue_occurrences = Hash.new(0)
  nodes_by_type = {}
  rescue_nodes.each do |rescue_node|
    signature = self.class.rescue_signature(rescue_node)
    occurrence = rescue_occurrences[signature]
    rescue_occurrences[signature] += 1
    nodes_by_type[[:rescue_clause, signature, occurrence]] = rescue_node
  end
  nodes_by_type[:else_clause] = node.else_clause if node.else_clause
  nodes_by_type[:ensure_clause] = node.ensure_clause if node.ensure_clause
  nodes_by_type
end

#clause_regionsObject



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
84
# File 'lib/prism/merge/begin_node_structure.rb', line 59

def clause_regions
  return [] unless begin_node?

  rescue_occurrences = Hash.new(0)
  region_defs = rescue_nodes.map do |rescue_node|
    signature = self.class.rescue_signature(rescue_node)
    occurrence = rescue_occurrences[signature]
    rescue_occurrences[signature] += 1
    { type: [:rescue_clause, signature, occurrence], start_line: rescue_node.location.start_line }
  end
  if node.else_clause&.location
    region_defs << { type: :else_clause, start_line: node.else_clause.location.start_line }
  end
  if node.ensure_clause&.location
    region_defs << { type: :ensure_clause, start_line: node.ensure_clause.location.start_line }
  end

  region_defs.each_with_index.map do |region_def, index|
    next_start_line = region_defs[index + 1]&.dig(:start_line)
    {
      type: region_def[:type],
      start_line: region_def[:start_line],
      end_line: (next_start_line ? next_start_line - 1 : node.location.end_line - 1)
    }
  end
end

#clause_start_lineObject



33
34
35
36
37
38
39
40
41
# File 'lib/prism/merge/begin_node_structure.rb', line 33

def clause_start_line
  return unless begin_node?

  [
    node.rescue_clause&.location&.start_line,
    node.else_clause&.location&.start_line,
    node.ensure_clause&.location&.start_line
  ].compact.min
end

#has_clause_or_body?Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/prism/merge/begin_node_structure.rb', line 102

def has_clause_or_body?
  !!(begin_node? && (node.statements || node.rescue_clause || node.else_clause || node.ensure_clause))
end

#line_map_for(other_structure) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/prism/merge/begin_node_structure.rb', line 106

def line_map_for(other_structure)
  return {} unless begin_node? && other_structure.begin_node?

  regions = clause_regions.each_with_object({}) { |region, by_type| by_type[region[:type]] = region }
  other_regions = other_structure.clause_regions.each_with_object({}) do |region, by_type|
    by_type[region[:type]] = region
  end

  regions.each_with_object({}) do |(type, region), mapping|
    other_region = other_regions[type]
    next unless other_region

    mapping[region[:start_line]] = other_region[:start_line]
  end
end

#rescue_nodesObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/prism/merge/begin_node_structure.rb', line 43

def rescue_nodes
  return [] unless begin_node?

  nodes = []
  current = node.rescue_clause
  while current.is_a?(Prism::RescueNode)
    nodes << current
    current = if current.respond_to?(:subsequent)
                current.subsequent
              else
                current.consequent
              end
  end
  nodes
end