Spec-Zone.ru › Ruby 3.4

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

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

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

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

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

Атрибуты

parse_result [R]

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

Общедоступные методы класса

new (parse_result)
Исходный код
# File lib/prism/parse_result/comments.rb, line 86
def initialize(parse_result)
  @parse_result = parse_result
end

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

Общедоступные методы экземпляра

attach! ()
Исходный код
# File lib/prism/parse_result/comments.rb, line 92
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 119
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–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

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