# Metrics from RTA
module rta_metrics
-import modelbuilder
private import rapid_type_analysis
-private import metrics_base
+import metrics_base
import mmodules_metrics
import mclasses_metrics
-import frontend
redef class ToolContext
- var rta_metrics_phase = new RTAMetricsPhase(self, null)
+
+ # RTA related metrics phase
+ var rta_metrics_phase: Phase = new RTAMetricsPhase(self, null)
end
private class RTAMetricsPhase
super Phase
- redef fun process_mainmodule(mainmodule)
+ redef fun process_mainmodule(mainmodule, given_mmodules)
do
if not toolcontext.opt_rta.value and not toolcontext.opt_all.value then return
var csv = toolcontext.opt_csv.value
var out = "{toolcontext.opt_dir.value or else "metrics"}/rta"
out.mkdir
+ var model = toolcontext.modelbuilder.model
+ var model_view = model.protected_view
+
print toolcontext.format_h1("\n# RTA metrics")
print toolcontext.format_h2("\n ## Live instances by mainmodules")
var mmetrics = new MetricSet
- mmetrics.register(new MNLC(toolcontext.modelbuilder))
- mmetrics.register(new MNLT(toolcontext.modelbuilder))
- mmetrics.register(new MNCT(toolcontext.modelbuilder))
- mmetrics.register(new MNLI(toolcontext.modelbuilder))
- mmetrics.register(new MNLM(toolcontext.modelbuilder))
- mmetrics.register(new MNLMD(toolcontext.modelbuilder))
- mmetrics.register(new MNLDD(toolcontext.modelbuilder))
+ mmetrics.register(new MNLC(mainmodule, model_view, toolcontext.modelbuilder))
+ mmetrics.register(new MNLT(mainmodule, model_view, toolcontext.modelbuilder))
+ mmetrics.register(new MNCT(mainmodule, model_view, toolcontext.modelbuilder))
+ mmetrics.register(new MNLI(mainmodule, model_view, toolcontext.modelbuilder))
+ mmetrics.register(new MNLM(mainmodule, model_view, toolcontext.modelbuilder))
+ mmetrics.register(new MNLMD(mainmodule, model_view, toolcontext.modelbuilder))
+ mmetrics.register(new MNLDD(mainmodule, model_view, toolcontext.modelbuilder))
mmetrics.collect(new HashSet[MModule].from([mainmodule]))
mmetrics.to_console(1, not toolcontext.opt_nocolors.value)
- if csv then mmetrics.to_csv.save("{out}/{mainmodule}.csv")
+ if csv then mmetrics.to_csv.write_to_file("{out}/{mainmodule}.csv")
var mtypes = new HashSet[MType]
var analysis = new RapidTypeAnalysis(toolcontext.modelbuilder, mainmodule)
cmetrics.register(analysis.cnli)
cmetrics.register(analysis.cnlc)
cmetrics.to_console(1, not toolcontext.opt_nocolors.value)
- if csv then cmetrics.to_csv.save("{out}/mclasses.csv")
+ if csv then cmetrics.to_csv.write_to_file("{out}/mclasses.csv")
print toolcontext.format_h2("\n ## Total live instances by mtypes")
var tmetrics = new MetricSet
tmetrics.register(analysis.tnli)
tmetrics.register(analysis.tnlc)
tmetrics.to_console(1, not toolcontext.opt_nocolors.value)
- if csv then tmetrics.to_csv.save("{out}/mtypes.csv")
+ if csv then tmetrics.to_csv.write_to_file("{out}/mtypes.csv")
print toolcontext.format_h2("\n ## MType complexity")
var gmetrics = new MetricSet
gmetrics.register(new TDGS)
gmetrics.collect(mtypes)
gmetrics.to_console(1, not toolcontext.opt_nocolors.value)
- if csv then gmetrics.to_csv.save("{out}/complexity.csv")
+ if csv then gmetrics.to_csv.write_to_file("{out}/complexity.csv")
+
+ callsite_info(analysis)
# dump type and method infos
if csv then
- analysis.live_types_to_csv.save("{out}/rta_types.csv")
+ analysis.live_types_to_csv.write_to_file("{out}/rta_types.csv")
+ analysis.live_methods_to_tree.write_to_file("{out}/rta_methods.dat")
+ end
+ end
- var s = new OFStream.open("{out}/rta_methods.dat")
- analysis.live_methods_to_tree.pretty(s)
- s.close
+ fun callsite_info(rta: RapidTypeAnalysis)
+ do
+ print toolcontext.format_h2("\n ## Callsites")
+ print "* {rta.live_callsites.length} live callsites"
+
+ var csep = new Counter[MPropDef]
+ var cglo = new Counter[MPropDef]
+ var morphisme = new Counter[Int]
+ for cs in rta.live_callsites do
+ csep.inc(cs.mpropdef)
+ var targets = rta.live_targets(cs)
+ for d in targets do
+ cglo.inc(d)
+ end
+ morphisme.inc(targets.length)
end
+
+ print toolcontext.format_h3("MMethodDef locally designated (by number of CallSites)")
+ csep.print_summary
+ csep.print_elements(5)
+
+ print toolcontext.format_h3("MMethodDef possibly invoked at runtime (by number of CallSites)")
+ cglo.print_summary
+ cglo.print_elements(5)
end
end
# Summary metrics
+# RTA related metric that needs a `modelbuilder`
+class RTAMetric
+ super MModuleMetric
+
+ # Modelbuilder used to access AST
+ var modelbuilder: ModelBuilder
+end
+
# MModule Metric: Number of Live Types
class MNLI
- super MModuleMetric
+ super RTAMetric
super IntMetric
redef fun name do return "mnli"
redef fun desc do return "number of live instances in a mmodule"
- var modelbuilder: ModelBuilder
- init(modelbuilder: ModelBuilder) do self.modelbuilder = modelbuilder
redef fun collect(mainmodules) do
for mainmodule in mainmodules do
# MModule Metric: Number of Live Types
class MNLT
- super MModuleMetric
+ super RTAMetric
super IntMetric
redef fun name do return "mnlt"
redef fun desc do return "number of live mtypes in a mmodule"
- var modelbuilder: ModelBuilder
- init(modelbuilder: ModelBuilder) do self.modelbuilder = modelbuilder
-
redef fun collect(mainmodules) do
for mainmodule in mainmodules do
var analysis = new RapidTypeAnalysis(modelbuilder, mainmodule)
# MModule Metric: Number of Live Cast Types
class MNCT
- super MModuleMetric
+ super RTAMetric
super IntMetric
redef fun name do return "mnct"
redef fun desc do return "number of live cast mtypes in a mmodule"
- var modelbuilder: ModelBuilder
- init(modelbuilder: ModelBuilder) do self.modelbuilder = modelbuilder
-
redef fun collect(mainmodules) do
for mainmodule in mainmodules do
var analysis = new RapidTypeAnalysis(modelbuilder, mainmodule)
# MModule Metric: Number of Live Classes
class MNLC
- super MModuleMetric
+ super RTAMetric
super IntMetric
redef fun name do return "mnlc"
redef fun desc do return "number of live mclasses in a mmodule"
- var modelbuilder: ModelBuilder
- init(modelbuilder: ModelBuilder) do self.modelbuilder = modelbuilder
-
redef fun collect(mainmodules) do
for mainmodule in mainmodules do
var live = new HashSet[MClass]
# MModule Metric: Number of Live Methods
class MNLM
- super MModuleMetric
+ super RTAMetric
super IntMetric
redef fun name do return "mnlm"
redef fun desc do return "number of live methods in a mmodule"
- var modelbuilder: ModelBuilder
- init(modelbuilder: ModelBuilder) do self.modelbuilder = modelbuilder
-
redef fun collect(mainmodules) do
for mainmodule in mainmodules do
var analysis = new RapidTypeAnalysis(modelbuilder, mainmodule)
# MModule Metric: Number of Live MethodDefs
class MNLMD
- super MModuleMetric
+ super RTAMetric
super IntMetric
redef fun name do return "mnlmd"
redef fun desc do return "number of live method definitions in a mmodule"
- var modelbuilder: ModelBuilder
- init(modelbuilder: ModelBuilder) do self.modelbuilder = modelbuilder
-
redef fun collect(mainmodules) do
for mainmodule in mainmodules do
var analysis = new RapidTypeAnalysis(modelbuilder, mainmodule)
# MModule Metric: Number of Dead MethodDefs
class MNLDD
- super MModuleMetric
+ super RTAMetric
super IntMetric
redef fun name do return "mnldd"
redef fun desc do return "number of dead method definitions in a mmodule"
- var modelbuilder: ModelBuilder
- init(modelbuilder: ModelBuilder) do self.modelbuilder = modelbuilder
-
redef fun collect(mainmodules) do
for mainmodule in mainmodules do
var dead = 0
# rta redef
redef class RapidTypeAnalysis
- var cnli = new CNLI
- var cnlc = new CNLC
+
+ # Class Live Instances
+ var cnli: CNLI is lazy do return new CNLI(mainmodule, modelbuilder.model.protected_view)
+
+ # Class Live Casts
+ var cnlc: CNLC is lazy do return new CNLC(mainmodule, modelbuilder.model.protected_view)
+
+ # Type Live Instances
var tnli = new TNLI
+
+ # Rtpe Live Casts
var tnlc = new TNLC
redef fun add_new(recv, mtype) do
super
tnlc.values.inc(mtype)
- if mtype isa MNullableType then mtype = mtype.mtype
+ mtype = mtype.undecorate
if mtype isa MClassType then
cnlc.values.inc(mtype.mclass)
end
redef class MType
private fun signature_depth: Int do
- var mtype = self
- if mtype isa MNullableType then mtype = mtype.mtype
+ var mtype = self.undecorate
if not mtype isa MGenericType then return 0
var depth = 0
return depth + 1
end
end
-