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