Spec-Zone.ru › Ruby 3.3

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

Spec-Zone.ru

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