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
))
37 # The project’s graph.
41 # The node reperesenting the project.
43 # Once the project’s graph is initialized, this node must not be edited.
44 var project
= new NeoNode
46 # Entities by `model_id`.
47 var by_id
: Map[String, Entity] = new HashMap[String, Entity]
49 # Initialize a new project graph using the specified project name.
51 # The specified name will label all nodes of the project’s graph.
53 project
.labels
.add
(name
)
54 project
.labels
.add
("MEntity")
55 project
.labels
.add
("MProject")
56 project
["name"] = name
57 all_nodes
.add
(project
)
59 var root
= new RootNamespace(self)
64 # Request to all nodes in the graph to add their related edges.
67 add_edge
(project
, "ROOT", by_id
[""])
78 # In practice, this is the base class of every node in a `ProjectGraph`.
82 # Graph that will embed the entity.
83 var graph
: ProjectGraph
85 # ID of the entity in the model.
87 # Is empty for entities without an ID.
88 var model_id
: String = "" is writable
90 # Associated documentation.
91 var doc
= new JsonArray is writable
94 self.labels
.add
(graph
.project
["name"].to_s
)
95 self.labels
.add
("MEntity")
98 # The short (unqualified) name.
100 # May be also set by `full_name=`.
101 fun name
=(name
: String) do
105 # The short (unqualified) name.
107 var name
= self["name"]
108 assert name
isa String
112 # Include the documentation of `self` in the graph.
113 protected fun set_mdoc
do
117 # The namespace separator of Nit/C++.
118 fun ns_separator
: String do return "::"
120 # The name separator used when calling `full_name=`.
121 fun name_separator
: String do return ns_separator
123 # The full (qualified) name.
125 # Also set `name` using `name_separator`.
126 fun full_name
=(full_name
: String) do
127 var m
: nullable Match = full_name
.search_last
(name_separator
)
129 self["full_name"] = full_name
133 name
= full_name
.substring_from
(m
.after
)
137 # The full (qualified) name.
138 fun full_name
: String do
139 var full_name
= self["full_name"]
140 assert full_name
isa String
144 # Set the full name using the current name and the specified parent name.
145 fun parent_name
=(parent_name
: String) do
146 self["full_name"] = parent_name
+ name_separator
+ self["name"].as(not null).to_s
149 # Set the location of the entity in the source code.
150 fun location
=(location
: nullable Location) do
151 self["location"] = location
154 # Put the entity in the graph.
156 # Called by the loader when it has finished to read the entity.
158 if doc
.length
> 0 then
161 graph
.all_nodes
.add
(self)
162 if model_id
!= "" then graph
.by_id
[model_id
] = self
165 # Put the related edges in the graph.
167 # This method is called on each node by `ProjectGraph.put_edges`.
169 # Note: Even at this step, the entity may modify its own attributes and
170 # inner entities’ ones because some values are only known once the entity
171 # know its relationships with the rest of the graph.
175 # An entity whose the location is mandatory.
176 abstract class CodeBlock
180 self["location"] = new Location
183 redef fun location
=(location
: nullable Location) do
184 if location
== null then
194 # Usually corresponds to a `<compounddef>` element in of the XML output of
196 abstract class Compound
199 # Set the declared visibility (the proctection) of the compound.
200 fun visibility
=(visibility
: String) do
201 self["visibility"] = visibility
204 # Set the specific kind of the compound.
205 fun kind
=(kind
: String) do
209 # Declare an inner namespace.
211 # Note: Althought Doxygen indicates that the name is optional,
212 # declarations with an empty name are not supported yet.
216 # * `id`: `model_id` of the inner namespace. May be empty.
217 # * `full_name`: qualified name of the inner namespace.
218 fun declare_namespace
(id
: String, full_name
: String) do end
220 # Declare an inner class.
222 # Note: Althought Doxygen indicates that both arguments are optional,
223 # declarations with either an empty name or an empty ID are not
228 # * `id`: `model_id` of the inner class.
229 # * `full_name`: qualified name of the inner class.
230 fun declare_class
(id
: String, full_name
: String) do end
232 # Declare a base compound (usually, a base class).
236 # * `id`: `model_id` of the base compound. May be empty.
237 # * `full_name`: qualified name of the base compound. May be empty.
238 # * `prot`: visibility (proctection) of the relationship.
239 # * `virt`: level of virtuality of the relationship.
240 fun declare_super
(id
: String, full_name
: String, prot
: String,
244 # An unrecognized compound.
246 # Used to simplify the handling of ignored entities.
247 class UnknownCompound
250 redef fun put_in_graph
do end
251 redef fun put_edges
do end
256 # Corresponds to a group in Nit.
260 # Inner namespaces (IDs).
262 # Left empty for the root namespace.
263 var inner_namespaces
: SimpleCollection[String] = new Array[String]
267 self.labels
.add
("MGroup")
270 redef fun declare_namespace
(id
: String, name
: String) do
271 inner_namespaces
.add
(id
)
274 redef fun put_edges
do
276 graph
.add_edge
(self, "PROJECT", graph
.project
)
277 if self["name"] == self["full_name"] and self["full_name"] != "" then
278 # The root namespace does not know its children.
279 var root
= graph
.by_id
[""]
280 graph
.add_edge
(self, "PARENT", root
)
281 graph
.add_edge
(root
, "NESTS", self)
283 for ns
in inner_namespaces
do
284 var node
= graph
.by_id
[ns
]
285 graph
.add_edge
(node
, "PARENT", self)
286 graph
.add_edge
(self, "NESTS", node
)
291 # The root namespace of a `ProjectGraph`.
293 # This the only entity in the graph whose `model_id` is really `""`.
294 # Added automatically at the initialization of a `ProjectGraph`.
300 self["full_name"] = ""
301 self["name"] = graph
.project
["name"]
304 redef fun declare_namespace
(id
: String, name
: String) do end