класс Prism::Node
Представляет узел дерева. Это родительский класс для всех типов узлов.
Атрибуты
Битовый набор флагов этого узла. Некоторые флаги являются общими для всех узлов, а некоторые узлы имеют собственные флаги.
Уникальный идентификатор этого узла. Он используется в особом случае, когда нужно сохранить ссылку на узел, не сохраняя в памяти синтаксическое дерево. Этот уникальный идентификатор будет одинаковым при нескольких разборах одного и того же исходного кода.
Указатель на исходный код, из которого был создан этот узел.
Открытые методы класса
# 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 Возвращает список полей этого класса узлов. Поля описывают структуру узла. Такая возможность рефлексии полезна, например, для рекурсивного обхода каждого узла и поля дерева.
Открытые методы экземпляра
# 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 }
# 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 соответствующего объекта расположения.
# 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 соответствующего объекта расположения.
# 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 соответствующего объекта расположения.
# 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 соответствующего объекта расположения.
# File lib/prism/node.rb, line 133 def comments location.comments end
Перенаправляет вызов к комментариям соответствующего объекта расположения.
# File lib/prism/node.rb, line 106 def end_character_column location.end_character_column end
Перенаправляет вызов к методу end_character_column соответствующего объекта расположения.
# File lib/prism/node.rb, line 74 def end_character_offset location.end_character_offset end
Перенаправляет вызов к методу end_character_offset соответствующего объекта расположения.
# File lib/prism/node.rb, line 96 def end_column location.end_column end
Перенаправляет вызов к методу end_column соответствующего объекта расположения.
# File lib/prism/node.rb, line 50 def end_line location.end_line end
Перенаправляет вызов к методу end_line соответствующего объекта расположения.
# File lib/prism/node.rb, line 63 def end_offset location = @location location.is_a?(Location) ? location.end_offset : ((location >> 32) + (location & 0xFFFFFFFF)) end
Конечное смещение узла в исходном коде. По сути, этот метод перенаправляет вызов к объекту расположения.
# File lib/prism/node.rb, line 123 def leading_comments location.leading_comments end
Перенаправляет вызов к методу leading_comments соответствующего объекта расположения.
# 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, представляющий расположение этого узла в исходном коде.
# File lib/prism/node.rb, line 164 def newline? flags.anybits?(NodeFlags::NEWLINE) end
Возвращает true, если для узла установлен флаг новой строки.
# 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, но учитывает текущий уровень отступа, заданный объектом форматированного вывода.
# File lib/prism/node.rb, line 27 def save(repository) repository.enter(node_id, :itself) end
Сохраняет этот узел с помощью сохранённого исходного кода, чтобы позднее его можно было получить.
# File lib/prism/node.rb, line 40 def save_location(repository) repository.enter(node_id, :location) end
Сохраняет расположение с помощью сохранённого исходного кода, чтобы позднее его можно было получить.
Псевдоним для source_lines, предназначенный для имитации API RubyVM::AbstractSyntaxTree и упрощения перехода.
# File lib/prism/node.rb, line 147 def slice location.slice end
Извлекает фрагмент исходного кода, соответствующий расположению узла.
# File lib/prism/node.rb, line 154 def slice_lines location.slice_lines end
Извлекает фрагмент исходного кода, соответствующий расположению узла: начиная с начала строки, на которой начинается расположение, и заканчивая концом строки, на которой оно заканчивается.
# File lib/prism/node.rb, line 138 def source_lines location.source_lines end
Возвращает все строки исходного кода, связанного с этим узлом.
# File lib/prism/node.rb, line 101 def start_character_column location.start_character_column end
Перенаправляет вызов к методу start_character_column соответствующего объекта расположения.
# File lib/prism/node.rb, line 69 def start_character_offset location.start_character_offset end
Перенаправляет вызов к методу start_character_offset соответствующего объекта расположения.
# File lib/prism/node.rb, line 91 def start_column location.start_column end
Перенаправляет вызов к методу start_column соответствующего объекта расположения.
# File lib/prism/node.rb, line 45 def start_line location.start_line end
Перенаправляет вызов к методу start_line соответствующего объекта расположения.
# File lib/prism/node.rb, line 56 def start_offset location = @location location.is_a?(Location) ? location.start_offset : location >> 32 end
Начальное смещение узла в исходном коде. По сути, этот метод перенаправляет вызов к объекту расположения.
# File lib/prism/node.rb, line 169 def static_literal? flags.anybits?(NodeFlags::STATIC_LITERAL) end
Возвращает true, если для узла установлен флаг статического литерала.
# File lib/prism/node.rb, line 183
def to_dot
# @type self: node
DotVisitor.new.tap { |visitor| accept(visitor) }.to_dot
end Преобразует этот узел в строку графа Graphviz DOT.
# File lib/prism/node.rb, line 128 def trailing_comments location.trailing_comments end
Перенаправляет вызов к методу trailing_comments соответствующего объекта расположения.
# 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.each_child_node 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
Открытые методы класса
# File lib/prism/node.rb, line 317
def self.type
raise NoMethodError, "undefined method `type' for #{inspect}"
end Открытые методы экземпляра
# File lib/prism/node.rb, line 261
def accept(visitor)
raise NoMethodError, "undefined method `accept' for #{inspect}"
end Принимает посетителя и вызывает специализированную функцию visit.
# File lib/prism/node.rb, line 267
def child_nodes
raise NoMethodError, "undefined method `child_nodes' for #{inspect}"
end Возвращает массив дочерних узлов, включая nil на месте отсутствующих необязательных узлов.
# File lib/prism/node.rb, line 288
def comment_targets
raise NoMethodError, "undefined method `comment_targets' for #{inspect}"
end Возвращает массив дочерних узлов и расположений, к которым потенциально могут быть прикреплены комментарии.
# File lib/prism/node.rb, line 282
def compact_child_nodes
raise NoMethodError, "undefined method `compact_child_nodes' for #{inspect}"
end Возвращает массив дочерних узлов, исключая nil на месте отсутствующих необязательных узлов.
# File lib/prism/node.rb, line 276
def each_child_node
raise NoMethodError, "undefined method `each_child_node' for #{inspect}"
end Если передан блок, передаёт ему каждый дочерний узел. Если блок не передан, возвращает перечислитель, содержащий все дочерние узлы. Исключает любые nil на месте отсутствующих необязательных узлов.
# File lib/prism/node.rb, line 293
def inspect
raise NoMethodError, "undefined method `inspect' for #{inspect}"
end Возвращает строковое представление узла.
# File lib/prism/node.rb, line 309
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.