Skip to content

Commit

Permalink
Fix a bug when the descendant containing the old suffix
Browse files Browse the repository at this point in the history
  • Loading branch information
scottming committed Mar 28, 2024
1 parent 5cecc8b commit a1303c8
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ defmodule Lexical.RemoteControl.CodeMod.Rename.Module do
)
end

@spec resolve(Analysis.t(), Position.t()) ::
@spec resolve(Analysis.t() | Lexical.path(), Position.t()) ::
{:ok, {atom(), atom()}, Range.t()} | {:error, term()}
def resolve(%Analysis{} = analysis, %Position{} = position) do
case Entity.resolve(analysis, position) do
Expand All @@ -35,6 +35,15 @@ defmodule Lexical.RemoteControl.CodeMod.Rename.Module do
end
end

def resolve(path, %Position{} = position) do
uri = Document.Path.ensure_uri(path)

with {:ok, _} <- Document.Store.open_temporary(uri),
{:ok, _document, analysis} <- Document.Store.fetch(uri, :analysis) do
resolve(analysis, position)
end
end

defp diff(old_range_text, new_name) do
diff = String.myers_difference(old_range_text, new_name)

Expand Down Expand Up @@ -105,23 +114,24 @@ defmodule Lexical.RemoteControl.CodeMod.Rename.Module do
{:error, :not_found}
end

defp resolve_module_range(entry, _entity, [[{start, length}]]) do
defp resolve_module_range(entry, entity, [[{start, length}]]) do
range = adjust_range_characters(entry.range, {start, length})
{:ok, range}

with {:ok, {:module, result}, _} <- resolve(entry.path, range.start),
true <- entity == result do
{:ok, range}
end
end

defp resolve_module_range(entry, entity, [[{start, length}] | tail] = _matches) do
# This function is mainly for the duplicated suffixes
# For example, if we have a module named `Foo.Bar.Foo.Bar` and we want to rename it to `Foo.Bar.Baz`
# The `Foo.Bar` will be duplicated in the range text, so we need to resolve the correct range
# and only rename the second occurrence of `Foo.Bar`
uri = Document.Path.ensure_uri(entry.path)
start_character = entry.range.start.character + start
position = %{entry.range.start | character: start_character}

with {:ok, _} <- Document.Store.open_temporary(uri),
{:ok, _document, analysis} <- Document.Store.fetch(uri, :analysis),
start_character = entry.range.start.character + start,
position = %{entry.range.start | character: start_character},
{:ok, {:module, result}, range} <- resolve(analysis, position) do
with {:ok, {:module, result}, range} <- resolve(entry.path, position) do
if result == entity do
range = adjust_range_characters(range, {start, length})
{:ok, range}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,22 @@ defmodule Lexical.RemoteControl.CodeMod.RenameTest do
assert result =~ ~S[defmodule Foo do # skip this]
assert result =~ ~S[alias TopLevel.Renamed.Foo]
end

test "it shouldn't rename the descendant module if the module only contains old suffix" do
{:ok, result} =
~q[
defmodule |TopLevel.Ast do
end
defmodule TopLevel.AnotherModule do
alias TopLevel.Ast.Detection
Detection.Bitstring.detected?() # Bitstring contains the old suffix: `st`
end
] |> rename("TopLevel.AST")

refute result =~ ~S[Detection.BitSTring.detected?()]
end
end

describe "rename struct" do
Expand Down

0 comments on commit a1303c8

Please sign in to comment.