Collect metrics about inheritance usage

Introduced classes

class CDITC

nitc :: CDITC

MClass metric: Class Depth in Inheritance Tree
class CDITI

nitc :: CDITI

MClass metric: Interface Depth in Inheritance Tree
class CNOAA

nitc :: CNOAA

MClass metric: Number of Abstract Class Ancestors
class CNOAC

nitc :: CNOAC

MClass metric: Number of Class Ancestors
class CNOAI

nitc :: CNOAI

MClass metric: Number of Interface Ancestors
class CNOCC

nitc :: CNOCC

MClass metric: Number of Class Children
class CNOCI

nitc :: CNOCI

MClass metric: Number of Interface Children
class CNODC

nitc :: CNODC

MClass metric: Number of Class Descendants
class CNODI

nitc :: CNODI

MClass metric: Number of Interface Descendants
class CNOPC

nitc :: CNOPC

MClass metric: Number of Class Parents
class CNOPI

nitc :: CNOPI

MClass metric: Number of Interface Parents
private class InheritanceMetricsPhase

nitc :: InheritanceMetricsPhase

Extract metrics about inheritance from model.
class MDUI

nitc :: MDUI

Module metric: proportion of MClasses Defined Using Inheritance
class MDUIC

nitc :: MDUIC

Module metric: proportion of abstract, concrete and extern Classes Defined Using Inheritance
class MDUII

nitc :: MDUII

Module metric: proportion of Interface Defined Using Inheritance
class MIF

nitc :: MIF

Module metric: proportion of MClass Inherited From
class MIFC

nitc :: MIFC

Module metric: proportion of abstract, concrete and extern Class Inherited From
class MIFI

nitc :: MIFI

Module metric: proportion of Interface Inherited From

Redefined classes

redef class MClass

nitc :: inheritance_metrics $ MClass

A named class
redef class ToolContext

nitc :: inheritance_metrics $ ToolContext

Global context for tools

All class definitions

class CDITC

nitc $ CDITC

MClass metric: Class Depth in Inheritance Tree
class CDITI

nitc $ CDITI

MClass metric: Interface Depth in Inheritance Tree
class CNOAA

nitc $ CNOAA

MClass metric: Number of Abstract Class Ancestors
class CNOAC

nitc $ CNOAC

MClass metric: Number of Class Ancestors
class CNOAI

nitc $ CNOAI

MClass metric: Number of Interface Ancestors
class CNOCC

nitc $ CNOCC

MClass metric: Number of Class Children
class CNOCI

nitc $ CNOCI

MClass metric: Number of Interface Children
class CNODC

nitc $ CNODC

MClass metric: Number of Class Descendants
class CNODI

nitc $ CNODI

MClass metric: Number of Interface Descendants
class CNOPC

nitc $ CNOPC

MClass metric: Number of Class Parents
class CNOPI

nitc $ CNOPI

MClass metric: Number of Interface Parents
private class InheritanceMetricsPhase

nitc $ InheritanceMetricsPhase

Extract metrics about inheritance from model.
redef class MClass

nitc :: inheritance_metrics $ MClass

A named class
class MDUI

nitc $ MDUI

Module metric: proportion of MClasses Defined Using Inheritance
class MDUIC

nitc $ MDUIC

Module metric: proportion of abstract, concrete and extern Classes Defined Using Inheritance
class MDUII

nitc $ MDUII

Module metric: proportion of Interface Defined Using Inheritance
class MIF

nitc $ MIF

Module metric: proportion of MClass Inherited From
class MIFC

nitc $ MIFC

Module metric: proportion of abstract, concrete and extern Class Inherited From
class MIFI

nitc $ MIFI

Module metric: proportion of Interface Inherited From
redef class ToolContext

nitc :: inheritance_metrics $ ToolContext

Global context for tools
package_diagram nitc::inheritance_metrics inheritance_metrics nitc::mmodules_metrics mmodules_metrics nitc::inheritance_metrics->nitc::mmodules_metrics nitc::mclasses_metrics mclasses_metrics nitc::inheritance_metrics->nitc::mclasses_metrics nitc::metrics_base metrics_base nitc::mmodules_metrics->nitc::metrics_base nitc::model_collect model_collect nitc::mmodules_metrics->nitc::model_collect nitc::mclasses_metrics->nitc::metrics_base nitc::mclasses_metrics->nitc::model_collect ...nitc::metrics_base ... ...nitc::metrics_base->nitc::metrics_base ...nitc::model_collect ... ...nitc::model_collect->nitc::model_collect nitc::metrics metrics nitc::metrics->nitc::inheritance_metrics nitc::nitmetrics nitmetrics nitc::nitmetrics->nitc::metrics nitc::api_metrics api_metrics nitc::api_metrics->nitc::metrics nitc::nitmetrics... ... nitc::nitmetrics...->nitc::nitmetrics nitc::api_metrics... ... nitc::api_metrics...->nitc::api_metrics

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module annotation

nitc :: annotation

Management and utilities on annotations
module array

core :: array

This module introduces the standard array structure.
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module caching

serialization :: caching

Services for caching serialization engines
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module console

console :: console

Defines some ANSI Terminal Control Escape Sequences.
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module counter

counter :: counter

Simple numerical statistical analysis and presentation
module csv

csv :: csv

CSV document handling.
module digraph

graph :: digraph

Implementation of directed graphs, also called digraphs.
module engine_tools

serialization :: engine_tools

Advanced services for serialization engines
module environ

core :: environ

Access to the environment variables of the process
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module ini

ini :: ini

Read and write INI configuration files
module inspect

serialization :: inspect

Refine Serializable::inspect to show more useful information
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module kernel

core :: kernel

Most basic classes and methods.
module lexer

nitc :: lexer

Lexer and its tokens.
module lexer_work

nitc :: lexer_work

Internal algorithm and data structures for the Nit lexer
module list

core :: list

This module handle double linked lists
module literal

nitc :: literal

Parsing of literal values in the abstract syntax tree.
module loader

nitc :: loader

Loading of Nit source files
module location

nitc :: location

Nit source-file and locations in source-file
module math

core :: math

Mathematical operations
module mdoc

nitc :: mdoc

Documentation of model entities
module meta

meta :: meta

Simple user-defined meta-level to manipulate types of instances as object.
module metrics_base

nitc :: metrics_base

Helpers for various statistics tools.
module mmodule

nitc :: mmodule

modules and module hierarchies in the metamodel
module mmodule_data

nitc :: mmodule_data

Define and retrieve data in modules
module model

nitc :: model

Classes, types and properties
module model_base

nitc :: model_base

The abstract concept of model and related common things
module model_collect

nitc :: model_collect

Collect things from the model.
module model_examples

nitc :: model_examples

Examples for Model entities
module modelbuilder_base

nitc :: modelbuilder_base

Load nit source files and build the associated model
module modelize_class

nitc :: modelize_class

Analysis and verification of class definitions to instantiate model element
module modelize_property

nitc :: modelize_property

Analysis and verification of property definitions to instantiate model element
module more_collections

more_collections :: more_collections

Highly specific, but useful, collections-related classes.
module mpackage

nitc :: mpackage

Modelisation of a Nit package
module native

core :: native

Native structures for text and bytes
module nitpm_shared

nitc :: nitpm_shared

Services related to the Nit package manager
module numeric

core :: numeric

Advanced services for Numeric types
module opts

opts :: opts

Management of options on the command line
module ordered_tree

ordered_tree :: ordered_tree

Manipulation and presentation of ordered trees.
module parse_annotations

nitc :: parse_annotations

Simple annotation parsing
module parser

nitc :: parser

Parser.
module parser_nodes

nitc :: parser_nodes

AST nodes of the Nit language
module parser_prod

nitc :: parser_prod

Production AST nodes full definition.
module parser_work

nitc :: parser_work

Internal algorithm and data structures for the Nit parser
module phase

nitc :: phase

Phases of the processing of nit programs
module poset

poset :: poset

Pre order sets and partial order set (ie hierarchies)
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module serialization

serialization :: serialization

General serialization services
module serialization_core

serialization :: serialization_core

Abstract services to serialize Nit objects to different formats
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module stream

core :: stream

Input and output streams of characters
module tables

nitc :: tables

Module that interfaces the parsing tables.
module template

template :: template

Basic template system
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module toolcontext

nitc :: toolcontext

Common command-line tool infrastructure than handle options and error messages
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O
module version

nitc :: version

This file was generated by git-gen-version.sh

Parents

module mclasses_metrics

nitc :: mclasses_metrics

Collect common metrics about mclasses
module mmodules_metrics

nitc :: mmodules_metrics

Collect common metrics about modules

Children

module metrics

nitc :: metrics

Various statistics about Nit models and programs

Descendants

module a_star-m

a_star-m

module api

nitc :: api

Components required to build a web server about the nit model.
module nitmetrics

nitc :: nitmetrics

A program that collects various metrics on nit programs and libraries
module nitweb

nitc :: nitweb

Runs a webserver based on nitcorn that render things from model.
# Collect metrics about inheritance usage
module inheritance_metrics

import metrics_base
import mmodules_metrics
import mclasses_metrics

redef class ToolContext

	# Inheritance related metrics phase
	var inheritance_metrics_phase: Phase = new InheritanceMetricsPhase(self, null)
end

# Extract metrics about inheritance from model.
private class InheritanceMetricsPhase
	super Phase
	redef fun process_mainmodule(mainmodule, given_mmodules)
	do
		if not toolcontext.opt_inheritance.value and not toolcontext.opt_all.value then return
		var csv = toolcontext.opt_csv.value
		var out = "{toolcontext.opt_dir.value or else "metrics"}/inheritance"
		out.mkdir

		var model = toolcontext.modelbuilder.model
		var filter = new ModelFilter(min_visibility = private_visibility)

		print toolcontext.format_h1("\n# Inheritance metrics")

		var hmetrics = new MetricSet
		hmetrics.register(new MDUI(model, mainmodule))
		hmetrics.register(new MDUIC(model, mainmodule))
		hmetrics.register(new MDUII(model, mainmodule))
		hmetrics.register(new MIF(model, mainmodule))
		hmetrics.register(new MIFC(model, mainmodule))
		hmetrics.register(new MIFI(model, mainmodule))

		var cmetrics = new MetricSet
		cmetrics.register(new CNOAC(model, mainmodule, filter))
		cmetrics.register(new CNOPC(model, mainmodule, filter))
		cmetrics.register(new CNOCC(model, mainmodule, filter))
		cmetrics.register(new CNODC(model, mainmodule, filter))
		cmetrics.register(new CNOPI(model, mainmodule, filter))
		cmetrics.register(new CNOCI(model, mainmodule, filter))
		cmetrics.register(new CNODI(model, mainmodule, filter))
		cmetrics.register(new CDITC(model, mainmodule, filter))
		cmetrics.register(new CDITI(model, mainmodule, filter))

		var mmodules = new HashSet[MModule]
		var mclasses = new HashSet[MClass]
		for mpackage in model.mpackages do

			print toolcontext.format_h2("\n ## package {mpackage}")

			for mgroup in mpackage.mgroups do
				if mgroup.mmodules.is_empty then continue

				# Scalar metrics
				print toolcontext.format_h3("  `- group {mgroup.full_name}")

				var mod_mclasses = new HashSet[MClass]
				for mmodule in mgroup.mmodules do mod_mclasses.add_all(mmodule.intro_mclasses)
				if mod_mclasses.is_empty then continue
				mmodules.add_all(mgroup.mmodules)
				mclasses.add_all(mod_mclasses)
				cmetrics.clear
				cmetrics.collect(new HashSet[MClass].from(mod_mclasses))
				cmetrics.to_console(1, not toolcontext.opt_nocolors.value)
				if csv then cmetrics.to_csv.write_to_file("{out}/{mgroup}_classes.csv")
				hmetrics.clear
				hmetrics.collect(new HashSet[MModule].from(mgroup.mmodules))
				hmetrics.to_console(1, not toolcontext.opt_nocolors.value)
				if csv then hmetrics.to_csv.write_to_file("{out}/{mgroup}_inheritance.csv")
			end
		end
		if not mclasses.is_empty then
			# Global metrics
			print toolcontext.format_h2("\n ## global metrics")
			cmetrics.clear
			cmetrics.collect(mclasses)
			cmetrics.to_console(1, not toolcontext.opt_nocolors.value)
			if csv then cmetrics.to_csv.write_to_file("{out}/summary_classes.csv")
			hmetrics.clear
			hmetrics.collect(mmodules)
			hmetrics.to_console(1, not toolcontext.opt_nocolors.value)
			if csv then hmetrics.to_csv.write_to_file("{out}/summary_inheritance.csv")
		end
	end
end

# Module metric: proportion of MClasses Defined Using Inheritance
#
# Count MClasses that have another parents than Object
class MDUI
	super MModuleMetric
	super FloatMetric
	redef fun name do return "mdui"
	redef fun desc do return "proportion of mclass defined using inheritance (has other parent than Object)"

	redef fun collect(mmodules) do
		for mmodule in mmodules do
			var count = 0
			for mclass in mmodule.intro_mclasses do
				if mclass.in_hierarchy(mainmodule).greaters.length > 2 then count += 1
			end
			if mmodule.intro_mclasses.is_empty then
				values[mmodule] = 0.0
			else
				values[mmodule] = count.to_f / mmodule.intro_mclasses.length.to_f
			end
		end
	end
end

# Module metric: proportion of abstract, concrete and extern Classes Defined Using Inheritance
#
# Count classes that have another parents than Object
class MDUIC
	super MModuleMetric
	super FloatMetric
	redef fun name do return "mduic"
	redef fun desc do return "proportion of class_kind defined using inheritance"

	redef fun collect(mmodules) do
		for mmodule in mmodules do
			var count = 0
			var nb = 0
			for mclass in mmodule.intro_mclasses do
				if mclass.kind == abstract_kind or mclass.kind == concrete_kind or mclass.kind == extern_kind then
					if mclass.in_hierarchy(mainmodule).greaters.length > 2 then count += 1
				end
				nb += 1
			end
			if mmodule.intro_mclasses.is_empty then
				values[mmodule] = 0.0
			else
				values[mmodule] = count.to_f / nb.to_f
			end
		end
	end
end

# Module metric: proportion of Interface Defined Using Inheritance
#
# Count interface that have another parents than Object
class MDUII
	super MModuleMetric
	super FloatMetric
	redef fun name do return "mduii"
	redef fun desc do return "proportion of interface_kind defined using inheritance"

	redef fun collect(mmodules) do
		for mmodule in mmodules do
			var count = 0
			var nb = 0
			for mclass in mmodule.intro_mclasses do
				if mclass.kind == interface_kind then
					if mclass.in_hierarchy(mainmodule).greaters.length > 2 then count += 1
				end
				nb += 1
			end
			if mmodule.intro_mclasses.is_empty then
				values[mmodule] = 0.0
			else
				values[mmodule] = count.to_f / nb.to_f
			end
		end
	end
end

# Module metric: proportion of MClass Inherited From
#
# Count classes that have at least a child
class MIF
	super MModuleMetric
	super FloatMetric
	redef fun name do return "mif"
	redef fun desc do return "proportion of mclass inherited from"

	redef fun collect(mmodules) do
		for mmodule in mmodules do
			var count = 0
			for mclass in mmodule.intro_mclasses do
				if mclass.in_hierarchy(mainmodule).direct_smallers.length > 0 then count += 1
			end
			if mmodule.intro_mclasses.is_empty then
				values[mmodule] = 0.0
			else
				values[mmodule] = count.to_f / mmodule.intro_mclasses.length.to_f
			end
		end
	end
end

# Module metric: proportion of abstract, concrete and extern Class Inherited From
#
# Count classes that have at least a child
class MIFC
	super MModuleMetric
	super FloatMetric
	redef fun name do return "mifc"
	redef fun desc do return "proportion of class_kind inherited from"

	redef fun collect(mmodules) do
		for mmodule in mmodules do
			var count = 0
			var nb = 0
			for mclass in mmodule.intro_mclasses do
				if mclass.kind == abstract_kind or mclass.kind == concrete_kind or mclass.kind == extern_kind then
					if mclass.in_hierarchy(mainmodule).direct_smallers.length > 0 then count += 1
				end
				nb += 1
			end
			if mmodule.intro_mclasses.is_empty then
				values[mmodule] = 0.0
			else
				values[mmodule] = count.to_f / nb.to_f
			end
		end
	end
end

# Module metric: proportion of Interface Inherited From
#
# Count interfaces that have at least a child
class MIFI
	super MModuleMetric
	super FloatMetric
	redef fun name do return "mifi"
	redef fun desc do return "proportion of interface_kind inherited from"

	redef fun collect(mmodules) do
		for mmodule in mmodules do
			var count = 0
			var nb = 0
			for mclass in mmodule.intro_mclasses do
				if mclass.kind == interface_kind then
					if mclass.in_hierarchy(mainmodule).direct_smallers.length > 0 then count += 1
				end
				nb += 1
			end
			if mmodule.intro_mclasses.is_empty then
				values[mmodule] = 0.0
			else
				values[mmodule] = count.to_f / nb.to_f
			end
		end
	end
end

# MClass metric: Number of Class Ancestors
#
# Count only absrtract, concrete and extern classes
class CNOAC
	super MClassMetric
	super IntMetric
	redef fun name do return "cnoac"
	redef fun desc do return "number of class_kind ancestor"

	redef fun collect(mclasses) do
		for mclass in mclasses do
			var count = 0
			for parent in mclass.in_hierarchy(mainmodule).greaters do
				if parent == mclass then continue
				if parent.kind == abstract_kind or parent.kind == concrete_kind or parent.kind == extern_kind then
					count += 1
				end
			end
			values[mclass] = count
		end
	end
end

# MClass metric: Number of Class Parents
#
# Count only absrtract, concrete and extern classes
class CNOPC
	super MClassMetric
	super IntMetric
	redef fun name do return "cnopc"
	redef fun desc do return "number of class_kind parent"

	redef fun collect(mclasses) do
		for mclass in mclasses do
			var count = 0
			for parent in mclass.in_hierarchy(mainmodule).direct_greaters do
				if parent == mclass then continue
				if parent.kind == abstract_kind or parent.kind == concrete_kind or parent.kind == extern_kind then
					count += 1
				end
			end
			values[mclass] = count
		end
	end
end

# MClass metric: Number of Class Children
#
# Count only absrtract, concrete and extern classes
class CNOCC
	super MClassMetric
	super IntMetric
	redef fun name do return "cnocc"
	redef fun desc do return "number of class_kind children"

	redef fun collect(mclasses) do
		for mclass in mclasses do
			var count = 0
			for parent in mclass.in_hierarchy(mainmodule).direct_smallers do
				if parent == mclass then continue
				if parent.kind == abstract_kind or parent.kind == concrete_kind or parent.kind == extern_kind then
					count += 1
				end
			end
			values[mclass] = count
		end
	end
end

# MClass metric: Number of Class Descendants
#
# Count only absrtract, concrete and extern classes
class CNODC
	super MClassMetric
	super IntMetric
	redef fun name do return "cnodc"
	redef fun desc do return "number of class_kind descendants"

	redef fun collect(mclasses) do
		for mclass in mclasses do
			var count = 0
			for parent in mclass.in_hierarchy(mainmodule).smallers do
				if parent == mclass then continue
				if parent.kind == abstract_kind or parent.kind == concrete_kind or parent.kind == extern_kind then
					count += 1
				end
			end
			values[mclass] = count
		end
	end
end

# MClass metric: Number of Abstract Class Ancestors
#
# Count only absrtract classes
class CNOAA
	super MClassMetric
	super IntMetric
	redef fun name do return "cnoaa"
	redef fun desc do return "number of abstract class ancestors"

	redef fun collect(mclasses) do
		for mclass in mclasses do
			var count = 0
			for parent in mclass.in_hierarchy(mainmodule).greaters do
				if parent == mclass then continue
				if parent.kind == abstract_kind then
					count += 1
				end
			end
			values[mclass] = count
		end
	end
end

# MClass metric: Number of Interface Ancestors
#
# Count only interfaces
class CNOAI
	super MClassMetric
	super IntMetric
	redef fun name do return "cnoai"
	redef fun desc do return "number of interface_kind ancestor"

	redef fun collect(mclasses) do
		for mclass in mclasses do
			var count = 0
			for parent in mclass.in_hierarchy(mainmodule).greaters do
				if parent == mclass then continue
				if parent.kind == interface_kind then
					count += 1
				end
			end
			values[mclass] = count
		end
	end
end

# MClass metric: Number of Interface Parents
#
# Count only interfaces
class CNOPI
	super MClassMetric
	super IntMetric
	redef fun name do return "cnopi"
	redef fun desc do return "number of interface_kind parent"

	redef fun collect(mclasses) do
		for mclass in mclasses do
			var count = 0
			for parent in mclass.in_hierarchy(mainmodule).direct_greaters do
				if parent == mclass then continue
				if parent.kind == interface_kind then
					count += 1
				end
			end
			values[mclass] = count
		end
	end
end

# MClass metric: Number of Interface Children
#
# Count only interfaces
class CNOCI
	super MClassMetric
	super IntMetric
	redef fun name do return "cnoci"
	redef fun desc do return "number of interface_kind children"

	redef fun collect(mclasses) do
		for mclass in mclasses do
			var count = 0
			for parent in mclass.in_hierarchy(mainmodule).direct_smallers do
				if parent == mclass then continue
				if parent.kind == interface_kind then
					count += 1
				end
			end
			values[mclass] = count
		end
	end
end

# MClass metric: Number of Interface Descendants
#
# Count only interfaces
class CNODI
	super MClassMetric
	super IntMetric
	redef fun name do return "cnodi"
	redef fun desc do return "number of interface_kind descendants"

	redef fun collect(mclasses) do
		for mclass in mclasses do
			var count = 0
			for parent in mclass.in_hierarchy(mainmodule).smallers do
				if parent == mclass then continue
				if parent.kind == interface_kind then
					count += 1
				end
			end
			values[mclass] = count
		end
	end
end

# MClass metric: Class Depth in Inheritance Tree
#
# Following the longest path composed only of extends edges from self to Object
class CDITC
	super MClassMetric
	super IntMetric
	redef fun name do return "cditc"
	redef fun desc do return "depth in class tree following only class, abstract, extern kind"

	redef fun collect(mclasses) do
		for mclass in mclasses do
			values[mclass] = mclass.ditc(mainmodule)
		end
	end
end

# MClass metric: Interface Depth in Inheritance Tree
#
# Following the longest path composed only of implements edges from self to Object
class CDITI
	super MClassMetric
	super IntMetric
	redef fun name do return "cditi"
	redef fun desc do return "depth in class tree following only interface_kind"

	redef fun collect(mclasses) do
		for mclass in mclasses do
			values[mclass] = mclass.diti(mainmodule)
		end
	end
end

# model redef

redef class MClass

	# Class Depth in Inheritance Tree
	#
	# Following the longest path composed only of extends edges from self to Object
	fun ditc(mainmodule: MModule): Int do
		if in_hierarchy(mainmodule).direct_greaters.is_empty then
			return 0
		end
		var min = -1
		for p in in_hierarchy(mainmodule).direct_greaters do
			if p.kind != abstract_kind and p.kind != concrete_kind and p.kind != extern_kind then continue
			var d = p.ditc(mainmodule) + 1
			if min == -1 or d < min then
				min = d
			end
		end
		if min == -1 then min = 0
		return min
	end

	# Interface Depth in Inheritance Tree
	#
	# Following the longest path composed only of implements edges from self to Object
	fun diti(mainmodule: MModule): Int do
		if in_hierarchy(mainmodule).direct_greaters.is_empty then
			return 0
		end
		var min = -1
		for p in in_hierarchy(mainmodule).direct_greaters do
			if p.kind != interface_kind then continue
			var d = p.diti(mainmodule) + 1
			if min == -1 or d < min then
				min = d
			end
		end
		if min == -1 then min = 0
		return min
	end
end
src/metrics/inheritance_metrics.nit:17,1--546,3