Skip to content
This repository has been archived by the owner on Nov 24, 2020. It is now read-only.

Preserve comments from quoted source. #4

Merged
merged 2 commits into from
Apr 18, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions src/merl.erl
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,9 @@ quote_1(StartLine, StartCol, Text) ->
_ when StartCol =:= undefined -> StartLine;
_ -> {StartLine, StartCol}
end,
{ok, Ts, _} = erl_scan:string(flatten_text(Text), StartPos),
case parse_1(Ts) of
[T] -> T;
Other -> Other
end.
FlatText = flatten_text(Text),
{ok, Ts, _} = erl_scan:string(FlatText, StartPos),
merge_comments(StartLine, erl_comment_scan:string(FlatText), parse_1(Ts)).

parse_1(Ts) ->
%% if dot tokens are present, it is assumed that the text represents
Expand Down Expand Up @@ -916,3 +914,35 @@ make_tree(record_field, [[N], []]) -> erl_syntax:record_field(N);
make_tree(record_field, [[N], [E]]) -> erl_syntax:record_field(N, E);
make_tree(Type, Groups) ->
erl_syntax:make_tree(Type, Groups).

merge_comments(_StartLine, [], [T]) -> T;
merge_comments(_StartLine, [], Ts) -> Ts;
merge_comments(StartLine, Comments, Ts) ->
merge_comments(StartLine, Comments, Ts, []).

merge_comments(_StartLine, [], [], [T]) -> T;
merge_comments(_StartLine, [], [T], []) -> T;
merge_comments(_StartLine, [], Ts, Acc) ->
lists:reverse(Acc, Ts);
merge_comments(StartLine, Cs, [], Acc) ->
merge_comments(StartLine, [], [],
[erl_syntax:set_pos(
erl_syntax:comment(Indent, Text),
StartLine + Line - 1)
|| {Line, _, Indent, Text} <- Cs] ++ Acc);
merge_comments(StartLine, [C|Cs], [T|Ts], Acc) ->
{Line, _Col, Indent, Text} = C,
CommentLine = StartLine + Line - 1,
case erl_syntax:get_pos(T) of
Pos when Pos < CommentLine ->
%% TODO: traverse sub-tree rather than only the top level nodes
merge_comments(StartLine, [C|Cs], Ts, [T|Acc]);
CommentLine ->
Tc = erl_syntax:add_postcomments(
[erl_syntax:comment(Indent, Text)], T),
merge_comments(StartLine, Cs, [Tc|Ts], Acc);
_ ->
Tc = erl_syntax:add_precomments(
[erl_syntax:comment(Indent, Text)], T),
merge_comments(StartLine, Cs, [Tc|Ts], Acc)
end.
13 changes: 13 additions & 0 deletions src/merl_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,19 @@ quote_case_clause_test_() ->
"{X, Y} when X > Y -> 1;"
"_ -> 0"])))].

quote_comment_test_() ->
[?_assertEqual("%% comment preserved\n"
"{foo, 42}",
f(?Q(["%% comment preserved",
"{foo, 42}"]))),
?_assertEqual("{foo, 42}"
"%% comment preserved\n",
f(?Q(["{foo, 42}",
"%% comment preserved"]))),
?_assertEqual(" % just a comment (with indent)\n",
f(?Q(" % just a comment (with indent)")))
].

metavar_test_() ->
[?_assertEqual("'@foo'", f(merl:tree(merl:template(?Q("'@foo'"))))),
?_assertEqual("'@foo'", f(merl:tree(merl:template(?Q("_@foo"))))),
Expand Down