--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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"}
+
+