module doc_base
import toolcontext
-import model_utils
import model_ext
# The model of a Nitdoc documentation.
module doc_concerns
import doc_pages
+import model::model_collect
# ConcernsPhase computes the ConcernsTree used for each page layout.
class ConcernsPhase
# Populates the given DocModel.
redef fun apply do
- for page in doc.pages.values do page.build_concerns(doc)
+ for page in doc.pages.values do page.build_concerns(self)
end
end
# Build the `concerns` tree for this page.
#
# Since only `MEntityPage`, this method is a no-op for everything else.
- private fun build_concerns(doc: DocModel) do end
+ private fun build_concerns(v: ConcernsPhase) do end
end
redef class MEntityPage
# Refined classes in `mentity` that should appear in this page.
var redefs = new HashSet[MClass]
- redef fun build_concerns(doc) do
+ redef fun build_concerns(v) do
+ var doc = v.doc
var mmodules = new HashSet[MModule]
- for mmodule in mentity.collect_mmodules do
+ for mmodule in mentity.mmodules do
if doc.mmodules.has(mmodule) then mmodules.add mmodule
# collect mclasses
for mclass in mmodule.intro_mclasses do
if doc.mclasses.has(mclass) then intros.add mclass
end
- for mclass in mmodule.redef_mclasses do
+ for mclass in mmodule.collect_redef_mclasses(v.ctx.min_visibility) do
if doc.mclasses.has(mclass) then redefs.add mclass
end
end
# MClassDefs located in `mentity` to display in this page.
var mclassdefs = new HashSet[MClassDef]
- redef fun build_concerns(doc) do
+ redef fun build_concerns(v) do
+ var doc = v.doc
# extract mclassdefs in mmodule
for mclassdef in mentity.mclassdefs do
if doc.mclassdefs.has(mclassdef) then mclassdefs.add mclassdef
# MPropdefs to display in this page.
var mpropdefs = new HashSet[MPropDef]
- redef fun build_concerns(doc) do
+ redef fun build_concerns(v) do
+ var doc = v.doc
# collect mclassdefs
for mclassdef in mentity.mclassdefs do
if doc.mclassdefs.has(mclassdef) then mclassdefs.add mclassdef
# MPropdefs to display in this page.
var mpropdefs = new HashSet[MPropDef]
- redef fun build_concerns(doc) do
+ redef fun build_concerns(v) do
+ var doc = v.doc
# collect mpropdefs
for mpropdef in mentity.mpropdefs do
# FIXME diff hack
# TODO filter here?
super
var mclasses = new HashSet[MClass]
- mclasses.add_all mentity.filter_intro_mclasses(v.ctx.min_visibility)
- mclasses.add_all mentity.filter_redef_mclasses(v.ctx.min_visibility)
+ mclasses.add_all mentity.collect_intro_mclasses(v.ctx.min_visibility)
+ mclasses.add_all mentity.collect_redef_mclasses(v.ctx.min_visibility)
if mclasses.is_empty then return
var list = new UnorderedList
list.css_classes.add "list-unstyled list-labeled"
private fun mclass_inherited_mprops(v: RenderHTMLPhase, doc: DocModel): Set[MProperty] do
var res = new HashSet[MProperty]
- var local = mentity.local_mproperties(v.ctx.min_visibility)
- for mprop in mentity.inherited_mproperties(doc.mainmodule, v.ctx.min_visibility) do
+ var local = mentity.collect_local_mproperties(v.ctx.min_visibility)
+ for mprop in mentity.collect_inherited_mproperties(v.ctx.min_visibility) do
if local.has(mprop) then continue
#if mprop isa MMethod and mprop.is_init then continue
if mprop.intro.mclassdef.mclass.name == "Object" and
module doc_intros_redefs
import doc_structure
+import model::model_collect
# Computes intro / redef mentity list for each DefinitionArticle.
class IntroRedefListPhase
var section = new TabbedGroup("{mentity.nitdoc_id}.intros_redefs")
section.toc_title = "Intros / Redefs"
var group = new PanelGroup("list.group", "List")
- var intros = mmodule.intro_mclassdefs(v.ctx.min_visibility).to_a
+ var intros = mmodule.collect_intro_mclassdefs(v.ctx.min_visibility).to_a
doc.mainmodule.linearize_mclassdefs(intros)
group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.intros", "Introduces", intros)
- var redefs = mmodule.redef_mclassdefs(v.ctx.min_visibility).to_a
+ var redefs = mmodule.collect_redef_mclassdefs(v.ctx.min_visibility).to_a
doc.mainmodule.linearize_mclassdefs(redefs)
group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.redefs", "Redefines", redefs)
section.add_child group
module doc_poset
import doc_pages
+import model::model_collect
# This phase computes importation and inheritance POSet for pages.
class POSetPhase
end
# make poset
var mmodules = new HashSet[MModule]
- mmodules.add_all mentity.nested_mmodules
+ var mgroup = mentity.mgroup
+ if mgroup != null and mgroup.default_mmodule == mentity then
+ mmodules.add_all mgroup.mmodules
+ end
mmodules.add_all imports
if clients.length < 10 then mmodules.add_all clients
mmodules.add mentity
return mmodules.is_empty and mclasses.is_empty and mprops.is_empty
end
end
+
+# Concerns ranking
+
+# Sort MConcerns based on the module importation hierarchy ranking
+# see also: `MConcern::concern_rank` and `MConcern::booster_rank`
+#
+# Comparison is made with the formula:
+#
+# ~~~nitish
+# a.concern_rank + a.booster_rank <=> b.concern_rank + b.booster_ran
+# ~~~
+#
+# If both `a` and `b` have the same ranking,
+# ordering is based on lexicographic comparison of `a.name` and `b.name`
+class MConcernRankSorter
+ super Comparator
+ redef type COMPARED: MConcern
+
+ redef fun compare(a, b) do
+ if a.concern_rank == b.concern_rank then
+ return a.name <=> b.name
+ end
+ return a.concern_rank + a.booster_rank <=> b.concern_rank + b.booster_rank
+ end
+end
+
+redef class MConcern
+
+ # Boost a MConcern rank
+ # see: `MConcernRankSorter`
+ # Use a positive booster to push down a result in the list
+ # A negative booster can be used to push up the result
+ var booster_rank: Int = 0 is writable
+
+ # Concern ranking used for ordering
+ # see: `MConcernRankSorter`
+ # Rank can be positive or negative
+ fun concern_rank: Int is abstract
+end
+
+redef class MProject
+ redef var concern_rank is lazy do
+ var max = 0
+ for mgroup in mgroups do
+ var mmax = mgroup.concern_rank
+ if mmax > max then max = mmax
+ end
+ return max + 1
+ end
+end
+
+redef class MGroup
+ redef var concern_rank is lazy do
+ var max = 0
+ for mmodule in mmodules do
+ var mmax = mmodule.concern_rank
+ if mmax > max then max = mmax
+ end
+ return max + 1
+ end
+end
+
+redef class MModule
+ redef var concern_rank is lazy do
+ var max = 0
+ for p in in_importation.direct_greaters do
+ var pmax = p.concern_rank
+ if pmax > max then max = pmax
+ end
+ return max + 1
+ end
+end
import html_components
import html::bootstrap
import ordered_tree
+import model::model_collect
redef class MEntity
# URL of this entity’s Nitdoc page.
redef fun css_classes do
var set = new HashSet[String]
if is_intro then set.add "intro"
- for m in mclass.intro.modifiers do set.add m.to_cmangle
- for m in modifiers do set.add m.to_cmangle
+ for m in mclass.intro.collect_modifiers do set.add m.to_cmangle
+ for m in collect_modifiers do set.add m.to_cmangle
return set.to_a
end
end
redef fun css_classes do
var set = new HashSet[String]
if is_intro then set.add "intro"
- for m in mproperty.intro.modifiers do set.add m.to_cmangle
- for m in modifiers do set.add m.to_cmangle
+ for m in mproperty.intro.collect_modifiers do set.add m.to_cmangle
+ for m in collect_modifiers do set.add m.to_cmangle
return set.to_a
end
end
import modelbuilder
import phase
import modelize::modelize_class
-import model_utils
+import model::model_collect
redef class ToolContext
# Phase generating the files for the Vim plugin
stream.write line_separator*2
stream.write "## Properties"
stream.write line_separator
- var props = mclass.all_mproperties(mainmodule, protected_visibility).to_a
+ var props = mclass.collect_accessible_mproperties(protected_visibility).to_a
alpha_comparator.sort props
for prop in props do
if mclass.name == "Object" or prop.intro.mclassdef.mclass.name != "Object" then
# Can it be instantiated?
if mclass.kind != interface_kind and mclass.kind != abstract_kind then
- for prop in mclass.all_mproperties(mainmodule, public_visibility) do
+ for prop in mclass.collect_accessible_mproperties(public_visibility) do
if prop isa MMethod and prop.is_init then
mclass_intro.target_constructor = prop.intro
mclass_intro.write_doc(mainmodule, constructors_stream)
module mclasses_metrics
import metrics_base
+import model::model_collect
redef class ToolContext
var mclasses_metrics_phase: Phase = new MClassesMetricsPhase(self, null)
redef fun collect(mclasses) do
for mclass in mclasses do
- values[mclass] = mclass.all_mproperties(mainmodule, min_visibility).length
+ values[mclass] = mclass.collect_accessible_mproperties(min_visibility).length
end
end
end
redef fun collect(mclasses) do
for mclass in mclasses do
- values[mclass] = mclass.all_mattributes(mainmodule, min_visibility).length
+ values[mclass] = mclass.collect_accessible_mattributes(min_visibility).length
end
end
end
redef fun collect(mclasses) do
for mclass in mclasses do
- values[mclass] = mclass.intro_mproperties(min_visibility).length
+ values[mclass] = mclass.collect_intro_mproperties(min_visibility).length
end
end
end
redef fun collect(mclasses) do
for mclass in mclasses do
- values[mclass] = mclass.redef_mproperties(min_visibility).length
+ values[mclass] = mclass.collect_redef_mproperties(min_visibility).length
end
end
end
redef fun collect(mclasses) do
for mclass in mclasses do
- values[mclass] = mclass.inherited_mproperties(mainmodule, min_visibility).length
+ values[mclass] = mclass.collect_inherited_mproperties(min_visibility).length
end
end
end
redef fun collect(mclasses) do
for mclass in mclasses do
- values[mclass] = mclass.local_mproperties(min_visibility).length
+ values[mclass] = mclass.collect_local_mproperties(min_visibility).length
end
end
end
redef fun collect(mclasses) do
for mclass in mclasses do
- var totc = mclass.all_mproperties(mainmodule, protected_visibility).length
+ var totc = mclass.collect_accessible_mproperties(protected_visibility).length
var ditc = mclass.in_hierarchy(mainmodule).depth
values[mclass] = totc.to_f / (ditc + 1).to_f
end
cbms.clear
cbms.collect(new HashSet[MClass].from(parents))
# compute class novelty index
- var locc = mclass.local_mproperties(protected_visibility).length
+ var locc = mclass.collect_accessible_mproperties(protected_visibility).length
values[mclass] = locc.to_f / cbms.avg
else
values[mclass] = 0.0
var cnvi = new CNVI(mainmodule)
cnvi.collect(mclasses)
for mclass in mclasses do
- var locc = mclass.local_mproperties(protected_visibility).length
+ var locc = mclass.collect_local_mproperties(protected_visibility).length
values[mclass] = cnvi.values[mclass] * locc.to_f
end
end
# pure overriders contain only redefinitions
private fun is_pure_overrider(min_visibility: MVisibility): Bool do
- var news = intro_mproperties(min_visibility).length
- var locs = local_mproperties(min_visibility).length
+ var news = collect_intro_mproperties(min_visibility).length
+ var locs = collect_local_mproperties(min_visibility).length
if news == 0 and locs > 0 then return true
return false
end
# overriders contain more definitions than introductions
private fun is_overrider(min_visibility: MVisibility): Bool do
- var rdfs = redef_mproperties(min_visibility).length
- var news = intro_mproperties(min_visibility).length
- var locs = local_mproperties(min_visibility).length
+ var rdfs = collect_redef_mproperties(min_visibility).length
+ var news = collect_intro_mproperties(min_visibility).length
+ var locs = collect_local_mproperties(min_visibility).length
if rdfs >= news and locs > 0 then return true
return false
end
# pure extenders contain only introductions
private fun is_pure_extender(min_visibility: MVisibility): Bool do
- var rdfs = redef_mproperties(min_visibility).length
- var locs = local_mproperties(min_visibility).length
+ var rdfs = collect_redef_mproperties(min_visibility).length
+ var locs = collect_local_mproperties(min_visibility).length
if rdfs == 0 and locs > 0 then return true
return false
end
# extenders contain more introduction than redefinitions
private fun is_extender(min_visibility: MVisibility): Bool do
- var rdfs = redef_mproperties(min_visibility).length
- var news = intro_mproperties(min_visibility).length
- var locs = local_mproperties(min_visibility).length
+ var rdfs = collect_redef_mproperties(min_visibility).length
+ var news = collect_intro_mproperties(min_visibility).length
+ var locs = collect_local_mproperties(min_visibility).length
if news > rdfs and locs > 0 then return true
return false
end
# pure specializers always call to super in its redefinitions
private fun is_pure_specializer(min_visibility: MVisibility): Bool do
var ovrs = overriden_mproperties(min_visibility).length
- var rdfs = redef_mproperties(min_visibility).length
+ var rdfs = collect_redef_mproperties(min_visibility).length
if ovrs == 0 and rdfs > 0 then return true
return false
end
private fun is_specializer(min_visibility: MVisibility): Bool do
var spcs = extended_mproperties(min_visibility).length
var ovrs = overriden_mproperties(min_visibility).length
- var rdfs = redef_mproperties(min_visibility).length
+ var rdfs = collect_redef_mproperties(min_visibility).length
if spcs > ovrs and rdfs > 0 then return true
return false
end
# pure replacers never call to super in its redefinitions
private fun is_pure_replacer(min_visibility: MVisibility): Bool do
var spcs = extended_mproperties(min_visibility).length
- var rdfs = redef_mproperties(min_visibility).length
+ var rdfs = collect_redef_mproperties(min_visibility).length
if spcs == 0 and rdfs > 0 then return true
return false
end
private fun is_replacer(min_visibility: MVisibility): Bool do
var spcs = extended_mproperties(min_visibility).length
var ovrs = overriden_mproperties(min_visibility).length
- var rdfs = redef_mproperties(min_visibility).length
+ var rdfs = collect_redef_mproperties(min_visibility).length
if ovrs > spcs and rdfs > 0 then return true
return false
end
private fun is_equal(min_visibility: MVisibility): Bool do
var spcs = extended_mproperties(min_visibility).length
var ovrs = overriden_mproperties(min_visibility).length
- var rdfs = redef_mproperties(min_visibility).length
+ var rdfs = collect_redef_mproperties(min_visibility).length
if spcs == ovrs and rdfs > 0 then return true
return false
end
# Helpers for various statistics tools.
module metrics_base
-import model_utils
import modelbuilder
import csv
import counter
redef fun collect(mclasses) do
for mclass in mclasses do
- var all = mclass.all_mattributes(mainmodule, min_visibility)
+ var all = mclass.collect_accessible_mattributes(min_visibility)
for mattr in all do
if mattr.is_nullable then values.inc(mclass)
end
end
end
+redef class MAttribute
+ # Is this attribute nullable for sure?
+ #
+ # This mean that its introduction is declarred with a nullable static type
+ # since attributes are invariant this will work on most cases
+ # attributes with static type anchored with a virtual type are not "nullable for-sure"
+ # because this type can be redefined in subclasses
+ private fun is_nullable: Bool do return intro.static_mtype isa MNullableType
+end
private class NullableSends
super Visitor
# Is there a `new` factory to allow the pseudo instantiation?
var has_new_factory = false is writable
+
+ # Is `self` a standard or abstract class kind?
+ var is_class: Bool is lazy do return kind == concrete_kind or kind == abstract_kind
+
+ # Is `self` an interface kind?
+ var is_interface: Bool is lazy do return kind == interface_kind
+
+ # Is `self` an enum kind?
+ var is_enum: Bool is lazy do return kind == enum_kind
+
+ # Is `self` and abstract class?
+ var is_abstract: Bool is lazy do return kind == abstract_kind
end
end
end
+# A `Comparator` to sort mentities by their names.
+class MEntityNameSorter
+ super Comparator
+
+ redef type COMPARED: MEntity
+
+ # Returns `a.name <=> b.name`.
+ redef fun compare(a, b) do return a.name <=> b.name
+end
+
# The visibility level `intrude`
fun intrude_visibility: MVisibility do return once new MVisibility("intrude", 5)
# The visibility level `public`
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2008 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 things from a `Model`.
+#
+# **Warning**
+#
+# `model_collect` offers a flattened view of the model without considering any
+# main module.
+# For this reason, `model_collect` lists all the definitions reachable from all
+# modules
+#
+# This is usefull for tools that need a global view of a model like `nitdoc`,
+# `nitx` or `nituml`.
+# It shoul not be used for compiling stuffs like computing VFT, where the listed
+# entities could not be reachable depending on the modules really imported.
+module model_collect
+
+import model
+
+redef class MModule
+
+ # Collect mclassdefs introduced in `self` with `visibility >= to min_visibility`.
+ fun collect_intro_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
+ var res = new HashSet[MClassDef]
+ for mclassdef in mclassdefs do
+ if not mclassdef.is_intro then continue
+ if mclassdef.mclass.visibility < min_visibility then continue
+ res.add mclassdef
+ end
+ return res
+ end
+
+ # Collect mclassdefs redefined in `self` with `visibility >= to min_visibility`.
+ fun collect_redef_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
+ var res = new HashSet[MClassDef]
+ for mclassdef in mclassdefs do
+ if mclassdef.is_intro then continue
+ if mclassdef.mclass.visibility < min_visibility then continue
+ res.add mclassdef
+ end
+ return res
+ end
+
+ # Collect mclasses introduced in `self` with `visibility >= to min_visibility`.
+ fun collect_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
+ var res = new HashSet[MClass]
+ for mclass in intro_mclasses do
+ if mclass.visibility < min_visibility then continue
+ res.add mclass
+ end
+ return res
+ end
+
+ # Collect mclasses redefined in `self` with `visibility >= to min_visibility`.
+ fun collect_redef_mclasses(min_visibility: MVisibility): Set[MClass] do
+ var mclasses = new HashSet[MClass]
+ for c in mclassdefs do
+ if c.mclass.visibility < min_visibility then continue
+ if not c.is_intro then mclasses.add(c.mclass)
+ end
+ return mclasses
+ end
+end
+
+redef class MClass
+
+ # Collect direct parents of `self` with `visibility >= to min_visibility`.
+ fun collect_parents(min_visibility: MVisibility): Set[MClass] do
+ var res = new HashSet[MClass]
+ for mclassdef in mclassdefs do
+ for mclasstype in mclassdef.supertypes do
+ var mclass = mclasstype.mclass
+ if mclass.visibility < min_visibility then continue
+ res.add(mclass)
+ end
+ end
+ return res
+ end
+
+ # Collect all ancestors of `self` with `visibility >= to min_visibility`.
+ fun collect_ancestors(min_visibility: MVisibility): Set[MClass] do
+ var res = new HashSet[MClass]
+ for mclassdef in self.mclassdefs do
+ for super_mclassdef in mclassdef.in_hierarchy.greaters do
+ if super_mclassdef == mclassdef then continue # skip self
+ var mclass = super_mclassdef.mclass
+ if mclass.visibility < min_visibility then continue
+ res.add(mclass)
+ end
+ end
+ return res
+ end
+
+ # Collect direct children of `self` with `visibility >= to min_visibility`.
+ fun collect_children(min_visibility: MVisibility): Set[MClass] do
+ var res = new HashSet[MClass]
+ for mclassdef in self.mclassdefs do
+ for sub_mclassdef in mclassdef.in_hierarchy.direct_smallers do
+ if sub_mclassdef == mclassdef then continue # skip self
+ var mclass = sub_mclassdef.mclass
+ if mclass.visibility < min_visibility then continue
+ res.add(mclass)
+ end
+ end
+ return res
+ end
+
+ # Collect all descendants of `self` with `visibility >= to min_visibility`.
+ fun descendants(min_visibility: MVisibility): Set[MClass] do
+ var res = new HashSet[MClass]
+ for mclassdef in self.mclassdefs do
+ for sub_mclassdef in mclassdef.in_hierarchy.smallers do
+ if sub_mclassdef == mclassdef then continue # skip self
+ var mclass = sub_mclassdef.mclass
+ if mclass.visibility < min_visibility then continue
+ res.add(mclass)
+ end
+ end
+ return res
+ end
+
+ # Collect all mproperties introduced in 'self' with `visibility >= min_visibility`.
+ fun collect_intro_mproperties(min_visibility: MVisibility): Set[MProperty] do
+ var set = new HashSet[MProperty]
+ for mclassdef in mclassdefs do
+ for mprop in mclassdef.intro_mproperties do
+ if mprop.visibility < min_visibility then continue
+ set.add(mprop)
+ end
+ end
+ return set
+ end
+
+ # Collect all mproperties redefined in 'self' with `visibility >= min_visibility`.
+ fun collect_redef_mproperties(min_visibility: MVisibility): Set[MProperty] do
+ var set = new HashSet[MProperty]
+ for mclassdef in mclassdefs do
+ for mpropdef in mclassdef.mpropdefs do
+ if mpropdef.mproperty.visibility < min_visibility then continue
+ if mpropdef.mproperty.intro_mclassdef.mclass != self then set.add(mpropdef.mproperty)
+ end
+ end
+ return set
+ end
+
+ # Collect mproperties introduced and redefined in 'self' with `visibility >= min_visibility`.
+ fun collect_local_mproperties(min_visibility: MVisibility): Set[MProperty] do
+ var set = new HashSet[MProperty]
+ set.add_all collect_intro_mproperties(min_visibility)
+ set.add_all collect_redef_mproperties(min_visibility)
+ return set
+ end
+
+ # Collect all mproperties inehrited by 'self' with `visibility >= min_visibility`.
+ fun collect_inherited_mproperties(min_visibility: MVisibility): Set[MProperty] do
+ var set = new HashSet[MProperty]
+ for parent in collect_parents(min_visibility) do
+ set.add_all(parent.collect_intro_mproperties(min_visibility))
+ set.add_all(parent.collect_inherited_mproperties(min_visibility))
+ end
+ return set
+ end
+
+ # Collect all mproperties accessible by 'self' with `visibility >= min_visibility`.
+ #
+ # This include introduced, redefined, inherited mproperties.
+ fun collect_accessible_mproperties(min_visibility: MVisibility): Set[MProperty] do
+ var set = new HashSet[MProperty]
+ set.add_all(collect_intro_mproperties(min_visibility))
+ set.add_all(collect_redef_mproperties(min_visibility))
+ set.add_all(collect_inherited_mproperties(min_visibility))
+ return set
+ end
+
+ # Collect mmethods introduced in 'self' with `visibility >= min_visibility`.
+ fun collect_intro_mmethods(min_visibility: MVisibility): Set[MMethod] do
+ var res = new HashSet[MMethod]
+ for mproperty in collect_intro_mproperties(min_visibility) do
+ if mproperty isa MMethod then res.add(mproperty)
+ end
+ return res
+ end
+
+ # Collect mmethods redefined in 'self' with `visibility >= min_visibility`.
+ fun collect_redef_mmethods(min_visibility: MVisibility): Set[MMethod] do
+ var res = new HashSet[MMethod]
+ for mproperty in collect_redef_mproperties(min_visibility) do
+ if mproperty isa MMethod then res.add(mproperty)
+ end
+ return res
+ end
+
+ # Collect mmethods introduced and redefined in 'self' with `visibility >= min_visibility`.
+ fun collect_local_mmethods(min_visibility: MVisibility): Set[MMethod] do
+ var set = new HashSet[MMethod]
+ set.add_all collect_intro_mmethods(min_visibility)
+ set.add_all collect_redef_mmethods(min_visibility)
+ return set
+ end
+
+ # Collect mattributes introduced in 'self' with `visibility >= min_visibility`.
+ fun collect_intro_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+ var res = new HashSet[MAttribute]
+ for mproperty in collect_intro_mproperties(min_visibility) do
+ if mproperty isa MAttribute then res.add(mproperty)
+ end
+ return res
+ end
+
+ # Collect mattributes redefined in 'self' with `visibility >= min_visibility`.
+ fun collect_redef_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+ var res = new HashSet[MAttribute]
+ for mproperty in collect_redef_mproperties(min_visibility) do
+ if mproperty isa MAttribute then res.add(mproperty)
+ end
+ return res
+ end
+
+ # Collect mattributes introduced and redefined in 'self' with `visibility >= min_visibility`.
+ fun collect_local_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+ var set = new HashSet[MAttribute]
+ set.add_all collect_intro_mattributes(min_visibility)
+ set.add_all collect_redef_mattributes(min_visibility)
+ return set
+ end
+
+ # Collect mattributes inherited by 'self' with `visibility >= min_visibility`.
+ fun collect_inherited_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+ var res = new HashSet[MAttribute]
+ for mproperty in collect_inherited_mproperties(min_visibility) do
+ if mproperty isa MAttribute then res.add(mproperty)
+ end
+ return res
+ end
+
+ # Collect all mattributes accessible by 'self' with `visibility >= min_visibility`.
+ #
+ # This include introduced, redefined, inherited mattributes.
+ fun collect_accessible_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+ var set = new HashSet[MAttribute]
+ set.add_all(collect_intro_mattributes(min_visibility))
+ set.add_all(collect_redef_mattributes(min_visibility))
+ set.add_all(collect_inherited_mattributes(min_visibility))
+ return set
+ end
+end
+
+redef class MClassDef
+ # Collect mpropdefs in 'self' with `visibility >= min_visibility`.
+ fun collect_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
+ var res = new HashSet[MPropDef]
+ for mpropdef in mpropdefs do
+ if mpropdef.mproperty.visibility < min_visibility then continue
+ res.add mpropdef
+ end
+ return res
+ end
+
+ # Collect mpropdefs introduced in 'self' with `visibility >= min_visibility`.
+ fun collect_intro_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
+ var res = new HashSet[MPropDef]
+ for mpropdef in mpropdefs do
+ if not mpropdef.is_intro then continue
+ if mpropdef.mproperty.visibility < min_visibility then continue
+ res.add mpropdef
+ end
+ return res
+ end
+
+ # Collect mpropdefs redefined in 'self' with `visibility >= min_visibility`.
+ fun collect_redef_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
+ var res = new HashSet[MPropDef]
+ for mpropdef in mpropdefs do
+ if mpropdef.is_intro then continue
+ if mpropdef.mproperty.visibility < min_visibility then continue
+ res.add mpropdef
+ end
+ return res
+ end
+
+ # Collect modifiers like redef, private etc.
+ fun collect_modifiers: Array[String] do
+ var res = new Array[String]
+ if not is_intro then
+ res.add "redef"
+ else
+ res.add mclass.visibility.to_s
+ end
+ res.add mclass.kind.to_s
+ return res
+ end
+end
+
+redef class MPropDef
+ # Collect modifiers like redef, private, abstract, intern, fun etc.
+ fun collect_modifiers: Array[String] do
+ var res = new Array[String]
+ if not is_intro then
+ res.add "redef"
+ else
+ res.add mproperty.visibility.to_s
+ end
+ var mprop = self
+ if mprop isa MVirtualTypeDef then
+ res.add "type"
+ else if mprop isa MMethodDef then
+ if mprop.is_abstract then
+ res.add "abstract"
+ else if mprop.is_intern then
+ res.add "intern"
+ end
+ if mprop.mproperty.is_init then
+ res.add "init"
+ else
+ res.add "fun"
+ end
+ end
+ return res
+ end
+end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2008 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.
-
-# Model exploration and traversing facilities
-module model_utils
-
-import model
-
-redef class MConcern
-
- # Boost a MConcern rank
- # see: `MConcernRankSorter`
- # Use a positive booster to push down a result in the list
- # A negative booster can be used to push up the result
- var booster_rank: Int = 0 is writable
-
- # Concern ranking used for ordering
- # see: `MConcernRankSorter`
- # Rank can be positive or negative
- fun concern_rank: Int is abstract
-end
-
-redef class MProject
- redef var concern_rank is lazy do
- var max = 0
- for mgroup in mgroups do
- var mmax = mgroup.concern_rank
- if mmax > max then max = mmax
- end
- return max + 1
- end
-end
-
-redef class MGroup
- fun in_nesting_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
- var res = new HashSet[MClass]
- var lst = in_nesting.direct_smallers
- for mmodule in mmodules do res.add_all mmodule.filter_intro_mclasses(min_visibility)
- for mgrp in lst do res.add_all mgrp.in_nesting_intro_mclasses(min_visibility)
- return res
- end
-
- fun in_nesting_redef_mclasses(min_visibility: MVisibility): Set[MClass] do
- var res = new HashSet[MClass]
- var lst = in_nesting.direct_smallers
- for mmodule in mmodules do res.add_all mmodule.filter_redef_mclasses(min_visibility)
- for mgrp in lst do res.add_all mgrp.in_nesting_redef_mclasses(min_visibility)
- return res
- end
-
- fun in_nesting_intro_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
- var res = new HashSet[MClassDef]
- var lst = in_nesting.direct_smallers
- for mmodule in mmodules do res.add_all mmodule.intro_mclassdefs(min_visibility)
- for mgrp in lst do res.add_all mgrp.in_nesting_intro_mclassdefs(min_visibility)
- return res
- end
-
- fun in_nesting_redef_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
- var res = new HashSet[MClassDef]
- var lst = in_nesting.direct_smallers
- for mmodule in mmodules do res.add_all mmodule.redef_mclassdefs(min_visibility)
- for mgrp in lst do res.add_all mgrp.in_nesting_redef_mclassdefs(min_visibility)
- return res
- end
-
- # Collect nested modules
- fun collect_mmodules: Set[MModule] do
- var res = new HashSet[MModule]
- res.add_all mmodules
- for mgroup in in_nesting.direct_smallers do
- res.add_all mgroup.collect_mmodules
- end
- return res
- end
-
- redef var concern_rank is lazy do
- var max = 0
- for mmodule in collect_mmodules do
- var mmax = mmodule.concern_rank
- if mmax > max then max = mmax
- end
- return max + 1
- end
-end
-
-redef class MModule
-
- # The list of intro mclassdef in the module.
- # with visibility >= to min_visibility
- fun intro_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
- var res = new HashSet[MClassDef]
- for mclassdef in mclassdefs do
- if not mclassdef.is_intro then continue
- if mclassdef.mclass.visibility < min_visibility then continue
- res.add mclassdef
- end
- return res
- end
-
- # The list of redef mclassdef in the module.
- # with visibility >= to min_visibility
- fun redef_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
- var res = new HashSet[MClassDef]
- for mclassdef in mclassdefs do
- if mclassdef.is_intro then continue
- if mclassdef.mclass.visibility < min_visibility then continue
- res.add mclassdef
- end
- return res
- end
-
- # The list of intro mclass in the module.
- # with visibility >= to min_visibility
- fun filter_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
- var res = new HashSet[MClass]
- for mclass in intro_mclasses do
- if mclass.visibility < min_visibility then continue
- res.add mclass
- end
- return res
- end
-
- # Get the list of mclasses refined in 'self'.
- fun redef_mclasses: Set[MClass] do
- var mclasses = new HashSet[MClass]
- for c in mclassdefs do
- if not c.is_intro then mclasses.add(c.mclass)
- end
- return mclasses
- end
-
- # Get the list of mclasses refined in 'self'.
- fun filter_redef_mclasses(min_visibility: MVisibility): Set[MClass] do
- var mclasses = new HashSet[MClass]
- for c in mclassdefs do
- if c.mclass.visibility < min_visibility then continue
- if not c.is_intro then mclasses.add(c.mclass)
- end
- return mclasses
- end
-
- # Get the list of all mclasses imported by 'self'.
- fun imported_mclasses: Set[MClass] do
- var mclasses = new HashSet[MClass]
- for m in in_importation.greaters do
- if m == self then continue
- for c in m.mclassdefs do mclasses.add(c.mclass)
- end
- return mclasses
- end
-
- redef var concern_rank is lazy do
- var max = 0
- for p in in_importation.direct_greaters do
- var pmax = p.concern_rank
- if pmax > max then max = pmax
- end
- return max + 1
- end
-
- # Find all mmodules nested in `self` if `self` is the default module of a `MGroup`.
- fun nested_mmodules: Array[MModule] do
- var res = new Array[MModule]
- var mgroup = mgroup
- if mgroup == null or self != mgroup.default_mmodule then return res
- for mmodule in mgroup.mmodules do
- if mmodule == self then continue
- res.add mmodule
- end
- for nested in mgroup.in_nesting.direct_smallers do
- var default = nested.default_mmodule
- if default == null then continue
- res.add default
- end
- return res
- end
-end
-
-redef class MClass
-
- # Get direct parents of 'self'.
- fun parents: Set[MClass] do
- var ret = new HashSet[MClass]
- for mclassdef in mclassdefs do
- for mclasstype in mclassdef.supertypes do
- ret.add(mclasstype.mclass)
- end
- end
- return ret
- end
-
- # Get all ancestors of 'self'.
- 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
- if super_mclassdef == mclassdef then continue # skip self
- lst.add(super_mclassdef.mclass)
- end
- end
- return lst
- end
-
- # Get direct children of 'self'.
- fun children: Set[MClass] do
- var lst = new HashSet[MClass]
- for mclassdef in self.mclassdefs do
- for sub_mclassdef in mclassdef.in_hierarchy.direct_smallers do
- if sub_mclassdef == mclassdef then continue # skip self
- lst.add(sub_mclassdef.mclass)
- end
- end
- return lst
- end
-
- # Get all children of 'self'.
- 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
- if sub_mclassdef == mclassdef then continue # skip self
- lst.add(sub_mclassdef.mclass)
- end
- end
- return lst
- end
-
- # Get the list of constructors available for 'self'.
- fun constructors: Set[MMethod] do
- var res = new HashSet[MMethod]
- for mclassdef in mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef isa MMethodDef then
- if mpropdef.mproperty.is_init then res.add(mpropdef.mproperty)
- end
- end
- end
- return res
- end
-
- # Get the list of methods introduced in 'self'.
- fun intro_methods: Set[MMethod] do
- var res = new HashSet[MMethod]
- for mclassdef in mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef isa MMethodDef then
- if mpropdef.is_intro and not mpropdef.mproperty.is_init then res.add(mpropdef.mproperty)
- end
- end
- end
- return res
- end
-
- # the set of properties introduced in 'self'.
- fun intro_mproperties(min_visibility: MVisibility): Set[MProperty] do
- var set = new HashSet[MProperty]
- for mclassdef in mclassdefs do
- for mprop in mclassdef.intro_mproperties do
- if mprop.visibility < min_visibility then continue
- set.add(mprop)
- end
- end
- return set
- end
-
- fun intro_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
- var set = new HashSet[MPropDef]
- for mclassdef in mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if not mpropdef.is_intro then continue
- if mpropdef.mproperty.visibility < min_visibility then continue
- set.add(mpropdef)
- end
- end
- return set
- end
-
- # the set of locally refined properties in 'self'.
- fun redef_mproperties(min_visibility: MVisibility): Set[MProperty] do
- var set = new HashSet[MProperty]
- for mclassdef in mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef.mproperty.visibility < min_visibility then continue
- if mpropdef.mproperty.intro_mclassdef.mclass != self then set.add(mpropdef.mproperty)
- end
- end
- return set
- end
-
- fun redef_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
- var set = new HashSet[MPropDef]
- for mclassdef in mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef.is_intro then continue
- if mpropdef.mproperty.visibility < min_visibility then continue
- set.add(mpropdef)
- end
- end
- return set
- end
-
- # the set of methods inherited by 'self'.
- fun inherited_mproperties(mainmodule: MModule, min_visibility: MVisibility): Set[MProperty] do
- var set = new HashSet[MProperty]
- for parent in in_hierarchy(mainmodule).direct_greaters do
- set.add_all(parent.intro_mproperties(min_visibility))
- set.add_all(parent.inherited_mproperties(mainmodule, min_visibility))
- end
- return set
- end
-
- # the set of introduced and redefined mproperties
- fun local_mproperties(min_visibility: MVisibility): Set[MProperty] do
- var set = new HashSet[MProperty]
- set.add_all(intro_mproperties(min_visibility))
- set.add_all(redef_mproperties(min_visibility))
- return set
- end
-
- # the set of all accessible mproperties for this class
- fun all_mproperties(mainmodule: MModule, min_visibility: MVisibility): Set[MProperty] do
- var set = new HashSet[MProperty]
- set.add_all(local_mproperties(min_visibility))
- set.add_all(inherited_mproperties(mainmodule, min_visibility))
- return set
- end
-
- # the set of all accessible mattributes for this class
- fun all_mattributes(mainmodule: MModule, min_visibility: MVisibility): Set[MAttribute] do
- var set = new HashSet[MAttribute]
- for mprop in all_mproperties(mainmodule, min_visibility) do
- if mprop isa MAttribute then set.add(mprop)
- end
- return set
- end
-
- # Get the list of locally refined methods in 'self'.
- fun redef_methods: Set[MMethod] do
- var res = new HashSet[MMethod]
- for mclassdef in mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef isa MMethodDef then
- if not mpropdef.is_intro and not mpropdef.mproperty.is_init then res.add(mpropdef.mproperty)
- end
- end
- end
- return res
- end
-
- fun inherited_methods: Set[MMethod] do
- var res = new HashSet[MMethod]
- for s in ancestors do
- for m in s.intro_methods do
- if not self.intro_methods.has(m) and not self.redef_methods.has(m) then res.add(m)
- end
- end
- return res
- end
-
- # Get the list of all virtual types available in 'self'.
- fun virtual_types: Set[MVirtualTypeProp] do
- var res = new HashSet[MVirtualTypeProp]
- for mclassdef in mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef isa MVirtualTypeDef then
- res.add(mpropdef.mproperty)
- end
- end
- end
- for ancestor in ancestors do
- for mclassdef in ancestor.mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef isa MVirtualTypeDef then
- res.add(mpropdef.mproperty)
- end
- end
- end
- end
- return res
- end
-
- # Get the list of all parameter types in 'self'.
- fun parameter_types: Map[String, MType] do
- var res = new HashMap[String, MType]
- for p in mparameters do
- res[p.name] = p
- end
- return res
- end
-
- fun is_class: Bool do
- return self.kind == concrete_kind or self.kind == abstract_kind
- end
-
- fun is_interface: Bool do
- return self.kind == interface_kind
- end
-
- fun is_enum: Bool do
- return self.kind == enum_kind
- end
-
- fun is_abstract: Bool do
- return self.kind == abstract_kind
- end
-end
-
-redef class MAttribute
- # Is this attribute nullable for sure?
- #
- # This mean that its introduction is declarred with a nullable static type
- # since attributes are invariant this will work on most cases
- # attributes with static type anchored with a virtual type are not "nullable for-sure"
- # because this type can be redefined in subclasses
- fun is_nullable: Bool do return intro.static_mtype isa MNullableType
-end
-
-redef class MClassDef
- # modifiers are keywords like redef, private etc.
- fun modifiers: Array[String] do
- var res = new Array[String]
- if not is_intro then
- res.add "redef"
- else
- res.add mclass.visibility.to_s
- end
- res.add mclass.kind.to_s
- return res
- end
-
- fun collect_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
- var res = new HashSet[MPropDef]
- for mpropdef in mpropdefs do
- if mpropdef.mproperty.visibility < min_visibility then continue
- res.add mpropdef
- end
- return res
- end
-
- fun collect_intro_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
- var res = new HashSet[MPropDef]
- for mpropdef in mpropdefs do
- if not mpropdef.is_intro then continue
- if mpropdef.mproperty.visibility < min_visibility then continue
- res.add mpropdef
- end
- return res
- end
-
- fun collect_redef_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
- var res = new HashSet[MPropDef]
- for mpropdef in mpropdefs do
- if mpropdef.is_intro then continue
- if mpropdef.mproperty.visibility < min_visibility then continue
- res.add mpropdef
- end
- return res
- end
-end
-
-redef class MPropDef
- # modifiers are keywords like redef, private etc.
- fun modifiers: Array[String] do
- var res = new Array[String]
- if not is_intro then
- res.add "redef"
- else
- res.add mproperty.visibility.to_s
- end
- var mprop = self
- if mprop isa MVirtualTypeDef then
- res.add "type"
- else if mprop isa MMethodDef then
- if mprop.is_abstract then
- res.add "abstract"
- else if mprop.is_intern then
- res.add "intern"
- end
- if mprop.mproperty.is_init then
- res.add "init"
- else
- res.add "fun"
- end
- end
- return res
- end
-end
-
-# Sorters
-
-# Sort mentities by their name
-class MEntityNameSorter
- super Comparator
- redef type COMPARED: MEntity
- redef fun compare(a, b) do return a.name <=> b.name
-end
-
-# Sort MConcerns based on the module importation hierarchy ranking
-# see also: `MConcern::concern_rank` and `MConcern::booster_rank`
-#
-# Comparison is made with the formula:
-#
-# ~~~nitish
-# a.concern_rank + a.booster_rank <=> b.concern_rank + b.booster_ran
-# ~~~
-#
-# If both `a` and `b` have the same ranking,
-# ordering is based on lexicographic comparison of `a.name` and `b.name`
-class MConcernRankSorter
- super Comparator
- redef type COMPARED: MConcern
-
- redef fun compare(a, b) do
- if a.concern_rank == b.concern_rank then
- return a.name <=> b.name
- end
- return a.concern_rank + a.booster_rank <=> b.concern_rank + b.booster_rank
- end
-end
import frontend
import rapid_type_analysis
-import model_utils
import template
# A Nit module
module test_neo
import neo
-import model_utils
+import model
import frontend
var test_name = "test_{get_time.to_s}"
module uml_base
import toolcontext
-import model_utils
+import model
redef class ToolContext
# -p
module uml_class
import uml_base
+import model::model_collect
redef class UMLModel
# Generates a UML class diagram from a `Model`
redef class MClass
- redef fun tpl_class(ctx, main): Writable do
+ redef fun tpl_class(ctx, main) do
var t = new Template
t.add "{name} [\n label = \"\{"
if kind == abstract_kind then
t.add "|"
var props: Collection[MProperty]
if ctx.private_gen then
- props = intro_mproperties(none_visibility)
+ props = collect_intro_mproperties(none_visibility)
else
- props = intro_mproperties(public_visibility)
+ props = collect_intro_mproperties(public_visibility)
end
for i in props do
if i isa MAttribute then
end
end
t.add "|"
- for i in intro_methods do
- if not ctx.private_gen and i.visibility != public_visibility then continue
+ var meths
+ if ctx.private_gen then
+ meths = collect_intro_mmethods(none_visibility)
+ else
+ meths = collect_intro_mmethods(public_visibility)
+ end
+ for i in meths do
t.add i.tpl_class(ctx, main)
t.add "\\l"
end
min: base_simple3 (1)
std: 0.0
sum: 1
-
-# MClasses metrics
-
- ## project base_simple3
- `- group base_simple3
- cnoa: number of ancestor classes
- avg: 0.0
- max: Bool (1)
- min: Object (0)
- std: 0.926
- sum: 6
- cnop: number of parent classes
- avg: 0.0
- max: Bool (1)
- min: Object (0)
- std: 0.926
- sum: 6
- cnoc: number of child classes
- avg: 0.0
- max: Object (6)
- min: Bool (0)
- std: 2.268
- sum: 6
- cnod: number of descendant classes
- avg: 0.0
- max: Object (6)
- min: Bool (0)
- std: 2.268
- sum: 6
- cdit: depth in class tree
- avg: 0.0
- max: Bool (1)
- min: Object (0)
- std: 0.926
- sum: 6
- cnbp: number of accessible properties (inherited + local)
- avg: 3.0
- max: C (7)
- min: Object (1)
- std: 2.36
- sum: 24
- cnba: number of accessible attributes (inherited + local)
- avg: 0.0
- max: C (2)
- min: Object (0)
- std: 0.845
- sum: 3
- cnbip: number of introduced properties
- avg: 2.0
- max: C (6)
- min: Bool (0)
- std: 2.268
- sum: 18
- cnbrp: number of redefined properties
- avg: 0.0
- max: A (1)
- min: Object (0)
- std: 0.535
- sum: 2
- cnbhp: number of inherited properties
- avg: 0.0
- max: Bool (1)
- min: Object (0)
- std: 0.926
- sum: 6
-
- ## global metrics
- cnoa: number of ancestor classes
- avg: 0.0
- max: Bool (1)
- min: Object (0)
- std: 0.926
- sum: 6
- cnop: number of parent classes
- avg: 0.0
- max: Bool (1)
- min: Object (0)
- std: 0.926
- sum: 6
- cnoc: number of child classes
- avg: 0.0
- max: Object (6)
- min: Bool (0)
- std: 2.268
- sum: 6
- cnod: number of descendant classes
- avg: 0.0
- max: Object (6)
- min: Bool (0)
- std: 2.268
- sum: 6
- cdit: depth in class tree
- avg: 0.0
- max: Bool (1)
- min: Object (0)
- std: 0.926
- sum: 6
- cnbp: number of accessible properties (inherited + local)
- avg: 3.0
- max: C (7)
- min: Object (1)
- std: 2.36
- sum: 24
- cnba: number of accessible attributes (inherited + local)
- avg: 0.0
- max: C (2)
- min: Object (0)
- std: 0.845
- sum: 3
- cnbip: number of introduced properties
- avg: 2.0
- max: C (6)
- min: Bool (0)
- std: 2.268
- sum: 18
- cnbrp: number of redefined properties
- avg: 0.0
- max: A (1)
- min: Object (0)
- std: 0.535
- sum: 2
- cnbhp: number of inherited properties
- avg: 0.0
- max: Bool (1)
- min: Object (0)
- std: 0.926
- sum: 6
--- Metrics of refinement usage ---
Number of modules: 1
bivariants: 0 (na%)
invariants: 0 (na%)
total: 0
+
+# MClasses metrics
+
+ ## project base_simple3
+ `- group base_simple3
+ cnoa: number of ancestor classes
+ avg: 0.0
+ max: Bool (1)
+ min: Object (0)
+ std: 0.926
+ sum: 6
+ cnop: number of parent classes
+ avg: 0.0
+ max: Bool (1)
+ min: Object (0)
+ std: 0.926
+ sum: 6
+ cnoc: number of child classes
+ avg: 0.0
+ max: Object (6)
+ min: Bool (0)
+ std: 2.268
+ sum: 6
+ cnod: number of descendant classes
+ avg: 0.0
+ max: Object (6)
+ min: Bool (0)
+ std: 2.268
+ sum: 6
+ cdit: depth in class tree
+ avg: 0.0
+ max: Bool (1)
+ min: Object (0)
+ std: 0.926
+ sum: 6
+ cnbp: number of accessible properties (inherited + local)
+ avg: 3.0
+ max: C (7)
+ min: Object (1)
+ std: 2.36
+ sum: 24
+ cnba: number of accessible attributes (inherited + local)
+ avg: 0.0
+ max: C (2)
+ min: Object (0)
+ std: 0.845
+ sum: 3
+ cnbip: number of introduced properties
+ avg: 2.0
+ max: C (6)
+ min: Bool (0)
+ std: 2.268
+ sum: 18
+ cnbrp: number of redefined properties
+ avg: 0.0
+ max: A (1)
+ min: Object (0)
+ std: 0.535
+ sum: 2
+ cnbhp: number of inherited properties
+ avg: 0.0
+ max: Bool (1)
+ min: Object (0)
+ std: 0.926
+ sum: 6
+
+ ## global metrics
+ cnoa: number of ancestor classes
+ avg: 0.0
+ max: Bool (1)
+ min: Object (0)
+ std: 0.926
+ sum: 6
+ cnop: number of parent classes
+ avg: 0.0
+ max: Bool (1)
+ min: Object (0)
+ std: 0.926
+ sum: 6
+ cnoc: number of child classes
+ avg: 0.0
+ max: Object (6)
+ min: Bool (0)
+ std: 2.268
+ sum: 6
+ cnod: number of descendant classes
+ avg: 0.0
+ max: Object (6)
+ min: Bool (0)
+ std: 2.268
+ sum: 6
+ cdit: depth in class tree
+ avg: 0.0
+ max: Bool (1)
+ min: Object (0)
+ std: 0.926
+ sum: 6
+ cnbp: number of accessible properties (inherited + local)
+ avg: 3.0
+ max: C (7)
+ min: Object (1)
+ std: 2.36
+ sum: 24
+ cnba: number of accessible attributes (inherited + local)
+ avg: 0.0
+ max: C (2)
+ min: Object (0)
+ std: 0.845
+ sum: 3
+ cnbip: number of introduced properties
+ avg: 2.0
+ max: C (6)
+ min: Bool (0)
+ std: 2.268
+ sum: 18
+ cnbrp: number of redefined properties
+ avg: 0.0
+ max: A (1)
+ min: Object (0)
+ std: 0.535
+ sum: 2
+ cnbhp: number of inherited properties
+ avg: 0.0
+ max: Bool (1)
+ min: Object (0)
+ std: 0.926
+ sum: 6
generating project_hierarchy.dot
generating module_hierarchy.dot
# Mendel metrics
large mclasses (threshold: 3.354)
Sys: 4
- budding mclasses (threshold: 3.51)
- Sys: 4.0
- blooming mclasses (threshold: 12.0)
- Sys: 16.0
+ budding mclasses (threshold: 4.177)
+ Sys: 5.0
+ blooming mclasses (threshold: 14.626)
+ Sys: 20.0
--- Detection of the usage of covariance static type conformance ---
-- Total --
- Kinds of the subtype -
fontsize = 8
]
Object [
- label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ sys(): Sys\l}"
+ label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ sys(): Sys\l+ init()\l}"
]
Sys [
fontsize = 8
]
Object [
- label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ sys(): Sys\l}"
+ label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ sys(): Sys\l+ init()\l}"
]
Sys [