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),
read_module_dependencies_3(Globals, SearchDirs, ModuleName,
ModuleDir, Term, Result, !Info, !IO)
ModuleDir, ModuleDepFile, Term, Result, !Info, !IO)
;
TermResult = 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,
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.
read_module_dependencies_3(Globals, SearchDirs, ModuleName, ModuleDir,
Term, Result, !Info, !IO) :-
ModuleDepFile, Term, Result, !Info, !IO) :-
(
atom_term(Term, "module", ModuleArgs),
ModuleArgs = [
@@ -549,24 +549,43 @@ read_module_dependencies_3(Globals, SearchDirs, ModuleName, ModuleDir,
ContainsForeignExport,
Items, Specs, Errors, MaybeTimestamps, HasMain, ModuleDir),
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")
% Discard the module dependencies if the module is a local module
% but the source file no longer exists.
( ModuleDir = dir.this_directory ->
check_regular_file_exists(SourceFileName, SourceFileExists, !IO),
(
SourceFileExists = ok
;
SourceFileExists = error(_),
io.remove_file(ModuleDepFile, _, !IO)
)
;
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")
@@ -657,6 +676,37 @@ some_bad_module_dependency(Info, ModuleNames) :-
list.member(ModuleName, ModuleNames),
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.