class RubyLsp::Requests::Rename

def perform

: -> Interface::WorkspaceEdit?
@override
def perform
  char_position, _ = @document.find_index_by_position(@position)
  node_context = RubyDocument.locate(
    @document.ast,
    char_position,
    node_types: [Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::ConstantPathTargetNode],
    code_units_cache: @document.code_units_cache,
  )
  target = node_context.node
  parent = node_context.parent
  return if !target || target.is_a?(Prism::ProgramNode)
  if target.is_a?(Prism::ConstantReadNode) && parent.is_a?(Prism::ConstantPathNode)
    target = determine_target(
      target,
      parent,
      @position,
    )
  end
  target = target #: as Prism::ConstantReadNode | Prism::ConstantPathNode | Prism::ConstantPathTargetNode
  name = RubyIndexer::Index.constant_name(target)
  return unless name
  entries = @global_state.index.resolve(name, node_context.nesting)
  return unless entries
  if (conflict_entries = @global_state.index.resolve(@new_name, node_context.nesting))
    raise InvalidNameError, "The new name is already in use by #{conflict_entries.first&.name}"
  end
  fully_qualified_name = entries.first #: as !nil
    .name
  reference_target = RubyIndexer::ReferenceFinder::ConstTarget.new(fully_qualified_name)
  changes = collect_text_edits(reference_target, name)
  # If the client doesn't support resource operations, such as renaming files, then we can only return the basic
  # text changes
  unless @global_state.client_capabilities.supports_rename?
    return Interface::WorkspaceEdit.new(changes: changes)
  end
  # Text edits must be applied before any resource operations, such as renaming files. Otherwise, the file is
  # renamed and then the URI associated to the text edit no longer exists, causing it to be dropped
  document_changes = changes.map do |uri, edits|
    Interface::TextDocumentEdit.new(
      text_document: Interface::VersionedTextDocumentIdentifier.new(uri: uri, version: nil),
      edits: edits,
    )
  end
  collect_file_renames(fully_qualified_name, document_changes)
  Interface::WorkspaceEdit.new(document_changes: document_changes)
end