[m-rev.] for review: Use source file map to exclude default source file names.

Peter Wang novalazy at gmail.com
Tue Jan 14 13:31:35 AEDT 2020


If a file name is listed in the source file map then
do not use that file name as the source file for any other module.
Fixes Mantis bug #489.

compiler/source_file_map.m:
    Make the source_file_map a bimap.

    Make lookup_module_source_file return `no' if there is no source
    file for the requested module, because the default file name for
    that module has been mapped to another module.

compiler/file_names.m:
    Make module_name_to_file_name_general return a dummy file name
    (that is not supposed to exist) when lookup_module_source_file
    returns `no'.

compiler/globals.m:
compiler/introduce_parallelism.m:
compiler/xml_documentation.m:
    Conform to changes.

diff --git a/compiler/file_names.m b/compiler/file_names.m
index 3f8141243..6541a7738 100644
--- a/compiler/file_names.m
+++ b/compiler/file_names.m
@@ -39,7 +39,7 @@
 
 %---------------------------------------------------------------------------%
 %
-% XXX This interface should be improved in two ways.
+% XXX This interface should be improved in three ways.
 %
 % - First, the argument order
 %
@@ -68,6 +68,10 @@
 %   have a version of this predicate for each type, one with and one
 %   without an I/O state pair.
 %
+% - Third, calls which search for a source file for reading (that may not
+%   exist) should be separated from calls that construct a file name
+%   to write the file.
+%
 % XXX Given the wide variety of uses cases that choose_file_name has
 % to handle for its callers, the only way to ensure that a diff implementing
 % the above ideas handles *all* of those uses cases correctly is probably to
@@ -224,6 +228,7 @@
 :- import_module library.
 :- import_module list.
 :- import_module map.
+:- import_module maybe.
 :- import_module require.
 :- import_module string.
 
@@ -284,7 +289,18 @@ module_name_to_file_name_general(Globals, Search, MkDir, Ext,
         Ext = ".m"
     then
         % Look up the module in the module->file mapping.
-        source_file_map.lookup_module_source_file(ModuleName, FileName, !IO)
+        source_file_map.lookup_module_source_file(ModuleName, MaybeFileName,
+            !IO),
+        (
+            MaybeFileName = yes(FileName)
+        ;
+            MaybeFileName = no,
+            % XXX We should propagate the fact that no source file is available
+            % for the given module back to the caller. That can be left for a
+            % more comprehensive improvement of the module_to_*file_name
+            % interface.
+            FileName = "Mercury/.missing." ++ default_source_file(ModuleName)
+        )
     else
         ( if
             % Java files need to be placed into a package subdirectory
diff --git a/compiler/globals.m b/compiler/globals.m
index b26d9fbc2..bf1c0e70b 100644
--- a/compiler/globals.m
+++ b/compiler/globals.m
@@ -28,6 +28,7 @@
 :- import_module mdbcomp.feedback.
 :- import_module mdbcomp.sym_name. % for module_name
 
+:- import_module bimap.
 :- import_module bool.
 :- import_module getopt_io.
 :- import_module io.
@@ -219,7 +220,7 @@
 
     % Map from module name to file name.
     %
-:- type source_file_map == map(module_name, string).
+:- type source_file_map == bimap(module_name, string).
 
 :- type line_number_range
     --->    line_number_range(
diff --git a/compiler/introduce_parallelism.m b/compiler/introduce_parallelism.m
index 3f8b6ce55..823337f21 100644
--- a/compiler/introduce_parallelism.m
+++ b/compiler/introduce_parallelism.m
@@ -62,6 +62,7 @@
 :- import_module transform_hlds.implicit_parallelism.push_goals_together.
 
 :- import_module assoc_list.
+:- import_module bimap.
 :- import_module list.
 :- import_module map.
 :- import_module maybe.
@@ -125,7 +126,7 @@ do_apply_implicit_parallelism_transformation(SourceFileMap, Specs,
             module_info_set_has_parallel_conj(!ModuleInfo)
         )
     else
-        map.lookup(SourceFileMap, ModuleName, ModuleFilename),
+        bimap.lookup(SourceFileMap, ModuleName, ModuleFilename),
         Context = context(ModuleFilename, 1),
         Pieces = [words("Implicit parallelism was requested but the"),
             words("feedback file does not the candidate parallel"),
diff --git a/compiler/source_file_map.m b/compiler/source_file_map.m
index 8ac588aa2..22a8c9207 100644
--- a/compiler/source_file_map.m
+++ b/compiler/source_file_map.m
@@ -2,6 +2,7 @@
 % vim: ft=mercury ts=4 sw=4 et
 %-----------------------------------------------------------------------------%
 % Copyright (C) 2002-2009, 2011 The University of Melbourne.
+% Copyright (C) 2014-2015, 2019-2020 The Mercury team.
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %-----------------------------------------------------------------------------%
@@ -29,12 +30,17 @@
 :- import_module bool.
 :- import_module io.
 :- import_module list.
+:- import_module maybe.
 
 %-----------------------------------------------------------------------------%
 
-    % lookup_module_source_file(ModuleName, FileName, !IO)
+    % lookup_module_source_file(ModuleName, MaybeFileName, !IO)
+    % Return `yes(FileName)' if FileName is the source file for ModuleName,
+    % either through the source file map, or by default. Return `no' if no
+    % source file is available for ModuleName because the default file name
+    % is mapped to another module.
     %
-:- pred lookup_module_source_file(module_name::in, file_name::out,
+:- pred lookup_module_source_file(module_name::in, maybe(file_name)::out,
     io::di, io::uo) is det.
 
     % Return `yes' if there is a valid Mercury.modules file.
@@ -59,25 +65,29 @@
 :- import_module parse_tree.find_module.
 :- import_module parse_tree.prog_out.
 
+:- import_module bimap.
 :- import_module char.
 :- import_module dir.
-:- import_module map.
-:- import_module maybe.
 :- import_module string.
 
 %-----------------------------------------------------------------------------%
 
-lookup_module_source_file(ModuleName, FileName, !IO) :-
+lookup_module_source_file(ModuleName, MaybeFileName, !IO) :-
     get_source_file_map(SourceFileMap, !IO),
-    ( if map.search(SourceFileMap, ModuleName, FileName0) then
-        FileName = FileName0
+    ( if bimap.search(SourceFileMap, ModuleName, FileName) then
+        MaybeFileName = yes(FileName)
     else
-        FileName = default_source_file(ModuleName)
+        DefaultFileName = default_source_file(ModuleName),
+        ( if bimap.reverse_search(SourceFileMap, _, DefaultFileName) then
+            MaybeFileName = no
+        else
+            MaybeFileName = yes(DefaultFileName)
+        )
     ).
 
 have_source_file_map(HaveMap, !IO) :-
     get_source_file_map(SourceFileMap, !IO),
-    ( if map.is_empty(SourceFileMap) then
+    ( if bimap.is_empty(SourceFileMap) then
         HaveMap = no
     else
         HaveMap = yes
@@ -101,13 +111,13 @@ get_source_file_map(SourceFileMap, !IO) :-
         (
             OpenRes = ok(Stream),
             io.set_input_stream(Stream, OldStream, !IO),
-            read_source_file_map([], map.init, SourceFileMap, !IO),
+            read_source_file_map([], bimap.init, SourceFileMap, !IO),
             io.set_input_stream(OldStream, _, !IO),
             io.close_input(Stream, !IO)
         ;
             OpenRes = error(_),
             % If the file doesn't exist, then the mapping is empty.
-            SourceFileMap = map.init
+            SourceFileMap = bimap.init
         ),
         globals.io_set_maybe_source_file_map(yes(SourceFileMap), !IO)
     ).
@@ -125,7 +135,7 @@ read_source_file_map(ModuleChars, !Map, !IO) :-
         (
             FileNameCharsResult = ok(FileNameChars),
             string.from_rev_char_list(FileNameChars, FileName),
-            map.set(ModuleName, FileName, !Map),
+            bimap.set(ModuleName, FileName, !Map),
             read_source_file_map(ModuleChars, !Map, !IO)
         ;
             FileNameCharsResult = eof,
@@ -183,7 +193,7 @@ write_source_file_map(Globals, FileNames, !IO) :-
     (
         OpenRes = ok(Stream),
         list.foldl2(write_source_file_map_2(Globals, Stream), FileNames,
-            map.init, _, !IO),
+            bimap.init, _, !IO),
         io.close_output(Stream, !IO)
     ;
         OpenRes = error(Error),
@@ -196,7 +206,7 @@ write_source_file_map(Globals, FileNames, !IO) :-
 
 :- pred write_source_file_map_2(globals::in, io.output_stream::in,
     file_name::in,
-    map(module_name, file_name)::in, map(module_name, file_name)::out,
+    bimap(module_name, file_name)::in, bimap(module_name, file_name)::out,
     io::di, io::uo) is det.
 
 write_source_file_map_2(Globals, MapStream, FileName,
@@ -205,7 +215,7 @@ write_source_file_map_2(Globals, MapStream, FileName,
     (
         MaybeModuleName = yes(ModuleName),
         ( if
-            map.search(SeenModules0, ModuleName, PrevFileName),
+            bimap.search(SeenModules0, ModuleName, PrevFileName),
             PrevFileName \= FileName
         then
             io.write_string("mercury_compile: module `", !IO),
@@ -218,7 +228,7 @@ write_source_file_map_2(Globals, MapStream, FileName,
             io.set_exit_status(1, !IO),
             SeenModules = SeenModules0
         else
-            map.set(ModuleName, FileName, SeenModules0, SeenModules)
+            bimap.set(ModuleName, FileName, SeenModules0, SeenModules)
         ),
         ( if string.remove_suffix(FileName, ".m", PartialFileName0) then
             PartialFileName = PartialFileName0
diff --git a/compiler/xml_documentation.m b/compiler/xml_documentation.m
index e1e19bb55..3ab951aa2 100644
--- a/compiler/xml_documentation.m
+++ b/compiler/xml_documentation.m
@@ -90,29 +90,35 @@ xml_documentation(ModuleInfo, !IO) :-
     module_name_to_file_name(Globals, do_create_dirs, ".xml",
         ModuleName, FileName, !IO),
 
-    lookup_module_source_file(ModuleName, SrcFileName, !IO),
-    io.open_input(SrcFileName, SrcResult, !IO),
+    lookup_module_source_file(ModuleName, MaybeSrcFileName, !IO),
     (
-        SrcResult = ok(SrcStream),
-        build_comments(SrcStream, comments(map.init), Comments, !IO),
+        MaybeSrcFileName = yes(SrcFileName),
+        io.open_input(SrcFileName, SrcResult, !IO),
+        (
+            SrcResult = ok(SrcStream),
+            build_comments(SrcStream, comments(map.init), Comments, !IO),
 
-        % XXX We should find the ":- module " declaration
-        % and get the comment from there.
-        ModuleComment = get_comment_forwards(Comments, 1),
+            % XXX We should find the ":- module " declaration
+            % and get the comment from there.
+            ModuleComment = get_comment_forwards(Comments, 1),
 
-        io.open_output(FileName, OpenResult, !IO),
-        (
-            OpenResult = ok(Stream),
-            MIXmlDoc = module_info_xml_doc(Comments, ModuleComment,
-                ModuleInfo),
-            write_xml_doc(Stream, MIXmlDoc, !IO)
+            io.open_output(FileName, OpenResult, !IO),
+            (
+                OpenResult = ok(Stream),
+                MIXmlDoc = module_info_xml_doc(Comments, ModuleComment,
+                    ModuleInfo),
+                write_xml_doc(Stream, MIXmlDoc, !IO)
+            ;
+                OpenResult = error(Err),
+                unable_to_open_file(FileName, Err, !IO)
+            )
         ;
-            OpenResult = error(Err),
-            unable_to_open_file(FileName, Err, !IO)
+            SrcResult = error(SrcErr),
+            unable_to_open_file(SrcFileName, SrcErr, !IO)
         )
     ;
-        SrcResult = error(SrcErr),
-        unable_to_open_file(SrcFileName, SrcErr, !IO)
+        MaybeSrcFileName = no,
+        unexpected($pred, "no source file name")
     ).
 
 %-----------------------------------------------------------------------------%
-- 
2.24.1



More information about the reviews mailing list