neo_doxygen: Avoid clearing the namespace’s id of a module.
[nit.git] / contrib / neo_doxygen / src / model / module_compound.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Nodes for modules and files.
16 module model::module_compound
17
18 import graph
19 import class_compound
20
21 # A source file.
22 #
23 # Creates one modules by inner namespace. The full name of the modules begin
24 # with the namespace’s full name, and end with the unqualified name of the file,
25 # without the extension.
26 class FileCompound
27 super Compound
28 super CodeBlock
29
30 # Mapping between inner namespace’s names and corresponding modules.
31 private var inner_namespaces: Map[String, Module] = new HashMap[String, Module]
32
33 # The last component of the path, without the extension.
34 #
35 # Used as the unqualified name of the modules.
36 private var basename: String = ""
37
38 init do
39 super
40 end
41
42 redef fun name_separator: String do return "/"
43
44 redef fun location=(location: nullable Location) do
45 super
46 if location != null and location.path != null then
47 full_name = location.path.as(not null)
48 end
49 for m in inner_namespaces.values do m.location = location
50 end
51
52 redef fun name=(name: String) do
53 # Example: `MyClass.java`
54 super
55 var match = name.search_last(".")
56
57 if match == null then
58 basename = name
59 else
60 basename = name.substring(0, match.from)
61 end
62 # Update the modules’ name.
63 for ns, m in inner_namespaces do
64 m.full_name = "{ns}{ns_separator}{basename}"
65 end
66 end
67
68 redef fun declare_namespace(id: String, name: String) do
69 var m: Module
70
71 if inner_namespaces.keys.has(name) then
72 m = inner_namespaces[name]
73 if id != "" then m.parent = id
74 else
75 m = new Module(graph)
76 m.full_name = "{name}{ns_separator}{basename}"
77 m.parent = id
78 m.location = self["location"].as(nullable Location)
79 inner_namespaces[name] = m
80 end
81 end
82
83 redef fun declare_class(id: String, name: String) do
84 var match = name.search_last(ns_separator)
85 var ns_name: String
86 var m: Module
87
88 if match == null then
89 ns_name = ""
90 else
91 ns_name = name.substring(0, match.from)
92 end
93 if inner_namespaces.keys.has(ns_name) then
94 m = inner_namespaces[ns_name]
95 else
96 declare_namespace("", ns_name)
97 m = inner_namespaces[ns_name]
98 end
99 m.declare_class(id, name)
100 end
101
102 redef fun put_in_graph do
103 # Do not add `self` to the Neo4j graph...
104 # ... but add its modules...
105 for m in inner_namespaces.values do m.put_in_graph
106 # ... and add `self` to the index.
107 if model_id != "" then graph.by_id[model_id] = self
108 end
109 end
110
111 # A module.
112 class Module
113 super Compound
114 super CodeBlock
115
116 # The `model_id` of the parent namespace.
117 var parent: String = "" is writable
118
119 # The classes defined in the module.
120 var inner_classes: SimpleCollection[String] = new Array[String]
121
122 init do
123 super
124 self.labels.add("MModule")
125 end
126
127 redef fun declare_class(id: String, name: String) do
128 inner_classes.add(id)
129 end
130
131 redef fun put_edges do
132 graph.add_edge(graph.by_id[parent], "DECLARES", self)
133 for c in inner_classes do
134 var node = graph.by_id[c].as(ClassCompound)
135 graph.add_edge(self, "INTRODUCES", node)
136 graph.add_edge(self, "DEFINES", node.class_def)
137 end
138 end
139 end