899930d1ebb0ed6ece8de52241e4ae30191b2950
[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 # Java class in construction
35 var java_class: JavaClass is noinit
36
37 redef fun visit(n) do n.accept_visitor(self)
38 end
39
40 redef class Node
41 private fun accept_visitor(v: JavaVisitor) do visit_children(v)
42 end
43
44 # ---
45 # Class Header
46
47 redef class Nclass_declaration
48 redef fun accept_visitor(v)
49 do
50 var jtype = n_full_class_name.to_java_type
51
52 v.java_class = new JavaClass(jtype)
53 v.model.add_class v.java_class
54
55 # Visit all properties
56 super
57 end
58 end
59
60 # Extends declaration in the class header
61 redef class Nextends_declaration
62 redef fun accept_visitor(v)
63 do
64 # TODO
65 end
66 end
67
68 # Implements declaration in the class header
69 redef class Nimplements_declaration
70 redef fun accept_visitor(v)
71 do
72 # TODO
73 end
74 end
75
76 # ---
77 # Properties
78
79 # Method declaration
80 redef class Nproperty_declaration_method
81 redef fun accept_visitor(v)
82 do
83 var is_static = false
84 var modifiers = n_modifier
85 if modifiers != null then is_static = modifiers.has_static
86
87 var id = n_identifier.text
88 var return_jtype = n_type.to_java_type
89
90 # Generic parameters
91 var n_params = n_generic_parameters
92 var generic_params
93 if n_params != null then
94 generic_params = n_params.n_parameters.to_a
95 else generic_params = new Array[JavaType]
96
97 # Collect parameters
98 var n_parameters = n_parameters
99 var params
100 if n_parameters != null then
101 params = n_parameters.to_a
102 else params = new Array[JavaType]
103
104 var method = new JavaMethod(is_static, return_jtype, params, generic_params)
105 v.java_class.methods[id].add method
106 end
107 end
108
109 # Constructor declaration
110 redef class Nproperty_declaration_constructor
111 redef fun accept_visitor(v)
112 do
113 # Collect parameters
114 var n_parameters = n_parameters
115 var params
116 if n_parameters != null then
117 params = n_parameters.to_a
118 else params = new Array[JavaType]
119
120 # Generic parameters
121 var n_params = n_generic_parameters
122 var generic_params
123 if n_params != null then
124 generic_params = n_params.n_parameters.to_a
125 else generic_params = new Array[JavaType]
126
127 var method = new JavaConstructor(params, generic_params)
128 v.java_class.constructors.add method
129 end
130 end
131
132 # Variable property declaration
133 redef class Nproperty_declaration_attribute
134 redef fun accept_visitor(v)
135 do
136 var id = n_identifier.text
137 var jtype = n_type.to_java_type
138
139 # Manually count the array depth as it is after the id
140 var brackets = n_brackets
141 if brackets != null then jtype.array_dimension += brackets.children.length
142
143 var is_static = false
144 var modifiers = n_modifier
145 if modifiers != null then is_static = modifiers.has_static
146
147 v.java_class.attributes[id] = new JavaAttribute(is_static, jtype)
148 end
149 end
150
151 # Static property declaration
152 redef class Nproperty_declaration_static
153 redef fun accept_visitor(v)
154 do
155 # TODO
156 end
157 end
158
159 # ---
160 # Services
161
162 redef class Ntype
163 private fun to_java_type: JavaType
164 do
165 var jtype = n_base_type.to_java_type
166
167 var brackets = n_brackets
168 if brackets != null then jtype.array_dimension += brackets.children.length
169
170 return jtype
171 end
172 end
173
174 redef class Nbase_type
175 private fun to_java_type: JavaType
176 do
177 # By default, everything is bound by object
178 # TODO use a more precise bound
179 var jtype = new JavaType
180 jtype.identifier.add_all(["java", "lang", "object"])
181 return jtype
182 end
183 end
184
185 redef class Nbase_type_class
186 redef fun to_java_type do return n_full_class_name.to_java_type
187 end
188
189 redef class Nbase_type_primitive
190 redef fun to_java_type
191 do
192 # All the concrete nodes under this production are tokens
193 for node in depth do
194 if not node isa NToken then continue
195
196 var jtype = new JavaType
197 jtype.identifier.add node.text
198 return jtype
199 end
200
201 abort
202 end
203 end
204
205 redef class Nbase_type_void
206 redef fun to_java_type
207 do
208 var jtype = new JavaType
209 jtype.is_void = true
210 return jtype
211 end
212 end
213
214 redef class Nbase_type_extends
215 redef fun to_java_type do return n_generic_identifier.to_java_type
216 end
217
218 redef class Ngeneric_identifier
219 private fun to_java_type: JavaType is abstract
220 end
221
222 redef class Ngeneric_identifier_class
223 redef fun to_java_type do return n_full_class_name.to_java_type
224 end
225
226 redef class Ngeneric_identifier_wildcard
227 redef fun to_java_type
228 do
229 var jtype = new JavaType
230 jtype.identifier.add_all(["java", "lang", "Object"])
231 return jtype
232 end
233 end
234
235 redef class Nfull_class_name
236 # All the identifiers composing this class name
237 private fun to_a: Array[String] is abstract
238
239 # Access `n_class_name` on both alternatives
240 private fun n_class_name_common: Nclass_name is abstract
241
242 private fun to_java_type: JavaType
243 do
244 var jtype = new JavaType
245 jtype.identifier = to_a
246
247 # Generic parameters
248 var n_params = n_class_name_common.n_generic_parameters
249 if n_params != null then jtype.generic_params = n_params.n_parameters.to_a
250
251 return jtype
252 end
253 end
254
255 redef class Nfull_class_name_head
256 redef fun n_class_name_common do return n_class_name
257
258 redef fun to_a do return [n_class_name.n_identifier.text]
259 end
260
261 redef class Nfull_class_name_tail
262 redef fun n_class_name_common do return n_class_name
263
264 redef fun to_a
265 do
266 var a = n_full_class_name.to_a
267 a.add n_class_name.n_identifier.text
268 return a
269 end
270 end
271
272 redef class Nparameters
273 # Get the types composing this list of parameters
274 #
275 # This is used both on methods signatures and type parameters.
276 private fun to_a: Array[JavaType] is abstract
277 end
278
279 redef class Nparameters_head
280 redef fun to_a do return [n_parameter.to_java_type]
281 end
282
283 redef class Nparameters_tail
284 redef fun to_a
285 do
286 var a = n_parameters.to_a
287 a.add n_parameter.to_java_type
288 return a
289 end
290 end
291
292 redef class Nparameter
293 private fun to_java_type: JavaType
294 do
295 var jtype = n_type.to_java_type
296
297 var dots = n_dots
298 if dots != null then jtype.is_vararg = true
299
300 return jtype
301 end
302 end
303
304 redef class Nodes
305 private fun has_static: Bool
306 do
307 for modifier in depth do
308 if modifier isa NToken and modifier.text == "static" then return true
309 end
310
311 return false
312 end
313 end