Skip to content

Commit 3537bbb

Browse files
author
José Valim
committed
Refactor aliases handling
1 parent cd51c80 commit 3537bbb

File tree

3 files changed

+48
-35
lines changed

3 files changed

+48
-35
lines changed

lib/elixir/src/elixir_aliases.erl

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,38 @@
11
-module(elixir_aliases).
2-
-export([nesting_alias/2, last/1, concat/1, safe_concat/1, lookup/2,
2+
-export([nesting_alias/2, last/1, concat/1, safe_concat/1,
33
format_error/1, ensure_loaded/3, expand/2]).
44
-include("elixir.hrl").
55
-compile({parse_transform, elixir_transform}).
66

7-
%% Expand an alias returning an atom if possible.
8-
%% Otherwise returns the list of aliases args.
9-
10-
expand({ '__aliases__', _Line, [H] }, Aliases) when H /= 'Elixir' ->
11-
expand_one(H, Aliases);
12-
13-
expand({ '__aliases__', _Line, [H|T] }, Aliases) when is_atom(H) ->
14-
concat(case H of
15-
'Elixir' -> [H|T];
16-
_ -> [expand_one(H, Aliases)|T]
17-
end);
18-
19-
expand({ '__aliases__', _Line, List }, _Aliases) ->
7+
%% Expand an alias. It returns an atom (mearning that there
8+
%% was an expansion) or a list of atoms.
9+
10+
expand({ '__aliases__', _Meta, [H] }, Aliases) when H /= 'Elixir' ->
11+
case expand_one(H, Aliases) of
12+
false -> [H];
13+
Atom -> Atom
14+
end;
15+
16+
expand({ '__aliases__', _Meta, [H|T] }, Aliases) when is_atom(H) ->
17+
case H of
18+
'Elixir' ->
19+
concat(T);
20+
_ ->
21+
case expand_one(H, Aliases) of
22+
false -> [H|T];
23+
Atom -> concat([Atom|T])
24+
end
25+
end;
26+
27+
expand({ '__aliases__', _Meta, List }, _Aliases) ->
2028
List.
2129

2230
expand_one(H, Aliases) ->
23-
lookup(list_to_atom("Elixir-" ++ atom_to_list(H)), Aliases).
31+
Lookup = list_to_atom("Elixir-" ++ atom_to_list(H)),
32+
case lookup(Lookup, Aliases) of
33+
Lookup -> false;
34+
Else -> Else
35+
end.
2436

2537
%% Ensure a module is loaded before its usage.
2638

@@ -39,7 +51,7 @@ ensure_loaded(Line, Ref, S) ->
3951
elixir_errors:form_error(Line, S#elixir_scope.file, ?MODULE, { Kind, Ref })
4052
end.
4153

42-
%% Receives an atom and returns the last alias.
54+
%% Receives an atom and returns the last bit as an alias.
4355

4456
last(Atom) ->
4557
Last = last(lists:reverse(atom_to_list(Atom)), []),
@@ -56,8 +68,13 @@ last([], Acc) -> Acc.
5668
%%
5769
%% Examples:
5870
%%
59-
%% nesting_alias('Elixir.Foo.Bar', 'Elixir.Foo.Bar.Baz')
60-
%% { '__aliases__', [], ['Elixir', 'Foo', 'Bar', 'Baz'] }
71+
%% nesting_alias('Elixir.Foo.Bar', 'Elixir.Foo.Bar.Baz.Bat')
72+
%% { '__aliases__', [], ['Elixir', 'Foo', 'Bar', 'Baz'] }
73+
%%
74+
%% When passed to alias, the example above will generate an
75+
%% alias like:
76+
%%
77+
%% 'Elixir.Baz' => 'Elixir.Foo.Bar.Baz'
6178
%%
6279
nesting_alias(nil, _Full) -> false;
6380

@@ -69,18 +86,18 @@ nesting_alias(Prefix, Full) ->
6986
do_nesting([X|PreTail], [X|Tail], Acc) ->
7087
do_nesting(PreTail, Tail, [X|Acc]);
7188
do_nesting([], [H|_], Acc) ->
72-
{ '__aliases__', [], ['Elixir'|[binary_to_atom(X, utf8) || X <- lists:reverse([H|Acc])]] };
89+
{ '__aliases__', [], ['Elixir'|[list_to_atom(X) || X <- lists:reverse([H|Acc])]] };
7390
do_nesting(_, _, _Acc) ->
7491
false.
7592

7693
list_nesting(Atom) ->
77-
case binary:split(atom_to_binary(Atom, utf8), <<$->>, [global]) of
78-
[<<"Elixir">>|T] -> T;
94+
case string:tokens(atom_to_list(Atom), "-") of
95+
["Elixir"|T] -> T;
7996
_ -> []
8097
end.
8198

82-
%% Receives a list of atoms representing modules
83-
%% and concatenate them.
99+
%% Receives a list of atoms, binaries or lists
100+
%% representing modules and concatenates them.
84101

85102
concat(Args) -> list_to_atom(raw_concat(Args)).
86103
safe_concat(Args) -> list_to_existing_atom(raw_concat(Args)).
@@ -104,7 +121,7 @@ dot_to_dash(List) ->
104121
_ -> X
105122
end || X <- List].
106123

107-
%% Lookup an alias in the current scope
124+
%% Lookup an alias in the current scope.
108125

109126
lookup(Else, Dict) ->
110127
case orddict:find(Else, Dict) of

lib/elixir/src/elixir_macros.erl

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -330,16 +330,12 @@ rewrite_case_clauses(Clauses) ->
330330
module_ref(Raw, Module, #elixir_scope{module=Nesting}) when is_atom(Raw); Nesting == nil ->
331331
Module;
332332

333-
module_ref({ '__aliases__', _, ['Elixir'|_] }, Module, _S) ->
334-
Module;
335-
336-
% In case the module is an alias and it was already
337-
% expanded we should not expand it twice
338-
module_ref({ '__aliases__', _, [H|_] }, Module, #elixir_scope{aliases=Aliases} = S) ->
339-
Full = list_to_atom("Elixir-" ++ atom_to_list(H)),
340-
case elixir_aliases:lookup(Full, Aliases) of
341-
Full -> elixir_aliases:concat([S#elixir_scope.module, Module]);
342-
_ -> Module
333+
module_ref({ '__aliases__', _, _ } = Alias, Module, S) ->
334+
case elixir_aliases:expand(Alias, S#elixir_scope.aliases) of
335+
Atom when is_atom(Atom) ->
336+
Module;
337+
Aliases when is_list(Aliases) ->
338+
elixir_aliases:concat([S#elixir_scope.module, Module])
343339
end;
344340

345341
module_ref(_Raw, Module, S) ->

lib/elixir/src/elixir_translator.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ translate_each({ '__CALLER__', Meta, Atom }, S) when is_atom(Atom) ->
214214

215215
translate_each({ '__aliases__', Meta, _ } = Alias, S) ->
216216
case elixir_aliases:expand(Alias, S#elixir_scope.aliases) of
217-
Atom when is_atom(Atom) -> { { atom, ?line(Meta), Atom}, S };
217+
Atom when is_atom(Atom) -> { { atom, ?line(Meta), Atom }, S };
218218
Aliases ->
219219
{ TAliases, SA } = translate_args(Aliases, S),
220220

0 commit comments

Comments
 (0)