# See graphviz http://www.graphviz.org/
module generate_hierarchies
-import model
+import metrics_base
+import model::model_viz
-private import metrics_base
+redef class ToolContext
+ var generate_hierarchies_phase: Phase = new GenerateHierarchyPhase(self, null)
+end
+
+private class GenerateHierarchyPhase
+ super Phase
+
+ redef fun process_mainmodule(mainmodule, given_mmodules)
+ do
+ if not toolcontext.opt_generate_hyperdoc.value and not toolcontext.opt_all.value then return
+ var model = toolcontext.modelbuilder.model
+ generate_module_hierarchy(toolcontext, given_mmodules)
+ generate_classdef_hierarchy(toolcontext, model)
+ generate_class_hierarchy(toolcontext, mainmodule)
+ end
+end
# Create a dot file representing the module hierarchy of a model.
# Importation relation is represented with arrow
# Nesting relation is represented with nested boxes
-fun generate_module_hierarchy(toolcontext: ToolContext, model: Model)
+fun generate_module_hierarchy(toolcontext: ToolContext, given_mmodules: Collection[MModule])
do
- var buf = new Buffer
- buf.append("digraph \{\n")
- buf.append("node [shape=box];\n")
- buf.append("rankdir=BT;\n")
- for mmodule in model.mmodules do
- if mmodule.direct_owner == null then
- generate_module_hierarchy_for(mmodule, buf)
- end
- end
- for mmodule in model.mmodules do
- for s in mmodule.in_importation.direct_greaters do
- buf.append("\"{mmodule}\" -> \"{s}\";\n")
- end
- end
- buf.append("\}\n")
- var f = new OFStream.open(toolcontext.output_dir.join_path("module_hierarchy.dot"))
- f.write(buf.to_s)
- f.close
-end
+ var model = given_mmodules.first.model
+ var dot = new MPackageDot(model)
-# Helper function for `generate_module_hierarchy'.
-# Create graphviz nodes for the module and recusrively for its nested modules
-private fun generate_module_hierarchy_for(mmodule: MModule, buf: Buffer)
-do
- if mmodule.in_nesting.direct_greaters.is_empty then
- buf.append("\"{mmodule.name}\";\n")
- else
- buf.append("subgraph \"cluster_{mmodule.name}\" \{label=\"\"\n")
- buf.append("\"{mmodule.name}\";\n")
- for s in mmodule.in_nesting.direct_greaters do
- generate_module_hierarchy_for(s, buf)
- end
- buf.append("\}\n")
+ # Collect requested packages
+ for m in given_mmodules do
+ var g = m.mgroup
+ if g == null then continue
+ dot.mpackages.add(g.mpackage)
end
+ var packagepath = toolcontext.output_dir.join_path("package_hierarchy.dot")
+ print "generating package_hierarchy.dot"
+ dot.write_to_file(packagepath)
+
+ var modulepath = toolcontext.output_dir.join_path("module_hierarchy.dot")
+ dot.mpackages.add_all(model.mpackages)
+ print "generating module_hierarchy.dot"
+ dot.write_to_file(modulepath)
end
# Create a dot file representing the class hierarchy of a model.
fun generate_class_hierarchy(toolcontext: ToolContext, mmodule: MModule)
do
- var buf = new Buffer
+ var buf = new FlatBuffer
buf.append("digraph \{\n")
buf.append("node [shape=box];\n")
buf.append("rankdir=BT;\n")
end
end
buf.append("\}\n")
- var f = new OFStream.open(toolcontext.output_dir.join_path("class_hierarchy.dot"))
+ var f = new FileWriter.open(toolcontext.output_dir.join_path("class_hierarchy.dot"))
f.write(buf.to_s)
f.close
end
# For a simple user of the model, the classdef hierarchy is not really usefull, it is more an internal thing.
fun generate_classdef_hierarchy(toolcontext: ToolContext, model: Model)
do
- var buf = new Buffer
+ var buf = new FlatBuffer
buf.append("digraph \{\n")
buf.append("node [shape=box];\n")
buf.append("rankdir=BT;\n")
end
end
buf.append("\}\n")
- var f = new OFStream.open(toolcontext.output_dir.join_path("classdef_hierarchy.dot"))
+ var f = new FileWriter.open(toolcontext.output_dir.join_path("classdef_hierarchy.dot"))
f.write(buf.to_s)
f.close
end