neo_doxygen: Include namespaces’ members.
authorJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Tue, 9 Dec 2014 20:50:25 +0000 (15:50 -0500)
committerJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Mon, 15 Dec 2014 19:11:19 +0000 (14:11 -0500)
Signed-off-by: Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>

contrib/neo_doxygen/src/model/model.nit
contrib/neo_doxygen/src/model/module_compound.nit
contrib/neo_doxygen/src/model/namespace_members.nit [new file with mode: 0644]
contrib/neo_doxygen/src/tests/neo_doxygen_namespace_members.nit [new file with mode: 0644]
tests/nitg-g.skip
tests/sav/neo_doxygen_namespace_members.res [new file with mode: 0644]

index a89c8f3..8ad7e5e 100644 (file)
@@ -22,3 +22,4 @@ import class_compound
 import module_compound
 import member
 import inner_class
+import namespace_members
index 404bcac..c95cb84 100644 (file)
@@ -17,6 +17,7 @@ module model::module_compound
 
 import graph
 import class_compound
+import namespace_members
 
 # A source file.
 #
@@ -146,8 +147,14 @@ private class Module
                parent_name = namespace.full_name
        end
 
+       redef fun put_in_graph do
+               super
+       end
+
        redef fun put_edges do
                var ns_compound = namespace.seek_in(graph)
+               var self_class = ns_compound.self_class
+
                graph.add_edge(ns_compound, "DECLARES", self)
 
                for c in file_compound.inner_classes do
@@ -156,6 +163,13 @@ private class Module
                        graph.add_edge(self, "INTRODUCES", class_compound)
                        graph.add_edge(self, "DEFINES", class_compound.class_def)
                end
+
+               if self_class isa SelfClass then
+                       # We assume that only one file is linked to the namespace.
+                       # TODO When Doxygen will provide a way to know which file defines which member, use it.
+                       graph.add_edge(self, "INTRODUCES", self_class)
+                       graph.add_edge(self, "DEFINES", self_class.class_def)
+               end
        end
 end
 
diff --git a/contrib/neo_doxygen/src/model/namespace_members.nit b/contrib/neo_doxygen/src/model/namespace_members.nit
new file mode 100644 (file)
index 0000000..dba1a43
--- /dev/null
@@ -0,0 +1,86 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Add support for namespace’s members.
+module model::namespace_members
+
+import class_compound
+import member
+
+redef class Namespace
+       # The class that contains the namespace’s direct members.
+       #
+       # Left `null` for the root namespace and for any namespace with no direct
+       # member. Automatically put in the graph with the namespace.
+       #
+       # Note: In the graph, the `self_class` not linked directly to the namespace.
+       # This is the role of the modules implicitly created by `FileCompound`s to
+       # link a namespace to its `self_class`.
+       #
+       # SEE: `declare_member`
+       var self_class: nullable SelfClass = null
+
+       # Add the specified member as a direct children of the namespace.
+       redef fun declare_member(member) do
+               if self_class == null then self_class = new SelfClass(graph, self)
+               self_class.as(not null).declare_member(member)
+       end
+
+       redef fun full_name=(full_name) do
+               super
+               var self_class = self.self_class
+               if self_class isa SelfClass then self_class.update_name
+       end
+
+       redef fun parent_name=(parent_name) do
+               super
+               var self_class = self.self_class
+               if self_class isa SelfClass then self_class.update_name
+       end
+
+       redef fun put_in_graph do
+               super
+               var self_class = self.self_class
+               if self_class isa SelfClass then self_class.put_in_graph
+       end
+end
+
+redef class RootNamespace
+       redef fun declare_member(member) do
+               assert false else
+                       # TODO Check how Doxygen modelize member of the root namespace.
+                       # Note: Doxygen does not modelize the root namespace.
+                       sys.stderr.write "The addition of a member to the root namespace is not supported yet."
+               end
+       end
+end
+
+# A class that contains a namespace’s direct members.
+class SelfClass
+       super ClassCompound
+
+       # The namespace of the members
+       var namespace: Namespace
+
+       init do
+               super
+               name = "(self)"
+               update_name
+       end
+
+       # Update the `full_name`.
+       #
+       # Update the parent name to the `full_name` of the namespace.
+       private fun update_name do parent_name = namespace.full_name
+end
diff --git a/contrib/neo_doxygen/src/tests/neo_doxygen_namespace_members.nit b/contrib/neo_doxygen/src/tests/neo_doxygen_namespace_members.nit
new file mode 100644 (file)
index 0000000..f23d35e
--- /dev/null
@@ -0,0 +1,40 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import tests
+import model
+
+var graph = new ProjectGraph("foo")
+var file = new FileCompound(graph)
+var ns = new Namespace(graph)
+var member = new Attribute(graph)
+var buffer = new RopeBuffer
+
+file.full_name = "foo.py"
+file.model_id = "_foo_8py"
+file.declare_namespace("namespacefoo", "foo")
+file.put_in_graph
+
+member.name = "bar"
+member.put_in_graph
+
+ns.model_id = "namespacefoo"
+ns.full_name = "foo"
+ns.declare_member(member)
+ns.put_in_graph
+
+graph.add_global_modules
+graph.put_edges
+graph.debug buffer
+print buffer
index 8725c3e..e901186 100644 (file)
@@ -5,6 +5,7 @@ neo_doxygen_dump
 neo_doxygen_file_compound
 neo_doxygen_graph_empty_project
 neo_doxygen_member_resolve_introducer
+neo_doxygen_namespace_members
 test_docdown
 nith
 nit_pretty
diff --git a/tests/sav/neo_doxygen_namespace_members.res b/tests/sav/neo_doxygen_namespace_members.res
new file mode 100644 (file)
index 0000000..c591293
--- /dev/null
@@ -0,0 +1,346 @@
+# 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=Node
+=labels=Array(3):
+3:foo
+7:MEntity
+8:MProject
+=properties=JsonObject(1):
+{"name":"foo"}
+
+Edge
+=type=8:DECLARES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#12:namespacefoo
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"foo","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":"foo","full_name":"foo::foo"}
+
+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":"foo","full_name":"foo::foo"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","name":"(self)","full_name":"foo::(self)"}
+
+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":"foo","full_name":"foo::foo"}
+----
+=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":"(self)","full_name":"foo::(self)"}
+
+Edge
+=type=7:DEFINES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(4):
+3:foo
+7:MEntity
+8:MPropDef
+13:MAttributeDef
+=properties=JsonObject(4):
+{"location":"\/dev\/null:1,1--1,1","name":"bar","is_intro":true,"full_name":"foo::(self)::bar"}
+----
+=to=Entity#0:
+=labels=Array(4):
+3:foo
+7:MEntity
+9:MProperty
+10:MAttribute
+=properties=JsonObject(3):
+{"visibility":"public","name":"bar","full_name":"foo::(self)::bar"}
+
+Edge
+=type=7:PROJECT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#12:namespacefoo
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"foo","name":"foo"}
+----
+=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#12:namespacefoo
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"foo","name":"foo"}
+----
+=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#12:namespacefoo
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MGroup
+=properties=JsonObject(2):
+{"full_name":"foo","name":"foo"}
+
+Edge
+=type=9:CLASSTYPE
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","name":"(self)","full_name":"foo::(self)"}
+----
+=to=Entity#0:
+=labels=Array(4):
+3:foo
+7:MEntity
+5:MType
+10:MClassType
+=properties=JsonObject(2):
+{"name":"(self)","full_name":"foo::(self)"}
+
+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":"(self)","full_name":"foo::(self)"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","name":"(self)","full_name":"foo::(self)"}
+
+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":"(self)","full_name":"foo::(self)"}
+----
+=to=Entity#0:
+=labels=Array(4):
+3:foo
+7:MEntity
+5:MType
+10:MClassType
+=properties=JsonObject(2):
+{"name":"(self)","full_name":"foo::(self)"}
+
+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":"(self)","full_name":"foo::(self)"}
+----
+=to=Entity#0:
+=labels=Array(3):
+3:foo
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","name":"(self)","full_name":"foo::(self)"}
+
+Edge
+=type=10:INTRODUCES
+=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":"(self)","full_name":"foo::(self)"}
+----
+=to=Entity#0:
+=labels=Array(4):
+3:foo
+7:MEntity
+9:MProperty
+10:MAttribute
+=properties=JsonObject(3):
+{"visibility":"public","name":"bar","full_name":"foo::(self)::bar"}
+
+Edge
+=type=14:INTRO_CLASSDEF
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(4):
+3:foo
+7:MEntity
+9:MProperty
+10:MAttribute
+=properties=JsonObject(3):
+{"visibility":"public","name":"bar","full_name":"foo::(self)::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":"(self)","full_name":"foo::(self)"}
+
+Edge
+=type=8:DECLARES
+=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":"(self)","full_name":"foo::(self)"}
+----
+=to=Entity#0:
+=labels=Array(4):
+3:foo
+7:MEntity
+8:MPropDef
+13:MAttributeDef
+=properties=JsonObject(4):
+{"location":"\/dev\/null:1,1--1,1","name":"bar","is_intro":true,"full_name":"foo::(self)::bar"}
+
+