@@ -2,6 +2,7 @@ defmodule Mix.Compilers.Elixir do
22 @ moduledoc false
33
44 @ manifest_vsn 13
5+ @ checkpoint_vsn 2
56
67 import Record
78
@@ -102,7 +103,7 @@ defmodule Mix.Compilers.Elixir do
102103 { false , stale , old_lock , old_config }
103104 end
104105
105- { stale_local_mods , stale_local_exports , all_local_exports } =
106+ { stale_modules , stale_exports , all_local_exports } =
106107 stale_local_deps ( manifest , stale , modified , all_local_exports )
107108
108109 prev_paths = for source ( source: source ) <- all_sources , do: source
@@ -120,8 +121,8 @@ defmodule Mix.Compilers.Elixir do
120121 all_modules ,
121122 all_sources ,
122123 removed ,
123- stale_local_mods ,
124- Map . merge ( stale_local_exports , removed_modules ) ,
124+ Map . merge ( stale_modules , removed_modules ) ,
125+ Map . merge ( stale_exports , removed_modules ) ,
125126 dest
126127 )
127128 end
@@ -180,7 +181,7 @@ defmodule Mix.Compilers.Elixir do
180181 delete_compiler_info ( )
181182 end
182183 else
183- # We need to return ok if deps_changed? or stale_local_mods changed,
184+ # We need to return ok if deps_changed? or stale_modules changed,
184185 # even if no code was compiled, because we need to propagate the changed
185186 # status to compile.protocols. This will be the case whenever:
186187 #
@@ -193,7 +194,7 @@ defmodule Mix.Compilers.Elixir do
193194 # will only compute the diff with current protocols. In fact, there is no
194195 # need to reconsolidate if an Erlang file changes and it doesn't trigger
195196 # any other change, but the diff check should be reasonably fast anyway.
196- status = if removed != [ ] or deps_changed? or stale_local_mods != % { } , do: :ok , else: :noop
197+ status = if removed != [ ] or deps_changed? or stale_modules != % { } , do: :ok , else: :noop
197198
198199 # If nothing changed but there is one more recent mtime, bump the manifest
199200 if status != :noop or Enum . any? ( Map . values ( sources_stats ) , & ( elem ( & 1 , 0 ) > modified ) ) do
@@ -283,8 +284,8 @@ defmodule Mix.Compilers.Elixir do
283284 all_modules ,
284285 all_sources ,
285286 removed ,
286- stale_local_mods ,
287- stale_local_exports ,
287+ stale_modules ,
288+ stale_exports ,
288289 dest
289290 ) do
290291 # TODO: Use :maps.from_keys/2 on Erlang/OTP 24+
@@ -294,13 +295,17 @@ defmodule Mix.Compilers.Elixir do
294295 into: % { } ,
295296 do: { module , [ ] }
296297
297- { checkpoint_stale , checkpoint_modules } = parse_checkpoint ( manifest )
298+ { checkpoint_stale_modules , checkpoint_stale_exports , checkpoint_modules } =
299+ parse_checkpoint ( manifest )
300+
298301 modules_to_recompile = Map . merge ( checkpoint_modules , modules_to_recompile )
299- stale_local_mods = Map . merge ( checkpoint_stale , stale_local_mods )
302+ stale_modules = Map . merge ( checkpoint_stale_modules , stale_modules )
303+ stale_exports = Map . merge ( checkpoint_stale_exports , stale_exports )
300304
301- if map_size ( stale_local_mods ) != map_size ( checkpoint_stale ) or
305+ if map_size ( stale_modules ) != map_size ( checkpoint_stale_modules ) or
306+ map_size ( stale_exports ) != map_size ( checkpoint_stale_exports ) or
302307 map_size ( modules_to_recompile ) != map_size ( checkpoint_modules ) do
303- write_checkpoint ( manifest , stale_local_mods , modules_to_recompile )
308+ write_checkpoint ( manifest , stale_modules , stale_exports , modules_to_recompile )
304309 end
305310
306311 sources_stats =
@@ -332,8 +337,8 @@ defmodule Mix.Compilers.Elixir do
332337 all_modules ,
333338 all_sources ,
334339 removed ++ changed ,
335- stale_local_mods ,
336- stale_local_exports ,
340+ stale_modules ,
341+ stale_exports ,
337342 dest
338343 )
339344
@@ -654,16 +659,16 @@ defmodule Mix.Compilers.Elixir do
654659 # files that have changed. Then it recursively figures out
655660 # all the files that changed (via the module dependencies) and
656661 # return the non-changed entries and the removed sources.
657- defp update_stale_entries ( modules , _sources , [ ] , stale_mods , stale_exports , _compile_path )
658- when stale_mods == % { } and stale_exports == % { } do
662+ defp update_stale_entries ( modules , _sources , [ ] , stale_modules , stale_exports , _compile_path )
663+ when stale_modules == % { } and stale_exports == % { } do
659664 { modules , % { } , [ ] }
660665 end
661666
662- defp update_stale_entries ( modules , sources , changed , stale_mods , stale_exports , compile_path ) do
667+ defp update_stale_entries ( modules , sources , changed , stale_modules , stale_exports , compile_path ) do
663668 # TODO: Use :maps.from_keys/2 on Erlang/OTP 24+
664669 changed = Enum . into ( changed , % { } , & { & 1 , [ ] } )
665670 reducer = & remove_stale_entry ( & 1 , & 2 , sources , stale_exports , compile_path )
666- remove_stale_entries ( modules , % { } , changed , stale_mods , reducer )
671+ remove_stale_entries ( modules , % { } , changed , stale_modules , reducer )
667672 end
668673
669674 defp remove_stale_entries ( modules , exports , old_changed , old_stale , reducer ) do
@@ -720,14 +725,16 @@ defmodule Mix.Compilers.Elixir do
720725 defp stale_local_deps ( manifest , stale_modules , modified , old_exports ) do
721726 base = Path . basename ( manifest )
722727
728+ # The stale modules so far will become both stale_modules and stale_exports,
729+ # as any export from a dependency needs to be recompiled.
723730 # TODO: Use :maps.from_keys/2 on Erlang/OTP 24+
724731 stale_modules = for module <- stale_modules , do: { module , [ ] } , into: % { }
725732
726733 for % { scm: scm , opts: opts } = dep <- Mix.Dep . cached ( ) ,
727734 not scm . fetchable? ,
728735 manifest = Path . join ( [ opts [ :build ] , ".mix" , base ] ) ,
729736 Mix.Utils . last_modified ( manifest ) > modified ,
730- reduce: { stale_modules , % { } , old_exports } do
737+ reduce: { stale_modules , stale_modules , old_exports } do
731738 { modules , exports , new_exports } ->
732739 { _manifest_modules , dep_sources } = read_manifest ( manifest )
733740
@@ -1017,19 +1024,19 @@ defmodule Mix.Compilers.Elixir do
10171024 ( manifest <> ".checkpoint" ) |> File . read! ( ) |> :erlang . binary_to_term ( )
10181025 rescue
10191026 _ ->
1020- { % { } , % { } }
1027+ { % { } , % { } , % { } }
10211028 else
1022- { @ manifest_vsn , stale , recompile_modules } ->
1023- { stale , recompile_modules }
1029+ { @ checkpoint_vsn , stale_modules , stale_exports , recompile_modules } ->
1030+ { stale_modules , stale_exports , recompile_modules }
10241031
10251032 _ ->
1026- { % { } , % { } }
1033+ { % { } , % { } , % { } }
10271034 end
10281035 end
10291036
1030- defp write_checkpoint ( manifest , stale , recompile_modules ) do
1037+ defp write_checkpoint ( manifest , stale_modules , stale_exports , recompile_modules ) do
10311038 File . mkdir_p! ( Path . dirname ( manifest ) )
1032- term = { @ manifest_vsn , stale , recompile_modules }
1039+ term = { @ checkpoint_vsn , stale_modules , stale_exports , recompile_modules }
10331040 checkpoint_data = :erlang . term_to_binary ( term , [ :compressed ] )
10341041 File . write! ( manifest <> ".checkpoint" , checkpoint_data )
10351042 end
0 commit comments