[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