Skip to content
This repository was archived by the owner on Aug 15, 2025. It is now read-only.
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
1 change: 1 addition & 0 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
%% upstream version:
%% https://github.com/massemanet/redbug/pull/10
, [ {redbug, {git, "https://github.com/robertoaloi/redbug.git", {branch, "relax-beam-lib-error-matching"}}}
, {eflame, {git, "https://github.com/jfacorro/eflame.git", {branch, "various.improvements"}}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to bring in the upstream version, if possible.
What are the included changes?
Are you pull-requesting them to upstream?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the PR with all the improvements.

]
}
, { escript_emu_args
Expand Down
2 changes: 1 addition & 1 deletion src/els_code_navigation.erl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ find([Uri|Uris0], Kind, Data) ->
[] ->
find(lists:usort(include_uris(Document) ++ Uris0), Kind, Data);
Definitions ->
{ok, Uri, lists:last(Definitions)}
{ok, Uri, hd(lists:sort(Definitions))}
end;
{error, not_found} ->
find(Uris0, Kind, Data)
Expand Down
4 changes: 2 additions & 2 deletions src/els_dodger.erl
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@

-export([parse_file/1, quick_parse_file/1, parse_file/2,
quick_parse_file/2, parse/1, quick_parse/1, parse/2,
quick_parse/2, parse/3, quick_parse/3, parse_form/2,
quick_parse/2, parse/3, parse/4, quick_parse/3, parse_form/2,
parse_form/3, quick_parse_form/2, quick_parse_form/3,
format_error/1, tokens_to_string/1]).
format_error/1, tokens_to_string/1, normal_parser/2]).


%% The following should be: 1) pseudo-uniquely identifiable, and 2)
Expand Down
72 changes: 37 additions & 35 deletions src/els_parser.erl
Original file line number Diff line number Diff line change
Expand Up @@ -20,51 +20,55 @@
%%==============================================================================
-spec parse(binary()) -> {ok, [poi()]}.
parse(Text) ->
Pid = els_io_string:new(Text),
parse_file(Pid).
IoDevice = els_io_string:new(Text),
parse_file(IoDevice).

-spec parse_file(file:io_device()) -> {ok, [poi()]}.
parse_file(IoDevice) ->
{ok, Forms} = els_dodger:parse(IoDevice, {1, 1}),
Tree = erl_syntax:form_list(Forms),
%% Reset file pointer position.
{ok, 0} = file:position(IoDevice, 0),
{ok, Extra} = parse_attribute_pois(IoDevice, [], {1, 1}),
{ok, NestedPOIs} = els_dodger:parse(IoDevice, {1, 1}, fun parse_form/3, []),
ok = file:close(IoDevice),
POIs = points_of_interest(Tree),
{ok, Extra ++ POIs}.
{ok, lists:flatten(NestedPOIs)}.

%%==============================================================================
%% Internal Functions
%%==============================================================================

-spec parse_attribute_pois(io:device(), [poi()], erl_anno:location()) ->
{ok, [poi()]} | {error, any()}.
parse_attribute_pois(IoDevice, Acc, StartLoc) ->
case io:scan_erl_form(IoDevice, "", StartLoc) of
{ok, Tokens, EndLoc} ->
case erl_parse:parse_form(Tokens) of
{ok, Form} ->
POIs = find_attribute_pois(Form, Tokens),
parse_attribute_pois(IoDevice, POIs ++ Acc, EndLoc);
{error, _Error} ->
parse_attribute_pois(IoDevice, Acc, EndLoc)
%% Adapted from els_dodger
-spec parse_form(file:io_device(), any(), [any()]) ->
{'ok', erl_syntax:forms()
| none, integer()}
| {'eof', integer()}
| {'error', any(), integer()}.
parse_form(IoDevice, Location, Options) ->
parse_form(IoDevice, Location, fun els_dodger:normal_parser/2, Options).

%% Adapted from els_dodger
-spec parse_form(file:io_device(), any(), function(), [any()]) ->
{'ok', erl_syntax:forms() | none, integer()}
| {'eof', integer()}
| {'error', any(), integer()}.
parse_form(IoDevice, Location0, Parser, _Options) ->
case io:scan_erl_form(IoDevice, "", Location0) of
{ok, Tokens, Location1} ->
try {ok, Parser(Tokens, undefined)} of
{ok, F} ->
POIs = [find_attribute_pois(F, Tokens), points_of_interest(F)],
{ok, POIs, Location1}
catch
_:_ ->
{ok, [], Location1}
end;
{eof, _} ->
{ok, Acc};
{error, ErrorInfo, EndLoc} ->
lager:warning( "Could not parse extra information [end_loc=p] ~p"
, [EndLoc, ErrorInfo]
),
{ok, Acc}
{error, _IoErr, _Location1} = Err -> Err;
{error, _Reason} -> {eof, Location0};
{eof, _Location1} = Eof -> Eof
end.

-spec find_attribute_pois(erl_parse:abstract_form(), [erl_scan:token()]) ->
[poi()].
find_attribute_pois(Form, Tokens) ->
case erl_syntax:type(Form) of
attribute ->
case erl_syntax_lib:analyze_attribute(Form) of
try erl_syntax_lib:analyze_attribute(Form) of
{export, Exports} ->
%% The first atom is the attribute name, so we skip it.
[_|Atoms] = [T|| {atom, _, _} = T <- Tokens],
Expand All @@ -78,8 +82,9 @@ find_attribute_pois(Form, Tokens) ->
|| {{F, A}, {atom, Pos, _}} <- lists:zip(Imports, Atoms)];
{spec, {spec, {_, FTs}}} ->
lists:flatten([find_spec_points_of_interest(FT) || FT <- FTs]);
_ ->
[]
_ -> []
catch
error:syntax_error -> []
end;
_ ->
[]
Expand Down Expand Up @@ -114,11 +119,8 @@ do_find_spec_points_of_interest(Tree, Acc) ->

-spec points_of_interest(tree()) -> [poi()].
points_of_interest(Tree) ->
lists:flatten(
erl_syntax_lib:fold(
fun(T, Acc) ->
[do_points_of_interest(T)|Acc]
end, [], Tree)).
FoldFun = fun(T, Acc) -> [do_points_of_interest(T), Acc] end,
erl_syntax_lib:fold(FoldFun, [], Tree).

%% @edoc Return the list of points of interest for a given `Tree`.
-spec do_points_of_interest(tree()) -> [poi()].
Expand Down
2 changes: 1 addition & 1 deletion test/els_document_symbol_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ functions(Config) ->
} || {Name, {FromL, FromC}, {ToL, ToC}}
<- lists:append([functions()])],
?assertEqual(length(Expected), length(Symbols)),
Pairs = lists:zip(Expected, Symbols),
Pairs = lists:zip(lists:sort(Expected), lists:sort(Symbols)),
[?assertEqual(E, S) || {E, S} <- Pairs],
ok.

Expand Down