@@ -609,8 +609,8 @@ defmodule Mix.Compilers.Elixir do
609
609
# within the dependency, they will be recompiled. However, export
610
610
# and runtime dependencies won't have recompiled so we need to
611
611
# propagate them to the parent app.
612
- { dep_modules , _ , _ } =
613
- fixpoint_runtime_modules ( manifest_sources , Map . from_keys ( dep_modules , true ) )
612
+ dep_modules =
613
+ fixpoint_non_compile_modules ( manifest_sources , Map . from_keys ( dep_modules , true ) )
614
614
615
615
old_exports = Map . get ( deps_exports , app , % { } )
616
616
@@ -654,46 +654,39 @@ defmodule Mix.Compilers.Elixir do
654
654
end
655
655
end
656
656
657
- defp fixpoint_runtime_modules ( sources , modules ) when modules != % { } do
658
- fixpoint_runtime_modules ( Map . to_list ( sources ) , modules , false , [ ] , [ ] , sources )
657
+ defp fixpoint_non_compile_modules ( sources , modules ) when modules != % { } do
658
+ fixpoint_non_compile_modules ( Map . to_list ( sources ) , modules , false , [ ] )
659
659
end
660
660
661
- defp fixpoint_runtime_modules ( sources , modules ) do
662
- { modules , [ ] , sources }
661
+ defp fixpoint_non_compile_modules ( _sources , modules ) do
662
+ modules
663
663
end
664
664
665
- defp fixpoint_runtime_modules (
666
- [ { source_path , source_entry } = pair | sources ] ,
665
+ defp fixpoint_non_compile_modules (
666
+ [ { _source_path , source_entry } = pair | sources ] ,
667
667
modules ,
668
668
new? ,
669
- pending_sources ,
670
- acc_modules ,
671
- acc_sources
669
+ pending_sources
672
670
) do
673
671
source ( export_references: export_refs , runtime_references: runtime_refs ) = source_entry
674
672
675
673
if has_any_key? ( modules , export_refs ) or has_any_key? ( modules , runtime_refs ) do
676
674
new_modules = Enum . reject ( source ( source_entry , :modules ) , & Map . has_key? ( modules , & 1 ) )
677
675
modules = Enum . reduce ( new_modules , modules , & Map . put ( & 2 , & 1 , true ) )
678
676
new? = new? or new_modules != [ ]
679
- acc_modules = new_modules ++ acc_modules
680
-
681
- acc_sources =
682
- Map . replace! ( acc_sources , source_path , source ( source_entry , runtime_warnings: [ ] ) )
683
-
684
- fixpoint_runtime_modules ( sources , modules , new? , pending_sources , acc_modules , acc_sources )
677
+ fixpoint_non_compile_modules ( sources , modules , new? , pending_sources )
685
678
else
686
679
pending_sources = [ pair | pending_sources ]
687
- fixpoint_runtime_modules ( sources , modules , new? , pending_sources , acc_modules , acc_sources )
680
+ fixpoint_non_compile_modules ( sources , modules , new? , pending_sources )
688
681
end
689
682
end
690
683
691
- defp fixpoint_runtime_modules ( [ ] , modules , new? , pending_sources , acc_modules , acc_sources )
684
+ defp fixpoint_non_compile_modules ( [ ] , modules , new? , pending_sources )
692
685
when new? == false or pending_sources == [ ] ,
693
- do: { modules , acc_modules , acc_sources }
686
+ do: modules
694
687
695
- defp fixpoint_runtime_modules ( [ ] , modules , true , pending_sources , acc_modules , acc_sources ) ,
696
- do: fixpoint_runtime_modules ( pending_sources , modules , false , [ ] , acc_modules , acc_sources )
688
+ defp fixpoint_non_compile_modules ( [ ] , modules , true , pending_sources ) ,
689
+ do: fixpoint_non_compile_modules ( pending_sources , modules , false , [ ] )
697
690
698
691
defp exports_md5 ( module , use_attributes? ) do
699
692
cond do
@@ -1068,7 +1061,7 @@ defmodule Mix.Compilers.Elixir do
1068
1061
end
1069
1062
end
1070
1063
1071
- defp each_cycle ( runtime_modules , compile_path , timestamp , state ) do
1064
+ defp each_cycle ( stale_modules , compile_path , timestamp , state ) do
1072
1065
{ modules , _exports , sources , changed , pending_modules , stale_exports } = state
1073
1066
1074
1067
{ pending_modules , exports , changed } =
@@ -1081,11 +1074,33 @@ defmodule Mix.Compilers.Elixir do
1081
1074
end
1082
1075
1083
1076
if changed == [ ] do
1084
- # We merge runtime_modules (which is a map of %{module => true}) into
1085
- # a map of modules (which is a map of %{module => record}). This is fine
1086
- # since fixpoint_runtime_modules only cares about map keys.
1087
- { _ , runtime_modules , sources } =
1088
- fixpoint_runtime_modules ( sources , Map . merge ( modules , runtime_modules ) )
1077
+ # We merge stale_modules (which is a map of %{module => true} that the user changed)
1078
+ # into a map of modules we compiled (which is a map of %{module => record}). This is
1079
+ # fine because we only care about the keys.
1080
+ runtime_modules = Map . merge ( modules , stale_modules )
1081
+
1082
+ # Now we do a simple pass finding anything that directly depends on the modules that
1083
+ # changed. We don't need to compute a fixpoint, because now only the directly affected
1084
+ # matter.
1085
+ { sources , runtime_modules } =
1086
+ Enum . reduce ( sources , { sources , Map . keys ( runtime_modules ) } , fn
1087
+ { source_path , source_entry } , { acc_sources , acc_modules } ->
1088
+ source ( export_references: export_refs , runtime_references: runtime_refs ) =
1089
+ source_entry
1090
+
1091
+ if has_any_key? ( runtime_modules , export_refs ) or
1092
+ has_any_key? ( runtime_modules , runtime_refs ) do
1093
+ acc_sources =
1094
+ Map . replace! ( acc_sources , source_path , source ( source_entry , runtime_warnings: [ ] ) )
1095
+
1096
+ new_modules =
1097
+ Enum . reject ( source ( source_entry , :modules ) , & Map . has_key? ( runtime_modules , & 1 ) )
1098
+
1099
+ { acc_sources , new_modules ++ acc_modules }
1100
+ else
1101
+ { acc_sources , acc_modules }
1102
+ end
1103
+ end )
1089
1104
1090
1105
runtime_paths =
1091
1106
Enum . map ( runtime_modules , & { & 1 , Path . join ( compile_path , Atom . to_string ( & 1 ) <> ".beam" ) } )
0 commit comments