Spec-Zone.ru › Ruby 3.4
  1. Prism::
  2. ParseResult::
  3. Комментарии

класс Prism::ParseResult::Comments

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

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

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

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

Атрибуты

parse_result [R]

Результат разбора, к которому прикрепляются комментарии.

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

new (parse_result) Показать исходный код
# File lib/prism/parse_result/comments.rb, line 87
def initialize(parse_result)
  @parse_result = parse_result
end

Создает новый объект Comments, который прикрепляет комментарии к указанному результату разбора.

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

attach! () Показать исходный код
# File lib/prism/parse_result/comments.rb, line 93
def attach!
  parse_result.comments.each do |comment|
    preceding, enclosing, following = nearest_targets(parse_result.value, comment)

    if comment.trailing?
      if preceding
        preceding.trailing_comment(comment)
      else
        (following || enclosing || NodeTarget.new(parse_result.value)).leading_comment(comment)
      end
    else
      # If a comment exists on its own line, prefer a leading comment.
      if following
        following.leading_comment(comment)
      elsif preceding
        preceding.trailing_comment(comment)
      else
        (enclosing || NodeTarget.new(parse_result.value)).leading_comment(comment)
      end
    end
  end
end

Прикрепляет комментарии к соответствующим местам в дереве, изменяя результат разбора.

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

nearest_targets (node, comment) Показать исходный код
# File lib/prism/parse_result/comments.rb, line 120
def nearest_targets(node, comment)
  comment_start = comment.location.start_offset
  comment_end = comment.location.end_offset

  targets = [] #: Array[_Target]
  node.comment_targets.map do |value|
    case value
    when StatementsNode
      targets.concat(value.body.map { |node| NodeTarget.new(node) })
    when Node
      targets << NodeTarget.new(value)
    when Location
      targets << LocationTarget.new(value)
    end
  end

  targets.sort_by!(&:start_offset)
  preceding = nil #: _Target?
  following = nil #: _Target?

  left = 0
  right = targets.length

  # This is a custom binary search that finds the nearest nodes to the
  # given comment. When it finds a node that completely encapsulates the
  # comment, it recurses downward into the tree.
  while left < right
    middle = (left + right) / 2
    target = targets[middle]

    target_start = target.start_offset
    target_end = target.end_offset

    if target.encloses?(comment)
      # @type var target: NodeTarget
      # The comment is completely contained by this target. Abandon the
      # binary search at this level.
      return nearest_targets(target.node, comment)
    end

    if target_end <= comment_start
      # This target falls completely before the comment. Because we will
      # never consider this target or any targets before it again, this
      # target must be the closest preceding target we have encountered so
      # far.
      preceding = target
      left = middle + 1
      next
    end

    if comment_end <= target_start
      # This target falls completely after the comment. Because we will
      # never consider this target or any targets after it again, this
      # target must be the closest following target we have encountered so
      # far.
      following = target
      right = middle
      next
    end

    # This should only happen if there is a bug in this parser.
    raise "Comment location overlaps with a target location"
  end

  [preceding, NodeTarget.new(node), following]
end

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

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