класс 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–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.