класс SyntaxSuggest::BlockExpand
Этот класс отвечает за взятие блока кода, находящегося на большом отступе, и последующее итеративное увеличение блока таким образом, чтобы он охватывал все, что находится в том же блоке отступов.
def dog puts "bow" puts "wow" end
block = BlockExpand.new(code_lines: code_lines)
.call(CodeBlock.new(lines: code_lines[1]))
puts block.to_s # => puts “bow”
puts "wow"
После того, как блок кода захватит все элементы на заданном уровне отступа, он будет расширяться, чтобы захватить окружающие отступы.
block = BlockExpand.new(code_lines: code_lines)
.call(block)
block.to_s # => def dog
puts "bow" puts "wow" end
Публичные методы класса
# File lib/syntax_suggest/block_expand.rb, line 34 def initialize(code_lines:) @code_lines = code_lines end
Публичные методы экземпляра
# File lib/syntax_suggest/block_expand.rb, line 40
def call(block)
if (next_block = expand_neighbors(block))
next_block
else
expand_indent(block)
end
end Основной интерфейс. Расширить текущий отступ перед расширением до меньшего отступа
# File lib/syntax_suggest/block_expand.rb, line 63
def expand_indent(block)
now = AroundBlockScan.new(code_lines: @code_lines, block: block)
.force_add_hidden
.stop_after_kw
.scan_adjacent_indent
now.lookahead_balance_one_line
now.code_block
end Расширяет код до следующего меньшего отступа
Например:
1 def dog 2 print "dog" 3 end
Если блок начинается со строки 2, то он уже захватил всех своих «соседей» (код с таким же или большим отступом). Для продолжения расширения этот блок должен захватить строки 1 и 3, которые находятся на другом уровне отступа.
Этот метод позволяет полностью расширенным блокам уменьшить свой уровень отступа (чтобы они могли расшириться и захватить больше кода сверху и снизу). Он делает это консервативно, так как отмены нет (на данный момент).
# File lib/syntax_suggest/block_expand.rb, line 130
def expand_neighbors(block)
now = AroundBlockScan.new(code_lines: @code_lines, block: block)
# Initial scan
now
.force_add_hidden
.stop_after_kw
.scan_neighbors_not_empty
# Slurp up empties
now
.scan_while { |line| line.empty? }
# If next line is kw and it will balance us, take it
expanded_lines = now
.lookahead_balance_one_line
.lines
# Don't allocate a block if it won't be used
#
# If nothing was taken, return nil to indicate that status
# used in `def call` to determine if
# we need to expand up/out (`expand_indent`)
if block.lines == expanded_lines
nil
else
CodeBlock.new(lines: expanded_lines)
end
end Сосед — это код, который находится на том же или выше уровне отступа, чем текущая строка.
Сначала мы создаём блок со всеми соседями. Если мы не можем пойти дальше, то уменьшаем порог отступа и расширяемся по отступу, то есть с помощью «expand_indent»
Обрабатывает два общих случая.
## Случай № 1: Проверка кода внутри методов/классов и т. д.
Важно отметить, что не всё, что находится на данном уровне отступа, может быть обработано как допустимый код, даже если это часть допустимого кода. Например:
1 hash = {
2 name: "richard",
3 dog: "cinco",
4 } В этом случае строки 2 и 3 будут соседями, но они не являются допустимыми, пока на них не будет применено «expand_indent».
Когда мы добавляем код внутри метода или класса (на одном уровне отступа), используйте пустые строки, чтобы обозначить, что программист намеревался разбить код на логические части. Останавливайтесь и проверяйте каждую из них. Например:
1 def dog
2 print "dog"
3
4 hash = {
5 end Если мы не останавливались при анализе по пустым новым строкам, блок мог бы ошибочно взять все содержимое (строки 2, 3 и 4) и сообщить об этом как о проблеме, а не только о строке 4.
## Случай № 2: Расширить/взять другие логические блоки
После того, как алгоритм поиска преобразовал все строки в блоки с заданным отступом, он затем вызовет «expand_indent». После расширения блоков в качестве соседей мы начинаем видеть, что соседями являются другие логические блоки, например, метод или класс (что-то с ключевыми словами/end).
Например:
1 def bark 2 3 end 4 5 def sit 6 end
В этом случае, если строки 4, 5 и 6 находятся в блоке, когда он пытается расширить соседей, он будет расширяться вверх. Если он остановится после строки 2 или 3, это может вызвать проблемы, так как есть допустимая пара kw/end, но блок будет проверен без неё.
Мы стараемся решить этот крайний случай с помощью «lookahead_balance_one_line» ниже.
# File lib/syntax_suggest/block_expand.rb, line 161 def inspect "#<SyntaxSuggest::CodeBlock:0x0000123843lol >" end
Управление ошибками rspec
Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.