6fcd361352b9732d1a5ff2a6683478af97d13fc4
1 # This file is part of NIT (http://www.nitlanguage.org).
3 # Copyright 2014 Frédéric Vachon <fredvac@gmail.com>
4 # Copyright 2015 Alexis Laferrière <alexis.laf@xymus.net>
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
10 # http://www.apache.org/licenses/LICENSE-2.0
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.
18 # Uses a visitor to extract data from the javap output AST
19 # It sends the data to `code_generator` module
22 import javap_test_parser
24 import jtype_converter
30 var converter
: JavaTypeConverter
32 var java_class
= new JavaClass
33 var declaration_type
: nullable String = null
34 var declaration_element
: nullable String = null
35 var class_type
= new JavaType(self.converter
) is lazy
38 var variable_type
= new JavaType(self.converter
) is lazy
40 var is_generic_param
= false
41 var is_generic_id
= false
43 var gen_params_index
= 0
45 # Used to resolve generic return types (T -> foo.faz.Bar)
46 var generic_map
= new HashMap[String, Array[String]]
48 var is_primitive_array
= false
51 var method_return_type
= new JavaType(self.converter
) is lazy
52 var method_params
= new Array[JavaType]
55 redef fun visit
(n
) do n
.accept_visitor
(self)
57 # Add the identifier from `token` to the current context
58 fun add_identifier
(token
: NToken)
60 if declaration_type
== "variable" then
61 if declaration_element
== "type" then
62 variable_type
.identifier
.add
(token
.text
)
64 else if declaration_type
== "method" then
65 if declaration_element
== "return_type" then
66 method_return_type
.identifier
.add
(token
.text
)
67 else if declaration_element
== "parameter_list" then
68 method_params
[param_index
].identifier
.add
(token
.text
)
75 fun accept_visitor
(v
: JavaVisitor) do visit_children
(v
)
78 redef class Nidentifier
79 redef fun accept_visitor
(v
)
81 if v
.declaration_type
== "class_header" then
83 if v
.declaration_element
== "id" then
84 v
.class_type
.identifier
.add
(self.text
)
87 else if v
.declaration_type
== "variable" then
89 if v
.declaration_element
== "id" then
90 v
.variable_id
+= self.text
91 else if v
.declaration_element
== "type" then
92 if v
.is_generic_param
then
93 v
.variable_type
.generic_params
[v
.gen_params_index
].identifier
.add
(self.text
)
95 v
.variable_type
.identifier
.add
(self.text
)
99 else if v
.declaration_type
== "method" then
101 if v
.declaration_element
== "id" then
102 v
.method_id
= self.text
103 else if v
.declaration_element
== "return_type" then
104 if self.text
== "void" then
105 v
.method_return_type
.is_void
= true
106 else if v
.is_generic_param
then
107 v
.method_return_type
.generic_params
[v
.gen_params_index
].identifier
.add
(self.text
)
109 v
.method_return_type
.identifier
.add
(self.text
)
111 else if v
.declaration_element
== "parameter_list" then
112 if v
.is_generic_param
then
113 v
.method_params
[v
.param_index
].generic_params
[v
.gen_params_index
].identifier
.add
(self.text
)
115 v
.method_params
[v
.param_index
].identifier
.add
(self.text
)
118 # Creates a map to resolve generic return types
119 # Exemple : public **<T extends android/os/Bundle>** T foo();
120 else if v
.is_generic_param
then
121 if v
.is_generic_id
then
122 v
.generic_id
= self.text
123 v
.generic_map
[self.text
] = new Array[String]
125 if not v
.method_return_type
.has_unresolved_types
then v
.method_return_type
.has_unresolved_types
= true
127 v
.generic_map
[v
.generic_id
].add
(self.text
)
137 # Primitive array node
138 redef class Nbrackets
139 redef fun accept_visitor
(v
)
141 if v
.declaration_type
== "variable" then
142 if v
.declaration_element
== "type" then
143 if v
.is_generic_param
then
144 v
.variable_type
.generic_params
[v
.gen_params_index
].array_dimension
+= 1
146 v
.variable_type
.array_dimension
+= 1
150 else if v
.declaration_type
== "method" then
152 if v
.declaration_element
== "return_type" then
153 if v
.is_generic_param
then
154 v
.method_return_type
.generic_params
[v
.gen_params_index
].array_dimension
+= 1
156 v
.method_return_type
.array_dimension
+= 1
158 else if v
.declaration_element
== "parameter_list" then
159 if v
.is_generic_param
then
160 v
.method_params
[v
.param_index
].generic_params
[v
.gen_params_index
].array_dimension
+= 1
162 v
.method_params
[v
.param_index
].array_dimension
+= 1
172 redef class N_39dchar_39d
173 redef fun accept_visitor
(v
) do v
.add_identifier
self
176 redef class N_39dboolean_39d
177 redef fun accept_visitor
(v
) do v
.add_identifier
self
180 redef class N_39dfloat_39d
181 redef fun accept_visitor
(v
) do v
.add_identifier
self
184 redef class N_39ddouble_39d
185 redef fun accept_visitor
(v
) do v
.add_identifier
self
188 redef class N_39dbyte_39d
189 redef fun accept_visitor
(v
) do v
.add_identifier
self
192 redef class N_39dshort_39d
193 redef fun accept_visitor
(v
) do v
.add_identifier
self
196 redef class N_39dint_39d
197 redef fun accept_visitor
(v
) do v
.add_identifier
self
200 redef class N_39dlong_39d
201 redef fun accept_visitor
(v
) do v
.add_identifier
self
205 # C L A S S H E A D E R #
208 redef class Nclass_declaration
209 redef fun accept_visitor
(v
)
211 v
.declaration_type
= "class_header"
212 v
.declaration_element
= "id"
215 # Exit class declaration
216 v
.declaration_type
= null
217 v
.declaration_element
= null
219 v
.java_class
.class_type
= v
.class_type
223 # Extends declaration in the class header
224 redef class Nextends_declaration
225 redef fun accept_visitor
(v
)
227 v
.declaration_element
= "extends"
229 v
.declaration_element
= null
233 # Implements declaration in the class header
234 redef class Nimplements_declaration
235 redef fun accept_visitor
(v
)
237 v
.declaration_element
= "implements"
239 v
.declaration_element
= null
244 # P R O P E R T Y D E C L A R A T I O N S #
248 redef class Nproperty_declaration_method
249 redef fun accept_visitor
(v
)
251 v
.declaration_type
= "method"
252 v
.declaration_element
= null
254 v
.declaration_type
= null
256 if v
.method_return_type
.has_unresolved_types
then v
.method_return_type
.resolve_types
(v
.generic_map
)
258 var method
= new JavaMethod(v
.method_return_type
, v
.method_params
.clone
)
259 v
.java_class
.methods
[v
.method_id
].add method
261 v
.method_params
.clear
263 v
.method_return_type
= new JavaType(v
.converter
)
267 # Constructor declaration
268 redef class Nproperty_declaration_constructor
269 redef fun accept_visitor
(v
)
271 v
.declaration_type
= "constructor"
273 v
.declaration_type
= null
277 # Variable property declaration
278 redef class Nproperty_declaration_attribute
279 redef fun accept_visitor
(v
)
281 v
.declaration_type
= "variable"
283 v
.declaration_type
= null
285 v
.java_class
.attributes
[v
.variable_id
] = v
.variable_type
288 v
.variable_type
= new JavaType(v
.converter
)
292 # Static property declaration
293 redef class Nproperty_declaration_static
294 redef fun accept_visitor
(v
)
296 v
.declaration_type
= "static"
298 v
.declaration_type
= null
302 # Identifier of a variable
303 redef class Nattribute_id
304 redef fun accept_visitor
(v
)
306 v
.declaration_element
= "id"
308 v
.declaration_element
= null
312 # Identifier of the method
313 redef class Nmethod_id
314 redef fun accept_visitor
(v
)
316 v
.declaration_element
= "id"
318 v
.declaration_element
= null
323 redef fun accept_visitor
(v
)
325 if v
.declaration_type
== "variable" and v
.declaration_element
!= "id" then
326 v
.declaration_element
= "type"
329 if v
.declaration_type
== "method" and v
.declaration_element
== null then
330 # Makes sure it is not the generic return type definition
331 if not (v
.method_return_type
.identifier
.is_empty
and v
.is_generic_param
) then
332 v
.declaration_element
= "return_type"
338 if v
.declaration_element
== "variable" then
339 v
.declaration_element
= null
344 redef class Ngeneric_param
345 redef fun accept_visitor
(v
)
347 # Ignore the weird generic return type declaration
348 if v
.declaration_type
== "method" then
349 if v
.declaration_element
== null then
350 v
.is_generic_param
= true
352 v
.is_generic_param
= true
353 v
.gen_params_index
= 0
355 if v
.declaration_element
== "return_type" then
356 v
.method_return_type
.generic_params
= new Array[JavaType]
357 else if v
.declaration_element
== "parameter_list" then
358 v
.method_params
[v
.param_index
].generic_params
= new Array[JavaType]
361 else if v
.declaration_type
== "variable" then
362 if v
.declaration_element
== "type" then
363 v
.is_generic_param
= true
364 v
.gen_params_index
= 0
365 v
.variable_type
.generic_params
= new Array[JavaType]
371 v
.declaration_element
= null
372 v
.is_generic_param
= false
376 redef class Ngeneric_identifier
377 redef fun accept_visitor
(v
)
379 if v
.declaration_type
== "method" then
380 if v
.declaration_element
== null then
381 v
.is_generic_id
= true
387 v
.is_generic_id
= false
392 redef class Nparameter_list
393 redef fun accept_visitor
(v
)
395 v
.declaration_element
= "parameter_list"
398 v
.declaration_element
= null
403 redef class Nparameter
404 redef fun accept_visitor
(v
)
406 if v
.declaration_type
== "method" then
407 if v
.declaration_element
== "parameter_list" then
408 if v
.is_generic_param
then
409 v
.method_params
[v
.param_index
].generic_params
.add
(new JavaType(v
.converter
))
413 v
.gen_params_index
+= 1
415 v
.method_params
.add
(new JavaType(v
.converter
))
421 else if v
.declaration_element
== "return_type" and v
.is_generic_param
then
423 v
.method_return_type
.generic_params
.add
(new JavaType(v
.converter
))
427 v
.gen_params_index
+= 1
429 # For generic return type definition
430 else if v
.declaration_element
== null then
433 else if v
.declaration_type
== "variable" then
434 if v
.declaration_element
== "type" and v
.is_generic_param
then
435 v
.variable_type
.generic_params
.add
(new JavaType(v
.converter
))
439 v
.gen_params_index
+= 1