Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszsamson committed Feb 5, 2024
1 parent be50cde commit 27e598b
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 2 deletions.
23 changes: 22 additions & 1 deletion apps/language_server/lib/language_server/ast_utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ defmodule ElixirLS.LanguageServer.AstUtils do
@unary_operators ~w[@ + - ! ^ not &]a

def node_range(atom) when is_atom(atom), do: nil
def node_range([{{:__block__, _, [atom]} = first, _} | _] = list) when is_atom(atom) do
case List.last(list) do
{_, last} ->
case {node_range(first), node_range(last)} do
{range(start_line, start_character, _, _), range(_, _, end_line, end_character)} ->
range(start_line, start_character, end_line, end_character)
_ -> nil
end
_ -> nil
end
end
def node_range(list) when is_list(list), do: nil

def node_range({:__block__, meta, args} = ast) do
Expand Down Expand Up @@ -110,9 +121,13 @@ defmodule ElixirLS.LanguageServer.AstUtils do
# TODO is it needed
{line, column}
end
form == :"&" and match?([int] when is_integer(int), args) ->
[int] = args
{line, column}
form in @binary_operators and match?([_, _], args) ->
[left, _right] = args
operator_length = form |> to_string() |> String.length()

case node_range(left) do
range(line, column, _, _) ->
{line, column}
Expand Down Expand Up @@ -144,6 +159,7 @@ defmodule ElixirLS.LanguageServer.AstUtils do
closing_length =
case form do
:<<>> -> 2
:fn -> 3
_ -> 1
end

Expand Down Expand Up @@ -175,6 +191,9 @@ defmodule ElixirLS.LanguageServer.AstUtils do
# try to format it instead
get_eoe_by_formatting(ast, {line, column})

form == :"&" and match?([int] when is_integer(int), args) ->
[int] = args
{line, column + String.length(to_string(int))}
form in @binary_operators and match?([_, _], args) ->
[left, right] = args
operator_length = form |> to_string() |> String.length()
Expand Down Expand Up @@ -209,6 +228,8 @@ defmodule ElixirLS.LanguageServer.AstUtils do
{end_line, end_column}
nil ->
# TODO is it needed
nil
# {line, column + operator_length}
end
end
|> dbg
Expand All @@ -223,7 +244,7 @@ defmodule ElixirLS.LanguageServer.AstUtils do
_ ->
# local call no parens
last_arg = List.last(args)
case node_range(last_arg) do
case node_range(last_arg |> dbg) |> dbg do
range(_, _, end_line, end_column) ->
{end_line, end_column}
nil ->
Expand Down
46 changes: 45 additions & 1 deletion apps/language_server/test/ast_utils_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ defmodule ElixirLS.LanguageServer.AstUtilsTest do
assert get_range(text) == range(0, 0, 4, 3)
end

# TODO
test "if short notation" do
text = """
if true, do: 1
Expand Down Expand Up @@ -353,6 +352,10 @@ defmodule ElixirLS.LanguageServer.AstUtilsTest do
assert get_range("&Some.fun/1") == range(0, 0, 0, 11)
end

test "anonymous capture" do
assert get_range("& &1 + 1") == range(0, 0, 0, 8)
end

test "complicated local call" do
text = """
fun(%My{} = my, keyword: 123, other: [:a, ""])
Expand All @@ -370,5 +373,46 @@ defmodule ElixirLS.LanguageServer.AstUtilsTest do

assert get_range(text) == range(0, 0, 2, 3)
end

test "anonymous function no args" do
test = """
fn -> 1 end
"""
assert get_range(test) == range(0, 0, 0, 11)
end

test "anonymous function multiple args" do
test = """
fn a, b -> 1 end
"""
assert get_range(test) == range(0, 0, 0, 16)
end

test "anonymous function multiple clauses" do
test = """
fn
1 -> 1
_ -> 2
end
"""
assert get_range(test) == range(0, 0, 3, 3)
end

test "with" do
text = """
with {:ok, x} <- foo() do
x
end
"""
assert get_range(text) == range(0, 0, 2, 3)
end

test "def short notation" do
test = ~S"""
defp name(%Config{} = config),
do: :"#{__MODULE__}_#{config.node_id}_#{config.channel_unique_id}"
"""
assert get_range(test) == range(0, 0, 1, 39)
end
end
end

0 comments on commit 27e598b

Please sign in to comment.