02c8ee1f226a4de4b6a0d23a74c1c4db9808ea91
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
27 # Visitor of the AST generated from javap output
31 var converter
: JavaTypeConverter
33 # Model of all the analyzed classes
36 var java_class
: JavaClass is noinit
38 var declaration_type
: nullable String = null
39 var declaration_element
: nullable String = null
40 var class_type
: JavaType is noinit
43 var variable_type
= new JavaType(self.converter
) is lazy
45 var is_generic_param
= false
46 var is_generic_id
= false
48 var gen_params_index
= 0
50 # Used to resolve generic return types (T -> foo.faz.Bar)
51 var generic_map
= new HashMap[String, Array[String]]
53 var is_primitive_array
= false
56 var method_return_type
= new JavaType(self.converter
) is lazy
57 var method_params
= new Array[JavaType]
60 redef fun visit
(n
) do n
.accept_visitor
(self)
62 # Add the identifier from `token` to the current context
63 fun add_identifier
(token
: String)
65 if declaration_type
== "variable" then
66 if declaration_element
== "type" then
67 if is_generic_param
then
68 variable_type
.generic_params
[gen_params_index
].identifier
.add token
70 variable_type
.identifier
.add
(token
)
73 else if declaration_type
== "method" then
74 if declaration_element
== "return_type" then
75 if is_generic_param
then
76 method_return_type
.generic_params
[gen_params_index
].identifier
.add token
78 method_return_type
.identifier
.add
(token
)
80 else if declaration_element
== "parameter_list" then
81 if is_generic_param
then
82 method_params
[param_index
].generic_params
[gen_params_index
].identifier
.add token
84 method_params
[param_index
].identifier
.add
(token
)
92 fun accept_visitor
(v
: JavaVisitor) do visit_children
(v
)
95 redef class Nidentifier
96 redef fun accept_visitor
(v
)
98 if v
.declaration_type
== "class_header" then
100 if v
.declaration_element
== "id" then
101 v
.class_type
.identifier
.add text
105 else if v
.declaration_type
== "variable" then
106 # Attribute declaration
107 if v
.declaration_element
== "id" then
108 v
.variable_id
+= text
112 else if v
.declaration_type
== "method" then
114 if v
.declaration_element
== "id" then
116 v
.method_id
= self.text
118 else if v
.declaration_element
== "return_type" then
119 if self.text
== "void" then
121 v
.method_return_type
.is_void
= true
124 else if v
.declaration_element
== "parameter_list" then
125 # Parameters, leave it to add_identifier
127 else if v
.is_generic_param
then
128 # Creates a map to resolve generic return types
129 # Example : public **<T extends android/os/Bundle>** T foo();
130 if v
.is_generic_id
then
131 v
.generic_id
= self.text
132 v
.generic_map
[self.text
] = new Array[String]
134 if not v
.method_return_type
.has_unresolved_types
then v
.method_return_type
.has_unresolved_types
= true
136 v
.generic_map
[v
.generic_id
].add text
141 v
.add_identifier text
145 # Primitive array node
146 redef class Nbrackets
147 redef fun accept_visitor
(v
)
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
154 v
.variable_type
.array_dimension
+= 1
158 else if v
.declaration_type
== "method" then
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
164 v
.method_return_type
.array_dimension
+= 1
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
170 v
.method_params
[v
.param_index
].array_dimension
+= 1
180 redef class N_39dchar_39d
181 redef fun accept_visitor
(v
) do v
.add_identifier text
184 redef class N_39dboolean_39d
185 redef fun accept_visitor
(v
) do v
.add_identifier text
188 redef class N_39dfloat_39d
189 redef fun accept_visitor
(v
) do v
.add_identifier text
192 redef class N_39ddouble_39d
193 redef fun accept_visitor
(v
) do v
.add_identifier text
196 redef class N_39dbyte_39d
197 redef fun accept_visitor
(v
) do v
.add_identifier text
200 redef class N_39dshort_39d
201 redef fun accept_visitor
(v
) do v
.add_identifier text
204 redef class N_39dint_39d
205 redef fun accept_visitor
(v
) do v
.add_identifier text
208 redef class N_39dlong_39d
209 redef fun accept_visitor
(v
) do v
.add_identifier text
212 redef class Nwildcard
213 # TODO use the lower bound
214 redef fun accept_visitor
(v
) do v
.add_identifier
"Object"
218 # C L A S S H E A D E R #
221 redef class Nclass_declaration
222 redef fun accept_visitor
(v
)
224 v
.java_class
= new JavaClass
225 v
.model
.classes
.add v
.java_class
226 v
.class_type
= new JavaType(v
.converter
)
228 v
.declaration_type
= "class_header"
229 v
.declaration_element
= "id"
232 # Exit class declaration
233 v
.declaration_type
= null
234 v
.declaration_element
= null
236 v
.java_class
.class_type
= v
.class_type
240 # Extends declaration in the class header
241 redef class Nextends_declaration
242 redef fun accept_visitor
(v
)
244 v
.declaration_element
= "extends"
246 v
.declaration_element
= null
250 # Implements declaration in the class header
251 redef class Nimplements_declaration
252 redef fun accept_visitor
(v
)
254 v
.declaration_element
= "implements"
256 v
.declaration_element
= null
261 # P R O P E R T Y D E C L A R A T I O N S #
265 redef class Nproperty_declaration_method
266 redef fun accept_visitor
(v
)
268 v
.declaration_type
= "method"
269 v
.declaration_element
= null
271 v
.declaration_type
= null
273 if v
.method_return_type
.has_unresolved_types
then v
.method_return_type
.resolve_types
(v
.generic_map
)
275 var method
= new JavaMethod(v
.method_return_type
, v
.method_params
.clone
)
276 v
.java_class
.methods
[v
.method_id
].add method
278 v
.method_params
.clear
280 v
.method_return_type
= new JavaType(v
.converter
)
284 # Constructor declaration
285 redef class Nproperty_declaration_constructor
286 redef fun accept_visitor
(v
)
288 v
.declaration_type
= "constructor"
290 v
.declaration_type
= null
294 # Variable property declaration
295 redef class Nproperty_declaration_attribute
296 redef fun accept_visitor
(v
)
298 v
.declaration_type
= "variable"
300 v
.declaration_type
= null
302 v
.java_class
.attributes
[v
.variable_id
] = v
.variable_type
305 v
.variable_type
= new JavaType(v
.converter
)
309 # Static property declaration
310 redef class Nproperty_declaration_static
311 redef fun accept_visitor
(v
)
313 v
.declaration_type
= "static"
315 v
.declaration_type
= null
319 # Identifier of a variable
320 redef class Nattribute_id
321 redef fun accept_visitor
(v
)
323 v
.declaration_element
= "id"
325 v
.declaration_element
= null
329 # Identifier of the method
330 redef class Nmethod_id
331 redef fun accept_visitor
(v
)
333 v
.declaration_element
= "id"
335 v
.declaration_element
= null
340 redef fun accept_visitor
(v
)
342 if v
.declaration_type
== "variable" and v
.declaration_element
!= "id" then
343 v
.declaration_element
= "type"
346 if v
.declaration_type
== "method" and v
.declaration_element
== null then
347 # Makes sure it is not the generic return type definition
348 if not (v
.method_return_type
.identifier
.is_empty
and v
.is_generic_param
) then
349 v
.declaration_element
= "return_type"
355 if v
.declaration_element
== "variable" then
356 v
.declaration_element
= null
361 redef class Ngeneric_param
362 redef fun accept_visitor
(v
)
364 # Ignore the weird generic return type declaration
365 if v
.declaration_type
== "method" then
366 if v
.declaration_element
== null then
367 v
.is_generic_param
= true
369 v
.is_generic_param
= true
370 v
.gen_params_index
= 0
372 if v
.declaration_element
== "return_type" then
373 v
.method_return_type
.generic_params
= new Array[JavaType]
374 else if v
.declaration_element
== "parameter_list" then
375 v
.method_params
[v
.param_index
].generic_params
= new Array[JavaType]
378 else if v
.declaration_type
== "variable" then
379 if v
.declaration_element
== "type" then
380 v
.is_generic_param
= true
381 v
.gen_params_index
= 0
382 v
.variable_type
.generic_params
= new Array[JavaType]
388 v
.declaration_element
= null
389 v
.is_generic_param
= false
393 redef class Ngeneric_identifier
394 redef fun accept_visitor
(v
)
396 if v
.declaration_type
== "method" then
397 if v
.declaration_element
== null then
398 v
.is_generic_id
= true
404 v
.is_generic_id
= false
409 redef class Nparameter_list
410 redef fun accept_visitor
(v
)
412 v
.declaration_element
= "parameter_list"
415 v
.declaration_element
= null
420 redef class Nparameter
421 redef fun accept_visitor
(v
)
423 if v
.declaration_type
== "method" then
424 if v
.declaration_element
== "parameter_list" then
425 if v
.is_generic_param
then
426 v
.method_params
[v
.param_index
].generic_params
.add
(new JavaType(v
.converter
))
430 v
.gen_params_index
+= 1
432 v
.method_params
.add
(new JavaType(v
.converter
))
438 else if v
.declaration_element
== "return_type" and v
.is_generic_param
then
440 v
.method_return_type
.generic_params
.add
(new JavaType(v
.converter
))
444 v
.gen_params_index
+= 1
446 # For generic return type definition
447 else if v
.declaration_element
== null then
450 else if v
.declaration_type
== "variable" then
451 if v
.declaration_element
== "type" and v
.is_generic_param
then
452 v
.variable_type
.generic_params
.add
(new JavaType(v
.converter
))
456 v
.gen_params_index
+= 1