Spec-Zone.ru › Ruby 3.4

класс 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

Публичные Классовые Методы

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`. После того, как расширены блоки, которые генерирует, как соседи, мы начинаем видеть соседей как другие логические блоки, то есть соседи блока могут быть другим методом или классом (нечто с ключевыми словами/конечными).

Например:

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

Spec-Zone.ru

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