Skip to content

Commit

Permalink
Merge pull request erlang-ls#1178 from gomoripeti/parse_trailing_comment
Browse files Browse the repository at this point in the history
Fix parsing trailing comments in modules
  • Loading branch information
robertoaloi committed Jan 21, 2022
2 parents 339001b + b168d39 commit e648a96
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
9 changes: 7 additions & 2 deletions apps/els_lsp/src/els_parser.erl
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,17 @@ parse_form(Form) ->
scan_text(Text, StartLoc) ->
PaddedText = pad_text(Text, StartLoc),
{ok, Tokens, _Comments, _Cont} = erlfmt_scan:string_node(PaddedText),
ensure_dot(Tokens).
case Tokens of
[] -> [];
_ -> ensure_dot(Tokens)
end.

-spec parse_incomplete_tokens([erlfmt_scan:token()])
-> {ok, erlfmt_parse:abstract_node()} | error.
parse_incomplete_tokens([{dot, _}]) ->
error;
parse_incomplete_tokens([]) ->
error;
parse_incomplete_tokens(Tokens) ->
case erlfmt_parse:parse_node(Tokens) of
{ok, Form} ->
Expand Down Expand Up @@ -139,7 +144,7 @@ pad_text(Text, {StartLine, StartColumn}) ->
++ lists:duplicate(StartColumn - 1, $\s)
++ Text.

-spec ensure_dot([erlfmt_scan:token()]) -> [erlfmt_scan:token()].
-spec ensure_dot([erlfmt_scan:token(), ...]) -> [erlfmt_scan:token(), ...].
ensure_dot(Tokens) ->
case lists:last(Tokens) of
{dot, _} ->
Expand Down
23 changes: 23 additions & 0 deletions apps/els_lsp/test/els_parser_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
, parse_invalid_code/1
, parse_incomplete_function/1
, parse_incomplete_spec/1
, parse_no_tokens/1
, underscore_macro/1
, specs_with_record/1
, types_with_record/1
Expand Down Expand Up @@ -104,6 +105,28 @@ parse_incomplete_spec(_Config) ->
?assertMatch([#{id := aa}], parse_find_pois(Text, atom)),
ok.

%% Issue #1171
parse_no_tokens(_Config) ->
%% scanning text containing only whitespaces returns an empty list of tokens,
%% which used to crash els_parser
Text1 = " \n ",
{ok, []} = els_parser:parse(Text1),
%% `els_parser:parse' actually catches the exception and only prints a warning
%% log. In order to make sure there is no crash, we need to call an internal
%% debug function that would really crash and make the test case fail
error = els_parser:parse_incomplete_text(Text1, {1, 1}),

%% same for text only containing comments
Text2 = "%% only a comment",
{ok, []} = els_parser:parse(Text2),
error = els_parser:parse_incomplete_text(Text2, {1, 1}),

%% trailing comment, also used to crash els_parser
Text3 =
"-module(m).\n"
"%% trailing comment",
{ok, [#{id := m, kind := module}]} = els_parser:parse(Text3).

-spec underscore_macro(config()) -> ok.
underscore_macro(_Config) ->
?assertMatch({ok, [#{id := {'_', 1}, kind := define} | _]},
Expand Down

0 comments on commit e648a96

Please sign in to comment.