Generate graphiz files based on packages, groups and modules

Interesting elements must be selected. See mmodules, ` Display configuration can be set. Seecluster_group,package_group`

Introduced properties

private var _cluster_group: Bool

nitc :: MPackageDot :: _cluster_group

Should groups be shown as clusters?
private var _mmodules: HashSet[MModule]

nitc :: MPackageDot :: _mmodules

Set of modules to display
private var _model: Model

nitc :: MPackageDot :: _model

The model where to look for information
private var _mpackages: HashSet[MPackage]

nitc :: MPackageDot :: _mpackages

Set of packages to expand fully (ie all groups and modules are displayed)
private var _package_group: Bool

nitc :: MPackageDot :: _package_group

Should packages be shown as clusters?
fun cluster_group: Bool

nitc :: MPackageDot :: cluster_group

Should groups be shown as clusters?
fun cluster_group=(cluster_group: Bool)

nitc :: MPackageDot :: cluster_group=

Should groups be shown as clusters?
fun collect_important_importation

nitc :: MPackageDot :: collect_important_importation

Extends the set of mmodules by recursively adding the most specific imported modules of foreign packages
private fun dot_cluster(o: Writer, mgroup: MGroup)

nitc :: MPackageDot :: dot_cluster

Recursively generate node and clusters for a mgroup
fun mmodules: HashSet[MModule]

nitc :: MPackageDot :: mmodules

Set of modules to display
protected fun mmodules=(mmodules: HashSet[MModule])

nitc :: MPackageDot :: mmodules=

Set of modules to display
fun model: Model

nitc :: MPackageDot :: model

The model where to look for information
protected fun model=(model: Model)

nitc :: MPackageDot :: model=

The model where to look for information
fun mpackages: HashSet[MPackage]

nitc :: MPackageDot :: mpackages

Set of packages to expand fully (ie all groups and modules are displayed)
protected fun mpackages=(mpackages: HashSet[MPackage])

nitc :: MPackageDot :: mpackages=

Set of packages to expand fully (ie all groups and modules are displayed)
private fun node_for(mmodule: MModule): String

nitc :: MPackageDot :: node_for

fun package_group: Bool

nitc :: MPackageDot :: package_group

Should packages be shown as clusters?
fun package_group=(package_group: Bool)

nitc :: MPackageDot :: package_group=

Should packages be shown as clusters?

Redefined properties

redef type SELF: MPackageDot

nitc $ MPackageDot :: SELF

Type of this instance, automatically specialized in every class
redef fun write_to(stream: Writer)

nitc $ MPackageDot :: write_to

Generate the dot content with the current configuration

All properties

fun !=(other: nullable Object): Bool

core :: Object :: !=

Have self and other different values?
fun ==(other: nullable Object): Bool

core :: Object :: ==

Have self and other the same value?
type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
private var _cluster_group: Bool

nitc :: MPackageDot :: _cluster_group

Should groups be shown as clusters?
private var _mmodules: HashSet[MModule]

nitc :: MPackageDot :: _mmodules

Set of modules to display
private var _model: Model

nitc :: MPackageDot :: _model

The model where to look for information
private var _mpackages: HashSet[MPackage]

nitc :: MPackageDot :: _mpackages

Set of packages to expand fully (ie all groups and modules are displayed)
private var _package_group: Bool

nitc :: MPackageDot :: _package_group

Should packages be shown as clusters?
protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by get_class to create the specific class.
fun class_name: String

core :: Object :: class_name

The class name of the object.
fun cluster_group: Bool

nitc :: MPackageDot :: cluster_group

Should groups be shown as clusters?
fun cluster_group=(cluster_group: Bool)

nitc :: MPackageDot :: cluster_group=

Should groups be shown as clusters?
fun collect_important_importation

nitc :: MPackageDot :: collect_important_importation

Extends the set of mmodules by recursively adding the most specific imported modules of foreign packages
private fun dot_cluster(o: Writer, mgroup: MGroup)

nitc :: MPackageDot :: dot_cluster

Recursively generate node and clusters for a mgroup
fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
fun hash: Int

core :: Object :: hash

The hash code of the object.
init init

core :: Object :: init

fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if self and other are the same instance (i.e. same identity).
fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is self the same as other in a serialization context?
intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if self and other have the same dynamic type.
fun mmodules: HashSet[MModule]

nitc :: MPackageDot :: mmodules

Set of modules to display
protected fun mmodules=(mmodules: HashSet[MModule])

nitc :: MPackageDot :: mmodules=

Set of modules to display
fun model: Model

nitc :: MPackageDot :: model

The model where to look for information
protected fun model=(model: Model)

nitc :: MPackageDot :: model=

The model where to look for information
fun mpackages: HashSet[MPackage]

nitc :: MPackageDot :: mpackages

Set of packages to expand fully (ie all groups and modules are displayed)
protected fun mpackages=(mpackages: HashSet[MPackage])

nitc :: MPackageDot :: mpackages=

Set of packages to expand fully (ie all groups and modules are displayed)
private intern fun native_class_name: CString

core :: Object :: native_class_name

The class name of the object in CString format.
private fun node_for(mmodule: MModule): String

nitc :: MPackageDot :: node_for

intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
fun output

core :: Object :: output

Display self on stdout (debug only).
intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).
fun package_group: Bool

nitc :: MPackageDot :: package_group

Should packages be shown as clusters?
fun package_group=(package_group: Bool)

nitc :: MPackageDot :: package_group=

Should packages be shown as clusters?
fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
abstract fun write_to(stream: Writer)

core :: Writable :: write_to

Write itself to a stream
fun write_to_bytes: Bytes

core :: Writable :: write_to_bytes

Like write_to but return a new Bytes (may be quite large)
fun write_to_file(filepath: String)

core :: Writable :: write_to_file

Like write_to but take care of creating the file
fun write_to_string: String

core :: Writable :: write_to_string

Like write_to but return a new String (may be quite large).
package_diagram nitc::MPackageDot MPackageDot core::Writable Writable nitc::MPackageDot->core::Writable core::Object Object core::Writable->core::Object ...core::Object ... ...core::Object->core::Object

Ancestors

interface Object

core :: Object

The root of the class hierarchy.

Parents

interface Writable

core :: Writable

Things that can be efficienlty written to a Writer

Class definitions

nitc $ MPackageDot
# Generate graphiz files based on packages, groups and modules
#
# Interesting elements must be selected. See `mmodules`, ``
# Display configuration can be set. See `cluster_group`, `package_group`
class MPackageDot
	super Writable

	# The model where to look for information
	var model: Model

	# Set of packages to expand fully (ie all groups and modules are displayed)
	# Initially empty, packages can be added
	var mpackages = new HashSet[MPackage]

	# Set of modules to display
	# Initially empty, modules can be added
	var mmodules = new HashSet[MModule]

	private fun node_for(mmodule: MModule): String
	do
		return "m_{mmodule.object_id}"
	end

	# Should groups be shown as clusters?
	var cluster_group = true is writable

	# Should packages be shown as clusters?
	var package_group = true is writable

	# Recursively generate node and clusters for a mgroup
	private fun dot_cluster(o: Writer, mgroup: MGroup)
	do
		# Open the cluster, if required
		if mgroup.parent == null then
			# is is a root group, so display the package
			if package_group then
				o.write("subgraph cluster_{mgroup.object_id} \{\nlabel=\"{mgroup.mpackage.name}\\n({mgroup.filepath or else "?"})\"\ncolor=black\nstyle=dotted\n")
			end
		else
			if cluster_group then
				o.write("subgraph cluster_{mgroup.object_id} \{\nlabel=\"{mgroup.name}\"\ncolor=blue\nstyle=dotted\n")
			end
		end

		# outputs the mmodules to show
		for mmodule in mgroup.mmodules do
			if not mmodules.has(mmodule) then continue
			o.write("\t{node_for(mmodule)} [label=\"{mmodule.name}\",color=green]\n")
		end

		# recursively progress on sub-clusters
		for d in mgroup.in_nesting.direct_smallers do
			dot_cluster(o, d)
		end

		# close the cluster if required
		if mgroup.parent == null then
			if package_group then o.write("\}\n")
		else
			if cluster_group then o.write("\}\n")
		end
	end

	# Extends the set of `mmodules` by recursively adding the most specific imported modules of foreign packages
	fun collect_important_importation
	do
		var todo = new List[MModule]
		todo.add_all(mmodules)
		while not todo.is_empty do
			var m = todo.pop

			for psm in m.in_importation.greaters do
				if m.mgroup.mpackage != psm.mgroup.mpackage then continue
				for ssm in psm.in_importation.direct_greaters do
					if psm.mgroup.mpackage == ssm.mgroup.mpackage then continue
					mmodules.add(ssm)
					todo.add(ssm)
				end
			end
		end
	end

	# Generate the dot content with the current configuration
	redef fun write_to(stream)
	do
		# Collect interesting nodes
		for m in model.mmodules do
			# filter out modules outside wanted packages
			if m.mgroup == null then continue
			if not mpackages.has(m.mgroup.mpackage) then continue

			mmodules.add(m)
		end

		collect_important_importation

		# Collect interesting edges
		var sub_hierarchy = new POSet[MModule]
		for m in mmodules do
			sub_hierarchy.add_node(m)
			for sm in m.in_importation.greaters do
				if sm == m then continue
				if not mmodules.has(sm) then continue
				sub_hierarchy.add_edge(m, sm)
			end
		end

		stream.write("digraph g \{\n")
		stream.write("rankdir=BT;node[shape=box];\n")
		# Generate the nodes
		for p in model.mpackages do
			dot_cluster(stream, p.root.as(not null))
		end
		# Generate the edges
		for m in mmodules do
			for sm in sub_hierarchy[m].direct_greaters do
				var nm = node_for(m)
				var nsm = node_for(sm)
				if m.in_importation.direct_greaters.has(sm) then
					stream.write("\t{nm} -> {nsm}[style=bold]\n")
				else
					stream.write("\t{nm} -> {nsm}[style=solid]\n")
				end
			end
		end
		stream.write("\}\n")
	end
end
src/model/model_viz.nit:132,1--259,3