Make mmc --make account for source files disappearing.

mmc --make prints a grave error message when the source file of a module
can no longer be found:

** Module `foo' is imported or included by module `bar'.
** dependencies for `Mercury/int3s/foo.int3' do not exist: foo.m
** This indicates a bug in `mmc --make'.

compiler/make.module_dep_file.m:
	Check that the source file of a local `.module_dep' file still
	exists.  If it doesn't, delete the `.module_dep' file and ignore
	the information it contains.
This commit is contained in:
Peter Wang
2014-04-02 11:53:55 +11:00
parent a8619a4b50
commit a0a7b64d16

View File

@@ -456,7 +456,7 @@ read_module_dependencies_2(Globals, RebuildModuleDeps, SearchDirs, ModuleName,
( (
TermResult = term(_, Term), TermResult = term(_, Term),
read_module_dependencies_3(Globals, SearchDirs, ModuleName, read_module_dependencies_3(Globals, SearchDirs, ModuleName,
ModuleDir, Term, Result, !Info, !IO) ModuleDir, ModuleDepFile, Term, Result, !Info, !IO)
; ;
TermResult = eof, TermResult = eof,
Result = error("unexpected eof") Result = error("unexpected eof")
@@ -479,11 +479,11 @@ read_module_dependencies_2(Globals, RebuildModuleDeps, SearchDirs, ModuleName,
). ).
:- pred read_module_dependencies_3(globals::in, list(dir_name)::in, :- pred read_module_dependencies_3(globals::in, list(dir_name)::in,
module_name::in, dir_name::in, term::in, maybe_error::out, module_name::in, dir_name::in, file_name::in, term::in, maybe_error::out,
make_info::in, make_info::out, io::di, io::uo) is det. make_info::in, make_info::out, io::di, io::uo) is det.
read_module_dependencies_3(Globals, SearchDirs, ModuleName, ModuleDir, read_module_dependencies_3(Globals, SearchDirs, ModuleName, ModuleDir,
Term, Result, !Info, !IO) :- ModuleDepFile, Term, Result, !Info, !IO) :-
( (
atom_term(Term, "module", ModuleArgs), atom_term(Term, "module", ModuleArgs),
ModuleArgs = [ ModuleArgs = [
@@ -549,24 +549,43 @@ read_module_dependencies_3(Globals, SearchDirs, ModuleName, ModuleDir,
ContainsForeignExport, ContainsForeignExport,
Items, Specs, Errors, MaybeTimestamps, HasMain, ModuleDir), Items, Specs, Errors, MaybeTimestamps, HasMain, ModuleDir),
ModuleDepMap0 = !.Info ^ module_dependencies, % Discard the module dependencies if the module is a local module
% XXX Could this be map.det_insert? % but the source file no longer exists.
map.set(ModuleName, yes(Imports), ModuleDepMap0, ModuleDepMap), ( ModuleDir = dir.this_directory ->
!Info ^ module_dependencies := ModuleDepMap, check_regular_file_exists(SourceFileName, SourceFileExists, !IO),
(
% Read the dependencies for the nested children. If something SourceFileExists = ok
% goes wrong (for example one of the files was removed), the ;
% dependencies for all modules in the source file will be remade SourceFileExists = error(_),
% (make_module_dependencies expects to be given the top-level io.remove_file(ModuleDepFile, _, !IO)
% module in the source file). )
list.foldl2(
read_module_dependencies_2(Globals, do_not_rebuild_module_deps,
SearchDirs),
NestedChildren, !Info, !IO),
( some_bad_module_dependency(!.Info, NestedChildren) ->
Result = error("error in nested sub-modules")
; ;
Result = ok SourceFileExists = ok
),
(
SourceFileExists = ok,
ModuleDepMap0 = !.Info ^ module_dependencies,
% XXX Could this be map.det_insert?
map.set(ModuleName, yes(Imports), ModuleDepMap0, ModuleDepMap),
!Info ^ module_dependencies := ModuleDepMap,
% Read the dependencies for the nested children. If something
% goes wrong (for example one of the files was removed), the
% dependencies for all modules in the source file will be remade
% (make_module_dependencies expects to be given the top-level
% module in the source file).
list.foldl2(
read_module_dependencies_2(Globals, do_not_rebuild_module_deps,
SearchDirs),
NestedChildren, !Info, !IO),
( some_bad_module_dependency(!.Info, NestedChildren) ->
Result = error("error in nested sub-modules")
;
Result = ok
)
;
SourceFileExists = error(Error),
Result = error(Error)
) )
; ;
Result = error("failed to parse term") Result = error("failed to parse term")
@@ -657,6 +676,37 @@ some_bad_module_dependency(Info, ModuleNames) :-
list.member(ModuleName, ModuleNames), list.member(ModuleName, ModuleNames),
map.search(Info ^ module_dependencies, ModuleName, no). map.search(Info ^ module_dependencies, ModuleName, no).
:- pred check_regular_file_exists(file_name::in, maybe_error::out,
io::di, io::uo) is det.
check_regular_file_exists(FileName, FileExists, !IO) :-
FollowSymLinks = yes,
io.file_type(FollowSymLinks, FileName, ResFileType, !IO),
(
ResFileType = ok(FileType),
(
( FileType = regular_file
; FileType = unknown
),
FileExists = ok
;
( FileType = directory
; FileType = symbolic_link
; FileType = named_pipe
; FileType = socket
; FileType = character_device
; FileType = block_device
; FileType = message_queue
; FileType = semaphore
; FileType = shared_memory
),
FileExists = error(FileName ++ ": not a regular file")
)
;
ResFileType = error(Error),
FileExists = error(FileName ++ ": " ++ io.error_message(Error))
).
%-----------------------------------------------------------------------------% %-----------------------------------------------------------------------------%
% Something went wrong reading the dependencies, so just rebuild them. % Something went wrong reading the dependencies, so just rebuild them.