Clean up Macro.Env and hide private fields

This commit is contained in:
José Valim
2019-07-25 22:07:51 +02:00
parent 87ccbafced
commit 6c5ad7b661
8 changed files with 74 additions and 57 deletions
+15 -17
View File
@@ -21,8 +21,7 @@ new() ->
macro_aliases => [], %% keep aliases defined inside a macro
context_modules => [], %% modules defined in the current context
vars => [], %% a set of defined variables
unused_vars => #{}, %% a map with unused variables
current_vars => #{}, %% a map with current variables
current_vars => {#{}, #{}}, %% a tuple with maps of current and unused variables
prematch_vars => warn, %% behaviour outside and inside matches
lexical_tracker => nil, %% holds the lexical tracker PID
contextual_vars => []}. %% holds available contextual variables
@@ -34,7 +33,7 @@ linify(#{} = Env) ->
with_vars(Env, Vars) ->
CurrentVars = maps:from_list([{Var, 0} || Var <- Vars]),
Env#{vars := Vars, current_vars := CurrentVars}.
Env#{vars := Vars, current_vars := {CurrentVars, #{}}}.
env_to_scope(#{context := Context}) ->
#elixir_erl{context=Context}.
@@ -46,28 +45,27 @@ env_to_scope_with_vars(Env, Vars) ->
}.
reset_vars(Env) ->
Env#{vars := [], current_vars := #{}, unused_vars := #{}}.
Env#{vars := [], current_vars := {#{}, #{}}}.
%% SCOPE MERGING
%% Receives two scopes and return a new scope based on the second
%% with their variables merged.
%% Unrolled for performance reasons.
mergev(#{unused_vars := U1, current_vars := C1},
#{unused_vars := U2, current_vars := C2} = E2) ->
mergev(#{current_vars := {C1, U1}}, #{current_vars := {C2, U2}} = E2) ->
if
C1 =/= C2 ->
if
U1 =/= U2 ->
C = merge_vars(C1, C2),
E2#{vars := maps:keys(C), unused_vars := merge_vars(U1, U2), current_vars := C};
E2#{vars := maps:keys(C), current_vars := {C, merge_vars(U1, U2)}};
true ->
C = merge_vars(C1, C2),
E2#{vars := maps:keys(C), current_vars := C}
E2#{vars := maps:keys(C), current_vars := {C, U2}}
end;
U1 =/= U2 ->
E2#{unused_vars := merge_vars(U1, U2)};
E2#{current_vars := {C2, merge_vars(U1, U2)}};
true ->
E2
@@ -77,18 +75,18 @@ mergev(#{unused_vars := U1, current_vars := C1},
%% keeping the variables from the first (imports
%% and everything else are passed forward).
%% Unrolled for performance reasons.
mergea(#{unused_vars := U1, current_vars := C1, vars := V1},
#{unused_vars := U2, current_vars := C2} = E2) ->
mergea(#{current_vars := {C1, U1}, vars := V1},
#{current_vars := {C2, U2}} = E2) ->
if
C1 =/= C2 ->
if
U1 =/= U2 ->
E2#{vars := V1, unused_vars := U1, current_vars := C1};
E2#{vars := V1, current_vars := {C1, U1}};
true ->
E2#{vars := V1, current_vars := C1}
E2#{vars := V1, current_vars := {C1, U2}}
end;
U1 =/= U2 ->
E2#{unused_vars := U1};
E2#{current_vars := {C2, U1}};
true ->
E2
end.
@@ -104,13 +102,13 @@ merge_vars(V1, V2) ->
%% UNUSED VARS
check_unused_vars(#{unused_vars := Unused} = E) ->
check_unused_vars(#{current_vars := {_, Unused}} = E) ->
[elixir_errors:form_warn([{line, Line}], E, ?MODULE, {unused_var, Name}) ||
{{{Name, _}, _}, Line} <- maps:to_list(Unused), Line /= false, not_underscored(Name)],
E.
merge_and_check_unused_vars(#{unused_vars := Unused} = E, #{unused_vars := ClauseUnused}) ->
E#{unused_vars := merge_and_check_unused_vars(Unused, ClauseUnused, E)}.
merge_and_check_unused_vars(#{current_vars := {C, Unused}} = E, #{current_vars := {_, ClauseUnused}}) ->
E#{current_vars := {C, merge_and_check_unused_vars(Unused, ClauseUnused, E)}}.
merge_and_check_unused_vars(Unused, ClauseUnused, E) ->
maps:fold(fun(Key, ClauseValue, Acc) ->