1
1
-module (elixir_module ).
2
2
-export ([file /1 , data_tables /1 , is_open /1 , mode /1 , delete_definition_attributes /6 ,
3
- compile /4 , expand_callback /6 , format_error /1 , compiler_modules /0 ,
3
+ compile /5 , expand_callback /6 , format_error /1 , compiler_modules /0 ,
4
4
write_cache /3 , read_cache /2 , next_counter /1 ]).
5
5
-include (" elixir.hrl" ).
6
6
-define (counter_attr , {elixir , counter }).
@@ -64,7 +64,7 @@ next_counter(Module) ->
64
64
65
65
% % Compilation hook
66
66
67
- compile (Module , Block , Vars , Env ) when is_atom (Module ) ->
67
+ compile (Module , Block , Vars , Prune , Env ) when is_atom (Module ) ->
68
68
#{line := Line , function := Function , versioned_vars := OldVerVars } = Env ,
69
69
70
70
{VerVars , _ } =
@@ -82,16 +82,16 @@ compile(Module, Block, Vars, Env) when is_atom(Module) ->
82
82
#{lexical_tracker := nil } ->
83
83
elixir_lexical :run (
84
84
MaybeLexEnv ,
85
- fun (LexEnv ) -> compile (Line , Module , Block , Vars , LexEnv ) end ,
85
+ fun (LexEnv ) -> compile (Line , Module , Block , Vars , Prune , LexEnv ) end ,
86
86
fun (_LexEnv ) -> ok end
87
87
);
88
88
_ ->
89
- compile (Line , Module , Block , Vars , MaybeLexEnv )
89
+ compile (Line , Module , Block , Vars , Prune , MaybeLexEnv )
90
90
end ;
91
- compile (Module , _Block , _Vars , #{line := Line , file := File }) ->
91
+ compile (Module , _Block , _Vars , _Prune , #{line := Line , file := File }) ->
92
92
elixir_errors :form_error ([{line , Line }], File , ? MODULE , {invalid_module , Module }).
93
93
94
- compile (Line , Module , Block , Vars , E ) ->
94
+ compile (Line , Module , Block , Vars , Prune , E ) ->
95
95
File = ? key (E , file ),
96
96
check_module_availability (Line , File , Module ),
97
97
ModuleAsCharlist = validate_module_name (Line , File , Module ),
@@ -102,7 +102,7 @@ compile(Line, Module, Block, Vars, E) ->
102
102
103
103
try
104
104
put_compiler_modules ([Module | CompilerModules ]),
105
- {Result , NE } = eval_form (Line , Module , DataBag , Block , Vars , E ),
105
+ {Result , ModuleE , CallbackE } = eval_form (Line , Module , DataBag , Block , Vars , Prune , E ),
106
106
CheckerInfo = checker_info (),
107
107
108
108
{Binary , PersistedAttributes , Autoload } =
@@ -133,7 +133,7 @@ compile(Line, Module, Block, Vars, E) ->
133
133
CompileOpts = validate_compile_opts (RawCompileOpts , AllDefinitions , Unreachable , File , Line ),
134
134
135
135
AfterVerify = bag_lookup_element (DataBag , {accumulate , after_verify }, 2 ),
136
- [elixir_env :trace ({remote_function , [], VerifyMod , VerifyFun , 1 }, E ) ||
136
+ [elixir_env :trace ({remote_function , [], VerifyMod , VerifyFun , 1 }, CallbackE ) ||
137
137
{VerifyMod , VerifyFun } <- AfterVerify ],
138
138
139
139
ModuleMap = #{
@@ -158,8 +158,8 @@ compile(Line, Module, Block, Vars, E) ->
158
158
end ),
159
159
160
160
Autoload andalso code :load_binary (Module , beam_location (ModuleAsCharlist ), Binary ),
161
- eval_callbacks (Line , DataBag , after_compile , [NE , Binary ], NE ),
162
- elixir_env :trace ({on_module , Binary , none }, E ),
161
+ eval_callbacks (Line , DataBag , after_compile , [CallbackE , Binary ], CallbackE ),
162
+ elixir_env :trace ({on_module , Binary , none }, ModuleE ),
163
163
warn_unused_attributes (File , DataSet , DataBag , PersistedAttributes ),
164
164
make_module_available (Module , Binary ),
165
165
(CheckerInfo == undefined ) andalso
@@ -375,13 +375,27 @@ build(Line, File, Module) ->
375
375
376
376
% % Handles module and callback evaluations.
377
377
378
- eval_form (Line , Module , DataBag , Block , Vars , E ) ->
379
- {Value , EE } = elixir_compiler :compile (Block , Vars , E ),
378
+ eval_form (Line , Module , DataBag , Block , Vars , Prune , E ) ->
379
+ {Value , ExS , EE } = elixir_compiler :compile (Block , Vars , E ),
380
380
elixir_overridable :store_not_overridden (Module ),
381
381
EV = (elixir_env :reset_vars (EE ))#{line := Line },
382
382
EC = eval_callbacks (Line , DataBag , before_compile , [EV ], EV ),
383
383
elixir_overridable :store_not_overridden (Module ),
384
- {Value , EC }.
384
+ {Value , maybe_prune_versioned_vars (Prune , Vars , ExS , E ), EC }.
385
+
386
+ maybe_prune_versioned_vars (false , _Vars , _Exs , E ) ->
387
+ E ;
388
+ maybe_prune_versioned_vars (true , Vars , ExS , E ) ->
389
+ PruneBefore = length (Vars ),
390
+ # elixir_ex {vars = {ExVars , _ }, unused = {Unused , _ }} = ExS ,
391
+
392
+ VersionedVars =
393
+ maps :filter (fun
394
+ (Pair , Version ) when Version < PruneBefore , not is_map_key ({Pair , Version }, Unused ) -> false ;
395
+ (_ , _ ) -> true
396
+ end , ExVars ),
397
+
398
+ E #{versioned_vars := VersionedVars }.
385
399
386
400
eval_callbacks (Line , DataBag , Name , Args , E ) ->
387
401
Callbacks = bag_lookup_element (DataBag , {accumulate , Name }, 2 ),
0 commit comments