nitstats: renamed in nitmetrics
[nit.git] / src / metrics / generate_hierarchies.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2012 Jean Privat <jean@pryen.org>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Create dot files for various hierarchies of a model.
18 # See graphviz http://www.graphviz.org/
19 module generate_hierarchies
20
21 import model
22
23 private import metrics_base
24
25 # Create a dot file representing the module hierarchy of a model.
26 # Importation relation is represented with arrow
27 # Nesting relation is represented with nested boxes
28 fun generate_module_hierarchy(toolcontext: ToolContext, model: Model)
29 do
30 var buf = new Buffer
31 buf.append("digraph \{\n")
32 buf.append("node [shape=box];\n")
33 buf.append("rankdir=BT;\n")
34 for mmodule in model.mmodules do
35 if mmodule.direct_owner == null then
36 generate_module_hierarchy_for(mmodule, buf)
37 end
38 end
39 for mmodule in model.mmodules do
40 for s in mmodule.in_importation.direct_greaters do
41 buf.append("\"{mmodule}\" -> \"{s}\";\n")
42 end
43 end
44 buf.append("\}\n")
45 var f = new OFStream.open(toolcontext.output_dir.join_path("module_hierarchy.dot"))
46 f.write(buf.to_s)
47 f.close
48 end
49
50 # Helper function for `generate_module_hierarchy'.
51 # Create graphviz nodes for the module and recusrively for its nested modules
52 private fun generate_module_hierarchy_for(mmodule: MModule, buf: Buffer)
53 do
54 if mmodule.in_nesting.direct_greaters.is_empty then
55 buf.append("\"{mmodule.name}\";\n")
56 else
57 buf.append("subgraph \"cluster_{mmodule.name}\" \{label=\"\"\n")
58 buf.append("\"{mmodule.name}\";\n")
59 for s in mmodule.in_nesting.direct_greaters do
60 generate_module_hierarchy_for(s, buf)
61 end
62 buf.append("\}\n")
63 end
64 end
65
66 # Create a dot file representing the class hierarchy of a model.
67 fun generate_class_hierarchy(toolcontext: ToolContext, mmodule: MModule)
68 do
69 var buf = new Buffer
70 buf.append("digraph \{\n")
71 buf.append("node [shape=box];\n")
72 buf.append("rankdir=BT;\n")
73 var hierarchy = mmodule.flatten_mclass_hierarchy
74 for mclass in hierarchy do
75 buf.append("\"{mclass}\" [label=\"{mclass}\"];\n")
76 for s in hierarchy[mclass].direct_greaters do
77 buf.append("\"{mclass}\" -> \"{s}\";\n")
78 end
79 end
80 buf.append("\}\n")
81 var f = new OFStream.open(toolcontext.output_dir.join_path("class_hierarchy.dot"))
82 f.write(buf.to_s)
83 f.close
84 end
85
86 # Create a dot file representing the classdef hierarchy of a model.
87 # For a simple user of the model, the classdef hierarchy is not really usefull, it is more an internal thing.
88 fun generate_classdef_hierarchy(toolcontext: ToolContext, model: Model)
89 do
90 var buf = new Buffer
91 buf.append("digraph \{\n")
92 buf.append("node [shape=box];\n")
93 buf.append("rankdir=BT;\n")
94 for mmodule in model.mmodules do
95 for mclassdef in mmodule.mclassdefs do
96 buf.append("\"{mclassdef} {mclassdef.bound_mtype}\" [label=\"{mclassdef.mmodule}\\n{mclassdef.bound_mtype}\"];\n")
97 for s in mclassdef.in_hierarchy.direct_greaters do
98 buf.append("\"{mclassdef} {mclassdef.bound_mtype}\" -> \"{s} {s.bound_mtype}\";\n")
99 end
100 end
101 end
102 buf.append("\}\n")
103 var f = new OFStream.open(toolcontext.output_dir.join_path("classdef_hierarchy.dot"))
104 f.write(buf.to_s)
105 f.close
106 end