class RubyIndexer::Entry

def comments

: -> String
def comments
  @comments ||= begin
    # Parse only the comments based on the file path, which is much faster than parsing the entire file
    path = file_path
    parsed_comments = path ? Prism.parse_file_comments(path) : []
    # Group comments based on whether they belong to a single block of comments
    grouped = parsed_comments.slice_when do |left, right|
      left.location.start_line + 1 != right.location.start_line
    end
    # Find the group that is either immediately or two lines above the current entry
    correct_group = grouped.find do |group|
      comment_end_line = group.last.location.start_line
      (comment_end_line..comment_end_line + 1).cover?(@location.start_line - 1)
    end
    # If we found something, we join the comments together. Otherwise, the entry has no documentation and we don't
    # want to accidentally re-parse it, so we set it to an empty string. If an entry is updated, the entire entry
    # object is dropped, so this will not prevent updates
    if correct_group
      correct_group.filter_map do |comment|
        content = comment.slice.chomp
        if content.valid_encoding?
          content.delete_prefix!("#")
          content.delete_prefix!(" ")
          content
        end
      end.join("\n")
    else
      ""
    end
  rescue Errno::ENOENT
    # If the file was deleted, but the entry hasn't been removed yet (could happen due to concurrency), then we do
    # not want to fail. Just set the comments to an empty string
    ""
  end
end

def file_name

: -> String
def file_name
  if @uri.scheme == "untitled"
    @uri.opaque #: as !nil
  else
    File.basename(
      file_path, #: as !nil
    )
  end
end

def file_path

: -> String?
def file_path
  @uri.full_path
end

def initialize(name, uri, location, comments)

: (String name, URI::Generic uri, Location location, String? comments) -> void
def initialize(name, uri, location, comments)
  @name = name
  @uri = uri
  @comments = comments
  @visibility = :public #: Symbol
  @location = location
end

def private?

: -> bool
def private?
  @visibility == :private
end

def protected?

: -> bool
def protected?
  @visibility == :protected
end

def public?

: -> bool
def public?
  @visibility == :public
end