Spec-Zone.ru › Ruby 3.4
  1. Prism::
  2. Node

class Prism::Node

Родитель:
Object

Этот класс представляет узел дерева. Он является родительским классом для всех различных типов узлов.

Атрибуты

flags [R]

Битовый набор флагов для этого узла. Некоторые флаги являются общими для всех узлов, а некоторые узлы имеют собственные флаги.

node_id [R]

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

source [R]

Указатель на исходный текст, из которого был создан этот узел.

Публичные методы класса

fields () Показать исходный код
# File lib/prism/node.rb, line 245
def self.fields
  # This method should only be called on subclasses of Node, not Node
  # itself.
  raise NoMethodError, "undefined method `fields' for #{inspect}" if self == Node

  Reflection.fields_for(self)
end

Возвращает список полей, существующих для этого класса узлов. Поля описывают структуру узла. Такая рефлексия полезна, например, для рекурсивного обхода каждого узла и поля дерева.

Публичные методы экземпляра

breadth_first_search () { |node| ... } Показать исходный код
# File lib/prism/node.rb, line 231
def breadth_first_search(&block)
  queue = [self] #: Array[Prism::node]

  while (node = queue.shift)
    return node if yield node
    queue.concat(node.compact_child_nodes)
  end

  nil
end

Возвращает первый узел, соответствующий переданному блоку при обходе в глубину. Это удобно для поиска узла, удовлетворяющего определённому условию.

node.breadth_first_search { |node| node.node_id == node_id }
cached_end_code_units_column (cache) Показать исходный код
# File lib/prism/node.rb, line 118
def cached_end_code_units_column(cache)
  location.cached_end_code_units_column(cache)
end

Передаёт вызов методу cached_end_code_units_column связанного объекта расположения.

cached_end_code_units_offset (cache) Показать исходный код
# File lib/prism/node.rb, line 86
def cached_end_code_units_offset(cache)
  location.cached_end_code_units_offset(cache)
end

Передаёт вызов методу cached_end_code_units_offset связанного объекта расположения.

cached_start_code_units_column (cache) Показать исходный код
# File lib/prism/node.rb, line 112
def cached_start_code_units_column(cache)
  location.cached_start_code_units_column(cache)
end

Передаёт вызов методу cached_start_code_units_column связанного объекта расположения.

cached_start_code_units_offset (cache) Показать исходный код
# File lib/prism/node.rb, line 80
def cached_start_code_units_offset(cache)
  location.cached_start_code_units_offset(cache)
end

Передаёт вызов методу cached_start_code_units_offset связанного объекта расположения.

comments () Показать исходный код
# File lib/prism/node.rb, line 133
def comments
  location.comments
end

Передаёт вызов методу получения комментариев связанного объекта расположения.

end_character_column () Показать исходный код
# File lib/prism/node.rb, line 106
def end_character_column
  location.end_character_column
end

Передаёт вызов методу end_character_column связанного объекта расположения.

end_character_offset () Показать исходный код
# File lib/prism/node.rb, line 74
def end_character_offset
  location.end_character_offset
end

Передаёт вызов методу end_character_offset связанного объекта расположения.

end_column () Показать исходный код
# File lib/prism/node.rb, line 96
def end_column
  location.end_column
end

Передаёт вызов методу end_column связанного объекта расположения.

end_line () Показать исходный код
# File lib/prism/node.rb, line 50
def end_line
  location.end_line
end

Передаёт вызов методу end_line связанного объекта расположения.

end_offset () Показать исходный код
# File lib/prism/node.rb, line 63
def end_offset
  location = @location
  location.is_a?(Location) ? location.end_offset : ((location >> 32) + (location & 0xFFFFFFFF))
end

Конечное смещение узла в исходном тексте. По сути, этот метод делегирует вызов объекту расположения.

leading_comments () Показать исходный код
# File lib/prism/node.rb, line 123
def leading_comments
  location.leading_comments
end

Передаёт вызов методу leading_comments связанного объекта расположения.

location () Показать исходный код
# File lib/prism/node.rb, line 33
def location
  location = @location
  return location if location.is_a?(Location)
  @location = Location.new(source, location >> 32, location & 0xFFFFFFFF)
end

Экземпляр Location, представляющий расположение этого узла в исходном тексте.

newline? () Показать исходный код
# File lib/prism/node.rb, line 164
def newline?
  flags.anybits?(NodeFlags::NEWLINE)
end

Возвращает true, если для узла установлен флаг перевода строки.

pretty_print (q) Показать исходный код
# File lib/prism/node.rb, line 175
def pretty_print(q)
  q.seplist(inspect.chomp.each_line, -> { q.breakable }) do |line|
    q.text(line.chomp)
  end
  q.current_group.break
end

Подобен inspect, но учитывает текущий уровень отступа, заданный объектом форматированного вывода.

save (repository) Показать исходный код
# File lib/prism/node.rb, line 27
def save(repository)
  repository.enter(node_id, :itself)
end

Сохраняет этот узел с помощью сохранённого исходного текста, чтобы его можно было получить позже.

save_location (repository) Показать исходный код
# File lib/prism/node.rb, line 40
def save_location(repository)
  repository.enter(node_id, :location)
end

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

script_lines ()

Псевдоним для source_lines, используемый для имитации API RubyVM::AbstractSyntaxTree, чтобы упростить миграцию.

Псевдоним для: source_lines
slice () Показать исходный код
# File lib/prism/node.rb, line 147
def slice
  location.slice
end

Извлекает из исходного текста фрагмент, соответствующий расположению узла.

slice_lines () Показать исходный код
# File lib/prism/node.rb, line 154
def slice_lines
  location.slice_lines
end

Извлекает из исходного текста фрагмент, соответствующий расположению узла: от начала строки, в которой начинается расположение, до конца строки, в которой оно заканчивается.

source_lines () Показать исходный код
# File lib/prism/node.rb, line 138
def source_lines
  location.source_lines
end

Возвращает все строки исходного кода, связанные с этим узлом.

Также имеет псевдоним: script_lines
start_character_column () Показать исходный код
# File lib/prism/node.rb, line 101
def start_character_column
  location.start_character_column
end

Передаёт вызов методу start_character_column связанного объекта расположения.

start_character_offset () Показать исходный код
# File lib/prism/node.rb, line 69
def start_character_offset
  location.start_character_offset
end

Передаёт вызов методу start_character_offset связанного объекта расположения.

start_column () Показать исходный код
# File lib/prism/node.rb, line 91
def start_column
  location.start_column
end

Передаёт вызов методу start_column связанного объекта расположения.

start_line () Показать исходный код
# File lib/prism/node.rb, line 45
def start_line
  location.start_line
end

Передаёт вызов методу start_line связанного объекта расположения.

start_offset () Показать исходный код
# File lib/prism/node.rb, line 56
def start_offset
  location = @location
  location.is_a?(Location) ? location.start_offset : location >> 32
end

Начальное смещение узла в исходном тексте. По сути, этот метод делегирует вызов объекту расположения.

static_literal? () Показать исходный код
# File lib/prism/node.rb, line 169
def static_literal?
  flags.anybits?(NodeFlags::STATIC_LITERAL)
end

Возвращает true, если для узла установлен флаг статического литерала.

to_dot () Показать исходный код
# File lib/prism/node.rb, line 183
def to_dot
  # @type self: node
  DotVisitor.new.tap { |visitor| accept(visitor) }.to_dot
end

Преобразует этот узел в строку графа Graphviz DOT.

trailing_comments () Показать исходный код
# File lib/prism/node.rb, line 128
def trailing_comments
  location.trailing_comments
end

Передаёт вызов методу trailing_comments связанного объекта расположения.

tunnel (line, column) Показать исходный код
# File lib/prism/node.rb, line 194
def tunnel(line, column)
  queue = [self] #: Array[Prism::node]
  result = [] #: Array[Prism::node]

  while (node = queue.shift)
    result << node

    node.compact_child_nodes.each do |child_node|
      child_location = child_node.location

      start_line = child_location.start_line
      end_line = child_location.end_line

      if start_line == end_line
        if line == start_line && column >= child_location.start_column && column < child_location.end_column
          queue << child_node
          break
        end
      elsif (line == start_line && column >= child_location.start_column) || (line == end_line && column < child_location.end_column)
        queue << child_node
        break
      elsif line > start_line && line < end_line
        queue << child_node
        break
      end
    end
  end

  result
end

Возвращает список узлов — потомков этого узла, содержащих указанную строку и столбец. Это удобно для поиска узла, выбранного по строке и столбцу исходного кода.

Важно отметить, что столбец, передаваемый этому методу, должен быть задан в байтах, а не в символах или кодовых единицах.

Интерфейс Node

↑ наверх

Публичные методы класса

type () Показать исходный код
# File lib/prism/node.rb, line 310
def self.type
  raise NoMethodError, "undefined method `type' for #{inspect}"
end

Подобно type, этот метод возвращает символ, позволяющий выбирать действия по типу узла без длинной цепочки ===. Обратите внимание: как и type, он всё же работает медленнее, чем == для одного класса, но должен быть быстрее в операторе case или при сравнении с массивом.

Публичные методы экземпляра

accept (visitor) Показать исходный код
# File lib/prism/node.rb, line 261
def accept(visitor)
  raise NoMethodError, "undefined method `accept' for #{inspect}"
end

Принимает посетителя и вызывает соответствующую специализированную функцию посещения.

child_nodes () Показать исходный код
# File lib/prism/node.rb, line 267
def child_nodes
  raise NoMethodError, "undefined method `child_nodes' for #{inspect}"
end

Возвращает массив дочерних узлов, включая nil на месте отсутствующих необязательных узлов.

Также имеет псевдоним: deconstruct
comment_targets () Показать исходный код
# File lib/prism/node.rb, line 281
def comment_targets
  raise NoMethodError, "undefined method `comment_targets' for #{inspect}"
end

Возвращает массив дочерних узлов и расположений, к которым потенциально могут быть привязаны комментарии.

compact_child_nodes () Показать исходный код
# File lib/prism/node.rb, line 275
def compact_child_nodes
  raise NoMethodError, "undefined method `compact_child_nodes' for #{inspect}"
end

Возвращает массив дочерних узлов, исключая все nil на месте отсутствующих необязательных узлов.

deconstruct ()
Псевдоним для: child_nodes
inspect () Показать исходный код
# File lib/prism/node.rb, line 286
def inspect
  raise NoMethodError, "undefined method `inspect' for #{inspect}"
end

Возвращает строковое представление узла.

type () Показать исходный код
# File lib/prism/node.rb, line 302
def type
  raise NoMethodError, "undefined method `type' for #{inspect}"
end

Иногда требуется проверить экземпляр узла по списку классов, чтобы определить, какое поведение выполнить. Обычно для этого вызывают [cls1, cls2].include?(node.class) или помещают узел в оператор case и используют case node; when cls1; when cls2; end. Оба подхода относительно медленны из-за поиска констант, вызовов методов и/или выделения памяти под массивы.

Вместо этого можно вызвать type, который вернёт символ для сравнения. Этот способ быстрее остальных, поскольку использует одно сравнение целых чисел. Кроме того, при использовании CRuby можно воспользоваться тем, что операторы case, содержащие только символьные ключи, используют таблицу переходов.

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