contrib/jwrapper: fix parameter-less methods right after the constructor
[nit.git] / contrib / jwrapper / src / javap_visitor.nit
1 # This file is part of NIT (http://www.nitlanguage.org).
2 #
3 # Copyright 2014 Frédéric Vachon <fredvac@gmail.com>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Uses a visitor to extract data from the javap output AST
18 # It sends the data to `code_generator` module
19 module javap_visitor
20
21 import javap_test_parser
22 import code_generator
23 import jtype_converter
24 intrude import model
25
26 class JavaVisitor
27 super Visitor
28
29 var converter: JavaTypeConverter
30
31 var java_class = new JavaClass
32 var declaration_type: nullable String = null
33 var declaration_element: nullable String = null
34 var class_type: JavaType
35
36 var variable_id = ""
37 var variable_type: JavaType
38
39 var is_generic_param = false
40 var is_generic_id = false
41 var generic_id = ""
42 var gen_params_index = 0
43
44 # Used to resolve generic return types (T -> foo.faz.Bar)
45 var generic_map = new HashMap[String, Array[String]]
46
47 var is_primitive_array = false
48
49 var method_id = ""
50 var method_return_type: JavaType
51 var method_params = new Array[JavaType]
52 var param_index = 0
53
54 redef fun visit(n) do n.accept_visitor(self)
55
56 init(converter: JavaTypeConverter)
57 do
58 self.converter = converter
59 self.class_type = new JavaType(self.converter)
60 self.method_return_type = new JavaType(self.converter)
61 self.variable_type = new JavaType(self.converter)
62 super
63 end
64
65 # Add the identifier from `token` to the current context
66 fun add_identifier(token: NToken)
67 do
68 if declaration_type == "variable" then
69 if declaration_element == "type" then
70 variable_type.identifier.add(token.text)
71 end
72 else if declaration_type == "method" then
73 if declaration_element == "return_type" then
74 method_return_type.identifier.add(token.text)
75 else if declaration_element == "parameter_list" then
76 method_params[param_index].identifier.add(token.text)
77 end
78 end
79 end
80 end
81
82 redef class Node
83 fun accept_visitor(v: JavaVisitor) do visit_children(v)
84 end
85
86 redef class Nidentifier
87 redef fun accept_visitor(v)
88 do
89 if v.declaration_type == "class_header" then
90
91 if v.declaration_element == "id" then
92 v.class_type.identifier.add(self.text)
93 end
94
95 else if v.declaration_type == "variable" then
96
97 if v.declaration_element == "id" then
98 v.variable_id += self.text
99 else if v.declaration_element == "type" then
100 if v.is_generic_param then
101 v.variable_type.generic_params[v.gen_params_index].identifier.add(self.text)
102 else
103 v.variable_type.identifier.add(self.text)
104 end
105 end
106
107 else if v.declaration_type == "method" then
108
109 if v.declaration_element == "id" then
110 v.method_id = self.text
111 else if v.declaration_element == "return_type" then
112 if self.text == "void" then
113 v.method_return_type.is_void = true
114 else if v.is_generic_param then
115 v.method_return_type.generic_params[v.gen_params_index].identifier.add(self.text)
116 else
117 v.method_return_type.identifier.add(self.text)
118 end
119 else if v.declaration_element == "parameter_list" then
120 if v.is_generic_param then
121 v.method_params[v.param_index].generic_params[v.gen_params_index].identifier.add(self.text)
122 else
123 v.method_params[v.param_index].identifier.add(self.text)
124 end
125
126 # Creates a map to resolve generic return types
127 # Exemple : public **<T extends android/os/Bundle>** T foo();
128 else if v.is_generic_param then
129 if v.is_generic_id then
130 v.generic_id = self.text
131 v.generic_map[self.text] = new Array[String]
132
133 if not v.method_return_type.has_unresolved_types then v.method_return_type.has_unresolved_types = true
134 else
135 v.generic_map[v.generic_id].add(self.text)
136 end
137 end
138
139 end
140
141 super
142 end
143 end
144
145 # Primitive array node
146 redef class Nbrackets
147 redef fun accept_visitor(v)
148 do
149 if v.declaration_type == "variable" then
150 if v.declaration_element == "type" then
151 if v.is_generic_param then
152 v.variable_type.generic_params[v.gen_params_index].array_dimension += 1
153 else
154 v.variable_type.array_dimension += 1
155 end
156 end
157
158 else if v.declaration_type == "method" then
159
160 if v.declaration_element == "return_type" then
161 if v.is_generic_param then
162 v.method_return_type.generic_params[v.gen_params_index].array_dimension += 1
163 else
164 v.method_return_type.array_dimension += 1
165 end
166 else if v.declaration_element == "parameter_list" then
167 if v.is_generic_param then
168 v.method_params[v.param_index].generic_params[v.gen_params_index].array_dimension += 1
169 else
170 v.method_params[v.param_index].array_dimension += 1
171 end
172 end
173
174 end
175
176 super
177 end
178 end
179
180 redef class N_39dchar_39d
181 redef fun accept_visitor(v) do v.add_identifier self
182 end
183
184 redef class N_39dboolean_39d
185 redef fun accept_visitor(v) do v.add_identifier self
186 end
187
188 redef class N_39dfloat_39d
189 redef fun accept_visitor(v) do v.add_identifier self
190 end
191
192 redef class N_39ddouble_39d
193 redef fun accept_visitor(v) do v.add_identifier self
194 end
195
196 redef class N_39dbyte_39d
197 redef fun accept_visitor(v) do v.add_identifier self
198 end
199
200 redef class N_39dshort_39d
201 redef fun accept_visitor(v) do v.add_identifier self
202 end
203
204 redef class N_39dint_39d
205 redef fun accept_visitor(v) do v.add_identifier self
206 end
207
208 redef class N_39dlong_39d
209 redef fun accept_visitor(v) do v.add_identifier self
210 end
211
212 # #
213 # C L A S S H E A D E R #
214 # #
215
216 redef class Nclass_declaration
217 redef fun accept_visitor(v)
218 do
219 v.declaration_type = "class_header"
220 v.declaration_element = "id"
221 super
222
223 # Exit class declaration
224 v.declaration_type = null
225 v.declaration_element = null
226
227 v.java_class.class_type = v.class_type
228 end
229 end
230
231 # Extends declaration in the class header
232 redef class Nextends_declaration
233 redef fun accept_visitor(v)
234 do
235 v.declaration_element = "extends"
236 super
237 v.declaration_element = null
238 end
239 end
240
241 # Implements declaration in the class header
242 redef class Nimplements_declaration
243 redef fun accept_visitor(v)
244 do
245 v.declaration_element = "implements"
246 super
247 v.declaration_element = null
248 end
249 end
250
251 # #
252 # P R O P E R T Y D E C L A R A T I O N S #
253 # #
254
255 # Method declaration
256 redef class Nproperty_declaration_method
257 redef fun accept_visitor(v)
258 do
259 v.declaration_type = "method"
260 v.declaration_element = null
261 super
262 v.declaration_type = null
263
264 if v.method_return_type.has_unresolved_types then v.method_return_type.resolve_types(v.generic_map)
265 v.java_class.add_method(v.method_id, v.method_return_type, v.method_params)
266
267 v.method_params.clear
268 v.method_id = ""
269 v.method_return_type = new JavaType(v.converter)
270 end
271 end
272
273 # Constructor declaration
274 redef class Nproperty_declaration_constructor
275 redef fun accept_visitor(v)
276 do
277 v.declaration_type = "constructor"
278 super
279 v.declaration_type = null
280 end
281 end
282
283 # Variable property declaration
284 redef class Nproperty_declaration_attribute
285 redef fun accept_visitor(v)
286 do
287 v.declaration_type = "variable"
288 super
289 v.declaration_type = null
290
291 v.java_class.attributes[v.variable_id] = v.variable_type
292
293 v.variable_id = ""
294 v.variable_type = new JavaType(v.converter)
295 end
296 end
297
298 # Static property declaration
299 redef class Nproperty_declaration_static
300 redef fun accept_visitor(v)
301 do
302 v.declaration_type = "static"
303 super
304 v.declaration_type = null
305 end
306 end
307
308 # Identifier of a variable
309 redef class Nattribute_id
310 redef fun accept_visitor(v)
311 do
312 v.declaration_element = "id"
313 super
314 v.declaration_element = null
315 end
316 end
317
318 # Identifier of the method
319 redef class Nmethod_id
320 redef fun accept_visitor(v)
321 do
322 v.declaration_element = "id"
323 super
324 v.declaration_element = null
325 end
326 end
327
328 redef class Ntype
329 redef fun accept_visitor(v)
330 do
331 if v.declaration_type == "variable" and v.declaration_element != "id" then
332 v.declaration_element = "type"
333 end
334
335 if v.declaration_type == "method" and v.declaration_element == null then
336 # Makes sure it is not the generic return type definition
337 if not (v.method_return_type.identifier.is_empty and v.is_generic_param) then
338 v.declaration_element = "return_type"
339 end
340 end
341
342 super
343
344 if v.declaration_element == "variable" then
345 v.declaration_element = null
346 end
347 end
348 end
349
350 redef class Ngeneric_param
351 redef fun accept_visitor(v)
352 do
353 # Ignore the weird generic return type declaration
354 if v.declaration_type == "method" then
355 if v.declaration_element == null then
356 v.is_generic_param = true
357 else
358 v.is_generic_param = true
359 v.gen_params_index = 0
360
361 if v.declaration_element == "return_type" then
362 v.method_return_type.generic_params = new Array[JavaType]
363 else if v.declaration_element == "parameter_list" then
364 v.method_params[v.param_index].generic_params = new Array[JavaType]
365 end
366 end
367 else if v.declaration_type == "variable" then
368 if v.declaration_element == "type" then
369 v.is_generic_param = true
370 v.gen_params_index = 0
371 v.variable_type.generic_params = new Array[JavaType]
372 end
373 end
374
375 super
376
377 v.declaration_element = null
378 v.is_generic_param = false
379 end
380 end
381
382 redef class Ngeneric_identifier
383 redef fun accept_visitor(v)
384 do
385 if v.declaration_type == "method" then
386 if v.declaration_element == null then
387 v.is_generic_id = true
388 end
389 end
390
391 super
392
393 v.is_generic_id = false
394
395 end
396 end
397
398 redef class Nparameter_list
399 redef fun accept_visitor(v)
400 do
401 v.declaration_element = "parameter_list"
402 v.param_index = 0
403 super
404 v.declaration_element = null
405 v.param_index = 0
406 end
407 end
408
409 redef class Nparameter
410 redef fun accept_visitor(v)
411 do
412 if v.declaration_type == "method" then
413 if v.declaration_element == "parameter_list" then
414 if v.is_generic_param then
415 v.method_params[v.param_index].generic_params.add(new JavaType(v.converter))
416
417 super
418
419 v.gen_params_index += 1
420 else
421 v.method_params.add(new JavaType(v.converter))
422
423 super
424
425 v.param_index += 1
426 end
427 else if v.declaration_element == "return_type" and v.is_generic_param then
428
429 v.method_return_type.generic_params.add(new JavaType(v.converter))
430
431 super
432
433 v.gen_params_index += 1
434
435 # For generic return type definition
436 else if v.declaration_element == null then
437 super
438 end
439 else if v.declaration_type == "variable" then
440 if v.declaration_element == "type" and v.is_generic_param then
441 v.variable_type.generic_params.add(new JavaType(v.converter))
442
443 super
444
445 v.gen_params_index += 1
446 end
447 else
448 super
449 end
450 end
451 end