Skip to content

Commit 38d52c7

Browse files
committed
Add metadata about single-expression block closing/opening
1 parent 166c03d commit 38d52c7

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

lib/elixir/src/elixir_parser.yrl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,11 +782,36 @@ build_block(Exprs) -> build_block(Exprs, []).
782782

783783
build_block([{unquote_splicing, _, [_]}]=Exprs, Meta) ->
784784
{'__block__', Meta, Exprs};
785+
build_block([{Op, ExprMeta, Args}], Meta) ->
786+
ExprMetaWithExtra =
787+
case ?token_metadata() of
788+
true -> ExprMeta ++ block_meta(Meta);
789+
false -> ExprMeta
790+
end,
791+
{Op, ExprMetaWithExtra, Args};
785792
build_block([Expr], _Meta) ->
786793
Expr;
787794
build_block(Exprs, Meta) ->
788795
{'__block__', Meta, Exprs}.
789796

797+
block_meta(Meta) ->
798+
block_meta(Meta, [], []).
799+
800+
block_meta([], [], []) ->
801+
[];
802+
block_meta([], [], Closing) ->
803+
[{parens_closing, Closing}];
804+
block_meta([], Opening, Closing) ->
805+
[{parens_opening, lists:reverse(Opening)} | block_meta([], [], Closing)];
806+
block_meta([{line, Line} | Meta], Opening, Closing) ->
807+
block_meta(Meta, [{line, Line} | Opening], Closing);
808+
block_meta([{column, Column} | Meta], Opening, Closing) ->
809+
block_meta(Meta, [{column, Column} | Opening], Closing);
810+
block_meta([{closing, Closing} | Meta], Opening, _Closing) ->
811+
block_meta(Meta, Opening, Closing);
812+
block_meta([_ | Meta], Opening, Closing) ->
813+
block_meta(Meta, Opening, Closing).
814+
790815
%% Newlines
791816

792817
newlines_pair(Left, Right) ->

lib/elixir/test/elixir/kernel/parser_test.exs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,23 @@ defmodule Kernel.ParserTest do
609609
[[do: {:__block__, [], []}]]}
610610
end
611611

612+
test "adds opening and closing information for single-expression block" do
613+
file = "1 + (2 + 3)"
614+
615+
assert Code.string_to_quoted!(file, token_metadata: true, columns: true) ==
616+
{:+, [line: 1, column: 3],
617+
[
618+
1,
619+
{:+,
620+
[
621+
line: 1,
622+
column: 8,
623+
parens_opening: [line: 1, column: 5],
624+
parens_closing: [line: 1, column: 11]
625+
], [2, 3]}
626+
]}
627+
end
628+
612629
test "with :literal_encoder" do
613630
opts = [literal_encoder: &{:ok, {:__block__, &2, [&1]}}, token_metadata: true]
614631
string_to_quoted = &Code.string_to_quoted!(&1, opts)
@@ -646,10 +663,22 @@ defmodule Kernel.ParserTest do
646663
[
647664
{:->, [line: 1],
648665
[
649-
[{:__block__, [token: "1", line: 1], [1]}],
666+
[
667+
{:__block__,
668+
[
669+
token: "1",
670+
line: 1,
671+
parens_opening: [line: 1],
672+
parens_closing: [line: 1]
673+
], [1]}
674+
],
650675
{:__block__, [delimiter: "\"", line: 1], ["hello"]}
651676
]}
652677
]}
678+
679+
assert string_to_quoted.("(1)") ==
680+
{:__block__,
681+
[token: "1", line: 1, parens_opening: [line: 1], parens_closing: [line: 1]], [1]}
653682
end
654683

655684
test "adds identifier_location for qualified identifiers" do

0 commit comments

Comments
 (0)