6
6
7
7
-define (timeout , 30000 ).
8
8
-record (elixir_code_server , {
9
- compilation_status = [],
10
9
argv = [],
11
10
loaded = [],
12
11
at_exit = [],
13
- pool = {[],0 },
14
12
paths = {[],[]},
13
+ mod_pool = {[],0 },
14
+ mod_ets = dict :new (),
15
+ compilation_status = [],
15
16
compiler_options = [{docs ,true },{debug_info ,true },{warnings_as_errors ,false }],
16
17
erl_compiler_options = nil
17
18
}).
@@ -35,8 +36,19 @@ init(ok) ->
35
36
_ = code :ensure_loaded ('Elixir.Macro.Env' ),
36
37
_ = code :ensure_loaded ('Elixir.Module.LocalsTracker' ),
37
38
_ = code :ensure_loaded ('Elixir.Kernel.LexicalTracker' ),
39
+
40
+ % % The table where we store module definitions
41
+ _ = ets :new (elixir_modules , [set , protected , named_table , {read_concurrency , true }]),
42
+
38
43
{ok , # elixir_code_server {}}.
39
44
45
+ handle_call ({defmodule , Pid , Tuple }, _From , Config ) ->
46
+ {Ref , New } = defmodule (Pid , Tuple , Config ),
47
+ {reply , Ref , New };
48
+
49
+ handle_call ({undefmodule , Ref }, _From , Config ) ->
50
+ {reply , ok , undefmodule (Ref , Config )};
51
+
40
52
handle_call ({acquire , Path }, From , Config ) ->
41
53
Current = Config # elixir_code_server .loaded ,
42
54
case orddict :find (Path , Current ) of
@@ -73,11 +85,11 @@ handle_call({compilation_status, CompilerPid}, _From, Config) ->
73
85
Config # elixir_code_server {compilation_status = CompilationStatusListNew }};
74
86
75
87
handle_call (retrieve_module_name , _From , Config ) ->
76
- case Config # elixir_code_server .pool of
88
+ case Config # elixir_code_server .mod_pool of
77
89
{[H |T ], Counter } ->
78
- {reply , module_tuple (H ), Config # elixir_code_server {pool = {T ,Counter }}};
90
+ {reply , module_tuple (H ), Config # elixir_code_server {mod_pool = {T ,Counter }}};
79
91
{[], Counter } ->
80
- {reply , module_tuple (Counter ), Config # elixir_code_server {pool = {[],Counter + 1 }}}
92
+ {reply , module_tuple (Counter ), Config # elixir_code_server {mod_pool = {[],Counter + 1 }}}
81
93
end ;
82
94
83
95
handle_call (erl_compiler_options , _From , Config ) ->
@@ -137,16 +149,19 @@ handle_cast({unload_files, Files}, Config) ->
137
149
Unloaded = lists :foldl (fun (File , Acc ) -> orddict :erase (File , Acc ) end , Current , Files ),
138
150
{noreply , Config # elixir_code_server {loaded = Unloaded }};
139
151
140
- handle_cast ({return_module_name , H }, # elixir_code_server {pool = {T ,Counter }} = Config ) ->
141
- {noreply , Config # elixir_code_server {pool = {[H |T ],Counter }}};
152
+ handle_cast ({return_module_name , H }, # elixir_code_server {mod_pool = {T ,Counter }} = Config ) ->
153
+ {noreply , Config # elixir_code_server {mod_pool = {[H |T ],Counter }}};
142
154
143
155
handle_cast ({paths , PA , PZ }, # elixir_code_server {} = Config ) ->
144
156
{noreply , Config # elixir_code_server {paths = {PA ,PZ }}};
145
157
146
158
handle_cast (Request , Config ) ->
147
159
{stop , {badcast , Request }, Config }.
148
160
149
- handle_info (_Request , Config ) ->
161
+ handle_info ({'DOWN' , Ref , process , _Pid , _Reason }, Config ) ->
162
+ {noreply , undefmodule (Ref , Config )};
163
+
164
+ handle_info (_Msg , Config ) ->
150
165
{noreply , Config }.
151
166
152
167
terminate (_Reason , _Config ) ->
@@ -158,6 +173,21 @@ code_change(_Old, Config, _Extra) ->
158
173
module_tuple (I ) ->
159
174
{list_to_atom (" elixir_compiler_" ++ integer_to_list (I )), I }.
160
175
176
+ defmodule (Pid , Tuple , # elixir_code_server {mod_ets = ModEts } = Config ) ->
177
+ ets :insert (elixir_modules , Tuple ),
178
+ Ref = erlang :monitor (process , Pid ),
179
+ Mod = erlang :element (1 , Tuple ),
180
+ {Ref , Config # elixir_code_server {mod_ets = dict :store (Ref , Mod , ModEts )}}.
181
+
182
+ undefmodule (Ref , # elixir_code_server {mod_ets = ModEts } = Config ) ->
183
+ case dict :find (Ref , ModEts ) of
184
+ {ok , Mod } ->
185
+ ets :delete (elixir_modules , Mod ),
186
+ Config # elixir_code_server {mod_ets = dict :erase (Ref , ModEts )};
187
+ error ->
188
+ Config
189
+ end .
190
+
161
191
erl_compiler_options () ->
162
192
Key = " ERL_COMPILER_OPTIONS" ,
163
193
case os :getenv (Key ) of
0 commit comments