1 # frozen_string_literal: true
4 # This class is responsible for generating initial code blocks
5 # that will then later be expanded.
7 # The biggest concern when guessing code blocks, is accidentally
8 # grabbing one that contains only an "end". In this example:
11 # begonn # misspelled `begin`
16 # The following lines would be matched (from bottom to top):
27 # At this point it has no where else to expand, and it will yield this inner
29 class ParseBlocksFromIndentLine
30 attr_reader :code_lines
32 def initialize(code_lines:)
33 @code_lines = code_lines
36 # Builds blocks from bottom up
37 def each_neighbor_block(target_line)
38 scan = AroundBlockScan.new(code_lines: code_lines, block: CodeBlock.new(lines: target_line))
41 .scan_while { |line| line.indent >= target_line.indent }
43 neighbors = scan.code_block.lines
45 block = CodeBlock.new(lines: neighbors)
46 if neighbors.length <= 2 || block.valid?
49 until neighbors.empty?
50 lines = [neighbors.pop]
51 while (block = CodeBlock.new(lines: lines)) && block.invalid? && neighbors.any?
52 lines.prepend neighbors.pop