Skip to content

Commit 9a62a43

Browse files
author
José Valim
committed
Aliases for defmodule also works for raw atoms
1 parent 89cbe93 commit 9a62a43

File tree

3 files changed

+35
-22
lines changed

3 files changed

+35
-22
lines changed

lib/elixir/src/elixir_aliases.erl

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
-module(elixir_aliases).
2-
-export([first/1, last/1, concat/1, safe_concat/1, lookup/2,
2+
-export([nesting/2, last/1, concat/1, safe_concat/1, lookup/2,
33
format_error/1, ensure_loaded/3, expand/2]).
44
-include("elixir.hrl").
55
-compile({parse_transform, elixir_transform}).
@@ -39,17 +39,6 @@ ensure_loaded(Line, Ref, S) ->
3939
elixir_errors:form_error(Line, S#elixir_scope.file, ?MODULE, { Kind, Ref })
4040
end.
4141

42-
%% Receives an atom and returns the first alias.
43-
44-
first(Atom) ->
45-
First = first(atom_to_list(Atom), []),
46-
list_to_atom("Elixir-" ++ First).
47-
48-
first("Elixir-" ++ Rest, []) -> first(Rest, []);
49-
first([$-|_], Acc) -> lists:reverse(Acc);
50-
first([H|T], Acc) -> first(T, [H|Acc]);
51-
first([], Acc) -> lists:reverse(Acc).
52-
5342
%% Receives an atom and returns the last alias.
5443

5544
last(Atom) ->
@@ -60,6 +49,25 @@ last([$-|_], Acc) -> Acc;
6049
last([H|T], Acc) -> last(T, [H|Acc]);
6150
last([], Acc) -> Acc.
6251

52+
%% Returns the nesting between two aliases.
53+
54+
nesting(nil, _Full) -> false;
55+
56+
nesting(Prefix, Full) ->
57+
PrefixList = list_nesting(Prefix),
58+
FullList = list_nesting(Full),
59+
60+
(PrefixList /= []) andalso
61+
(PrefixList /= FullList) andalso
62+
lists:prefix(PrefixList, FullList) andalso
63+
binary_to_atom(<<"Elixir-", (hd(FullList -- PrefixList))/binary>>, utf8).
64+
65+
list_nesting(Atom) ->
66+
case binary:split(atom_to_binary(Atom, utf8), <<$->>, [global]) of
67+
[<<"Elixir">>|T] -> T;
68+
_ -> []
69+
end.
70+
6371
%% Receives a list of atoms representing modules
6472
%% and concatenate them.
6573

lib/elixir/src/elixir_macros.erl

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -196,19 +196,16 @@ translate({defmodule, Meta, [Ref, KV]}, S) ->
196196

197197
{ FRef, FS } = case TRef of
198198
{ atom, _, Module } ->
199-
NewModule = module_ref(Ref, Module, S#elixir_scope.module),
200-
201-
RS = case Module == NewModule of
202-
true -> S;
203-
false ->
204-
element(2, translate_each({
205-
alias, Meta, [NewModule, [{as, elixir_aliases:first(Module)}]]
206-
}, S))
199+
FullModule = module_ref(Ref, Module, S#elixir_scope.module),
200+
201+
RS = case elixir_aliases:nesting(S#elixir_scope.module, FullModule) of
202+
false -> S;
203+
Alias -> element(2, translate_each({ alias, Meta, [FullModule, [{ as, Alias }]] }, S))
207204
end,
208205

209206
{
210-
{ atom, Meta, NewModule },
211-
RS#elixir_scope{scheduled=[NewModule|S#elixir_scope.scheduled]}
207+
{ atom, Meta, FullModule },
208+
RS#elixir_scope{scheduled=[FullModule|S#elixir_scope.scheduled]}
212209
};
213210
_ ->
214211
{ TRef, S }

lib/elixir/test/elixir/module_test.exs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ defmodule ModuleTest do
114114
assert OverridableWithBeforeCompile.constant == 1
115115
end
116116

117+
test :alias_with_raw_atom do
118+
defmodule :"Elixir-ModuleTest-RawModule" do
119+
def hello, do: :world
120+
end
121+
122+
assert RawModule.hello == :world
123+
end
124+
117125
defmacro __before_compile__(_) do
118126
quote do
119127
def constant, do: 1

0 commit comments

Comments
 (0)