import javap_test_parser
import code_generator
-intrude import types
+import jtype_converter
+intrude import model
class JavaVisitor
super Visitor
+ var converter: JavaTypeConverter
+
var java_class = new JavaClass
var declaration_type: nullable String = null
var declaration_element: nullable String = null
- var full_class_name = new Array[String]
+ var class_type: JavaType
var variable_id = ""
- var variable_type = new JavaType
+ var variable_type: JavaType
var is_generic_param = false
+ var is_generic_id = false
+ var generic_id = ""
var gen_params_index = 0
+ # Used to resolve generic return types (T -> foo.faz.Bar)
+ var generic_map = new HashMap[String, Array[String]]
+
var is_primitive_array = false
var method_id = ""
- var method_return_type = new JavaType
+ var method_return_type: JavaType
var method_params = new Array[JavaType]
var param_index = 0
redef fun visit(n) do n.accept_visitor(self)
+
+ init(converter: JavaTypeConverter)
+ do
+ self.converter = converter
+ self.class_type = new JavaType(self.converter)
+ self.method_return_type = new JavaType(self.converter)
+ self.variable_type = new JavaType(self.converter)
+ super
+ end
end
redef class Node
if v.declaration_type == "class_header" then
if v.declaration_element == "id" then
- v.full_class_name.add(self.text)
+ v.class_type.identifier.add(self.text)
end
else if v.declaration_type == "variable" then
else
v.method_params[v.param_index].identifier.add(self.text)
end
+
+ # Creates a map to resolve generic return types
+ # Exemple : public **<T extends android/os/Bundle>** T foo();
+ else if v.is_generic_param then
+ if v.is_generic_id then
+ v.generic_id = self.text
+ v.generic_map[self.text] = new Array[String]
+
+ if not v.method_return_type.has_unresolved_types then v.method_return_type.has_unresolved_types = true
+ else
+ v.generic_map[v.generic_id].add(self.text)
+ end
end
end
# #
# C L A S S H E A D E R #
# #
+
redef class Nclass_header
redef fun accept_visitor(v)
do
v.declaration_type = null
v.declaration_element = null
- v.java_class.name = v.full_class_name
+ v.java_class.class_type = v.class_type
end
end
end
end
-# #
-# F I E L D D E C L A R A T I O N S #
-# #
+# #
+# P R O P E R T Y D E C L A R A T I O N S #
+# #
-# Method declaration in the field declarations
+# Method declaration
redef class Nmethod_declaration
redef fun accept_visitor(v)
do
super
v.declaration_type = null
+ if v.method_return_type.has_unresolved_types then v.method_return_type.resolve_types(v.generic_map)
v.java_class.add_method(v.method_id, v.method_return_type, v.method_params)
v.method_params.clear
v.method_id = ""
- v.method_return_type = new JavaType
+ v.method_return_type = new JavaType(v.converter)
end
end
-# Constructor declaration in the field declarations
+# Constructor declaration
redef class Nconstructor_declaration
redef fun accept_visitor(v)
do
end
end
-# Variable declaration in the field declarations
+# Variable property declaration
redef class Nvariable_declaration
redef fun accept_visitor(v)
do
v.java_class.attributes[v.variable_id] = v.variable_type
v.variable_id = ""
- v.variable_type = new JavaType
+ v.variable_type = new JavaType(v.converter)
end
end
-# Static declaration in the field declarations
+# Static property declaration
redef class Nstatic_declaration
redef fun accept_visitor(v)
do
end
end
-# Identifier of the field
+# Identifier of a variable
redef class Nvariable_id
redef fun accept_visitor(v)
do
end
if v.declaration_type == "method" and v.declaration_element == null then
- v.declaration_element = "return_type"
+ # Makes sure it is not the generic return type definition
+ if not (v.method_return_type.identifier.is_empty and v.is_generic_param) then
+ v.declaration_element = "return_type"
+ end
end
super
# Ignore the weird generic return type declaration
if v.declaration_type == "method" then
if v.declaration_element == null then
- v.declaration_element = "ignore"
+ v.is_generic_param = true
else
v.is_generic_param = true
v.gen_params_index = 0
end
end
+redef class Ngeneric_identifier
+ redef fun accept_visitor(v)
+ do
+ if v.declaration_type == "method" then
+ if v.declaration_element == null then
+ v.is_generic_id = true
+ end
+ end
+
+ super
+
+ v.is_generic_id = false
+
+ end
+end
+
redef class Nparameter_list
redef fun accept_visitor(v)
do
if v.declaration_type == "method" then
if v.declaration_element == "parameter_list" then
if v.is_generic_param then
- v.method_params[v.param_index].generic_params.add(new JavaType)
+ v.method_params[v.param_index].generic_params.add(new JavaType(v.converter))
super
v.gen_params_index += 1
else
- v.method_params.add(new JavaType)
+ v.method_params.add(new JavaType(v.converter))
super
end
else if v.declaration_element == "return_type" and v.is_generic_param then
- v.method_return_type.generic_params.add(new JavaType)
+ v.method_return_type.generic_params.add(new JavaType(v.converter))
super
v.gen_params_index += 1
+
+ # For generic return type definition
+ else if v.declaration_element == null then
+ super
end
else if v.declaration_type == "variable" then
if v.declaration_element == "type" and v.is_generic_param then
- v.variable_type.generic_params.add(new JavaType)
+ v.variable_type.generic_params.add(new JavaType(v.converter))
super
end
end
end
-
-var p = new TestParser_javap
-var tree = p.main
-
-var visitor = new JavaVisitor
-visitor.enter_visit(tree)
-
-var generator = new CodeGenerator("bundle.nit", visitor.java_class)
-generator.generate