ci: do not error when nothing with nitunit_some
[nit.git] / contrib / neo_doxygen / src / model / member.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 # Members.
16 module model::member
17
18 import graph
19 import type_entity
20
21 # A member or an inner class.
22 abstract class MemberOrInner
23 super CodeBlock
24
25 # The type of the introducer.
26 type INTRODUCER_TYPE: MemberIntroducer
27
28 # The node used to represent the `MProperty` node.
29 #
30 # Only defined if `self` is at the root of a reimplementation graph, and
31 # only once `put_in_graph` is called.
32 var introducer: nullable INTRODUCER_TYPE = null
33
34 init do
35 super
36 self.labels.add("MPropDef")
37 end
38
39 # Does this member introduce the property?
40 fun is_intro: Bool is abstract
41
42 redef fun put_in_graph do
43 super
44 self["is_intro"] = is_intro
45 if is_intro then
46 var visibility = self["visibility"]
47 var name = self["name"]
48
49 introducer = create_introducer
50 if name isa String then
51 introducer.name = name
52 end
53 if visibility isa String then
54 introducer.visibility = visibility
55 end
56 introducer.put_in_graph
57 end
58 end
59
60 redef fun put_edges do
61 super
62 var intro = resolve_introducer
63
64 assert intro != null
65 graph.add_edge(self, "DEFINES", intro)
66 end
67
68 # Set the visibility.
69 fun visibility=(visibility: String) do
70 self["visibility"] = visibility
71 if introducer != null then
72 introducer.as(not null).visibility = visibility
73 end
74 end
75
76 # Get the visibility.
77 #
78 # Return `""` by default.
79 fun visibility: String do
80 var visibility = self["visibility"]
81 if visibility isa String then return visibility
82 return ""
83 end
84
85 redef fun name=(name: String) do
86 super
87 if introducer != null then
88 introducer.as(not null).name = name
89 end
90 end
91
92 # Create an instance of `MemberIntroducer` that will be linked to `self`.
93 protected fun create_introducer: INTRODUCER_TYPE is abstract
94
95 # Find the nearest reimplementation root.
96 fun resolve_introducer: nullable INTRODUCER_TYPE is abstract
97 end
98
99 # A member.
100 abstract class Member
101 super MemberOrInner
102
103 # Members that this member redefines/reimplements.
104 var reimplemented: SimpleCollection[String] = new Array[String]
105
106 # Set the static type.
107 fun static_type=(static_type: nullable TypeEntity) is abstract
108
109 # Get the static type.
110 fun static_type: nullable TypeEntity is abstract
111
112 # Append the specified parameter to the signature.
113 fun add_parameter(parameter: MemberParameter) do end
114
115 # Append a member that is reimplemeneted by `self`.
116 fun reimplement(parent: String) do
117 reimplemented.add(parent)
118 end
119
120 redef fun is_intro do return reimplemented.length <= 0
121
122 # Is the member abstract?
123 fun is_abstract=(is_abstract: Bool) do
124 self["is_abstract"] = is_abstract
125 end
126
127 # Find the nearest reimplementation root.
128 #
129 # var g = new ProjectGraph("foo")
130 # var m1 = new Attribute(g)
131 # var m2 = new Attribute(g)
132 # var m3 = new Attribute(g)
133 # #
134 # m1.model_id = "1"
135 # m1.put_in_graph
136 # m2.reimplement("1")
137 # m2.put_in_graph
138 # assert m1.resolve_introducer == m1.introducer
139 # assert m2.resolve_introducer == m1.introducer
140 # #
141 # m3.model_id = "3"
142 # m3.reimplement("3")
143 # m3.put_in_graph
144 # assert m3.resolve_introducer == null
145 redef fun resolve_introducer do
146 if introducer == null then
147 var member_queue = new List[String]
148 var visited = new HashSet[Member]
149 var member: Member
150
151 member_queue.add_all(reimplemented)
152 while not member_queue.is_empty do
153 member = graph.by_id[member_queue.shift].as(Member)
154 if visited.has(member) then
155 return null
156 else if member.is_intro then
157 return member.introducer
158 else
159 visited.add(member)
160 member_queue.add_all(member.reimplemented)
161 end
162 end
163 return null
164 else
165 return introducer
166 end
167 end
168 end
169
170 # An unrecognized member.
171 #
172 # Used to simplify the handling of ignored entities.
173 class UnknownMember
174 super Member
175
176 redef fun put_in_graph do end
177 redef fun put_edges do end
178 end
179
180 # A local definition of a method.
181 class Method
182 super Member
183
184 redef type INTRODUCER_TYPE: MethodIntroducer
185
186 # The method’s signature.
187 var signature: Signature is noinit, writable
188
189 init do
190 super
191 self.labels.add("MMethodDef")
192 self["is_intern"] = false # TODO
193 self["is_extern"] = false # TODO
194 signature = new Signature(graph)
195 is_abstract = false
196 end
197
198 # Set the return type.
199 redef fun static_type=(static_type: nullable TypeEntity) do
200 signature.return_type = static_type
201 end
202
203 # Get the return type.
204 redef fun static_type: nullable TypeEntity do return signature.return_type
205
206 redef fun add_parameter(parameter: MemberParameter) do
207 signature.parameters.add(parameter)
208 end
209
210 redef fun create_introducer do return new MethodIntroducer(graph)
211
212 redef fun put_in_graph do
213 super
214 signature.put_in_graph
215 end
216
217 redef fun put_edges do
218 super
219 graph.add_edge(self, "SIGNATURE", signature)
220 end
221 end
222
223 # A local definition of an attribute.
224 class Attribute
225 super Member
226
227 redef type INTRODUCER_TYPE: AttributeIntroducer
228
229 # The declared type.
230 redef var static_type: nullable TypeEntity = null is writable
231
232 init do
233 super
234 self.labels.add("MAttributeDef")
235 end
236
237 redef fun create_introducer do return new AttributeIntroducer(graph)
238
239 redef fun put_in_graph do
240 super
241 if static_type != null then
242 static_type.as(not null).put_in_graph
243 end
244 end
245
246 redef fun put_edges do
247 super
248 if static_type != null then
249 graph.add_edge(self, "TYPE", static_type.as(not null))
250 end
251 end
252 end
253
254 # The `MProperty` node of a root of a reimplementation graph.
255 abstract class MemberIntroducer
256 super Entity
257
258 init do
259 super
260 self.labels.add("MProperty")
261 self["visibility"] = "public"
262 end
263
264 # Set the visibility.
265 fun visibility=(visibility: String) do
266 self["visibility"] = visibility
267 end
268
269 # Get the visibility.
270 #
271 # Return `""` by default.
272 fun visibility: String do
273 var visibility = self["visibility"]
274 if visibility isa String then return visibility
275 return ""
276 end
277 end
278
279 # A `MProperty` node for a method.
280 class MethodIntroducer
281 super MemberIntroducer
282
283 init do
284 super
285 self.labels.add("MMethod")
286 self["is_init"] = false # TODO
287 end
288 end
289
290 # A `MProperty` node for an attribute.
291 class AttributeIntroducer
292 super MemberIntroducer
293
294 init do
295 super
296 self.labels.add("MAttribute")
297 end
298 end
299
300 redef class Compound
301 # Append the specified member.
302 fun declare_member(member: Member) do end
303 end