1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2012 Jean Privat <jean@pryen.org>
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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.
21 private import rapid_type_analysis
22 private import metrics_base
23 import mmodules_metrics
24 import mclasses_metrics
27 redef class ToolContext
28 var rta_metrics_phase
= new RTAMetricsPhase(self, null)
31 private class RTAMetricsPhase
33 redef fun process_mainmodule
(mainmodule
)
35 if not toolcontext
.opt_rta
.value
and not toolcontext
.opt_all
.value
then return
36 var csv
= toolcontext
.opt_csv
.value
37 var out
= "{toolcontext.opt_dir.value or else "metrics"}/rta"
40 print toolcontext
.format_h1
("\n# RTA metrics")
42 print toolcontext
.format_h2
("\n ## Live instances by mainmodules")
43 var mmetrics
= new MetricSet
44 mmetrics
.register
(new MNLC(toolcontext
.modelbuilder
))
45 mmetrics
.register
(new MNLT(toolcontext
.modelbuilder
))
46 mmetrics
.register
(new MNCT(toolcontext
.modelbuilder
))
47 mmetrics
.register
(new MNLI(toolcontext
.modelbuilder
))
48 mmetrics
.register
(new MNLM(toolcontext
.modelbuilder
))
49 mmetrics
.register
(new MNLMD(toolcontext
.modelbuilder
))
50 mmetrics
.register
(new MNLDD(toolcontext
.modelbuilder
))
51 mmetrics
.collect
(new HashSet[MModule].from
([mainmodule
]))
52 mmetrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
53 if csv
then mmetrics
.to_csv
.save
("{out}/{mainmodule}.csv")
55 var mtypes
= new HashSet[MType]
56 var analysis
= new RapidTypeAnalysis(toolcontext
.modelbuilder
, mainmodule
)
58 mtypes
.add_all
(analysis
.live_types
)
59 mtypes
.add_all
(analysis
.live_cast_types
)
61 print toolcontext
.format_h2
("\n ## Total live instances by mclasses")
62 var cmetrics
= new MetricSet
63 cmetrics
.register
(analysis
.cnli
)
64 cmetrics
.register
(analysis
.cnlc
)
65 cmetrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
66 if csv
then cmetrics
.to_csv
.save
("{out}/mclasses.csv")
68 print toolcontext
.format_h2
("\n ## Total live instances by mtypes")
69 var tmetrics
= new MetricSet
70 tmetrics
.register
(analysis
.tnli
)
71 tmetrics
.register
(analysis
.tnlc
)
72 tmetrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
73 if csv
then tmetrics
.to_csv
.save
("{out}/mtypes.csv")
75 print toolcontext
.format_h2
("\n ## MType complexity")
76 var gmetrics
= new MetricSet
77 gmetrics
.register
(new TAGS)
78 gmetrics
.register
(new TDGS)
79 gmetrics
.collect
(mtypes
)
80 gmetrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
81 if csv
then gmetrics
.to_csv
.save
("{out}/complexity.csv")
87 # MModule Metric: Number of Live Types
91 redef fun name
do return "mnli"
92 redef fun desc
do return "number of live instances in a mmodule"
94 var modelbuilder
: ModelBuilder
95 init(modelbuilder
: ModelBuilder) do self.modelbuilder
= modelbuilder
97 redef fun collect
(mainmodules
) do
98 for mainmodule
in mainmodules
do
99 var analysis
= new RapidTypeAnalysis(modelbuilder
, mainmodule
)
100 analysis
.run_analysis
101 values
[mainmodule
] = analysis
.tnli
.sum
106 # MModule Metric: Number of Live Types
110 redef fun name
do return "mnlt"
111 redef fun desc
do return "number of live mtypes in a mmodule"
113 var modelbuilder
: ModelBuilder
114 init(modelbuilder
: ModelBuilder) do self.modelbuilder
= modelbuilder
116 redef fun collect
(mainmodules
) do
117 for mainmodule
in mainmodules
do
118 var analysis
= new RapidTypeAnalysis(modelbuilder
, mainmodule
)
119 analysis
.run_analysis
120 values
[mainmodule
] = analysis
.live_types
.length
125 # MModule Metric: Number of Live Cast Types
129 redef fun name
do return "mnct"
130 redef fun desc
do return "number of live cast mtypes in a mmodule"
132 var modelbuilder
: ModelBuilder
133 init(modelbuilder
: ModelBuilder) do self.modelbuilder
= modelbuilder
135 redef fun collect
(mainmodules
) do
136 for mainmodule
in mainmodules
do
137 var analysis
= new RapidTypeAnalysis(modelbuilder
, mainmodule
)
138 analysis
.run_analysis
139 values
[mainmodule
] = analysis
.live_cast_types
.length
144 # MModule Metric: Number of Live Classes
148 redef fun name
do return "mnlc"
149 redef fun desc
do return "number of live mclasses in a mmodule"
151 var modelbuilder
: ModelBuilder
152 init(modelbuilder
: ModelBuilder) do self.modelbuilder
= modelbuilder
154 redef fun collect
(mainmodules
) do
155 for mainmodule
in mainmodules
do
156 var live
= new HashSet[MClass]
157 var analysis
= new RapidTypeAnalysis(modelbuilder
, mainmodule
)
158 analysis
.run_analysis
159 for mtype
in analysis
.live_types
do
160 live
.add
(mtype
.mclass
)
162 values
[mainmodule
] = live
.length
167 # MModule Metric: Number of Live Methods
171 redef fun name
do return "mnlm"
172 redef fun desc
do return "number of live methods in a mmodule"
174 var modelbuilder
: ModelBuilder
175 init(modelbuilder
: ModelBuilder) do self.modelbuilder
= modelbuilder
177 redef fun collect
(mainmodules
) do
178 for mainmodule
in mainmodules
do
179 var analysis
= new RapidTypeAnalysis(modelbuilder
, mainmodule
)
180 analysis
.run_analysis
181 values
[mainmodule
] = analysis
.live_methods
.length
186 # MModule Metric: Number of Live MethodDefs
190 redef fun name
do return "mnlmd"
191 redef fun desc
do return "number of live method definitions in a mmodule"
193 var modelbuilder
: ModelBuilder
194 init(modelbuilder
: ModelBuilder) do self.modelbuilder
= modelbuilder
196 redef fun collect
(mainmodules
) do
197 for mainmodule
in mainmodules
do
198 var analysis
= new RapidTypeAnalysis(modelbuilder
, mainmodule
)
199 analysis
.run_analysis
200 values
[mainmodule
] = analysis
.live_methoddefs
.length
205 # MModule Metric: Number of Dead MethodDefs
209 redef fun name
do return "mnldd"
210 redef fun desc
do return "number of dead method definitions in a mmodule"
212 var modelbuilder
: ModelBuilder
213 init(modelbuilder
: ModelBuilder) do self.modelbuilder
= modelbuilder
215 redef fun collect
(mainmodules
) do
216 for mainmodule
in mainmodules
do
218 var analysis
= new RapidTypeAnalysis(modelbuilder
, mainmodule
)
219 analysis
.run_analysis
220 for mmethod
in analysis
.live_methods
do
221 for mdef
in mmethod
.mpropdefs
do
222 if analysis
.live_methoddefs
.has
(mdef
) or mdef
.is_abstract
then continue
226 values
[mainmodule
] = dead
233 # Class Metric: Number of Live Instances
235 # count all the `new` made on each mclass
239 redef fun name
do return "cnli"
240 redef fun desc
do return "number of live instances for a mclass"
242 redef fun collect
(mclasses
) do end
245 # Class Metric: Number of Live Cast
247 # count all the cast made on each mclass type
251 redef fun name
do return "cnlc"
252 redef fun desc
do return "number of live cast for a mclass type"
254 redef fun collect
(mclasses
) do end
259 # A metric about MType
260 interface MTypeMetric
262 redef type ELM: MType
265 # Type Metric: Number of Live Instances
267 # count all the `new` made on each types
271 redef fun name
do return "tnli"
272 redef fun desc
do return "number of live instances for a mtype"
274 redef fun collect
(mtypes
) do end
277 # Type Metric: Number of Live Cast
279 # count all the cast made to each types
283 redef fun name
do return "tnlc"
284 redef fun desc
do return "number of live casts to a mtype"
286 redef fun collect
(mtypes
) do end
289 # Type Metric: Arity of Generic Signature
292 # tags(Map[X, Y]) = 2
296 redef fun name
do return "tags"
297 redef fun desc
do return "arity of generic signature"
299 redef fun collect
(mtypes
) do
300 for mtype
in mtypes
do
301 if mtype
isa MGenericType then
302 values
[mtype
] = mtype
.arguments
.length
310 # Type Metric: Depth of Generic Signature
313 # tdgs(Map[X, List[Y]]) = 2
317 redef fun name
do return "tdos"
318 redef fun desc
do return "depth of generic signature"
320 redef fun collect
(mtypes
) do
321 for mtype
in mtypes
do
322 values
[mtype
] = mtype
.signature_depth
329 redef class RapidTypeAnalysis
335 redef fun add_new
(recv
, mtype
) do
337 tnli
.values
.inc
(mtype
)
338 cnli
.values
.inc
(mtype
.mclass
)
341 redef fun add_cast
(mtype
) do
343 tnlc
.values
.inc
(mtype
)
345 if mtype
isa MNullableType then mtype
= mtype
.mtype
346 if mtype
isa MClassType then
347 cnlc
.values
.inc
(mtype
.mclass
)
355 private fun signature_depth
: Int do
357 if mtype
isa MNullableType then mtype
= mtype
.mtype
358 if not mtype
isa MGenericType then return 0
361 for ft
in mtype
.arguments
do
362 var ftd
= ft
.signature_depth
363 if ftd
> depth
then depth
= ftd