contrib/jwrapper: rename the `types` module to `model`
[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 end
65
66 redef class Node
67 fun accept_visitor(v: JavaVisitor) do visit_children(v)
68 end
69
70 redef class Nidentifier
71 redef fun accept_visitor(v)
72 do
73 if v.declaration_type == "class_header" then
74
75 if v.declaration_element == "id" then
76 v.class_type.identifier.add(self.text)
77 end
78
79 else if v.declaration_type == "variable" then
80
81 if v.declaration_element == "id" then
82 v.variable_id += self.text
83 else if v.declaration_element == "type" then
84 if v.is_generic_param then
85 v.variable_type.generic_params[v.gen_params_index].identifier.add(self.text)
86 else
87 v.variable_type.identifier.add(self.text)
88 end
89 end
90
91 else if v.declaration_type == "method" then
92
93 if v.declaration_element == "id" then
94 v.method_id = self.text
95 else if v.declaration_element == "return_type" then
96 if self.text == "void" then
97 v.method_return_type.is_void = true
98 else if v.is_generic_param then
99 v.method_return_type.generic_params[v.gen_params_index].identifier.add(self.text)
100 else
101 v.method_return_type.identifier.add(self.text)
102 end
103 else if v.declaration_element == "parameter_list" then
104 if v.is_generic_param then
105 v.method_params[v.param_index].generic_params[v.gen_params_index].identifier.add(self.text)
106 else
107 v.method_params[v.param_index].identifier.add(self.text)
108 end
109
110 # Creates a map to resolve generic return types
111 # Exemple : public **<T extends android/os/Bundle>** T foo();
112 else if v.is_generic_param then
113 if v.is_generic_id then
114 v.generic_id = self.text
115 v.generic_map[self.text] = new Array[String]
116
117 if not v.method_return_type.has_unresolved_types then v.method_return_type.has_unresolved_types = true
118 else
119 v.generic_map[v.generic_id].add(self.text)
120 end
121 end
122
123 end
124
125 super
126 end
127 end
128
129 # Primitive array node
130 redef class N_39d_91d_93d_39d
131 redef fun accept_visitor(v)
132 do
133 if v.declaration_type == "variable" then
134 if v.declaration_element == "type" then
135 if v.is_generic_param then
136 v.variable_type.generic_params[v.gen_params_index].array_dimension += 1
137 else
138 v.variable_type.array_dimension += 1
139 end
140 end
141
142 else if v.declaration_type == "method" then
143
144 if v.declaration_element == "return_type" then
145 if v.is_generic_param then
146 v.method_return_type.generic_params[v.gen_params_index].array_dimension += 1
147 else
148 v.method_return_type.array_dimension += 1
149 end
150 else if v.declaration_element == "parameter_list" then
151 if v.is_generic_param then
152 v.method_params[v.param_index].generic_params[v.gen_params_index].array_dimension += 1
153 else
154 v.method_params[v.param_index].array_dimension += 1
155 end
156 end
157
158 end
159
160 super
161 end
162 end
163
164 redef class N_39dchar_39d
165 redef fun accept_visitor(v)
166 do
167 if v.declaration_type == "variable" then
168 if v.declaration_element == "type" then
169 v.variable_type.identifier.add(self.text)
170 end
171 else if v.declaration_type == "method" then
172 if v.declaration_element == "return_type" then
173 v.method_return_type.identifier.add(self.text)
174 else if v.declaration_element == "parameter_list" then
175 v.method_params[v.param_index].identifier.add(self.text)
176 end
177 end
178 end
179 end
180
181 redef class N_39dboolean_39d
182 redef fun accept_visitor(v)
183 do
184 if v.declaration_type == "variable" then
185 if v.declaration_element == "type" then
186 v.variable_type.identifier.add(self.text)
187 end
188 else if v.declaration_type == "method" then
189 if v.declaration_element == "return_type" then
190 v.method_return_type.identifier.add(self.text)
191 else if v.declaration_element == "parameter_list" then
192 v.method_params[v.param_index].identifier.add(self.text)
193 end
194 end
195 end
196 end
197
198 redef class N_39dfloat_39d
199 redef fun accept_visitor(v)
200 do
201 if v.declaration_type == "variable" then
202 if v.declaration_element == "type" then
203 v.variable_type.identifier.add(self.text)
204 end
205 else if v.declaration_type == "method" then
206 if v.declaration_element == "return_type" then
207 v.method_return_type.identifier.add(self.text)
208 else if v.declaration_element == "parameter_list" then
209 v.method_params[v.param_index].identifier.add(self.text)
210 end
211 end
212 end
213 end
214
215 redef class N_39ddouble_39d
216 redef fun accept_visitor(v)
217 do
218 if v.declaration_type == "variable" then
219 if v.declaration_element == "type" then
220 v.variable_type.identifier.add(self.text)
221 end
222 else if v.declaration_type == "method" then
223 if v.declaration_element == "return_type" then
224 v.method_return_type.identifier.add(self.text)
225 else if v.declaration_element == "parameter_list" then
226 v.method_params[v.param_index].identifier.add(self.text)
227 end
228 end
229 end
230 end
231
232 redef class N_39dbyte_39d
233 redef fun accept_visitor(v)
234 do
235 if v.declaration_type == "variable" then
236 if v.declaration_element == "type" then
237 v.variable_type.identifier.add(self.text)
238 end
239 else if v.declaration_type == "method" then
240 if v.declaration_element == "return_type" then
241 v.method_return_type.identifier.add(self.text)
242 else if v.declaration_element == "parameter_list" then
243 v.method_params[v.param_index].identifier.add(self.text)
244 end
245 end
246 end
247 end
248
249 redef class N_39dshort_39d
250 redef fun accept_visitor(v)
251 do
252 if v.declaration_type == "variable" then
253 if v.declaration_element == "type" then
254 v.variable_type.identifier.add(self.text)
255 end
256 else if v.declaration_type == "method" then
257 if v.declaration_element == "return_type" then
258 v.method_return_type.identifier.add(self.text)
259 else if v.declaration_element == "parameter_list" then
260 v.method_params[v.param_index].identifier.add(self.text)
261 end
262 end
263 end
264 end
265
266 redef class N_39dint_39d
267 redef fun accept_visitor(v)
268 do
269 if v.declaration_type == "variable" then
270 if v.declaration_element == "type" then
271 v.variable_type.identifier.add(self.text)
272 end
273 else if v.declaration_type == "method" then
274 if v.declaration_element == "return_type" then
275 v.method_return_type.identifier.add(self.text)
276 else if v.declaration_element == "parameter_list" then
277 v.method_params[v.param_index].identifier.add(self.text)
278 end
279 end
280 end
281 end
282
283 redef class N_39dlong_39d
284 redef fun accept_visitor(v)
285 do
286 if v.declaration_type == "variable" then
287 if v.declaration_element == "type" then
288 v.variable_type.identifier.add(self.text)
289 end
290 else if v.declaration_type == "method" then
291 if v.declaration_element == "return_type" then
292 v.method_return_type.identifier.add(self.text)
293 else if v.declaration_element == "parameter_list" then
294 v.method_params[v.param_index].identifier.add(self.text)
295 end
296 end
297 end
298 end
299
300 # #
301 # C L A S S H E A D E R #
302 # #
303
304 redef class Nclass_header
305 redef fun accept_visitor(v)
306 do
307 v.declaration_type = "class_header"
308 v.declaration_element = "id"
309 super
310
311 # Exit class declaration
312 v.declaration_type = null
313 v.declaration_element = null
314
315 v.java_class.class_type = v.class_type
316 end
317 end
318
319 # Extends declaration in the class header
320 redef class Nextends_declaration
321 redef fun accept_visitor(v)
322 do
323 v.declaration_element = "extends"
324 super
325 v.declaration_element = null
326 end
327 end
328
329 # Implements declaration in the class header
330 redef class Nimplements_declaration
331 redef fun accept_visitor(v)
332 do
333 v.declaration_element = "implements"
334 super
335 v.declaration_element = null
336 end
337 end
338
339 # #
340 # P R O P E R T Y D E C L A R A T I O N S #
341 # #
342
343 # Method declaration
344 redef class Nmethod_declaration
345 redef fun accept_visitor(v)
346 do
347 v.declaration_type = "method"
348 super
349 v.declaration_type = null
350
351 if v.method_return_type.has_unresolved_types then v.method_return_type.resolve_types(v.generic_map)
352 v.java_class.add_method(v.method_id, v.method_return_type, v.method_params)
353
354 v.method_params.clear
355 v.method_id = ""
356 v.method_return_type = new JavaType(v.converter)
357 end
358 end
359
360 # Constructor declaration
361 redef class Nconstructor_declaration
362 redef fun accept_visitor(v)
363 do
364 v.declaration_type = "constructor"
365 super
366 v.declaration_type = null
367 end
368 end
369
370 # Variable property declaration
371 redef class Nvariable_declaration
372 redef fun accept_visitor(v)
373 do
374 v.declaration_type = "variable"
375 super
376 v.declaration_type = null
377
378 v.java_class.attributes[v.variable_id] = v.variable_type
379
380 v.variable_id = ""
381 v.variable_type = new JavaType(v.converter)
382 end
383 end
384
385 # Static property declaration
386 redef class Nstatic_declaration
387 redef fun accept_visitor(v)
388 do
389 v.declaration_type = "static"
390 super
391 v.declaration_type = null
392 end
393 end
394
395 # Identifier of a variable
396 redef class Nvariable_id
397 redef fun accept_visitor(v)
398 do
399 v.declaration_element = "id"
400 super
401 v.declaration_element = null
402 end
403 end
404
405 # Identifier of the method
406 redef class Nmethod_id
407 redef fun accept_visitor(v)
408 do
409 v.declaration_element = "id"
410 super
411 v.declaration_element = null
412 end
413 end
414
415 redef class Ntype
416 redef fun accept_visitor(v)
417 do
418 if v.declaration_type == "variable" and v.declaration_element != "id" then
419 v.declaration_element = "type"
420 end
421
422 if v.declaration_type == "method" and v.declaration_element == null then
423 # Makes sure it is not the generic return type definition
424 if not (v.method_return_type.identifier.is_empty and v.is_generic_param) then
425 v.declaration_element = "return_type"
426 end
427 end
428
429 super
430
431 if v.declaration_element == "variable" then
432 v.declaration_element = null
433 end
434 end
435 end
436
437 redef class Ngeneric_param
438 redef fun accept_visitor(v)
439 do
440 # Ignore the weird generic return type declaration
441 if v.declaration_type == "method" then
442 if v.declaration_element == null then
443 v.is_generic_param = true
444 else
445 v.is_generic_param = true
446 v.gen_params_index = 0
447
448 if v.declaration_element == "return_type" then
449 v.method_return_type.generic_params = new Array[JavaType]
450 else if v.declaration_element == "parameter_list" then
451 v.method_params[v.param_index].generic_params = new Array[JavaType]
452 end
453 end
454 else if v.declaration_type == "variable" then
455 if v.declaration_element == "type" then
456 v.is_generic_param = true
457 v.gen_params_index = 0
458 v.variable_type.generic_params = new Array[JavaType]
459 end
460 end
461
462 super
463
464 v.declaration_element = null
465 v.is_generic_param = false
466 end
467 end
468
469 redef class Ngeneric_identifier
470 redef fun accept_visitor(v)
471 do
472 if v.declaration_type == "method" then
473 if v.declaration_element == null then
474 v.is_generic_id = true
475 end
476 end
477
478 super
479
480 v.is_generic_id = false
481
482 end
483 end
484
485 redef class Nparameter_list
486 redef fun accept_visitor(v)
487 do
488 v.declaration_element = "parameter_list"
489 v.param_index = 0
490 super
491 v.declaration_element = null
492 v.param_index = 0
493 end
494 end
495
496 redef class Nparameter
497 redef fun accept_visitor(v)
498 do
499 if v.declaration_type == "method" then
500 if v.declaration_element == "parameter_list" then
501 if v.is_generic_param then
502 v.method_params[v.param_index].generic_params.add(new JavaType(v.converter))
503
504 super
505
506 v.gen_params_index += 1
507 else
508 v.method_params.add(new JavaType(v.converter))
509
510 super
511
512 v.param_index += 1
513 end
514 else if v.declaration_element == "return_type" and v.is_generic_param then
515
516 v.method_return_type.generic_params.add(new JavaType(v.converter))
517
518 super
519
520 v.gen_params_index += 1
521
522 # For generic return type definition
523 else if v.declaration_element == null then
524 super
525 end
526 else if v.declaration_type == "variable" then
527 if v.declaration_element == "type" and v.is_generic_param then
528 v.variable_type.generic_params.add(new JavaType(v.converter))
529
530 super
531
532 v.gen_params_index += 1
533 end
534 else
535 super
536 end
537 end
538 end