Use explicit relationships instead of manipulating the names.
Signed-off-by: Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
module model::graph
import neo4j
+import more_collections
import location
# A Neo4j graph.
end
# A project’s graph.
+#
+# Here is the usual steps to build a project graph:
+#
+# <ul>
+# <li>Instantiate `ProjectGraph` by giving the name that will label the project.</li>
+# <li>For each compound:
+# <ul>
+# <li>Instantiate the compound.</li>
+# <li>Provide all the related data.</li>
+# <li>Call the `put_in_graph` method of the compound.</li>
+# </ul></li>
+# <li>Call the `add_global_modules` method of the project’s graph (defined in
+# the `module_compound` module). This permits to take global classes into
+# account correctly.</li>
+# <li>Call the `put_edges` method of the project’s graph.</li>
+# </ul>
class ProjectGraph
super NeoGraph
# Entities by `model_id`.
var by_id: Map[String, Entity] = new HashMap[String, Entity]
+ # Namespaces by `full_name`.
+ var namespaces: Map[String, Namespace] = new HashMap[String, Namespace]
+
+ # For each `ClassCompound` in the graph, the mapping between its `model_id` and its namespace.
+ #
+ # Defaults to the root namespace. An entry is added each time
+ # `Namespace.declare_class` is called.
+ #
+ # Note: In the graph, there is no direct link between a namespace and a
+ # class. It is the role of a module (created internally by a `FileCompound`)
+ # to link a class with its namespace. So, this collection is used by modules
+ # to know which class in a file belong to their related namespace. It is
+ # also used by `FileCompound` to detect classes in the root namespace.
+ var class_to_ns: Map[String, Namespace] is noinit
+
# Initialize a new project graph using the specified project name.
#
# The specified name will label all nodes of the project’s graph.
var root = new RootNamespace(self)
root.put_in_graph
by_id[""] = root
+ class_to_ns = new DefaultMap[String, Namespace](root)
end
# Request to all nodes in the graph to add their related edges.
+ #
+ # Note: For the rare cases where a node need to wait the `put_edges` to add
+ # an implicit node, this method makes sure to call the `put_edges` method
+ # of the newly added nodes only after processing all the nodes that was
+ # already there.
fun put_edges do
all_edges.clear
add_edge(project, "ROOT", by_id[""])
# Declare an inner class.
#
# Note: Althought Doxygen indicates that both arguments are optional,
- # declarations with either an empty name or an empty ID are not
- # supported yet.
+ # declarations with an empty ID are not supported yet.
#
# Parameters:
#
# * `id`: `model_id` of the inner class.
- # * `full_name`: qualified name of the inner class.
+ # * `full_name`: qualified name of the inner class. Ignored in practice.
+ #
+ # TODO: Handle cases where only the `full_name` is available.
fun declare_class(id: String, full_name: String) do end
# Declare a base compound (usually, a base class).
class Namespace
super Compound
- # Inner namespaces (IDs).
+ # The inner namespaces.
#
# Left empty for the root namespace.
- var inner_namespaces: SimpleCollection[String] = new Array[String]
+ var inner_namespaces: SimpleCollection[NamespaceRef] = new Array[NamespaceRef]
init do
super
self.labels.add("MGroup")
end
- redef fun declare_namespace(id: String, name: String) do
- inner_namespaces.add(id)
+ redef fun declare_namespace(id: String, full_name: String) do
+ inner_namespaces.add new NamespaceRef(id, full_name)
+ end
+
+ redef fun declare_class(id: String, full_name: String) do
+ graph.class_to_ns[id] = self
+ end
+
+ redef fun put_in_graph do
+ super
+ var full_name = self["full_name"]
+ if full_name isa String then graph.namespaces[full_name] = self
end
redef fun put_edges do
graph.add_edge(root, "NESTS", self)
end
for ns in inner_namespaces do
- var node = graph.by_id[ns]
+ var node = ns.seek_in(graph)
graph.add_edge(node, "PARENT", self)
graph.add_edge(self, "NESTS", node)
end
end
end
+# A reference to a namespace.
+class NamespaceRef
+ # The `model_id` of the target.
+ #
+ # Empty when unknown or for the root namespace.
+ var model_id: String
+
+ # The `full_name` of the target.
+ #
+ # Empty only for the root namespace.
+ var full_name: String
+
+ # Look for the targeted namespace in the specified graph.
+ fun seek_in(graph: ProjectGraph): Namespace do
+ var ns_compound: Namespace
+
+ if model_id.is_empty and not full_name.is_empty then
+ # ID unspecified. => We have to look by name
+ assert graph.namespaces.has_key(full_name) else
+ sys.stderr.write "Namespace `{full_name}` not found."
+ end
+ ns_compound = graph.namespaces[full_name]
+ else
+ ns_compound = graph.by_id[model_id].as(Namespace)
+ end
+ return ns_compound
+ end
+end
+
# The root namespace of a `ProjectGraph`.
#
# This the only entity in the graph whose `model_id` is really `""`.
# Creates one modules by inner namespace. The full name of the modules begin
# with the namespace’s full name, and end with the unqualified name of the file,
# without the extension.
+#
+# Note: If a module associated to the root namespace is needed, it is added to
+# the graph only when `put_edges` is called.
class FileCompound
super Compound
super CodeBlock
- # Mapping between inner namespace’s names and corresponding modules.
- private var inner_namespaces: Map[String, Module] = new HashMap[String, Module]
+ # Modules corresponding to the namespaces defined/redefined in the file.
+ private var inner_namespaces = new Array[Module]
+
+ # `model_id` of the classes declared in the file.
+ private var inner_classes = new Array[String]
# The last component of the path, without the extension.
#
if location != null and location.path != null then
full_name = location.path.as(not null)
end
- for m in inner_namespaces.values do m.location = location
+ for m in inner_namespaces do m.location = location
end
redef fun name=(name: String) do
basename = name.substring(0, match.from)
end
# Update the modules’ name.
- for ns, m in inner_namespaces do
- if ns.is_empty then
- m.full_name = basename
- else
- m.full_name = "{ns}{ns_separator}{basename}"
- end
- end
+ for m in inner_namespaces do m.update_name
end
redef fun declare_namespace(id: String, full_name: String) do
assert not full_name.is_empty or id.is_empty else
sys.stderr.write "Inner mamespace declarations without name are not yet supported (except for the root namespace).\n"
end
- if inner_namespaces.keys.has(full_name) then
- m = inner_namespaces[full_name]
- if id != "" then m.parent = id
- else
- m = new Module(graph)
- if full_name.is_empty then
- m.full_name = basename
- else
- m.full_name = "{full_name}{ns_separator}{basename}"
- end
- m.parent = id
- m.location = self["location"].as(nullable Location)
- inner_namespaces[full_name] = m
- end
+ m = new Module(graph, self, new NamespaceRef(id, full_name))
+ m.location = self["location"].as(nullable Location)
+ inner_namespaces.add m
end
redef fun declare_class(id: String, full_name: String) do
assert not id.is_empty else
sys.stderr.write "Inner class declarations without ID are not yet supported.\n"
end
- assert not full_name.is_empty else
- sys.stderr.write "Inner class declarations without name are not yet supported.\n"
- end
- var match = full_name.search_last(ns_separator)
- var ns_name: String
- var m: Module
-
- if match == null then
- ns_name = ""
- else
- ns_name = full_name.substring(0, match.from)
- end
- if inner_namespaces.keys.has(ns_name) then
- m = inner_namespaces[ns_name]
- else
- declare_namespace("", ns_name)
- m = inner_namespaces[ns_name]
- end
- m.declare_class(id, full_name)
+ inner_classes.add id
end
redef fun put_in_graph do
# Do not add `self` to the Neo4j graph...
# ... but add its modules...
- for m in inner_namespaces.values do m.put_in_graph
- # ... and add `self` to the index.
+ for m in inner_namespaces do m.put_in_graph
+ # ... and add `self` to the indexes.
if model_id != "" then graph.by_id[model_id] = self
+ graph.files.add self
+ end
+
+ # If the file contains some classes in the root namespace, add an implicit
+ # module to handle them.
+ #
+ # This method is called by `ProjectGraph.add_global_modules` and assumes
+ # that all the namespaces are already fully set and put in the graph.
+ fun declare_root_namespace do
+ if has_globals then
+ declare_namespace("", "")
+ inner_namespaces.last.put_in_graph
+ end
+ end
+
+ # Does this file contain classes in the root namespace?
+ private fun has_globals: Bool do
+ var root = graph.by_id[""]
+ for c in inner_classes do
+ if graph.class_to_ns[c] == root then return true
+ end
+ return false
end
end
-# A module.
-class Module
+# A `MModule` node.
+#
+# For each file, there is one module by inner namespace.
+private class Module
super Compound
super CodeBlock
- # The `model_id` of the parent namespace.
- var parent: String = "" is writable
+ # The file that declares the module.
+ var file_compound: FileCompound
- # The classes defined in the module.
- var inner_classes: SimpleCollection[String] = new Array[String]
+ # The namespace defined or redefined by the module.
+ var namespace: NamespaceRef
init do
super
self.labels.add("MModule")
+ update_name
end
- redef fun declare_class(id: String, full_name: String) do
- assert not id.is_empty else
- sys.stderr.write "Inner class declarations without ID not supported yet.\n"
- end
- inner_classes.add(id)
+ # Update the `full_name` and the `name`.
+ #
+ # Update the short name of the module to the `basename` of the file that
+ # declares it.
+ fun update_name do
+ name = file_compound.basename
+ parent_name = namespace.full_name
end
redef fun put_edges do
- graph.add_edge(graph.by_id[parent], "DECLARES", self)
- for c in inner_classes do
- var node = graph.by_id[c].as(ClassCompound)
- graph.add_edge(self, "INTRODUCES", node)
- graph.add_edge(self, "DEFINES", node.class_def)
+ var ns_compound = namespace.seek_in(graph)
+ graph.add_edge(ns_compound, "DECLARES", self)
+
+ for c in file_compound.inner_classes do
+ if graph.class_to_ns[c] != ns_compound then continue
+ var class_compound = graph.by_id[c].as(ClassCompound)
+ graph.add_edge(self, "INTRODUCES", class_compound)
+ graph.add_edge(self, "DEFINES", class_compound.class_def)
end
end
end
+
+# Adds the `add_global_modules` phase to `ProjectGraph`.
+redef class ProjectGraph
+
+ # Project’s source files.
+ var files: SimpleCollection[FileCompound] = new Array[FileCompound]
+
+ # Add the modules that define the root namespace.
+ #
+ # **Must** be called before any call to `put_edges`, and after all the
+ # namespaces are fully set and put in the graph.
+ #
+ # Note: This method is not idempotent so it has to be called only once.
+ fun add_global_modules do
+ for f in files do f.declare_root_namespace
+ end
+end
if directories.length <= 0 then break
dir = directories.pop
end
+ model.add_global_modules
print "Done."
if file_count < 2 then
print "{file_count} file read."
var file_2 = new FileCompound(graph)
var bar_class = new ClassCompound(graph)
var baz_class = new ClassCompound(graph)
+var a_ns = new Namespace(graph)
+var b_ns = new Namespace(graph)
var c_ns = new Namespace(graph)
+var d_ns = new Namespace(graph)
var buffer = new RopeBuffer
file.full_name = "Bar.java"
baz_class.full_name = "Baz"
baz_class.put_in_graph
+a_ns.full_name = "a"
+a_ns.declare_namespace("", "a::b")
+a_ns.put_in_graph
+
+b_ns.full_name = "a::b"
+b_ns.declare_class("classa_b_bar", "")
+b_ns.put_in_graph
+
c_ns.model_id = "namespacec"
c_ns.full_name = "c"
c_ns.put_in_graph
+d_ns.model_id = "namespaced"
+d_ns.full_name = "d"
+d_ns.put_in_graph
+
+print "---===WITHOUT GLOBALS===---"
+graph.put_edges
+graph.debug buffer
+print buffer
+
+print "---===WITH GLOBALS===---"
+#buffer.clear # Buggy.
+buffer = new RopeBuffer
+graph.add_global_modules
graph.put_edges
graph.debug buffer
print buffer
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/A.java:1,1--1,1","full_name":"org::example::foo::A","name":"A"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/A.java:1,1--1,1","name":"A","full_name":"org::example::foo::A"}
Edge
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/A.java:1,1--1,1","full_name":"org::example::foo::A","name":"A"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/A.java:1,1--1,1","name":"A","full_name":"org::example::foo::A"}
----
=to=Entity#32:classorg_1_1example_1_1foo_1_1_a
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/A.java:1,1--1,1","full_name":"org::example::foo::A","name":"A"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/A.java:1,1--1,1","name":"A","full_name":"org::example::foo::A"}
----
=to=Entity#0:
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/B.java:1,1--1,1","full_name":"org::example::foo::B","name":"B"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/B.java:1,1--1,1","name":"B","full_name":"org::example::foo::B"}
Edge
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/B.java:1,1--1,1","full_name":"org::example::foo::B","name":"B"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/B.java:1,1--1,1","name":"B","full_name":"org::example::foo::B"}
----
=to=Entity#32:classorg_1_1example_1_1foo_1_1_b
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/B.java:1,1--1,1","full_name":"org::example::foo::B","name":"B"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/B.java:1,1--1,1","name":"B","full_name":"org::example::foo::B"}
----
=to=Entity#0:
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:1,1--1,1","full_name":"org::example::foo::C","name":"C"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:1,1--1,1","name":"C","full_name":"org::example::foo::C"}
Edge
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:1,1--1,1","full_name":"org::example::foo::C","name":"C"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:1,1--1,1","name":"C","full_name":"org::example::foo::C"}
----
=to=Entity#36:interfaceorg_1_1example_1_1foo_1_1_c
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:1,1--1,1","full_name":"org::example::foo::C","name":"C"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:1,1--1,1","name":"C","full_name":"org::example::foo::C"}
----
=to=Entity#0:
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/EmptyClass.java:1,1--1,1","full_name":"org::example::foo::EmptyClass","name":"EmptyClass"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/EmptyClass.java:1,1--1,1","name":"EmptyClass","full_name":"org::example::foo::EmptyClass"}
Edge
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/EmptyClass.java:1,1--1,1","full_name":"org::example::foo::EmptyClass","name":"EmptyClass"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/EmptyClass.java:1,1--1,1","name":"EmptyClass","full_name":"org::example::foo::EmptyClass"}
----
=to=Entity#42:classorg_1_1example_1_1foo_1_1_empty_class
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/EmptyClass.java:1,1--1,1","full_name":"org::example::foo::EmptyClass","name":"EmptyClass"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/EmptyClass.java:1,1--1,1","name":"EmptyClass","full_name":"org::example::foo::EmptyClass"}
----
=to=Entity#0:
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/A.java:1,1--1,1","full_name":"org::example::foo::A","name":"A"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/A.java:1,1--1,1","name":"A","full_name":"org::example::foo::A"}
Edge
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/A.java:1,1--1,1","full_name":"org::example::foo::A","name":"A"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/A.java:1,1--1,1","name":"A","full_name":"org::example::foo::A"}
----
=to=Entity#32:classorg_1_1example_1_1foo_1_1_a
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/A.java:1,1--1,1","full_name":"org::example::foo::A","name":"A"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/A.java:1,1--1,1","name":"A","full_name":"org::example::foo::A"}
----
=to=Entity#0:
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/B.java:1,1--1,1","full_name":"org::example::foo::B","name":"B"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/B.java:1,1--1,1","name":"B","full_name":"org::example::foo::B"}
Edge
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/B.java:1,1--1,1","full_name":"org::example::foo::B","name":"B"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/B.java:1,1--1,1","name":"B","full_name":"org::example::foo::B"}
----
=to=Entity#32:classorg_1_1example_1_1foo_1_1_b
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/B.java:1,1--1,1","full_name":"org::example::foo::B","name":"B"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/B.java:1,1--1,1","name":"B","full_name":"org::example::foo::B"}
----
=to=Entity#0:
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:1,1--1,1","full_name":"org::example::foo::C","name":"C"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:1,1--1,1","name":"C","full_name":"org::example::foo::C"}
Edge
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:1,1--1,1","full_name":"org::example::foo::C","name":"C"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:1,1--1,1","name":"C","full_name":"org::example::foo::C"}
----
=to=Entity#36:interfaceorg_1_1example_1_1foo_1_1_c
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:1,1--1,1","full_name":"org::example::foo::C","name":"C"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:1,1--1,1","name":"C","full_name":"org::example::foo::C"}
----
=to=Entity#0:
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/EmptyClass.java:1,1--1,1","full_name":"org::example::foo::EmptyClass","name":"EmptyClass"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/EmptyClass.java:1,1--1,1","name":"EmptyClass","full_name":"org::example::foo::EmptyClass"}
Edge
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/EmptyClass.java:1,1--1,1","full_name":"org::example::foo::EmptyClass","name":"EmptyClass"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/EmptyClass.java:1,1--1,1","name":"EmptyClass","full_name":"org::example::foo::EmptyClass"}
----
=to=Entity#42:classorg_1_1example_1_1foo_1_1_empty_class
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/EmptyClass.java:1,1--1,1","full_name":"org::example::foo::EmptyClass","name":"EmptyClass"}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/EmptyClass.java:1,1--1,1","name":"EmptyClass","full_name":"org::example::foo::EmptyClass"}
----
=to=Entity#0:
=labels=Array(3):
Edge
-=type=8:DECLARES
+=type=9:CLASSTYPE
=properties=JsonObject(0):
{}
----
-=from=Entity#0:
+=from=Entity#9:class_foo
=labels=Array(3):
14:root-namespace
7:MEntity
-6:MGroup
-=properties=JsonObject(2):
-{"full_name":"","name":"root-namespace"}
+6:MClass
+=properties=JsonObject(6):
+{"kind":"class","visibility":"package","full_name":"Foo","name":"Foo","location":"%SOURCE_DIRECTORY%\/Foo.java:19,1--19,1","mdoc":["A class in the root namespace"]}
----
=to=Entity#0:
-=labels=Array(3):
+=labels=Array(4):
14:root-namespace
7:MEntity
-7:MModule
-=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/Foo.java:1,1--1,1","full_name":"Foo","name":"Foo"}
+5:MType
+10:MClassType
+=properties=JsonObject(2):
+{"name":"Foo","full_name":"Foo"}
Edge
-=type=10:INTRODUCES
+=type=5:CLASS
=properties=JsonObject(0):
{}
----
=from=Entity#0:
-=labels=Array(3):
+=labels=Array(4):
14:root-namespace
7:MEntity
-7:MModule
-=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/Foo.java:1,1--1,1","full_name":"Foo","name":"Foo"}
+5:MType
+10:MClassType
+=properties=JsonObject(2):
+{"name":"Foo","full_name":"Foo"}
----
=to=Entity#9:class_foo
=labels=Array(3):
Edge
-=type=7:DEFINES
+=type=9:BOUNDTYPE
=properties=JsonObject(0):
{}
----
=labels=Array(3):
14:root-namespace
7:MEntity
-7:MModule
-=properties=JsonObject(3):
-{"location":"%SOURCE_DIRECTORY%\/Foo.java:1,1--1,1","full_name":"Foo","name":"Foo"}
-----
-=to=Entity#0:
-=labels=Array(3):
-14:root-namespace
-7:MEntity
9:MClassDef
=properties=JsonObject(5):
{"location":"%SOURCE_DIRECTORY%\/Foo.java:19,1--19,1","is_intro":true,"name":"Foo","full_name":"Foo","mdoc":["A class in the root namespace"]}
-
-
-Edge
-=type=9:CLASSTYPE
-=properties=JsonObject(0):
-{}
-----
-=from=Entity#9:class_foo
-=labels=Array(3):
-14:root-namespace
-7:MEntity
-6:MClass
-=properties=JsonObject(6):
-{"kind":"class","visibility":"package","full_name":"Foo","name":"Foo","location":"%SOURCE_DIRECTORY%\/Foo.java:19,1--19,1","mdoc":["A class in the root namespace"]}
----
=to=Entity#0:
=labels=Array(4):
Edge
-=type=5:CLASS
+=type=6:MCLASS
=properties=JsonObject(0):
{}
----
=from=Entity#0:
-=labels=Array(4):
+=labels=Array(3):
14:root-namespace
7:MEntity
-5:MType
-10:MClassType
-=properties=JsonObject(2):
-{"name":"Foo","full_name":"Foo"}
+9:MClassDef
+=properties=JsonObject(5):
+{"location":"%SOURCE_DIRECTORY%\/Foo.java:19,1--19,1","is_intro":true,"name":"Foo","full_name":"Foo","mdoc":["A class in the root namespace"]}
----
=to=Entity#9:class_foo
=labels=Array(3):
Edge
-=type=9:BOUNDTYPE
+=type=8:DECLARES
=properties=JsonObject(0):
{}
----
=labels=Array(3):
14:root-namespace
7:MEntity
-9:MClassDef
-=properties=JsonObject(5):
-{"location":"%SOURCE_DIRECTORY%\/Foo.java:19,1--19,1","is_intro":true,"name":"Foo","full_name":"Foo","mdoc":["A class in the root namespace"]}
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"root-namespace"}
----
=to=Entity#0:
-=labels=Array(4):
+=labels=Array(3):
14:root-namespace
7:MEntity
-5:MType
-10:MClassType
-=properties=JsonObject(2):
-{"name":"Foo","full_name":"Foo"}
+7:MModule
+=properties=JsonObject(3):
+{"location":"%SOURCE_DIRECTORY%\/Foo.java:1,1--1,1","name":"Foo","full_name":"Foo"}
Edge
-=type=6:MCLASS
+=type=10:INTRODUCES
=properties=JsonObject(0):
{}
----
=labels=Array(3):
14:root-namespace
7:MEntity
-9:MClassDef
-=properties=JsonObject(5):
-{"location":"%SOURCE_DIRECTORY%\/Foo.java:19,1--19,1","is_intro":true,"name":"Foo","full_name":"Foo","mdoc":["A class in the root namespace"]}
+7:MModule
+=properties=JsonObject(3):
+{"location":"%SOURCE_DIRECTORY%\/Foo.java:1,1--1,1","name":"Foo","full_name":"Foo"}
----
=to=Entity#9:class_foo
=labels=Array(3):
{"kind":"class","visibility":"package","full_name":"Foo","name":"Foo","location":"%SOURCE_DIRECTORY%\/Foo.java:19,1--19,1","mdoc":["A class in the root namespace"]}
+Edge
+=type=7:DEFINES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+14:root-namespace
+7:MEntity
+7:MModule
+=properties=JsonObject(3):
+{"location":"%SOURCE_DIRECTORY%\/Foo.java:1,1--1,1","name":"Foo","full_name":"Foo"}
+----
+=to=Entity#0:
+=labels=Array(3):
+14:root-namespace
+7:MEntity
+9:MClassDef
+=properties=JsonObject(5):
+{"location":"%SOURCE_DIRECTORY%\/Foo.java:19,1--19,1","is_intro":true,"name":"Foo","full_name":"Foo","mdoc":["A class in the root namespace"]}
+
+
---===DONE===---
+---===WITHOUT GLOBALS===---
# Graph
Edge
=type=4:ROOT
7:MEntity
6:MGroup
=properties=JsonObject(2):
-{"full_name":"","name":"foo"}
+{"full_name":"a::b","name":"b"}
----
=to=Entity#0:
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"\/dev\/null:1,1--1,1","full_name":"a::b::Bar","name":"Bar"}
+{"location":"\/dev\/null:1,1--1,1","name":"Bar","full_name":"a::b::Bar"}
Edge
=type=10:INTRODUCES
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"\/dev\/null:1,1--1,1","full_name":"a::b::Bar","name":"Bar"}
+{"location":"\/dev\/null:1,1--1,1","name":"Bar","full_name":"a::b::Bar"}
----
=to=Entity#12:classa_b_bar
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"\/dev\/null:1,1--1,1","full_name":"a::b::Bar","name":"Bar"}
+{"location":"\/dev\/null:1,1--1,1","name":"Bar","full_name":"a::b::Bar"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+9:MClassDef
+=properties=JsonObject(4):
+{"location":"\/dev\/null:1,1--1,1","is_intro":true,"name":"Bar","full_name":"a::b::Bar"}
+
+Edge
+=type=8:DECLARES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#10:namespacec
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"c","name":"c"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+7:MModule
+=properties=JsonObject(3):
+{"location":"\/dev\/null:1,1--1,1","name":"Bar","full_name":"c::Bar"}
+
+Edge
+=type=8:DECLARES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#10:namespaced
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"d","name":"d"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+7:MModule
+=properties=JsonObject(3):
+{"location":"\/dev\/null:1,1--1,1","name":"Bar","full_name":"d::Bar"}
+
+Edge
+=type=9:CLASSTYPE
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#12:classa_b_bar
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","full_name":"a::b::Bar","name":"Bar"}
+----
+=to=Entity#0:
+=labels=Array(4):
+3:foo
+7:MEntity
+5:MType
+10:MClassType
+=properties=JsonObject(2):
+{"name":"Bar","full_name":"a::b::Bar"}
+
+Edge
+=type=5:CLASS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(4):
+3:foo
+7:MEntity
+5:MType
+10:MClassType
+=properties=JsonObject(2):
+{"name":"Bar","full_name":"a::b::Bar"}
+----
+=to=Entity#12:classa_b_bar
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","full_name":"a::b::Bar","name":"Bar"}
+
+Edge
+=type=9:BOUNDTYPE
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+9:MClassDef
+=properties=JsonObject(4):
+{"location":"\/dev\/null:1,1--1,1","is_intro":true,"name":"Bar","full_name":"a::b::Bar"}
+----
+=to=Entity#0:
+=labels=Array(4):
+3:foo
+7:MEntity
+5:MType
+10:MClassType
+=properties=JsonObject(2):
+{"name":"Bar","full_name":"a::b::Bar"}
+
+Edge
+=type=6:MCLASS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+9:MClassDef
+=properties=JsonObject(4):
+{"location":"\/dev\/null:1,1--1,1","is_intro":true,"name":"Bar","full_name":"a::b::Bar"}
+----
+=to=Entity#12:classa_b_bar
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","full_name":"a::b::Bar","name":"Bar"}
+
+Edge
+=type=9:CLASSTYPE
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#8:classbaz
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","full_name":"Baz","name":"Baz"}
+----
+=to=Entity#0:
+=labels=Array(4):
+3:foo
+7:MEntity
+5:MType
+10:MClassType
+=properties=JsonObject(2):
+{"name":"Baz","full_name":"Baz"}
+
+Edge
+=type=5:CLASS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(4):
+3:foo
+7:MEntity
+5:MType
+10:MClassType
+=properties=JsonObject(2):
+{"name":"Baz","full_name":"Baz"}
+----
+=to=Entity#8:classbaz
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","full_name":"Baz","name":"Baz"}
+
+Edge
+=type=9:BOUNDTYPE
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+9:MClassDef
+=properties=JsonObject(4):
+{"location":"\/dev\/null:1,1--1,1","is_intro":true,"name":"Baz","full_name":"Baz"}
+----
+=to=Entity#0:
+=labels=Array(4):
+3:foo
+7:MEntity
+5:MType
+10:MClassType
+=properties=JsonObject(2):
+{"name":"Baz","full_name":"Baz"}
+
+Edge
+=type=6:MCLASS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+9:MClassDef
+=properties=JsonObject(4):
+{"location":"\/dev\/null:1,1--1,1","is_intro":true,"name":"Baz","full_name":"Baz"}
+----
+=to=Entity#8:classbaz
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","full_name":"Baz","name":"Baz"}
+
+Edge
+=type=7:PROJECT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a","name":"a"}
+----
+=to=Node
+=labels=Array(3):
+3:foo
+7:MEntity
+8:MProject
+=properties=JsonObject(1):
+{"name":"foo"}
+
+Edge
+=type=6:PARENT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a","name":"a"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"foo"}
+
+Edge
+=type=5:NESTS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"foo"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a","name":"a"}
+
+Edge
+=type=6:PARENT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a::b","name":"b"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a","name":"a"}
+
+Edge
+=type=5:NESTS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a","name":"a"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a::b","name":"b"}
+
+Edge
+=type=7:PROJECT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a::b","name":"b"}
+----
+=to=Node
+=labels=Array(3):
+3:foo
+7:MEntity
+8:MProject
+=properties=JsonObject(1):
+{"name":"foo"}
+
+Edge
+=type=7:PROJECT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#10:namespacec
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"c","name":"c"}
+----
+=to=Node
+=labels=Array(3):
+3:foo
+7:MEntity
+8:MProject
+=properties=JsonObject(1):
+{"name":"foo"}
+
+Edge
+=type=6:PARENT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#10:namespacec
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"c","name":"c"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"foo"}
+
+Edge
+=type=5:NESTS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"foo"}
+----
+=to=Entity#10:namespacec
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"c","name":"c"}
+
+Edge
+=type=7:PROJECT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#10:namespaced
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"d","name":"d"}
+----
+=to=Node
+=labels=Array(3):
+3:foo
+7:MEntity
+8:MProject
+=properties=JsonObject(1):
+{"name":"foo"}
+
+Edge
+=type=6:PARENT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#10:namespaced
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"d","name":"d"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"foo"}
+
+Edge
+=type=5:NESTS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"foo"}
+----
+=to=Entity#10:namespaced
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"d","name":"d"}
+
+
+---===WITH GLOBALS===---
+# Graph
+Edge
+=type=4:ROOT
+=properties=JsonObject(0):
+{}
+----
+=from=Node
+=labels=Array(3):
+3:foo
+7:MEntity
+8:MProject
+=properties=JsonObject(1):
+{"name":"foo"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"foo"}
+
+Edge
+=type=7:PROJECT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"foo"}
----
-=to=Entity#0:
+=to=Node
=labels=Array(3):
3:foo
7:MEntity
-9:MClassDef
-=properties=JsonObject(4):
-{"location":"\/dev\/null:1,1--1,1","is_intro":true,"name":"Bar","full_name":"a::b::Bar"}
+8:MProject
+=properties=JsonObject(1):
+{"name":"foo"}
Edge
=type=8:DECLARES
7:MEntity
6:MGroup
=properties=JsonObject(2):
-{"full_name":"","name":"foo"}
+{"full_name":"a::b","name":"b"}
----
=to=Entity#0:
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"\/dev\/null:1,1--1,1","full_name":"Bar","name":"Bar"}
+{"location":"\/dev\/null:1,1--1,1","name":"Bar","full_name":"a::b::Bar"}
Edge
=type=10:INTRODUCES
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"\/dev\/null:1,1--1,1","full_name":"Bar","name":"Bar"}
+{"location":"\/dev\/null:1,1--1,1","name":"Bar","full_name":"a::b::Bar"}
----
-=to=Entity#8:classbaz
+=to=Entity#12:classa_b_bar
=labels=Array(3):
3:foo
7:MEntity
6:MClass
=properties=JsonObject(4):
-{"kind":"class","visibility":"public","full_name":"Baz","name":"Baz"}
+{"kind":"class","visibility":"public","full_name":"a::b::Bar","name":"Bar"}
Edge
=type=7:DEFINES
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"\/dev\/null:1,1--1,1","full_name":"Bar","name":"Bar"}
+{"location":"\/dev\/null:1,1--1,1","name":"Bar","full_name":"a::b::Bar"}
----
=to=Entity#0:
=labels=Array(3):
7:MEntity
9:MClassDef
=properties=JsonObject(4):
-{"location":"\/dev\/null:1,1--1,1","is_intro":true,"name":"Baz","full_name":"Baz"}
+{"location":"\/dev\/null:1,1--1,1","is_intro":true,"name":"Bar","full_name":"a::b::Bar"}
Edge
=type=8:DECLARES
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"\/dev\/null:1,1--1,1","full_name":"c::Bar","name":"Bar"}
+{"location":"\/dev\/null:1,1--1,1","name":"Bar","full_name":"c::Bar"}
Edge
=type=8:DECLARES
=properties=JsonObject(0):
{}
----
-=from=Entity#0:
+=from=Entity#10:namespaced
=labels=Array(3):
3:foo
7:MEntity
6:MGroup
=properties=JsonObject(2):
-{"full_name":"","name":"foo"}
+{"full_name":"d","name":"d"}
----
=to=Entity#0:
=labels=Array(3):
7:MEntity
7:MModule
=properties=JsonObject(3):
-{"location":"\/dev\/null:1,1--1,1","full_name":"d::Bar","name":"Bar"}
+{"location":"\/dev\/null:1,1--1,1","name":"Bar","full_name":"d::Bar"}
Edge
=type=9:CLASSTYPE
=properties=JsonObject(0):
{}
----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a","name":"a"}
+----
+=to=Node
+=labels=Array(3):
+3:foo
+7:MEntity
+8:MProject
+=properties=JsonObject(1):
+{"name":"foo"}
+
+Edge
+=type=6:PARENT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a","name":"a"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"foo"}
+
+Edge
+=type=5:NESTS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"foo"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a","name":"a"}
+
+Edge
+=type=6:PARENT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a::b","name":"b"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a","name":"a"}
+
+Edge
+=type=5:NESTS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a","name":"a"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a::b","name":"b"}
+
+Edge
+=type=7:PROJECT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"a::b","name":"b"}
+----
+=to=Node
+=labels=Array(3):
+3:foo
+7:MEntity
+8:MProject
+=properties=JsonObject(1):
+{"name":"foo"}
+
+Edge
+=type=7:PROJECT
+=properties=JsonObject(0):
+{}
+----
=from=Entity#10:namespacec
=labels=Array(3):
3:foo
=properties=JsonObject(2):
{"full_name":"c","name":"c"}
+Edge
+=type=7:PROJECT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#10:namespaced
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"d","name":"d"}
+----
+=to=Node
+=labels=Array(3):
+3:foo
+7:MEntity
+8:MProject
+=properties=JsonObject(1):
+{"name":"foo"}
+
+Edge
+=type=6:PARENT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#10:namespaced
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"d","name":"d"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"foo"}
+
+Edge
+=type=5:NESTS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"foo"}
+----
+=to=Entity#10:namespaced
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"d","name":"d"}
+
+Edge
+=type=8:DECLARES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"","name":"foo"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+7:MModule
+=properties=JsonObject(3):
+{"location":"\/dev\/null:1,1--1,1","name":"Bar","full_name":"Bar"}
+
+Edge
+=type=10:INTRODUCES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+7:MModule
+=properties=JsonObject(3):
+{"location":"\/dev\/null:1,1--1,1","name":"Bar","full_name":"Bar"}
+----
+=to=Entity#8:classbaz
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","full_name":"Baz","name":"Baz"}
+
+Edge
+=type=7:DEFINES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+7:MModule
+=properties=JsonObject(3):
+{"location":"\/dev\/null:1,1--1,1","name":"Bar","full_name":"Bar"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+9:MClassDef
+=properties=JsonObject(4):
+{"location":"\/dev\/null:1,1--1,1","is_intro":true,"name":"Baz","full_name":"Baz"}
+