Skip to content

Commit f99c856

Browse files
authored
Code.Fragment.surround_context/2 handles &123 as :capture_arg (#13847)
1 parent 9c42348 commit f99c856

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

lib/elixir/lib/code/fragment.ex

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,9 @@ defmodule Code.Fragment do
320320
_ ->
321321
{{:local_or_var, acc}, count}
322322
end
323+
324+
{:capture_arg, acc, count} ->
325+
{{:capture_arg, acc}, count}
323326
end
324327
end
325328

@@ -362,6 +365,14 @@ defmodule Code.Fragment do
362365
:none
363366
end
364367

368+
defp rest_identifier([?& | tail] = rest, count, acc) when tail == [] or hd(tail) != ?& do
369+
if Enum.all?(acc, &(&1 in ?0..?9)) do
370+
{:capture_arg, [?& | acc], count + 1}
371+
else
372+
tokenize_identifier(rest, count, acc)
373+
end
374+
end
375+
365376
defp rest_identifier(rest, count, acc) do
366377
tokenize_identifier(rest, count, acc)
367378
end
@@ -591,7 +602,8 @@ defmodule Code.Fragment do
591602
| {:struct, inside_struct}
592603
| {:unquoted_atom, charlist}
593604
| {:keyword, charlist}
594-
| {:key, charlist},
605+
| {:key, charlist}
606+
| {:capture_arg, charlist},
595607
inside_dot:
596608
{:alias, charlist}
597609
| {:alias, inside_alias, charlist}
@@ -696,6 +708,9 @@ defmodule Code.Fragment do
696708
{{:unquoted_atom, acc}, offset} ->
697709
build_surround({:unquoted_atom, acc}, reversed, line, offset)
698710

711+
{{:capture_arg, acc}, offset} ->
712+
build_surround({:capture_arg, acc}, reversed, line, offset)
713+
699714
_ ->
700715
maybe_operator(reversed_pre, post, line, opts)
701716
end
@@ -728,6 +743,16 @@ defmodule Code.Fragment do
728743
reversed = reversed_post ++ reversed_pre
729744

730745
case codepoint_cursor_context(reversed, opts) do
746+
{{:operator, ~c"&"}, offset} when hd(rest) in ?0..?9 ->
747+
arg = Enum.take_while(rest, &(&1 in ?0..?9))
748+
749+
build_surround(
750+
{:capture_arg, ~c"&" ++ arg},
751+
:lists.reverse(arg, reversed),
752+
line,
753+
offset + length(arg)
754+
)
755+
731756
{{:operator, acc}, offset} ->
732757
build_surround({:operator, acc}, reversed, line, offset)
733758

lib/elixir/test/elixir/code_fragment_test.exs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,38 @@ defmodule CodeFragmentTest do
10911091
end
10921092
end
10931093

1094+
test "capture operator" do
1095+
assert CF.surround_context("& &123 + 1", {1, 1}) == %{
1096+
context: {:operator, ~c"&"},
1097+
begin: {1, 1},
1098+
end: {1, 2}
1099+
}
1100+
1101+
for i <- 3..6 do
1102+
assert CF.surround_context("& &123 + 1", {1, i}) == %{
1103+
context: {:capture_arg, ~c"&123"},
1104+
begin: {1, 3},
1105+
end: {1, 7}
1106+
}
1107+
end
1108+
end
1109+
1110+
test "capture operator false positive" do
1111+
assert CF.surround_context("1&&2", {1, 3}) == %{
1112+
context: {:operator, ~c"&&"},
1113+
begin: {1, 2},
1114+
end: {1, 4}
1115+
}
1116+
1117+
assert CF.surround_context("1&&2", {1, 4}) == :none
1118+
1119+
assert CF.surround_context("&a", {1, 2}) == %{
1120+
context: {:local_or_var, ~c"a"},
1121+
begin: {1, 2},
1122+
end: {1, 3}
1123+
}
1124+
end
1125+
10941126
test "unquoted atom" do
10951127
for i <- 1..10 do
10961128
assert CF.surround_context(":hello_wor", {1, i}) == %{

0 commit comments

Comments
 (0)