contrib/jwrapper: revamp `gen_licence` to be more customizable
[nit.git] / contrib / jwrapper / src / code_generator.nit
index f0be48c..8141ee0 100644 (file)
@@ -1,6 +1,7 @@
 # This file is part of NIT (http://www.nitlanguage.org).
 #
 # Copyright 2014 Frédéric Vachon <fredvac@gmail.com>
+# Copyright 2015 Alexis Laferrière <alexis.laf@xymus.net>
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -21,30 +22,30 @@ intrude import model
 
 class CodeGenerator
 
-       var with_attributes: Bool
-       var comment_unknown_types: Bool
-       var file_out: FileWriter
+       # Path to the output file
+       var file_name: String
+
+       # Model of Java class being wrapped
        var java_class: JavaClass
-       var nb_params: Int
-       var module_name: nullable String = null
 
-       init (file_name: String, jclass: JavaClass, with_attributes, comment: Bool)
-       do
-               file_out = new FileWriter.open(file_name)
+       # Comment out methods with unknown (unwrapped) types
+       var comment_unknown_types: Bool
 
-               var nit_ext = ".nit"
-               if file_name.has_suffix(nit_ext) then
-                       # Output file ends with .nit, we expect it to be a valid name
-                       module_name = file_name.strip_extension(nit_ext)
+       # Generate stub classes for unknown types used in the generated module
+       var stub_for_unknown_types: Bool
 
-                       # Otherwise, it may be anything so do not declare a module
-               end
+       # Output file
+       var file_out: Writer = new FileWriter.open(file_name) is lazy, writable
 
-               self.java_class = jclass
-               self.with_attributes = with_attributes
-               self.comment_unknown_types = comment
+       # Name of the Nit module to generate
+       var module_name: nullable String is lazy do
+               if file_name.file_extension == "nit" then
+                       # Output file ends with .nit, we expect it to be a valid name
+                       return file_name.basename(".nit")
+               else return null
        end
 
+       # Generate the Nit module into `file_out`
        fun generate
        do
                var jclass = self.java_class
@@ -52,10 +53,6 @@ class CodeGenerator
                var class_content = new Array[String]
                class_content.add(gen_class_header(jclass.class_type))
 
-               if with_attributes then
-                       for id, jtype in jclass.attributes do class_content.add(gen_attribute(id, jtype))
-               end
-
                for id, methods_info in jclass.methods do
                        for method_info in methods_info do
                                var nid = id
@@ -66,10 +63,12 @@ class CodeGenerator
                class_content.add("\nend\n")
 
                var wrappers = new Array[String]
-               for jtype in jclass.unknown_types do
-                       if jtype == jclass.class_type then continue
-                       wrappers.add("\n")
-                       wrappers.add(gen_unknown_class_header(jtype))
+               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
 
                var imports = new Array[String]
@@ -78,21 +77,20 @@ class CodeGenerator
                        imports.add("import android::{import_}\n")
                end
 
-               file_out.write(gen_licence)
+               file_out.write license
 
                var module_name = module_name
                if module_name != null then file_out.write "module {module_name}\n"
 
                file_out.write("\n")
-               file_out.write(imports.join(""))
+               file_out.write(imports.join)
                file_out.write("\n")
-               file_out.write(class_content.join(""))
-               file_out.write(wrappers.join(""))
+               file_out.write(class_content.join)
+               file_out.write(wrappers.join)
        end
 
-       fun gen_licence: String
-       do
-               return """
+       # License for the header of the generated Nit module
+       var license = """
 # This file is part of NIT (http://www.nitlanguage.org).
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -108,8 +106,7 @@ class CodeGenerator
 # limitations under the License.
 
 # This code has been generated using `jwrapper`
-"""
-       end
+""" is writable
 
        fun gen_class_header(jtype: JavaType): String
        do
@@ -117,7 +114,7 @@ class CodeGenerator
                temp.add("extern class Native{jtype.id} in \"Java\" `\{ {jtype} `\}\n")
                temp.add("\tsuper JavaObject\n\n")
 
-               return temp.join("")
+               return temp.join
        end
 
        fun gen_unknown_class_header(jtype: JavaType): String
@@ -133,12 +130,7 @@ class CodeGenerator
                temp.add("extern class {nit_type} in \"Java\" `\{ {jtype.to_package_name} `\}\n")
                temp.add("\tsuper JavaObject\n\nend\n")
 
-               return temp.join("")
-       end
-
-       fun gen_attribute(jid: String, jtype: JavaType): String
-       do
-               return "\tvar {jid.to_nit_method_name}: {jtype.to_nit_type}\n"
+               return temp.join
        end
 
        fun gen_method(jmethod_id: String, nmethod_id: String, jreturn_type: JavaType, jparam_list: Array[JavaType]): String
@@ -159,11 +151,11 @@ class CodeGenerator
                                if jparam.is_wrapped then
                                        java_class.imports.add nit_type.mod.as(not null)
                                else
+                                       java_class.unknown_types.add jparam
                                        if comment_unknown_types then
                                                comment = "#"
                                        else
                                                nit_type = jparam.extern_name
-                                               java_class.unknown_types.add(jparam)
                                        end
                                end
                        end
@@ -205,11 +197,11 @@ 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
                                        if comment_unknown_types then
                                                comment = "#"
                                        else
                                                return_type = jreturn_type.extern_name
-                                               java_class.unknown_types.add(jreturn_type)
                                        end
                                end
                        end
@@ -219,23 +211,23 @@ class CodeGenerator
 
                var temp = new Array[String]
 
-               temp.add(comment + nit_signature.join(""))
+               temp.add(comment + nit_signature.join)
 
                # FIXME : This huge `if` block is only necessary to copy primitive arrays as long as there's no better way to do it
                if comment == "#" then
-                       temp.add(" in \"Java\" `\{\n{comment}\t\trecv.{jmethod_id}({java_params});\n{comment}\t`\}\n")
+                       temp.add(" in \"Java\" `\{\n{comment}\t\tself.{jmethod_id}({java_params});\n{comment}\t`\}\n")
                # Methods with return type
                else if return_type != null then
-                       temp.add(" in \"Java\" `\{\n{comment}\t\treturn {jreturn_type.return_cast}recv.{jmethod_id}({java_params});\n{comment}\t`\}\n")
+                       temp.add(" in \"Java\" `\{\n{comment}\t\treturn {jreturn_type.return_cast}self.{jmethod_id}({java_params});\n{comment}\t`\}\n")
                # Methods without return type
                else if jreturn_type.is_void then
-                       temp.add(" in \"Java\" `\{\n{comment}\t\trecv.{jmethod_id}({java_params});\n{comment}\t`\}\n")
+                       temp.add(" in \"Java\" `\{\n{comment}\t\tself.{jmethod_id}({java_params});\n{comment}\t`\}\n")
                # No copy
                else
-                       temp.add(" in \"Java\" `\{\n{comment}\t\trecv.{jmethod_id}({java_params});\n{comment}\t`\}\n")
+                       temp.add(" in \"Java\" `\{\n{comment}\t\tself.{jmethod_id}({java_params});\n{comment}\t`\}\n")
                end
 
-               return temp.join("")
+               return temp.join
        end
 end