Skip to content

Commit

Permalink
Make Document.Changes.RenameFile a struct and use root_module? in…
Browse files Browse the repository at this point in the history
…stead of `has_silibings?` and `has_parent?`
  • Loading branch information
scottming committed Mar 29, 2024
1 parent 508f63c commit 2e6cb4c
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -1,27 +1,38 @@
defmodule Lexical.RemoteControl.CodeMod.Rename.File do
alias Lexical.Ast
alias Lexical.Document
alias Lexical.ProcessCache
alias Lexical.Project
alias Lexical.RemoteControl
alias Lexical.RemoteControl.Search.Indexer
alias Lexical.RemoteControl.Search.Indexer.Entry
alias Lexical.RemoteControl.Search.Store

@spec maybe_rename(Entry.t(), String.t()) :: nil | {Lexical.uri(), Lexical.uri()}
@spec maybe_rename(Entry.t(), String.t()) :: Document.Changes.rename_file()
def maybe_rename(entry, new_suffix) do
with false <- has_parent?(entry),
false <- has_any_siblings?(entry) do
if root_module?(entry) do
rename_file(entry, new_suffix)
else
_ -> nil
end
end

defp has_parent?(entry) do
match?({:ok, _}, Store.parent(entry))
end
defp root_module?(entry) do
uri = Document.Path.ensure_uri(entry.path)

defp has_any_siblings?(entry) do
match?({:ok, [_, _ | _]}, Store.siblings(entry))
entries =
ProcessCache.trans("#{uri}-entries", 50, fn ->
with {:ok, document} <- Document.Store.open_temporary(uri),
{:ok, entries} <-
Indexer.Source.index_document(document, [Indexer.Extractors.Module]) do
entries
end
end)

case Enum.filter(entries, &(&1.block_id == :root)) do
[root_module] ->
root_module.subject == entry.subject and root_module.block_range == entry.block_range

_ ->
false
end
end

defp rename_file(entry, new_suffix) do
Expand All @@ -39,7 +50,9 @@ defmodule Lexical.RemoteControl.CodeMod.Rename.File do

new_path = Path.join([root_path, prefix, "#{suffix}#{extname}"])

{Document.Path.ensure_uri(entry.path), Document.Path.ensure_uri(new_path)}
old_uri = Document.Path.ensure_uri(entry.path)
new_uri = Document.Path.ensure_uri(new_path)
Document.Changes.RenameFile.new(old_uri, new_uri)
else
_ -> nil
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,7 @@ defmodule Lexical.RemoteControl.CodeMod.RenameTest do
end
] |> rename("Renamed", "lib/foo.ex")

assert {_, to_uri} = rename_file
assert to_uri == subject_uri(project, "lib/renamed.ex")
assert rename_file.new_uri == subject_uri(project, "lib/renamed.ex")
end

test "succeeds when the path matching the `apps/*` convension", %{project: project} do
Expand All @@ -378,8 +377,7 @@ defmodule Lexical.RemoteControl.CodeMod.RenameTest do
end
] |> rename("FooApp.Renamed", "apps/foo_app/lib/foo_app/bar.ex")

assert {_, to_uri} = rename_file
assert to_uri == subject_uri(project, "apps/foo_app/lib/foo_app/renamed.ex")
assert rename_file.new_uri == subject_uri(project, "apps/foo_app/lib/foo_app/renamed.ex")
end

test "succeeds when the path matching the `apps/*` convension with nested folders", %{
Expand All @@ -391,8 +389,8 @@ defmodule Lexical.RemoteControl.CodeMod.RenameTest do
end
] |> rename("Lexical.RemoteChaos", "apps/remote_control/lib/lexical/remote_control.ex")

assert {_, to_uri} = rename_file
assert to_uri == subject_uri(project, "apps/remote_control/lib/lexical/remote_chaos.ex")
assert rename_file.new_uri ==
subject_uri(project, "apps/remote_control/lib/lexical/remote_chaos.ex")
end

test "succeeds when the path matching the `test/*` convension", %{project: project} do
Expand All @@ -402,8 +400,7 @@ defmodule Lexical.RemoteControl.CodeMod.RenameTest do
end
] |> rename("RenamedTest", "test/foo_test.exs")

assert {_, to_uri} = rename_file
assert to_uri == subject_uri(project, "test/renamed_test.exs")
assert rename_file.new_uri == subject_uri(project, "test/renamed_test.exs")
end

test "leaves the `components` folder as is when renaming the live view", %{project: project} do
Expand All @@ -413,8 +410,8 @@ defmodule Lexical.RemoteControl.CodeMod.RenameTest do
end
] |> rename("DemoWeb.RenamedComponent", "lib/demo_web/components/foo_component.ex")

assert {_, to_uri} = rename_file
assert to_uri == subject_uri(project, "lib/demo_web/components/renamed_component.ex")
assert rename_file.new_uri ==
subject_uri(project, "lib/demo_web/components/renamed_component.ex")
end

test "leaves the `components` folder as is when renaming a component", %{project: project} do
Expand All @@ -428,9 +425,7 @@ defmodule Lexical.RemoteControl.CodeMod.RenameTest do
"lib/demo_web/components/some_context/foo_component.ex"
)

assert {_, to_uri} = rename_file

assert to_uri ==
assert rename_file.new_uri ==
subject_uri(project, "lib/demo_web/components/some_context/renamed_component.ex")
end

Expand All @@ -441,8 +436,8 @@ defmodule Lexical.RemoteControl.CodeMod.RenameTest do
end
] |> rename("DemoWeb.RenamedController", "lib/demo_web/controllers/foo_controller.ex")

assert {_, to_uri} = rename_file
assert to_uri == subject_uri(project, "lib/demo_web/controllers/renamed_controller.ex")
assert rename_file.new_uri ==
subject_uri(project, "lib/demo_web/controllers/renamed_controller.ex")
end

test "leaves the `controller` folder as is when renaming the `JSON` module", %{
Expand All @@ -458,9 +453,7 @@ defmodule Lexical.RemoteControl.CodeMod.RenameTest do
"lib/demo_web/controllers/foo_controller/json.ex"
)

assert {_, to_uri} = rename_file

assert to_uri ==
assert rename_file.new_uri ==
subject_uri(project, "lib/demo_web/controllers/foo_controller/renamed_json.ex")
end

Expand All @@ -471,8 +464,7 @@ defmodule Lexical.RemoteControl.CodeMod.RenameTest do
end
] |> rename("DemoWeb.RenamedLive", "lib/demo_web/live/foo_live.ex")

assert {_, to_uri} = rename_file
assert to_uri == subject_uri(project, "lib/demo_web/live/renamed_live.ex")
assert rename_file.new_uri == subject_uri(project, "lib/demo_web/live/renamed_live.ex")
end
end

Expand Down
6 changes: 3 additions & 3 deletions apps/server/lib/lexical/server/provider/handlers/rename.ex
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ defmodule Lexical.Server.Provider.Handlers.Rename do
TextDocument.Edit.new(edits: edits, text_document: text_document)
end

defp new_rename_file({from_uri, to_uri}) do
defp new_rename_file(%Document.Changes.RenameFile{} = rename_file) do
options = RenameFile.Options.new(overwrite: true)

RenameFile.new(
kind: "rename",
new_uri: to_uri,
old_uri: from_uri,
new_uri: rename_file.new_uri,
old_uri: rename_file.old_uri,
options: options
)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ defmodule Lexical.Server.Provider.Handlers.RenameTest do
end)

patch(RemoteControl.Api, :rename, fn ^project, _analysis, _position, _new_name ->
{:ok, %{}}
{:ok, []}
end)

{:ok, request} = build_request(uri, 1, 5)
Expand All @@ -90,7 +90,10 @@ defmodule Lexical.Server.Provider.Handlers.RenameTest do
range: %{start: %{line: 1, character: 5}, end: %{line: 1, character: 10}}
}
],
{document.uri, "file:///path/to/new_text.ex"}
Document.Changes.RenameFile.new(
document.uri,
"file:///path/to/new_text.ex"
)
)
]}
end)
Expand Down
13 changes: 12 additions & 1 deletion projects/lexical_shared/lib/lexical/document/changes.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,24 @@ defmodule Lexical.Document.Changes do
Using this struct allows efficient conversions at the language server border, as the document
doesn't have to be looked up (and possibly read off the filesystem) by the language server.
"""
defmodule RenameFile do
@type t :: %__MODULE__{old_uri: Lexical.uri(), new_uri: Lexical.uri()}

defstruct [:old_uri, :new_uri]

@spec new(Lexical.uri(), Lexical.uri()) :: t()
def new(old_uri, new_uri) do
%__MODULE__{old_uri: old_uri, new_uri: new_uri}
end
end

defstruct [:document, :edits, :rename_file]
alias Lexical.Document

use Lexical.StructAccess

@type edits :: Document.Edit.t() | [Document.Edit.t()]
@type rename_file :: nil | {Lexical.uri(), Lexical.uri()}
@type rename_file :: nil | RenameFile.t()
@type t :: %__MODULE__{
document: Document.t(),
edits: edits,
Expand Down

0 comments on commit 2e6cb4c

Please sign in to comment.