--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2012 Jean Privat <jean@pryen.org>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Collect metrics about genericity usage
+module genericity_metrics
+
+private import metrics_base
+private import inheritance_metrics
+
+redef class MClass
+ # Inheritance
+ private var nogp: Int = 0 # (NOP) Number of generic parents (direct superclasses)
+ private var nogpc: Int = 0 # (NOPC) Number of generic class parents
+ private var nogpi: Int = 0 # (NOPI) Number of generic interface parents
+ private var noga: Int = 0 # (NOA) Number of generic ancestors (direct and indirect)
+ private var nogac: Int = 0 # (NOAC) Number of generic class ancestors
+ private var nogai: Int = 0 # (NOAI) Number of generic interface ancestors
+ private var nogc: Int = 0 # (NOC) Number of generic children (direct subclasses)
+ private var nogcc: Int = 0 # (NOCC) Number of generic class children
+ private var nogci: Int = 0 # (NOCI) Number of generic interface children
+ private var nogd: Int = 0 # (NOD) Number of generic descendants (direct and indirect)
+ private var nogdc: Int = 0 # (NODC) Number of generic class descendants
+ private var nogdi: Int = 0 # (NODI) Number of generic interface descendants
+ private var ditg: Int = 0 # (DIT) Length of longest path to the root hierarchy and consisting only of generic edges
+ private var ditgc: Int = 0 # (DITC) Length of longest path to the root hierarchy and consisting only of generic extends edges
+ private var ditgi: Int = 0 # (DITI) Length of longest path to the root hierarchy and consisting only of generic implements edges
+
+ # User Defined inheritance
+ private var nogpud: Int = 0 # (NOPUD) Number of parents (direct superclasses)
+ private var nogpcud: Int = 0 # (NOPCUD) Number of class parents
+ private var nogpiud: Int = 0 # (NOPIUD) Number of interface parents
+ private var nogaud: Int = 0 # (NOAUD) Number of ancestors (direct and indirect)
+ private var nogacud: Int = 0 # (NOACUD) Number of class ancestors
+ private var nogaiud: Int = 0 # (NOAIUD) Number of interface ancestors
+ private var nogcud: Int = 0 # (NOCUD) Number of children (direct subclasses)
+ private var nogccud: Int = 0 # (NOCCUD) Number of class children
+ private var nogciud: Int = 0 # (NOCIUD) Number of interface children
+ private var nogdud: Int = 0 # (NODUD) Number of descendants (direct and indirect)
+ private var nogdcud: Int = 0 # (NODCUD) Number of class descendants
+ private var nogdiud: Int = 0 # (NODIUD) Number of interface descendants
+ private var ditgud: Int = 0 # (DITUD) Depth in Inheritance Tree (maximum distance to root of the hierarchy)
+ private var ditgcud: Int = 0 # (DITCUD) Length of longest path to the root hierarchy and consisting only of extends edges
+ private var ditgiud: Int = 0 # (DITIUD) Length of longest path to the root hierarchy and consisting only of extends implements
+
+ private fun compute_class_genericity_metrics(model: Model) do
+ # inheritance metrics
+ self.nogp = model.extract_generics(parents).length
+ self.nogpc = model.extract_generics(model.extract_classes(parents)).length
+ self.nogpi = model.extract_generics(model.extract_interfaces(parents)).length
+ self.noga = model.extract_generics(ancestors).length
+ self.nogac = model.extract_generics(model.extract_classes(ancestors)).length
+ self.nogai = model.extract_generics(model.extract_interfaces(ancestors)).length
+ self.nogc = model.extract_generics(children(model)).length
+ self.nogcc = model.extract_generics(model.extract_classes(children(model))).length
+ self.nogci = model.extract_generics(model.extract_interfaces(children(model))).length
+ self.nogd = model.extract_generics(descendants).length
+ self.nogdc = model.extract_generics(model.extract_classes(descendants)).length
+ self.nogdi = model.extract_generics(model.extract_interfaces(descendants)).length
+ self.ditg = gen_path_to_object.length
+ self.ditgc = gen_class_path_to_object.length
+ self.ditgi = gen_interface_path_to_object.length
+
+ # used defined metrics
+ self.nogpud = model.extract_generics(model.extract_user_defined(parents)).length
+ self.nogpcud = model.extract_generics(model.extract_user_defined(model.extract_classes(parents))).length
+ self.nogpiud = model.extract_generics(model.extract_user_defined(model.extract_interfaces(parents))).length
+ self.nogaud = model.extract_generics(model.extract_user_defined(ancestors)).length
+ self.nogacud = model.extract_generics(model.extract_user_defined(model.extract_classes(ancestors))).length
+ self.nogaiud = model.extract_generics(model.extract_user_defined(model.extract_interfaces(ancestors))).length
+ self.nogcud = model.extract_generics(model.extract_user_defined(children(model))).length
+ self.nogccud = model.extract_generics(model.extract_user_defined(model.extract_classes(children(model)))).length
+ self.nogciud = model.extract_generics(model.extract_user_defined(model.extract_interfaces(children(model)))).length
+ self.nogdud = model.extract_generics(model.extract_user_defined(descendants)).length
+ self.nogdcud = model.extract_generics(model.extract_user_defined(model.extract_classes(descendants))).length
+ self.nogdiud = model.extract_generics(model.extract_user_defined(model.extract_interfaces(descendants))).length
+ self.ditgud = model.extract_generics(model.extract_user_defined(path_to_object)).length
+ self.ditgcud = model.extract_generics(model.extract_user_defined(model.extract_classes(path_to_object))).length
+ self.ditgiud = model.extract_generics(model.extract_user_defined(model.extract_interfaces(path_to_object))).length
+ end
+
+ # Return the longest path from class to root hierarchy following only generic relations
+ fun gen_path_to_object: Array[MClass] do
+ var path = new Array[MClass]
+ if not self.arity > 0 then return path
+ var max_dit: nullable Int = null
+ var max_parent: nullable MClass = null
+ var parent_path: nullable Array[MClass] = null
+
+ for p in parents do
+ var dit = p.gen_path_to_object.length
+ if max_dit == null or dit >= max_dit then
+ max_dit = dit
+ max_parent = p
+ parent_path = p.gen_path_to_object
+ end
+ end
+
+ if max_parent != null and parent_path != null then
+ path.add(max_parent)
+ path.add_all(parent_path)
+ end
+
+ return path
+ end
+
+ # Return the longest path from class to root hierarchy following only classes relations
+ fun gen_class_path_to_object: Array[MClass] do
+ var path = new Array[MClass]
+ if not self.is_class or not self.arity > 0 then return path
+ var max_dit: nullable Int = null
+ var max_parent: nullable MClass = null
+ var parent_path: nullable Array[MClass] = null
+
+ for p in parents do
+ var dit = p.gen_class_path_to_object.length
+ if max_dit == null or dit >= max_dit then
+ max_dit = dit
+ max_parent = p
+ parent_path = p.gen_class_path_to_object
+ end
+ end
+
+ if max_parent != null and parent_path != null then
+ path.add(max_parent)
+ path.add_all(parent_path)
+ end
+
+ return path
+ end
+
+ # Return the longest path from class to root hierarchy following only interfaces relations
+ fun gen_interface_path_to_object: Array[MClass] do
+ var path = new Array[MClass]
+ if not self.is_interface or not self.arity > 0 then return path
+ var max_dit: nullable Int = null
+ var max_parent: nullable MClass = null
+ var parent_path: nullable Array[MClass] = null
+
+ for p in parents do
+ var dit = p.gen_interface_path_to_object.length
+ if max_dit == null or dit >= max_dit then
+ max_dit = dit
+ max_parent = p
+ parent_path = p.gen_interface_path_to_object
+ end
+ end
+
+ if max_parent != null and parent_path != null then
+ path.add(max_parent)
+ path.add_all(parent_path)
+ end
+
+ return path
+ end
+end
+
+redef class MModule
+
+ private var gdit = "" # (DIT) Global Depth in Inheritance Tree
+ private var gdui = "" # (DUI) Proportion of types that either implement an interface or extend another type other than Object
+ private var gccdui = "" # (CCDUI) Proportion of classes that extend some other class.
+ private var gcidui = "" # (CIDUI) Proportion of classes that implement some other interface.
+ private var giidui = "" # (IIDUI) Proportion of interfaces that extend some other interface.
+ private var ginhf = "" # (IF) Proportion of types Inherited From, that is, those types that are either extended or implemented
+ private var gccif = "" # (CCIF) Proportion of classes extended by some other class.
+ private var gicif = "" # (ICIF) Proportion of interfaces implemented by some other class.
+ private var giiif = "" # (IIIF) Proportion of interfaces extended by some other interface.
+
+ fun compute_module_genericity_metrics(model: Model) do
+ var ditsum = 0
+ var dui_count = 0
+ var ccdui_count = 0
+ var cidui_count = 0
+ var iidui_count = 0
+ var if_count = 0
+ var ccif_count = 0
+ var icif_count = 0
+ var iiif_count = 0
+
+ for mmodule in self.in_nesting.greaters do
+ for mclass in mmodule.intro_mclasses do
+ if not mclass.arity > 0 then continue
+ ditsum += mclass.gen_path_to_object.length
+ if mclass.arity > 0 and mclass.is_dui_eligible then dui_count += 1
+ if mclass.arity > 0 and mclass.is_ccdui_eligible then ccdui_count += 1
+ if mclass.arity > 0 and mclass.is_cidui_eligible then cidui_count += 1
+ if mclass.arity > 0 and mclass.is_iidui_eligible then iidui_count += 1
+ if mclass.arity > 0 and mclass.is_if_eligible(model) then if_count += 1
+ if mclass.arity > 0 and mclass.is_ccif_eligible(model) then ccif_count += 1
+ if mclass.arity > 0 and mclass.is_icif_eligible(model) then icif_count += 1
+ if mclass.arity > 0 and mclass.is_iiif_eligible(model) then iiif_count += 1
+ end
+ end
+
+ gdit = div(ditsum, ngc + ngi)
+ gdui = div(dui_count * 100, ngc + ngi)
+ gccdui = div(ccdui_count * 100, ngc)
+ gcidui = div(cidui_count * 100, ngc)
+ giidui = div(iidui_count * 100, ngi)
+ ginhf = div(if_count * 100, ngc + ngi)
+ gccif = div(ccif_count * 100, ngc)
+ gicif = div(icif_count * 100, ngi)
+ giiif = div(iiif_count * 100, ngi)
+ end
+end
+
+# Print inheritance usage metrics
+fun compute_genericity_metrics(toolcontext: ToolContext, model: Model)
+do
+ compute_inheritance_metrics(toolcontext, model)
+
+ # compute modules scalar metrics
+ for mmodule in model.mmodules do
+ mmodule.compute_module_genericity_metrics(model)
+ end
+
+ # compute class scalar metrics
+ for mclass in model.mclasses do
+ mclass.compute_class_genericity_metrics(model)
+ end
+
+ #TODO Comment monitorer l'évolution de la signature générique ? C[T, U] <: B <: A[V]
+
+ # CSV generation
+ if toolcontext.opt_generate_csv.value then
+ # inheritance metrics
+ var inheritanceCSV = new CSVDocument(toolcontext.output_dir.join_path("inheritance_genericity_metrics.csv"))
+ inheritanceCSV.set_header("scope", "GDIT", "GDUI", "GCCDUI", "GCIDUI", "GIIDUI", "GIF", "GCCIF", "GICIF", "GIIIF")
+ for m in model.mmodules do
+ if m.intro_mclasses.is_empty and m.in_nesting.greaters.length == 1 then continue
+ inheritanceCSV.add_line(m.name, m.gdit, m.gdui, m.gccdui, m.gcidui, m.giidui, m.ginhf, m.gccif, m.gicif, m.giiif)
+ end
+ inheritanceCSV.save
+
+ # scalar metrics
+ var scalarCSV = new CSVDocument(toolcontext.output_dir.join_path("global_scalar_generic_metrics.csv"))
+ var udscalarCSV = new CSVDocument(toolcontext.output_dir.join_path("ud_scalar_generic_metrics.csv"))
+ scalarCSV.set_header("mclass", "type", "FT", "DITG", "DITGC", "DITGI", "NOGP", "NOGPC", "NOGPI", "NOGA", "NOGAC", "NOGAI", "NOGC", "NOGCC", "NOGCI", "NOGD", "NOGDC", "NOGDI")
+ udscalarCSV.set_header("mclass", "type", "FT", "DITGUD", "DITGCUD", "DITGIUD", "NOGPUD", "NOGPCUD", "NOGPIUD", "NOGAUD", "NOGACUD", "NOGAIUD", "NOGCUD", "NOGCCUD", "NOGCIUD", "NOGDUD", "NOGDCUD", "NOGDIUD")
+ for c in model.mclasses do
+ if not c.arity > 0 then continue
+ var name = c.name
+ var typ = "class"
+ if c.is_interface then typ = "interface"
+ scalarCSV.add_line(name, typ, c.arity, c.ditg, c.ditgc, c.ditgi, c.nogp, c.nogpc, c.nogpi, c.noga, c.nogac, c.nogai, c.nogc, c.nogcc, c.nogci, c.nogd, c.nogdc, c.nogdi)
+ udscalarCSV.add_line(name, typ, c.arity, c.ditgud, c.ditgcud, c.ditgiud, c.nogpud, c.nogpcud, c.nogpiud, c.nogaud, c.nogacud, c.nogaiud, c.nogcud, c.nogccud, c.nogciud, c.nogdud, c.nogdcud, c.nogdiud)
+ end
+ scalarCSV.save
+ udscalarCSV.save
+ end
+end
self.ditiud = ud_interface_path_to_object.length
end
- private fun is_class: Bool do
+ fun is_class: Bool do
return self.kind == concrete_kind or self.kind == abstract_kind
end
- private fun is_interface: Bool do
+ fun is_interface: Bool do
return self.kind == interface_kind
end
- private fun is_abstract: Bool do
+ fun is_abstract: Bool do
return self.kind == abstract_kind
end
- private fun is_user_defined: Bool do
+ fun is_user_defined: Bool do
return self.intro_mmodule.is_user_defined
end
# Get parents of the class (direct super classes only)
- private fun parents: Set[MClass] do
+ fun parents: Set[MClass] do
var lst = new HashSet[MClass]
# explore all definitions of the class (refinement)
for mclassdef in self.mclassdefs do
end
# Get ancestors of the class (all super classes)
- private fun ancestors: Set[MClass] do
+ fun ancestors: Set[MClass] do
var lst = new HashSet[MClass]
for mclassdef in self.mclassdefs do
for super_mclassdef in mclassdef.in_hierarchy.greaters do
end
# Get children of the class (direct subclasses only)
- private fun children(model: Model): Set[MClass] do
+ fun children(model: Model): Set[MClass] do
var lst = new HashSet[MClass]
for other in model.mclasses do
if other == self then continue # skip self
end
# Get children of the class (direct subclasses only)
- private fun descendants: Set[MClass] do
+ fun descendants: Set[MClass] do
var lst = new HashSet[MClass]
for mclassdef in self.mclassdefs do
for sub_mclassdef in mclassdef.in_hierarchy.smallers do
return path
end
+
# Return the longest path from class to root hierarchy
fun ud_path_to_object: Array[MClass] do
var path = new Array[MClass]
# * -> * DUI
- private fun is_dui_eligible: Bool do
+ fun is_dui_eligible: Bool do
for parent in parents do if parent.name != "Object" then return true
return false
end
- private fun is_ccdui_eligible: Bool do
+ fun is_ccdui_eligible: Bool do
if not is_class then return false
for parent in parents do if parent.name != "Object" and parent.is_class then return true
return false
end
- private fun is_cidui_eligible: Bool do
+ fun is_cidui_eligible: Bool do
if not is_class then return false
for parent in parents do if parent.name != "Object" and parent.is_interface then return true
return false
end
- private fun is_iidui_eligible: Bool do
+ fun is_iidui_eligible: Bool do
if not is_interface then return false
for parent in parents do if parent.name != "Object" and parent.is_interface then return true
return false
end
- private fun is_if_eligible(model: Model): Bool do return not children(model).is_empty
- private fun is_ccif_eligible(model: Model): Bool do
+ fun is_if_eligible(model: Model): Bool do return not children(model).is_empty
+ fun is_ccif_eligible(model: Model): Bool do
if not is_class then return false
for child in children(model) do if child.is_class then return true
return false
end
- private fun is_icif_eligible(model: Model): Bool do
+ fun is_icif_eligible(model: Model): Bool do
if not is_interface then return false
for child in children(model) do if child.is_class then return true
return false
end
- private fun is_iiif_eligible(model: Model): Bool do
+ fun is_iiif_eligible(model: Model): Bool do
if not is_interface then return false
for child in children(model) do if child.is_interface then return true
return false
# SL -> * DUI
- private fun is_sldui_eligible: Bool do
+ fun is_sldui_eligible: Bool do
if is_user_defined then return false
for parent in parents do if parent.name != "Object" then return true
return false
end
- private fun is_slccdui_eligible: Bool do
+ fun is_slccdui_eligible: Bool do
if is_user_defined then return false
if not is_class then return false
for parent in parents do if parent.name != "Object" and parent.is_class then return true
return false
end
- private fun is_slcidui_eligible: Bool do
+ fun is_slcidui_eligible: Bool do
if is_user_defined then return false
if not is_class then return false
for parent in parents do if parent.name != "Object" and parent.is_interface then return true
return false
end
- private fun is_sliidui_eligible: Bool do
+ fun is_sliidui_eligible: Bool do
if is_user_defined then return false
if not is_interface then return false
for parent in parents do if parent.name != "Object" and parent.is_interface then return true
return false
end
- private fun is_slif_eligible(model: Model): Bool do
+ fun is_slif_eligible(model: Model): Bool do
if is_user_defined then return false
return not children(model).is_empty
end
- private fun is_slccif_eligible(model: Model): Bool do
+ fun is_slccif_eligible(model: Model): Bool do
if is_user_defined then return false
if not is_class then return false
for child in children(model) do if child.is_class then return true
return false
end
- private fun is_slicif_eligible(model: Model): Bool do
+ fun is_slicif_eligible(model: Model): Bool do
if is_user_defined then return false
if not is_interface then return false
for child in children(model) do if child.is_class then return true
return false
end
- private fun is_sliiif_eligible(model: Model): Bool do
+ fun is_sliiif_eligible(model: Model): Bool do
if is_user_defined then return false
if not is_interface then return false
for child in children(model) do if child.is_interface then return true
# SL -> SL
- private fun is_slifsl_eligible(model: Model): Bool do
+ fun is_slifsl_eligible(model: Model): Bool do
if is_user_defined then return false
for child in children(model) do if not child.is_user_defined then return true
return false
end
- private fun is_slccifsl_eligible(model: Model): Bool do
+ fun is_slccifsl_eligible(model: Model): Bool do
if is_user_defined then return false
if is_class then return false
for child in children(model) do if not child.is_user_defined and child.is_class then return true
return false
end
- private fun is_slicifsl_eligible(model: Model): Bool do
+ fun is_slicifsl_eligible(model: Model): Bool do
if is_user_defined then return false
if not is_interface then return false
for child in children(model) do if not child.is_user_defined and child.is_class then return true
return false
end
- private fun is_sliiifsl_eligible(model: Model): Bool do
+ fun is_sliiifsl_eligible(model: Model): Bool do
if is_user_defined then return false
if not is_interface then return false
for child in children(model) do if not child.is_user_defined and child.is_interface then return true
# SL -> UD
- private fun is_slifud_eligible(model: Model): Bool do
+ fun is_slifud_eligible(model: Model): Bool do
if is_user_defined then return false
for child in children(model) do if child.is_user_defined then return true
return false
end
- private fun is_slccifud_eligible(model: Model): Bool do
+ fun is_slccifud_eligible(model: Model): Bool do
if is_user_defined then return false
if not is_class then return false
for child in children(model) do if child.is_user_defined and child.is_class then return true
return false
end
- private fun is_slicifud_eligible(model: Model): Bool do
+ fun is_slicifud_eligible(model: Model): Bool do
if is_user_defined then return false
if not is_interface then return false
for child in children(model) do if child.is_user_defined and child.is_class then return true
return false
end
- private fun is_sliiifud_eligible(model: Model): Bool do
+ fun is_sliiifud_eligible(model: Model): Bool do
if is_user_defined then return false
if not is_interface then return false
for child in children(model) do if child.is_user_defined and child.is_interface then return true
# UD -> *
- private fun is_uddui_eligible: Bool do
+ fun is_uddui_eligible: Bool do
if not is_user_defined then return false
for parent in parents do if parent.name != "Object" then return true
return false
end
- private fun is_udccdui_eligible: Bool do
+ fun is_udccdui_eligible: Bool do
if not is_user_defined then return false
if not is_class then return false
for parent in parents do if parent.name != "Object" and parent.is_class then return true
return false
end
- private fun is_udcidui_eligible: Bool do
+ fun is_udcidui_eligible: Bool do
if not is_user_defined then return false
if not is_class then return false
for parent in parents do if parent.name != "Object" and parent.is_interface then return true
return false
end
- private fun is_udiidui_eligible: Bool do
+ fun is_udiidui_eligible: Bool do
if not is_user_defined then return false
if not is_interface then return false
for parent in parents do if parent.name != "Object" and parent.is_interface then return true
return false
end
- private fun is_udif_eligible(model: Model): Bool do
+ fun is_udif_eligible(model: Model): Bool do
if not is_user_defined then return false
return not children(model).is_empty
end
- private fun is_udccif_eligible(model: Model): Bool do
+ fun is_udccif_eligible(model: Model): Bool do
if not is_user_defined then return false
if not is_class then return false
for child in children(model) do if child.is_class then return true
return false
end
- private fun is_udicif_eligible(model: Model): Bool do
+ fun is_udicif_eligible(model: Model): Bool do
if not is_user_defined then return false
if not is_interface then return false
for child in children(model) do if child.is_class then return true
return false
end
- private fun is_udiiif_eligible(model: Model): Bool do
+ fun is_udiiif_eligible(model: Model): Bool do
if not is_user_defined then return false
if not is_interface then return false
for child in children(model) do if child.is_interface then return true
# UD -> SL
- private fun is_udduisl_eligible: Bool do
+ fun is_udduisl_eligible: Bool do
if not is_user_defined then return false
for parent in parents do if not parent.is_user_defined and parent.name != "Object" then return true
return false
end
- private fun is_udccduisl_eligible: Bool do
+ fun is_udccduisl_eligible: Bool do
if not is_user_defined then return false
if not is_class then return false
for parent in parents do if not parent.is_user_defined and parent.name != "Object" and parent.is_class then return true
return false
end
- private fun is_udciduisl_eligible: Bool do
+ fun is_udciduisl_eligible: Bool do
if not is_user_defined then return false
if not is_class then return false
for parent in parents do if not parent.is_user_defined and parent.name != "Object" and parent.is_interface then return true
return false
end
- private fun is_udiiduisl_eligible: Bool do
+ fun is_udiiduisl_eligible: Bool do
if not is_user_defined then return false
if not is_interface then return false
for parent in parents do if not parent.is_user_defined and parent.name != "Object" and parent.is_interface then return true
# UD -> UD
- private fun is_udduiud_eligible: Bool do
+ fun is_udduiud_eligible: Bool do
if not is_user_defined then return false
for parent in parents do if parent.name != "Object" and parent.is_user_defined then return true
return false
end
- private fun is_udccduiud_eligible: Bool do
+ fun is_udccduiud_eligible: Bool do
if not is_user_defined then return false
if not is_class then return false
for parent in parents do if parent.name != "Object" and parent.is_class and parent.is_user_defined then return true
return false
end
- private fun is_udciduiud_eligible: Bool do
+ fun is_udciduiud_eligible: Bool do
if not is_user_defined then return false
if not is_class then return false
for parent in parents do if parent.name != "Object" and parent.is_interface and parent.is_user_defined then return true
return false
end
- private fun is_udiiduiud_eligible: Bool do
+ fun is_udiiduiud_eligible: Bool do
if not is_user_defined then return false
if not is_interface then return false
for parent in parents do if parent.name != "Object" and parent.is_interface and parent.is_user_defined then return true
return false
end
- private fun is_udifud_eligible(model: Model): Bool do
+ fun is_udifud_eligible(model: Model): Bool do
if not is_user_defined then return false
return not children(model).is_empty
end
- private fun is_udccifud_eligible(model: Model): Bool do
+ fun is_udccifud_eligible(model: Model): Bool do
if not is_user_defined then return false
if not is_class then return false
for child in children(model) do if child.is_user_defined and child.is_class then return true
return false
end
- private fun is_udicifud_eligible(model: Model): Bool do
+ fun is_udicifud_eligible(model: Model): Bool do
if not is_user_defined then return false
if not is_interface then return false
for child in children(model) do if child.is_user_defined and child.is_class then return true
return false
end
- private fun is_udiiifud_eligible(model: Model): Bool do
+ fun is_udiiifud_eligible(model: Model): Bool do
if not is_user_defined then return false
if not is_interface then return false
for child in children(model) do if child.is_user_defined and child.is_interface then return true
private var nc: Int = 0 # (NC) Number of Classes
private var ni: Int = 0 # (NI) Number of Interfaces
private var nac : Int = 0 # (NAC) Number of Abstract Classes
- private var ngc : Int = 0 # (NGC) Number of Generic Classes
- private var ngi : Int = 0 # (NGI) Number of Generic Interfaces
+ protected var ngc : Int = 0 # (NGC) Number of Generic Classes
+ protected var ngi : Int = 0 # (NGI) Number of Generic Interfaces
private var dit = "" # (DIT) Global Depth in Inheritance Tree
private var dui = "" # (DUI) Proportion of types that either implement an interface or extend another type other than Object
private var icif = "" # (ICIF) Proportion of interfaces implemented by some other class.
private var iiif = "" # (IIIF) Proportion of interfaces extended by some other interface.
- private fun compute_module_inheritance_metrics(model: Model) do
+ fun compute_module_inheritance_metrics(model: Model) do
var ditsum = 0
var dui_count = 0
var ccdui_count = 0
iiif = div(iiif_count * 100, ni)
end
- private fun is_user_defined: Bool do
+ fun is_user_defined: Bool do
return not self.model.std_modules.has(self.name)
end
end