Spec-Zone.ru › Ruby 3.4
  1. SyntaxSuggest::
  2. BlockExpand

класс SyntaxSuggest::BlockExpand

Родительский класс:
Object

Этот класс отвечает за получение блока кода, расположенного на большом уровне отступа, и его последовательное расширение, чтобы он охватывал всё, что находится на том же уровне отступа.

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

Общедоступные методы класса

new (code_lines:) Показать исходный код
# File lib/syntax_suggest/block_expand.rb, line 34
def initialize(code_lines:)
  @code_lines = code_lines
end

Общедоступные методы экземпляра

call (block) Показать исходный код
# 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

Основной интерфейс. Расширяет текущий уровень отступа перед переходом к более низкому уровню отступа.

expand_indent (block) Показать исходный код
# 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, которые находятся на другом уровне отступа.

Этот метод позволяет полностью расширенным блокам уменьшать уровень отступа (чтобы они могли расширяться и захватывать больше кода сверху и снизу). Это делается осторожно, поскольку отмена изменений пока не предусмотрена.

expand_neighbors (block) Показать исходный код
# 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».

inspect () Показать исходный код
# 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.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API