[m-rev.] for review: --imports-graph option

Peter Ross pro at missioncriticalit.com
Wed Jun 13 10:38:15 AEST 2007


Hi,


===================================================================


Estimated hours taken: 3
Branches: main

Add the option --imports-graph which outputs the directed graph of
module A imports module B.

compiler/handle_options.m:
	imports_graph implies generate_dependencies
	
compiler/modules.m:
	Add code to output the import_graph.
	
compiler/options.m:
doc/user_guide.texi:
	Document the new option.


Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.301
diff -u -r1.301 handle_options.m
--- compiler/handle_options.m	12 Jun 2007 06:39:14 -0000	1.301
+++ compiler/handle_options.m	13 Jun 2007 00:34:14 -0000
@@ -752,7 +752,7 @@
         % and they don't need to be recreated when compiling to C.
         option_implies(invoked_by_mmc_make,
             generate_mmc_make_module_dependencies, bool(no), !Globals),
-      
+
         % `--transitive-intermodule-optimization' and `--make' are 
         % not compatible with each other.
         %
@@ -1575,6 +1575,11 @@
         % is only available while generating the dependencies.
         option_implies(generate_module_order, generate_dependencies,
             bool(yes), !Globals),
+
+        % The information needed for generating the imports graph
+        % is only available while generating the dependencies.
+        option_implies(imports_graph,
+            generate_dependencies, bool(yes), !Globals),
 
         % We only generate the source file mapping if the module name
         % doesn't match the file name.
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.430
diff -u -r1.430 modules.m
--- compiler/modules.m	8 Jun 2007 00:47:12 -0000	1.430
+++ compiler/modules.m	13 Jun 2007 00:34:15 -0000
@@ -4140,6 +4140,7 @@
         map.values(DepsMap, DepsList),
         deps_list_to_deps_rel(DepsList, DepsMap,
             IntDepsRel0, IntDepsRel, ImplDepsRel0, ImplDepsRel),
+        maybe_output_imports_graph(ModuleName, IntDepsRel, ImplDepsRel, !IO),
 
         %
         % Compute the trans-opt deps ordering, by doing an approximate
@@ -4182,9 +4183,6 @@
         %
         relation.tc(ImplDepsRel, IndirectOptDepsRel),
 
-        % write_relations("Rel", IntDepsRel, TransIntDepsRel,
-        %   ImplDepsRel, IndirectDepsRel, IndirectOptDepsRel),
-
         (
             Mode = output_d_file_only,
             DFilesToWrite = [ModuleDep]
@@ -4213,55 +4211,97 @@
         true
     ).
 
-%   % Output the various relations into a file which can be
-%   % processed by the dot package to draw the relations.
-%   %
-% :- pred write_relations(string::in, relation(sym_name)::in,
-%   relation(sym_name)::in, relation(sym_name)::in,
-%   relation(sym_name)::in, relation(sym_name)::in, io::di, io::uo) is det.
-%
-% write_relations(FileName, IntDepsRel, TransIntDepsRel,
-%       ImplDepsRel, IndirectDepsRel, IndirectOptDepsRel) -->
-%   io.open_output(FileName, Result),
-%   ( { Result = ok(Stream) } ->
-%       write_relation(Stream, "IntDepsRel", IntDepsRel),
-%       write_relation(Stream, "TransIntDepsRel", TransIntDepsRel),
-%       write_relation(Stream, "ImplDepsRel", ImplDepsRel),
-%       write_relation(Stream, "IndirectDepsRel", IndirectDepsRel),
-%       write_relation(Stream, "IndirectOptDepsRel",
-%           IndirectOptDepsRel)
-%   ;
-%       { error("unable to open file: " ++ FileName) }
-%   ).
-%
-% :- pred write_relation(io.output_stream::in, string::in,
-%   relation(sym_name)::in, io::di, io::uo) is det.
-%
-% write_relation(Stream, Name, Relation) -->
-%   io.write_string(Stream, "digraph " ++ Name ++ " {\n"),
-%   io.write_string(Stream, "label=\"" ++ Name ++ "\";\n"),
-%   io.write_string(Stream, "center=true;\n"),
-%   relation.traverse(Relation, write_node(Stream), write_edge(Stream)),
-%   io.write_string(Stream, "}\n").
-%
-% :- pred write_node(io.output_stream::in, sym_name::in, io::di, io::uo)
-%   is det.
-%
-% write_node(Stream, Node) -->
-%   { sym_name_to_string(Node, "__", NodeStr) },
-%   io.write_string(Stream, NodeStr),
-%   io.write_string(Stream, ";\n").
-%
-% :- pred write_edge(io.output_stream::in, sym_name::in, sym_name::in,
-%   io::di, io::uo) is det.
-%
-% write_edge(Stream, A, B) -->
-%   { sym_name_to_string(A, "__", AStr) },
-%   { sym_name_to_string(B, "__", BStr) },
-%   io.write_string(Stream, AStr),
-%   io.write_string(Stream, " -> "),
-%   io.write_string(Stream, BStr),
-%   io.write_string(Stream, ";\n").
+:- pred maybe_output_imports_graph(module_name::in,
+    relation(sym_name)::in, relation(sym_name)::in,
+    io::di, io::uo) is det.
+
+maybe_output_imports_graph(Module, IntDepsRel, ImplDepsRel, !IO) :-
+    globals.io_lookup_bool_option(imports_graph, ImportsGraph, !IO),
+    globals.io_lookup_bool_option(verbose, Verbose, !IO),
+    (
+        ImportsGraph = yes,
+        module_name_to_file_name(Module, ".imports_graph", yes, FileName, !IO),
+        maybe_write_string(Verbose, "% Creating imports graph file `", !IO),
+        maybe_write_string(Verbose, FileName, !IO),
+        maybe_write_string(Verbose, "'...", !IO),
+        io.open_output(FileName, ImpResult, !IO),
+        (
+            ImpResult = ok(ImpStream),
+
+            Rel0 = list.foldl(filter_relation,
+                relation.to_assoc_list(IntDepsRel), relation.init),
+            Rel = list.foldl(filter_relation,
+                relation.to_assoc_list(ImplDepsRel), Rel0),
+
+            write_relation(ImpStream, "imports", Rel, !IO),
+
+            io.close_output(ImpStream, !IO),
+            maybe_write_string(Verbose, " done.\n", !IO)
+        ;
+            ImpResult = error(IOError),
+            maybe_write_string(Verbose, " failed.\n", !IO),
+            maybe_flush_output(Verbose, !IO),
+            io.error_message(IOError, IOErrorMessage),
+            string.append_list(["error opening file `", FileName,
+                "' for output: ", IOErrorMessage], ImpMessage),
+            report_error(ImpMessage, !IO)
+        )
+    ;
+        ImportsGraph = no
+    ).
+
+:- func filter_relation(pair(sym_name, sym_name),
+    relation(sym_name)) = relation(sym_name).
+
+filter_relation(A - B, Relation) =
+    (
+        %
+        % Don't keep the relation if it points to a builtin-module
+        % or if the relationship is between two standard library
+        % modules
+        % XXX it would be better to change this to be only keep those
+        % relations for which the left-hand side is in the current
+        % directory.
+        %
+        (
+            any_mercury_builtin_module(B)
+        ;
+            is_std_lib_module_name(A, _),
+            is_std_lib_module_name(B, _)
+        )
+    ->
+        Relation
+    ;
+        relation.add_values(Relation, A, B)
+    ).
+
+
+:- pred write_relation(io.output_stream::in, string::in,
+    relation(sym_name)::in, io::di, io::uo) is det.
+ 
+write_relation(Stream, Name, Relation, !IO) :-
+    io.write_string(Stream, "digraph " ++ Name ++ " {\n", !IO),
+    io.write_string(Stream, "label=\"" ++ Name ++ "\";\n", !IO),
+    io.write_string(Stream, "center=true;\n", !IO),
+    relation.traverse(Relation, write_node(Stream), write_edge(Stream), !IO),
+    io.write_string(Stream, "}\n", !IO).
+ 
+:- pred write_node(io.output_stream::in, sym_name::in, io::di, io::uo) is det.
+ 
+write_node(Stream, Node, !IO) :-
+        % Names can't contain "." so use "__"
+    io.write_string(Stream, sym_name_to_string_sep(Node, "__"), !IO),
+    io.write_string(Stream, ";\n", !IO).
+
+:- pred write_edge(io.output_stream::in, sym_name::in, sym_name::in,
+    io::di, io::uo) is det.
+ 
+write_edge(Stream, A, B, !IO) :-
+        % Names can't contain "." so use "__"
+    io.write_string(Stream, sym_name_to_string_sep(A, "__"), !IO),
+    io.write_string(Stream, " -> ", !IO),
+    io.write_string(Stream, sym_name_to_string_sep(B, "__"), !IO),
+    io.write_string(Stream, ";\n", !IO).
 
 :- pred maybe_output_module_order(module_name::in, list(set(module_name))::in,
     io::di, io::uo) is det.
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.565
diff -u -r1.565 options.m
--- compiler/options.m	12 Jun 2007 06:39:16 -0000	1.565
+++ compiler/options.m	13 Jun 2007 00:34:15 -0000
@@ -214,6 +214,7 @@
     ;       auto_comments
     ;       frameopt_comments
     ;       show_dependency_graph
+    ;       imports_graph
     ;       dump_trace_counts
     ;       dump_hlds
     ;       dump_hlds_pred_id
@@ -1007,6 +1008,7 @@
     auto_comments                       -   bool(no),
     frameopt_comments                   -   bool(no),
     show_dependency_graph               -   bool(no),
+    imports_graph                       -   bool(no),
     dump_trace_counts                   -   accumulating([]),
     dump_hlds                           -   accumulating([]),
     dump_hlds_pred_id                   -   accumulating([]),
@@ -1769,6 +1771,7 @@
 long_option("auto-comments",        auto_comments).
 long_option("frameopt-comments",    frameopt_comments).
 long_option("show-dependency-graph",    show_dependency_graph).
+long_option("imports-graph",        imports_graph).
 long_option("dump-trace-counts",    dump_trace_counts).
 long_option("dump-hlds",            dump_hlds).
 long_option("hlds-dump",            dump_hlds).
@@ -3318,6 +3321,10 @@
         "\tuse the `--no-llds-optimize' option.)",
         "--show-dependency-graph",
         "\tWrite out the dependency graph to `<module>.dependency_graph'.",
+        "--imports-graph",
+        "\tWrite out the imports graph to `<module>.imports_graph'.",
+        "\tThe imports graph shows the directed graph module A",
+        "\timports module B.",
 % This option is for developers only.
 %       "--dump-trace-counts <stage number or name>",
 %       "\tIf the compiler was compiled with debugging enabled and is being",
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.525
diff -u -r1.525 user_guide.texi
--- doc/user_guide.texi	12 Jun 2007 06:39:17 -0000	1.525
+++ doc/user_guide.texi	13 Jun 2007 00:34:15 -0000
@@ -6678,6 +6678,13 @@
 @findex --show-dependency-graph
 Write out the dependency graph to @var{module}.dependency_graph.
 
+ at sp 1
+ at item --imports-graph
+ at findex --imports-graph
+Write out the imports graph to @var{module}.imports_graph.
+The imports graph shows the directed graph module A
+imports module B.
+
 @c @sp 1
 @c @item -d @var{stage}
 @c @itemx --dump-trace-counts @var{stage}

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list