класс 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`. После того, как расширены блоки, которые генерирует, как соседи, мы начинаем видеть соседей как другие логические блоки, то есть соседи блока могут быть другим методом или классом (нечто с ключевыми словами/конечными).
Например:
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–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.