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