Skip to content

Commit

Permalink
Code.Fragment.surround_context/2 handles &123 as :capture_arg (#13847)
Browse files Browse the repository at this point in the history
  • Loading branch information
sabiwara authored Oct 16, 2024
1 parent 9c42348 commit f99c856
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
27 changes: 26 additions & 1 deletion lib/elixir/lib/code/fragment.ex
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,9 @@ defmodule Code.Fragment do
_ ->
{{:local_or_var, acc}, count}
end

{:capture_arg, acc, count} ->
{{:capture_arg, acc}, count}
end
end

Expand Down Expand Up @@ -362,6 +365,14 @@ defmodule Code.Fragment do
:none
end

defp rest_identifier([?& | tail] = rest, count, acc) when tail == [] or hd(tail) != ?& do
if Enum.all?(acc, &(&1 in ?0..?9)) do
{:capture_arg, [?& | acc], count + 1}
else
tokenize_identifier(rest, count, acc)
end
end

defp rest_identifier(rest, count, acc) do
tokenize_identifier(rest, count, acc)
end
Expand Down Expand Up @@ -591,7 +602,8 @@ defmodule Code.Fragment do
| {:struct, inside_struct}
| {:unquoted_atom, charlist}
| {:keyword, charlist}
| {:key, charlist},
| {:key, charlist}
| {:capture_arg, charlist},
inside_dot:
{:alias, charlist}
| {:alias, inside_alias, charlist}
Expand Down Expand Up @@ -696,6 +708,9 @@ defmodule Code.Fragment do
{{:unquoted_atom, acc}, offset} ->
build_surround({:unquoted_atom, acc}, reversed, line, offset)

{{:capture_arg, acc}, offset} ->
build_surround({:capture_arg, acc}, reversed, line, offset)

_ ->
maybe_operator(reversed_pre, post, line, opts)
end
Expand Down Expand Up @@ -728,6 +743,16 @@ defmodule Code.Fragment do
reversed = reversed_post ++ reversed_pre

case codepoint_cursor_context(reversed, opts) do
{{:operator, ~c"&"}, offset} when hd(rest) in ?0..?9 ->
arg = Enum.take_while(rest, &(&1 in ?0..?9))

build_surround(
{:capture_arg, ~c"&" ++ arg},
:lists.reverse(arg, reversed),
line,
offset + length(arg)
)

{{:operator, acc}, offset} ->
build_surround({:operator, acc}, reversed, line, offset)

Expand Down
32 changes: 32 additions & 0 deletions lib/elixir/test/elixir/code_fragment_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,38 @@ defmodule CodeFragmentTest do
end
end

test "capture operator" do
assert CF.surround_context("& &123 + 1", {1, 1}) == %{
context: {:operator, ~c"&"},
begin: {1, 1},
end: {1, 2}
}

for i <- 3..6 do
assert CF.surround_context("& &123 + 1", {1, i}) == %{
context: {:capture_arg, ~c"&123"},
begin: {1, 3},
end: {1, 7}
}
end
end

test "capture operator false positive" do
assert CF.surround_context("1&&2", {1, 3}) == %{
context: {:operator, ~c"&&"},
begin: {1, 2},
end: {1, 4}
}

assert CF.surround_context("1&&2", {1, 4}) == :none

assert CF.surround_context("&a", {1, 2}) == %{
context: {:local_or_var, ~c"a"},
begin: {1, 2},
end: {1, 3}
}
end

test "unquoted atom" do
for i <- 1..10 do
assert CF.surround_context(":hello_wor", {1, i}) == %{
Expand Down

0 comments on commit f99c856

Please sign in to comment.