@@ -21,11 +21,11 @@ debug_info(elixir_v1, _Module, none, _Opts) ->
21
21
{error , missing };
22
22
debug_info (elixir_v1 , _Module , {elixir_v1 , Map , _Specs }, _Opts ) ->
23
23
{ok , Map };
24
- debug_info (erlang_v1 , _Module , {elixir_v1 , Map , Specs }, _Opts ) ->
25
- {Prefix , Forms , _ , _ } = dynamic_form (Map ),
24
+ debug_info (erlang_v1 , Module , {elixir_v1 , Map , Specs }, _Opts ) ->
25
+ {Prefix , Forms , _ , _ } = dynamic_form (Map , deprecated_chunk_from_beam ( Module ) ),
26
26
{ok , Prefix ++ Specs ++ Forms };
27
- debug_info (core_v1 , _Module , {elixir_v1 , Map , Specs }, Opts ) ->
28
- {Prefix , Forms , _ , _ } = dynamic_form (Map ),
27
+ debug_info (core_v1 , Module , {elixir_v1 , Map , Specs }, Opts ) ->
28
+ {Prefix , Forms , _ , _ } = dynamic_form (Map , deprecated_chunk_from_beam ( Module ) ),
29
29
#{compile_opts := CompileOpts } = Map ,
30
30
31
31
% % Do not rely on elixir_erl_compiler because we don't
@@ -39,6 +39,25 @@ debug_info(core_v1, _Module, {elixir_v1, Map, Specs}, Opts) ->
39
39
debug_info (_ , _ , _ , _ ) ->
40
40
{error , unknown_format }.
41
41
42
+ % % `ExDp` chunk from beam
43
+
44
+ deprecated_chunk_from_beam (Module ) ->
45
+ Chunk = binary_to_list (<<" ExDp" >>),
46
+ Beam = abstract_code_beam (Module ),
47
+
48
+ {elixir_deprecated_v1 , Deprecated } =
49
+ case beam_lib :chunks (Beam , [Chunk ]) of
50
+ {ok , {Module , [{Chunk , DeprecatedBin }]}} -> binary_to_term (DeprecatedBin );
51
+ _ -> {elixir_deprecated_v1 , []}
52
+ end ,
53
+ Deprecated .
54
+
55
+ abstract_code_beam (Module ) ->
56
+ case code :get_object_code (Module ) of
57
+ {Module , Beam , _ } -> Beam ;
58
+ error -> Module
59
+ end .
60
+
42
61
% % Builds Erlang AST annotation.
43
62
44
63
get_ann (Opts ) when is_list (Opts ) ->
@@ -149,16 +168,17 @@ definition_scope(Meta, File) ->
149
168
150
169
compile (#{module := Module } = Map ) ->
151
170
Data = elixir_module :data_table (Module ),
152
- {Prefix , Forms , Defmacro , Unreachable } = dynamic_form (Map ),
171
+ Deprecated = get_deprecated (Data ),
172
+ {Prefix , Forms , Defmacro , Unreachable } = dynamic_form (Map , Deprecated ),
153
173
Specs =
154
174
case elixir_config :get (bootstrap ) of
155
175
true -> [];
156
176
false -> specs_form (Map , Data , Defmacro , Unreachable , types_form (Data , []))
157
177
end ,
158
- load_form (Map , Data , Prefix , Forms , Specs ).
178
+ load_form (Map , Data , Prefix , Forms , Specs , Deprecated ).
159
179
160
180
dynamic_form (#{module := Module , line := Line , file := File , attributes := Attributes ,
161
- definitions := Definitions , unreachable := Unreachable }) ->
181
+ definitions := Definitions , unreachable := Unreachable }, Deprecated ) ->
162
182
{Def , Defmacro , Macros , Exports , Functions } =
163
183
split_definition (Definitions , File , Unreachable , [], [], [], [], {[], []}),
164
184
@@ -167,7 +187,7 @@ dynamic_form(#{module := Module, line := Line, file := File, attributes := Attri
167
187
{attribute , Line , module , Module },
168
188
{attribute , Line , compile , no_auto_import }],
169
189
170
- Forms0 = functions_form (Line , Module , Def , Defmacro , Exports , Functions ),
190
+ Forms0 = functions_form (Line , Module , Def , Defmacro , Exports , Functions , Deprecated ),
171
191
Forms1 = attributes_form (Line , Attributes , Forms0 ),
172
192
{Prefix , Forms1 , Macros , Unreachable }.
173
193
@@ -263,12 +283,12 @@ is_macro(_) -> false.
263
283
264
284
% Functions
265
285
266
- functions_form (Line , Module , Def , Defmacro , Exports , Body ) ->
267
- {Spec , Info } = add_info_function (Line , Module , Def , Defmacro ),
286
+ functions_form (Line , Module , Def , Defmacro , Exports , Body , Deprecated ) ->
287
+ {Spec , Info } = add_info_function (Line , Module , Def , Defmacro , Deprecated ),
268
288
[{attribute , Line , export , lists :sort ([{'__info__' , 1 } | Exports ])}, Spec , Info | Body ].
269
289
270
- add_info_function (Line , Module , Def , Defmacro ) ->
271
- AllowedAttrs = [attributes , compile , functions , macros , md5 , module ],
290
+ add_info_function (Line , Module , Def , Defmacro , Deprecated ) ->
291
+ AllowedAttrs = [attributes , compile , functions , macros , md5 , module , deprecated ],
272
292
AllowedArgs = lists :map (fun (Atom ) -> {atom , Line , Atom } end , AllowedAttrs ),
273
293
274
294
Spec =
@@ -303,7 +323,8 @@ add_info_function(Line, Module, Def, Defmacro) ->
303
323
macros_info (Defmacro ),
304
324
get_module_info (Module , attributes ),
305
325
get_module_info (Module , compile ),
306
- get_module_info (Module , md5 )
326
+ get_module_info (Module , md5 ),
327
+ deprecated_info (Deprecated )
307
328
]},
308
329
309
330
{Spec , Info }.
@@ -321,6 +342,9 @@ get_module_info(Module, Key) ->
321
342
Call = remote (0 , erlang , get_module_info , [{atom , 0 , Module }, {atom , 0 , Key }]),
322
343
{clause , 0 , [{atom , 0 , Key }], [], [Call ]}.
323
344
345
+ deprecated_info (Deprecated ) ->
346
+ {clause , 0 , [{atom , 0 , deprecated }], [], [elixir_erl :elixir_to_erl (Deprecated )]}.
347
+
324
348
% Types
325
349
326
350
types_form (Data , Forms ) ->
@@ -442,8 +466,9 @@ attributes_form(Line, Attributes, Forms) ->
442
466
443
467
% Loading forms
444
468
445
- load_form (#{line := Line , file := File , compile_opts := Opts } = Map , Data , Prefix , Forms , Specs ) ->
446
- {ExtraChunks , CompileOpts } = extra_chunks (Data , Line , debug_opts (Map , Specs , Opts )),
469
+ load_form (#{line := Line , file := File , compile_opts := Opts } = Map ,
470
+ Data , Prefix , Forms , Specs , Deprecated ) ->
471
+ {ExtraChunks , CompileOpts } = extra_chunks (Data , Deprecated , Line , debug_opts (Map , Specs , Opts )),
447
472
{_ , Binary } = elixir_erl_compiler :forms (Prefix ++ Specs ++ Forms , File , CompileOpts ),
448
473
add_beam_chunks (Binary , ExtraChunks ).
449
474
@@ -469,12 +494,17 @@ supports_debug_tuple() ->
469
494
_ -> true
470
495
end .
471
496
472
- extra_chunks (Data , Line , Opts ) ->
497
+ extra_chunks (Data , Deprecated , Line , Opts ) ->
473
498
Supported = supports_extra_chunks_option (),
474
- case docs_chunk (Data , Line , elixir_compiler :get_opt (docs )) of
499
+ Chunks0 = lists :flatten ([
500
+ docs_chunk (Data , Line , elixir_compiler :get_opt (docs )),
501
+ deprecated_chunk (Deprecated )
502
+ ]),
503
+
504
+ case Chunks0 of
475
505
[] -> {[], Opts };
476
- Chunks when Supported -> {[], [{extra_chunks , Chunks } | Opts ]};
477
- Chunks -> {Chunks , Opts }
506
+ Chunks1 when Supported -> {[], [{extra_chunks , Chunks1 } | Opts ]};
507
+ Chunks1 -> {Chunks1 , Opts }
478
508
end .
479
509
480
510
supports_extra_chunks_option () ->
@@ -495,6 +525,10 @@ docs_chunk(Data, Line, true) ->
495
525
docs_chunk (_ , _ , _ ) ->
496
526
[].
497
527
528
+ deprecated_chunk (Deprecated ) ->
529
+ ChunkData = term_to_binary ({elixir_deprecated_v1 , Deprecated }, [compressed ]),
530
+ [{<<" ExDp" >>, ChunkData }].
531
+
498
532
get_moduledoc (Line , Data ) ->
499
533
case ets :lookup_element (Data , moduledoc , 2 ) of
500
534
nil -> {Line , nil };
@@ -513,6 +547,9 @@ get_type_docs(Data) ->
513
547
lists :usort (ets :select (Data , [{{{typedoc , '$1' }, '$2' , '$3' , '$4' },
514
548
[], [{{'$1' , '$2' , '$3' , '$4' }}]}])).
515
549
550
+ get_deprecated (Data ) ->
551
+ lists :usort (ets :select (Data , [{{{deprecated , '$1' }, '$2' }, [], [{{'$1' , '$2' }}]}])).
552
+
516
553
% % Errors
517
554
518
555
form_error (#{line := Line , file := File }, Error ) ->
0 commit comments