neo_doxygen: Do not guess the namespace of the classes.
authorJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Sat, 29 Nov 2014 06:18:35 +0000 (01:18 -0500)
committerJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Tue, 2 Dec 2014 15:19:56 +0000 (10:19 -0500)
Use explicit relationships instead of manipulating the names.

Signed-off-by: Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>

contrib/neo_doxygen/src/model/graph.nit
contrib/neo_doxygen/src/model/module_compound.nit
contrib/neo_doxygen/src/neo_doxygen.nit
contrib/neo_doxygen/src/tests/neo_doxygen_file_compound.nit
tests/sav/neo_doxygen_dump_args4.res
tests/sav/neo_doxygen_dump_args5.res
tests/sav/neo_doxygen_dump_args6.res
tests/sav/neo_doxygen_file_compound.res

index 27b250d..aad1644 100644 (file)
@@ -16,6 +16,7 @@
 module model::graph
 
 import neo4j
+import more_collections
 import location
 
 # A Neo4j graph.
@@ -35,6 +36,22 @@ class NeoGraph
 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
 
@@ -49,6 +66,21 @@ class ProjectGraph
        # 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.
@@ -62,9 +94,15 @@ class ProjectGraph
                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[""])
@@ -229,13 +267,14 @@ abstract class Compound
        # 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).
@@ -266,18 +305,28 @@ end
 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
@@ -290,13 +339,42 @@ class Namespace
                        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 `""`.
index f76df4d..069b50b 100644 (file)
@@ -23,12 +23,18 @@ import class_compound
 # 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.
        #
@@ -46,7 +52,7 @@ class FileCompound
                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
@@ -60,13 +66,7 @@ class FileCompound
                        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
@@ -75,85 +75,103 @@ class FileCompound
                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
index d70f008..48bb5ad 100644 (file)
@@ -74,6 +74,7 @@ class NeoDoxygenJob
                        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."
index ec80446..9a5c59c 100644 (file)
@@ -20,7 +20,10 @@ var file = new FileCompound(graph)
 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"
@@ -44,10 +47,31 @@ baz_class.model_id = "classbaz"
 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
index 6ceb76f..f44e8ea 100644 (file)
@@ -67,7 +67,7 @@ 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"}
 
 
 Edge
@@ -81,7 +81,7 @@ 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):
@@ -103,7 +103,7 @@ 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#0:
 =labels=Array(3):
@@ -133,7 +133,7 @@ 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"}
 
 
 Edge
@@ -147,7 +147,7 @@ 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):
@@ -169,7 +169,7 @@ 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#0:
 =labels=Array(3):
@@ -199,7 +199,7 @@ 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"}
 
 
 Edge
@@ -213,7 +213,7 @@ 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):
@@ -235,7 +235,7 @@ 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#0:
 =labels=Array(3):
@@ -265,7 +265,7 @@ 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"}
 
 
 Edge
@@ -279,7 +279,7 @@ 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):
@@ -301,7 +301,7 @@ 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#0:
 =labels=Array(3):
index a41654d..ae6cb05 100644 (file)
@@ -67,7 +67,7 @@ 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"}
 
 
 Edge
@@ -81,7 +81,7 @@ 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):
@@ -103,7 +103,7 @@ 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#0:
 =labels=Array(3):
@@ -133,7 +133,7 @@ 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"}
 
 
 Edge
@@ -147,7 +147,7 @@ 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):
@@ -169,7 +169,7 @@ 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#0:
 =labels=Array(3):
@@ -199,7 +199,7 @@ 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"}
 
 
 Edge
@@ -213,7 +213,7 @@ 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):
@@ -235,7 +235,7 @@ 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#0:
 =labels=Array(3):
@@ -265,7 +265,7 @@ 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"}
 
 
 Edge
@@ -279,7 +279,7 @@ 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):
@@ -301,7 +301,7 @@ 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#0:
 =labels=Array(3):
index 3f1f05e..65d20ff 100644 (file)
@@ -49,39 +49,41 @@ Edge
 
 
 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):
@@ -93,7 +95,7 @@ Edge
 
 
 Edge
-=type=7:DEFINES
+=type=9:BOUNDTYPE
 =properties=JsonObject(0):
 {}
 ----
@@ -101,31 +103,9 @@ Edge
 =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):
@@ -138,18 +118,17 @@ Edge
 
 
 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):
@@ -161,7 +140,7 @@ Edge
 
 
 Edge
-=type=9:BOUNDTYPE
+=type=8:DECLARES
 =properties=JsonObject(0):
 {}
 ----
@@ -169,22 +148,21 @@ Edge
 =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):
 {}
 ----
@@ -192,9 +170,9 @@ Edge
 =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):
@@ -205,4 +183,26 @@ Edge
 {"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===---
index 8e5f740..ab885c0 100644 (file)
@@ -1,3 +1,4 @@
+---===WITHOUT GLOBALS===---
 # Graph
 Edge
 =type=4:ROOT
@@ -52,7 +53,7 @@ Edge
 7:MEntity
 6:MGroup
 =properties=JsonObject(2):
-{"full_name":"","name":"foo"}
+{"full_name":"a::b","name":"b"}
 ----
 =to=Entity#0:
 =labels=Array(3):
@@ -60,7 +61,7 @@ Edge
 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
@@ -73,7 +74,7 @@ Edge
 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):
@@ -94,15 +95,528 @@ Edge
 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
@@ -115,7 +629,7 @@ Edge
 7:MEntity
 6:MGroup
 =properties=JsonObject(2):
-{"full_name":"","name":"foo"}
+{"full_name":"a::b","name":"b"}
 ----
 =to=Entity#0:
 =labels=Array(3):
@@ -123,7 +637,7 @@ Edge
 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
@@ -136,15 +650,15 @@ Edge
 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
@@ -157,7 +671,7 @@ Edge
 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):
@@ -165,7 +679,7 @@ Edge
 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
@@ -186,20 +700,20 @@ Edge
 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):
@@ -207,7 +721,7 @@ Edge
 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
@@ -388,6 +902,132 @@ Edge
 =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
@@ -446,4 +1086,130 @@ Edge
 =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"}
+