Spec-Zone.ru › Ruby 3.3

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

Родитель:
Объект

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

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

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

Атрибуты

parse_result[R]

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

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

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

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

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

attach!() Показать исходный код
# File lib/prism/parse_result/comments.rb, line 84
def attach!
  parse_result.comments.each do |comment|
    preceding, enclosing, following = nearest_targets(parse_result.value, comment)
    target =
      if comment.trailing?
        preceding || following || enclosing || NodeTarget.new(parse_result.value)
      else
        # If a comment exists on its own line, prefer a leading comment.
        following || preceding || enclosing || NodeTarget.new(parse_result.value)
      end

    target << comment
  end
end

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

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

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

  targets = []
  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
  following = nil

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

Spec-Zone.ru

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