Print class tables metrics for the classes of the program main

Property definitions

nitc :: tables_metrics $ Sys :: compute_tables_metrics
# Print class tables metrics for the classes of the program main
fun compute_tables_metrics(main: MModule)
do
	var nc = 0 # Number of runtime classes
	var nl = 0 # Number of usages of class definitions (a class definition can be used more than once)
	var nhp = 0 # Number of usages of properties (a property can be used more than once)
	var npas = 0 # Number of usages of properties without lookup (easy easy case, easier that CHA)

	# Collect the full class hierarchy
	var hier = main.flatten_mclass_hierarchy
	for c in hier do
		# Skip classes without direct instances
		if c.kind == interface_kind or c.kind == abstract_kind then continue

		nc += 1

		# Now, we need to collect all properties defined/inherited/imported
		# So, visit all definitions of all super-classes
		for sup in hier[c].greaters do
			for cd in sup.mclassdefs do
				nl += 1

				# Now, search properties introduced
				for p in cd.intro_mproperties do

					nhp += 1
					# Select property definition
					if p.mpropdefs.length == 1 then
						npas += 1
					else
						var sels = p.lookup_definitions(main, c.intro.bound_mtype)
						if sels.length > 1 then
							print "conflict for {p.full_name} in class {c.full_name}: {sels.join(", ")}"
						else if sels.is_empty then
							print "ERROR: no property for {p.full_name} in class {c.full_name}!"
						end
					end
				end
			end
		end
	end

	print "--- Construction of tables ---"
	print "Number of runtime classes: {nc} (excluding interfaces and abstract classes)"
	print "Average number of composing class definition by runtime class: {div(nl,nc)}"
	print "Total size of tables (classes and instances): {nhp} (not including stuff like info for subtyping or call-next-method)"
	print "Average size of table by runtime class: {div(nhp,nc)}"
	print "Values never redefined: {npas} ({div(npas*100,nhp)}%)"
end
src/metrics/tables_metrics.nit:35,1--83,3