contrib/jwrapper: main logic use `JavaModel` and support many files at once
authorAlexis Laferrière <alexis.laf@xymus.net>
Sun, 19 Jul 2015 20:01:36 +0000 (16:01 -0400)
committerAlexis Laferrière <alexis.laf@xymus.net>
Mon, 20 Jul 2015 21:34:28 +0000 (17:34 -0400)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

contrib/jwrapper/src/code_generator.nit
contrib/jwrapper/src/javap_visitor.nit

index 8141ee0..6ea8974 100644 (file)
@@ -26,7 +26,7 @@ class CodeGenerator
        var file_name: String
 
        # Model of Java class being wrapped
-       var java_class: JavaClass
+       var model: JavaModel
 
        # Comment out methods with unknown (unwrapped) types
        var comment_unknown_types: Bool
@@ -48,45 +48,46 @@ class CodeGenerator
        # Generate the Nit module into `file_out`
        fun generate
        do
-               var jclass = self.java_class
+               # License
+               file_out.write license
 
-               var class_content = new Array[String]
-               class_content.add(gen_class_header(jclass.class_type))
+               # Module declaration
+               var module_name = module_name
+               if module_name != null then file_out.write "module {module_name}\n"
+               file_out.write "\n"
 
-               for id, methods_info in jclass.methods do
-                       for method_info in methods_info do
-                               var nid = id
-                               if methods_info.length > 1 then nid += "{methods_info.index_of(method_info)}"
-                               class_content.add gen_method(id, nid, method_info.return_type, method_info.params)
-                       end
+               # All importations
+               var imports = new HashSet[String]
+               imports.add "import mnit_android\n"
+               for jclass in model.classes do
+                       for import_ in jclass.imports do imports.add "import android::{import_}\n"
                end
-               class_content.add("\nend\n")
+               file_out.write imports.join("\n")
 
-               var wrappers = new Array[String]
-               if stub_for_unknown_types then
-                       for jtype in jclass.unknown_types do
-                               if jtype == jclass.class_type then continue
-                               wrappers.add("\n")
-                               wrappers.add(gen_unknown_class_header(jtype))
-                       end
-               end
+               for jclass in model.classes do
 
-               var imports = new Array[String]
-               imports.add("import mnit_android\n")
-               for import_ in jclass.imports do
-                       imports.add("import android::{import_}\n")
-               end
+                       file_out.write gen_class_header(jclass.class_type)
 
-               file_out.write license
+                       for id, signatures in jclass.methods do
+                               var c = 0
+                               for signature in signatures do
+                                       var nid = id
+                                       if c > 0 then nid += c.to_s
+                                       c += 1
 
-               var module_name = module_name
-               if module_name != null then file_out.write "module {module_name}\n"
+                                       file_out.write gen_method(jclass, id, nid, signature.return_type, signature.params)
+                                       file_out.write "\n"
+                               end
+                       end
+                       file_out.write "end\n\n"
+               end
 
-               file_out.write("\n")
-               file_out.write(imports.join)
-               file_out.write("\n")
-               file_out.write(class_content.join)
-               file_out.write(wrappers.join)
+               if stub_for_unknown_types then
+                       for jtype in model.unknown_types do
+                               file_out.write gen_unknown_class_header(jtype)
+                               file_out.write "\n"
+                       end
+               end
        end
 
        # License for the header of the generated Nit module
@@ -133,7 +134,7 @@ class CodeGenerator
                return temp.join
        end
 
-       fun gen_method(jmethod_id: String, nmethod_id: String, jreturn_type: JavaType, jparam_list: Array[JavaType]): String
+       fun gen_method(java_class: JavaClass, jmethod_id, nmethod_id: String, jreturn_type: JavaType, jparam_list: Array[JavaType]): String
        do
                var java_params = ""
                var nit_params  = ""
@@ -151,7 +152,7 @@ class CodeGenerator
                                if jparam.is_wrapped then
                                        java_class.imports.add nit_type.mod.as(not null)
                                else
-                                       java_class.unknown_types.add jparam
+                                       model.unknown_types.add jparam
                                        if comment_unknown_types then
                                                comment = "#"
                                        else
@@ -197,7 +198,7 @@ class CodeGenerator
                                if jreturn_type.is_wrapped then
                                        java_class.imports.add return_type.mod.as(not null)
                                else
-                                       java_class.unknown_types.add jreturn_type
+                                       model.unknown_types.add jreturn_type
                                        if comment_unknown_types then
                                                comment = "#"
                                        else
index 6fcd361..d4a0ea2 100644 (file)
@@ -24,15 +24,20 @@ import code_generator
 import jtype_converter
 intrude import model
 
+# Visitor of the AST generated from javap output
 class JavaVisitor
        super Visitor
 
        var converter: JavaTypeConverter
 
-       var java_class = new JavaClass
+       # Model of all the analyzed classes
+       var model: JavaModel
+
+       var java_class: JavaClass is noinit
+
        var declaration_type: nullable String =  null
        var declaration_element: nullable String = null
-       var class_type = new JavaType(self.converter) is lazy
+       var class_type: JavaType is noinit
 
        var variable_id = ""
        var variable_type = new JavaType(self.converter) is lazy
@@ -101,7 +106,7 @@ redef class Nidentifier
                        if v.declaration_element == "id" then
                                v.method_id = self.text
                        else if v.declaration_element == "return_type" then
-                               if self.text == "void" then 
+                               if self.text == "void" then
                                        v.method_return_type.is_void = true
                                else if v.is_generic_param then
                                        v.method_return_type.generic_params[v.gen_params_index].identifier.add(self.text)
@@ -208,6 +213,10 @@ end
 redef class Nclass_declaration
        redef fun accept_visitor(v)
        do
+               v.java_class = new JavaClass
+               v.model.classes.add v.java_class
+               v.class_type = new JavaType(v.converter)
+
                v.declaration_type = "class_header"
                v.declaration_element = "id"
                super