98244eba24ab2b63c6554f88a707670b5221827b
1 # This file is part of NIT ( http://www.nitlanguage.org ).
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
15 # Graphs and basic entities.
23 # All the nodes in the graph.
24 var all_nodes
: SimpleCollection[NeoNode] = new Array[NeoNode]
26 # All the edges in the graph.
27 var all_edges
: SimpleCollection[NeoEdge] = new Array[NeoEdge]
29 # Add a relationship between two nodes.
31 # Parameters are the same than for the constructor of `NeoEdge`.
32 fun add_edge
(from
: NeoNode, rel_type
: String, to
: NeoNode) do
33 all_edges
.add
(new NeoEdge(from
, rel_type
, to
))
42 var project_name
: String
44 # The node reperesenting the project.
46 # Once the project’s graph is initialized, this node must not be edited.
47 var project
= new NeoNode
49 # Entities by `model_id`.
50 var by_id
: Map[String, Entity] = new HashMap[String, Entity]
52 # Initialize a new project graph using the specified project name.
54 # The specified name will label all nodes of the project’s graph.
56 project
.labels
.add
(project_name
)
57 project
.labels
.add
("MEntity")
58 project
.labels
.add
("MProject")
59 project
["name"] = project_name
60 all_nodes
.add
(project
)
62 var root
= new RootNamespace(self)
67 # Request to all nodes in the graph to add their related edges.
70 add_edge
(project
, "ROOT", by_id
[""])
81 # In practice, this is the base class of every node in a `ProjectGraph`.
85 # Graph that will embed the entity.
86 var graph
: ProjectGraph
88 # ID of the entity in the model.
90 # Is empty for entities without an ID.
91 var model_id
: String = "" is writable
93 # Associated documentation.
94 var doc
= new JsonArray is writable
97 self.labels
.add
(graph
.project_name
)
98 self.labels
.add
("MEntity")
101 # The short (unqualified) name.
103 # May be also set by `full_name=`.
104 fun name
=(name
: String) do
108 # The short (unqualified) name.
110 var name
= self["name"]
111 assert name
isa String
115 # Include the documentation of `self` in the graph.
116 protected fun set_mdoc
do
120 # The namespace separator of Nit/C++.
121 fun ns_separator
: String do return "::"
123 # The name separator used when calling `full_name=`.
124 fun name_separator
: String do return ns_separator
126 # The full (qualified) name.
128 # Also set `name` using `name_separator`.
129 fun full_name
=(full_name
: String) do
130 var m
: nullable Match = full_name
.search_last
(name_separator
)
132 self["full_name"] = full_name
136 name
= full_name
.substring_from
(m
.after
)
140 # The full (qualified) name.
141 fun full_name
: String do
142 var full_name
= self["full_name"]
143 assert full_name
isa String
147 # Set the full name using the current name and the specified parent name.
148 fun parent_name
=(parent_name
: String) do
149 self["full_name"] = parent_name
+ name_separator
+ self["name"].as(not null).to_s
152 # Set the location of the entity in the source code.
153 fun location
=(location
: nullable Location) do
154 self["location"] = location
157 # Put the entity in the graph.
159 # Called by the loader when it has finished to read the entity.
161 if doc
.length
> 0 then
164 graph
.all_nodes
.add
(self)
165 if model_id
!= "" then graph
.by_id
[model_id
] = self
168 # Put the related edges in the graph.
170 # This method is called on each node by `ProjectGraph.put_edges`.
172 # Note: Even at this step, the entity may modify its own attributes and
173 # inner entities’ ones because some values are only known once the entity
174 # know its relationships with the rest of the graph.
178 # An entity whose the location is mandatory.
179 abstract class CodeBlock
183 self["location"] = new Location
186 redef fun location
=(location
: nullable Location) do
187 if location
== null then
197 # Usually corresponds to a `<compounddef>` element in of the XML output of
199 abstract class Compound
202 # Set the declared visibility (the proctection) of the compound.
203 fun visibility
=(visibility
: String) do
204 self["visibility"] = visibility
207 # Set the specific kind of the compound.
208 fun kind
=(kind
: String) do
212 # Declare an inner namespace.
214 # Note: Althought Doxygen indicates that the name is optional,
215 # declarations with an empty name are not supported yet.
219 # * `id`: `model_id` of the inner namespace. May be empty.
220 # * `full_name`: qualified name of the inner namespace.
221 fun declare_namespace
(id
: String, full_name
: String) do end
223 # Declare an inner class.
225 # Note: Althought Doxygen indicates that both arguments are optional,
226 # declarations with either an empty name or an empty ID are not
231 # * `id`: `model_id` of the inner class.
232 # * `full_name`: qualified name of the inner class.
233 fun declare_class
(id
: String, full_name
: String) do end
235 # Declare a base compound (usually, a base class).
239 # * `id`: `model_id` of the base compound. May be empty.
240 # * `full_name`: qualified name of the base compound. May be empty.
241 # * `prot`: visibility (proctection) of the relationship.
242 # * `virt`: level of virtuality of the relationship.
243 fun declare_super
(id
: String, full_name
: String, prot
: String,
247 # An unrecognized compound.
249 # Used to simplify the handling of ignored entities.
250 class UnknownCompound
253 redef fun put_in_graph
do end
254 redef fun put_edges
do end
259 # Corresponds to a group in Nit.
263 # Inner namespaces (IDs).
265 # Left empty for the root namespace.
266 var inner_namespaces
: SimpleCollection[String] = new Array[String]
270 self.labels
.add
("MGroup")
273 redef fun declare_namespace
(id
: String, name
: String) do
274 inner_namespaces
.add
(id
)
277 redef fun put_edges
do
279 graph
.add_edge
(self, "PROJECT", graph
.project
)
280 if self["name"] == self["full_name"] and self["full_name"] != "" then
281 # The root namespace does not know its children.
282 var root
= graph
.by_id
[""]
283 graph
.add_edge
(self, "PARENT", root
)
284 graph
.add_edge
(root
, "NESTS", self)
286 for ns
in inner_namespaces
do
287 var node
= graph
.by_id
[ns
]
288 graph
.add_edge
(node
, "PARENT", self)
289 graph
.add_edge
(self, "NESTS", node
)
294 # The root namespace of a `ProjectGraph`.
296 # This the only entity in the graph whose `model_id` is really `""`.
297 # Added automatically at the initialization of a `ProjectGraph`.
303 self["full_name"] = ""
304 self["name"] = graph
.project
["name"]
307 redef fun declare_namespace
(id
: String, name
: String) do end