Skip to content

Commit 8c5c421

Browse files
committed
Avoid compiling some values twice when building .beam
1 parent 420fefc commit 8c5c421

File tree

3 files changed

+18
-25
lines changed

3 files changed

+18
-25
lines changed

lib/elixir/src/elixir_erl.erl

+15-22
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ compile(#{module := Module, line := Line} = Map) ->
125125
{Types, Callbacks, TypeSpecs} = typespecs_form(Map, TranslatedTypespecs, Macros),
126126

127127
DocsChunk = docs_chunk(Set, Module, Line, Def, Defmacro, Types, Callbacks),
128-
CheckerChunk = checker_chunk(Map),
128+
CheckerChunk = checker_chunk(Def, Defmacro, Map),
129129
load_form(Map, Prefix, Forms, TypeSpecs, DocsChunk ++ CheckerChunk).
130130

131131
dynamic_form(#{module := Module, line := Line, relative_file := RelativeFile,
@@ -158,7 +158,7 @@ split_definition([{Tuple, Kind, Meta, Clauses} | T], Unreachable, Line,
158158
split_definition(T, Unreachable, Line, Def, Defmacro, Macros, Exports, Functions)
159159
end;
160160
split_definition([], _Unreachable, _Line, Def, Defmacro, Macros, Exports, {Head, Tail}) ->
161-
{Def, Defmacro, Macros, Exports, Head ++ Tail}.
161+
{lists:usort(Def), lists:usort(Defmacro), Macros, Exports, Head ++ Tail}.
162162

163163
split_definition(Tuple, def, Meta, Clauses, T, Unreachable, Line,
164164
Def, Defmacro, Macros, Exports, Functions) ->
@@ -247,13 +247,11 @@ is_macro(_) -> false.
247247

248248
functions_form(Line, Module, Def, Defmacro, Exports, Body, Deprecated, Struct) ->
249249
{Spec, Info} = add_info_function(Line, Module, Def, Defmacro, Deprecated, Struct),
250-
[{attribute, Line, export, lists:sort([{'__info__', 1} | Exports])}, Spec, Info | Body].
250+
[{attribute, Line, export, lists:usort([{'__info__', 1} | Exports])}, Spec, Info | Body].
251251

252252
add_info_function(Line, Module, Def, Defmacro, Deprecated, Struct) ->
253253
AllowedAttrs = [attributes, compile, functions, macros, md5, exports_md5, module, deprecated, struct],
254254
AllowedArgs = lists:map(fun(Atom) -> {atom, Line, Atom} end, AllowedAttrs),
255-
SortedDef = lists:sort(Def),
256-
SortedDefmacro = lists:sort(Defmacro),
257255

258256
Spec =
259257
{attribute, Line, spec, {{'__info__', 1},
@@ -268,10 +266,10 @@ add_info_function(Line, Module, Def, Defmacro, Deprecated, Struct) ->
268266
Info =
269267
{function, 0, '__info__', 1, [
270268
get_module_info(Module),
271-
functions_info(SortedDef),
272-
macros_info(SortedDefmacro),
269+
functions_info(Def),
270+
macros_info(Defmacro),
273271
struct_info(Struct),
274-
exports_md5_info(Struct, SortedDef, SortedDefmacro),
272+
exports_md5_info(Struct, Def, Defmacro),
275273
get_module_info(Module, attributes),
276274
get_module_info(Module, compile),
277275
get_module_info(Module, md5),
@@ -418,7 +416,7 @@ callspecs_form(Kind, Entries, Optional, Macros, Forms, ModuleMap) ->
418416
false ->
419417
[{attribute, Line, Kind, {Key, lists:reverse(Value)}} | Acc]
420418
end
421-
end, Forms, lists:sort(Signatures)).
419+
end, Forms, lists:usort(Signatures)).
422420

423421
spec_for_macro({type, Line, 'bounded_fun', [H | T]}) ->
424422
{type, Line, 'bounded_fun', [spec_for_macro(H) | T]};
@@ -567,28 +565,23 @@ signature_to_binary(_, Name, Signature) ->
567565
Doc = 'Elixir.Inspect.Algebra':format('Elixir.Code':quoted_to_algebra(Quoted), infinity),
568566
'Elixir.IO':iodata_to_binary(Doc).
569567

570-
checker_chunk(#{definitions := Definitions, deprecated := Deprecated, defines_behaviour := DefinesBehaviour}) ->
568+
checker_chunk(Def, Defmacro, #{deprecated := Deprecated, defines_behaviour := DefinesBehaviour}) ->
571569
DeprecatedMap = maps:from_list(Deprecated),
572570

573571
Exports =
574-
lists:foldl(fun({Function, Kind, _Meta, _Clauses}, Acc) ->
575-
case Kind of
576-
_ when Kind == def orelse Kind == defmacro ->
577-
Reason = maps:get(Function, DeprecatedMap, nil),
578-
[{Function, #{kind => Kind, deprecated_reason => Reason}} | Acc];
579-
_ ->
580-
Acc
581-
end
582-
end, [], Definitions),
572+
[{FA, #{kind => def, deprecated_reason => maps:get(FA, DeprecatedMap, nil)}}
573+
|| FA <- prepend_behaviour_info(DefinesBehaviour, Def)] ++
574+
[{FA, #{kind => defmacro, deprecated_reason => maps:get(FA, DeprecatedMap, nil)}}
575+
|| FA <- Defmacro],
583576

584577
Contents = #{
585-
exports => lists:sort(behaviour_info_exports(DefinesBehaviour) ++ Exports)
578+
exports => Exports
586579
},
587580

588581
[{<<"ExCk">>, term_to_binary({elixir_checker_v1, Contents}, [deterministic])}].
589582

590-
behaviour_info_exports(true) -> [{{behaviour_info, 1}, #{kind => def, deprecated_reason => nil}}];
591-
behaviour_info_exports(false) -> [].
583+
prepend_behaviour_info(true, Def) -> [{behaviour_info, 1} | Def];
584+
prepend_behaviour_info(false, Def) -> Def.
592585

593586
%% Errors
594587

lib/elixir/src/elixir_module.erl

+1-1
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ warn_unused_attributes(DataSet, DataBag, PersistedAttrs, E) ->
501501
get_struct(Set) ->
502502
case ets:lookup(Set, {elixir, struct}) of
503503
[] -> nil;
504-
[{_, Struct}] -> Struct
504+
[{_, Fields}] -> [maps:remove(default, FieldInfo) || FieldInfo <- Fields]
505505
end.
506506

507507
get_deprecated(Bag) ->

lib/elixir/test/elixir/module/types/integration_test.exs

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ defmodule Module.Types.IntegrationTest do
4040

4141
assert read_chunk(modules[A]).exports == [
4242
{{:c, 0}, %{deprecated_reason: nil, kind: :def}},
43-
{{:d, 0}, %{deprecated_reason: nil, kind: :defmacro}},
44-
{{:e, 0}, %{deprecated_reason: "oops", kind: :def}}
43+
{{:e, 0}, %{deprecated_reason: "oops", kind: :def}},
44+
{{:d, 0}, %{deprecated_reason: nil, kind: :defmacro}}
4545
]
4646

4747
assert read_chunk(modules[B]).exports == [

0 commit comments

Comments
 (0)