src: extract modelize_class.nit from modelbuiler.nit
[nit.git] / src / metrics / static_types_metrics.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 # Metrics on the usage of explicit static types.
18 module static_types_metrics
19
20 private import metrics_base
21 import modelbuilder
22 import modelize_class
23
24 # The job of this visitor is to resolve all types found
25 private class ATypeCounterVisitor
26 super Visitor
27 var modelbuilder: ModelBuilder
28 var nclassdef: AClassdef
29
30 var typecount: Counter[MType]
31
32 # Get a new visitor on a classef to add type count in `typecount'.
33 init(modelbuilder: ModelBuilder, nclassdef: AClassdef, typecount: Counter[MType])
34 do
35 self.modelbuilder = modelbuilder
36 self.nclassdef = nclassdef
37 self.typecount = typecount
38 end
39
40 redef fun visit(n)
41 do
42 if n isa AType then
43 var mtype = modelbuilder.resolve_mtype(self.nclassdef, n)
44 if mtype != null then
45 self.typecount.inc(mtype)
46 end
47 end
48 n.visit_all(self)
49 end
50 end
51
52 # Visit the AST and print metrics on the usage of explicit static types.
53 fun compute_static_types_metrics(modelbuilder: ModelBuilder)
54 do
55 # Count each occurence of a specific static type
56 var typecount = new Counter[MType]
57
58 # Visit all the source code to collect data
59 for nmodule in modelbuilder.nmodules do
60 for nclassdef in nmodule.n_classdefs do
61 var visitor = new ATypeCounterVisitor(modelbuilder, nclassdef, typecount)
62 visitor.enter_visit(nclassdef)
63 end
64 end
65
66 # Display data
67 print "--- Metrics of the explitic static types ---"
68 print "Total number of explicit static types: {typecount.total}"
69 if typecount.total == 0 then return
70
71 # types sorted by usage
72 var types = typecount.sort
73
74 # Display most used types (ie the last of `types')
75 print "Most used types: "
76 var min = 10
77 if types.length < min then min = types.length
78 for i in [0..min[ do
79 var t = types[types.length-i-1]
80 print " {t}: {typecount[t]}"
81 end
82
83 # Compute the distribution of type usage
84 print "Distribution of type usage:"
85 var count = 0
86 var sum = 0
87 var limit = 1
88 for t in types do
89 if typecount[t] > limit then
90 print " <={limit}: {count} ({div(count*100,types.length)}% of types; {div(sum*100,typecount.total)}% of usage)"
91 count = 0
92 sum = 0
93 while typecount[t] > limit do limit = limit * 2
94 end
95 count += 1
96 sum += typecount[t]
97 end
98 print " <={limit}: {count} ({div(count*100,types.length)}% of types; {div(sum*100,typecount.total)}% of usage)"
99 end