contrib/objcwrapper: generate minimal doc above generated properties
[nit.git] / contrib / objcwrapper / src / objc_generator.nit
index db273cb..408d731 100644 (file)
@@ -42,7 +42,7 @@ redef class Sys
                "Wrap `init...` constructors as Nit methods instead of Nit constructors",
                "--init-as-methods")
 
-       private var nit_to_java_types: Map[String, String] is lazy do
+       private var objc_to_nit_types: Map[String, String] is lazy do
                var types = new HashMap[String, String]
                types["char"] = "Byte"
                types["short"] = "Int"
@@ -59,14 +59,30 @@ redef class Sys
                types["NSUInteger"] = "Int"
                types["BOOL"] = "Bool"
                types["id"] = "NSObject"
+               types["constid"] = "NSObject"
+               types["SEL"] = "NSObject"
+               types["void"] = "Pointer"
+
                return types
        end
 end
 
+redef class ObjcModel
+       redef fun knows_type(objc_type) do return super or
+               objc_to_nit_types.keys.has(objc_type)
+end
+
+# Wrapper generator
 class CodeGenerator
+
+       # `ObjcModel` to wrap
+       var model: ObjcModel
+
        # Generate Nit code to wrap `classes`
-       fun generate(classes: Array[ObjcClass])
+       fun generate
        do
+               var classes = model.classes
+
                # Open specified path or stdin
                var file
                var path = opt_output.value
@@ -81,7 +97,7 @@ class CodeGenerator
                end
 
                # Generate code
-               file.write "import cocoa::foundation\n\n"
+               file.write "import cocoa::foundation\n"
                for classe in classes do
                        write_class(classe, file)
                end
@@ -105,8 +121,6 @@ extern class {{{classe.name}}} in "ObjC" `{ {{{classe.name}}} * `}
        super NSObject
 """
 
-               file.write "\n"
-
                # Constructor or constructors
                write_constructors(classe, file)
 
@@ -115,10 +129,12 @@ extern class {{{classe.name}}} in "ObjC" `{ {{{classe.name}}} * `}
                        write_attribute(attribute, file)
                end
 
-               # Methods
+               # Instance methods '-'
                for method in classe.methods do
+                       if not model.knows_all_types(method) then method.is_commented = true
 
                        if not opt_init_as_methods.value and method.is_init then continue
+                       if method.is_class_property then continue
 
                        write_method_signature(method, file)
                        write_objc_method_call(method, file)
@@ -127,6 +143,14 @@ extern class {{{classe.name}}} in "ObjC" `{ {{{classe.name}}} * `}
                file.write """
 end
 """
+
+               # Class methods '+'
+               for method in classe.methods do
+                       if not method.is_class_property then continue
+
+                       write_method_signature(method, file)
+                       write_objc_method_call(method, file)
+               end
        end
 
        private fun write_constructors(classe: ObjcClass, file: Writer)
@@ -134,10 +158,10 @@ end
                if opt_init_as_methods.value then
                        # A single constructor for `alloc`
                        file.write """
+
        new in "ObjC" `{
                return [{{{classe.name}}} alloc];
        `}
-
 """
                        return
                end
@@ -146,14 +170,18 @@ end
                for method in classe.methods do
                        if not method.is_init then continue
 
+                       if not model.knows_all_types(method) then method.is_commented = true
+
                        write_method_signature(method, file)
 
-                               write_objc_init_call(classe.name, method, file)
+                       write_objc_init_call(classe.name, method, file)
                end
        end
 
        private fun write_attribute(attribute: ObjcAttribute, file: Writer)
        do
+               if not model.knows_type(attribute.return_type) then attribute.is_commented = true
+
                write_attribute_getter(attribute, file)
                # TODO write_attribute_setter if there is no `readonly` annotation
        end
@@ -161,30 +189,32 @@ end
        private fun write_attribute_getter(attribute: ObjcAttribute, file: Writer)
        do
                var nit_attr_name = attribute.name.to_snake_case
-               var nit_attr_type = attribute.return_type.to_nit_type
+               var nit_attr_type = attribute.return_type.objc_to_nit_type
 
                var c = attribute.comment_str
 
                file.write """
+
+{{{attribute.doc}}}
 {{{c}}}        fun {{{nit_attr_name}}}: {{{nit_attr_type}}} in "ObjC" `{
 {{{c}}}                return [self {{{attribute.name}}}];
 {{{c}}}        `}
-
 """
        end
 
        private fun write_attribute_setter(attribute: ObjcAttribute, file: Writer)
        do
                var nit_attr_name = attribute.name.to_snake_case
-               var nit_attr_type = attribute.return_type.to_nit_type
+               var nit_attr_type = attribute.return_type.objc_to_nit_type
 
                var c = attribute.comment_str
 
                file.write """
+
+{{{attribute.doc}}}
 {{{c}}}        fun {{{nit_attr_name}}}=(value: {{{nit_attr_type}}}) in "ObjC" `{
 {{{c}}}                return self.{{{attribute.name}}} = value;
 {{{c}}}        `}
-
 """
        end
 
@@ -201,6 +231,9 @@ end
 
                if name == "init" then name = ""
 
+               # If class method, prefix with class name
+               if method.is_class_property then name = "{method.objc_class.name.to_snake_case}_{name}"
+
                # Kind of method
                var fun_keyword = "fun"
                if not opt_init_as_methods.value and method.is_init then
@@ -211,7 +244,7 @@ end
                var params = new Array[String]
                for param in method.params do
                        if param.is_single then break
-                       params.add "{param.variable_name}: {param.return_type.to_nit_type}"
+                       params.add "{param.variable_name}: {param.return_type.objc_to_nit_type}"
                end
 
                var params_with_par = ""
@@ -220,11 +253,13 @@ end
                # Return
                var ret = ""
                if method.return_type != "void" and fun_keyword != "new" then
-                       ret = ": {method.return_type.to_nit_type}"
+                       ret = ": {method.return_type.objc_to_nit_type}"
                end
 
                file.write """
-{{{c}}}        {{{fun_keyword}}} {{{name}}}{{{params_with_par}}}{{{ret}}} in "ObjC" `{
+
+{{{method.doc}}}
+{{{c}}}{{{fun_keyword}}} {{{name}}}{{{params_with_par}}}{{{ret}}} in "ObjC" `{
 """
        end
 
@@ -242,9 +277,8 @@ end
                var c = method.comment_str
 
                file.write """
-{{{c}}}                return [[{{{class_name}}} alloc] {{{params.join(" ")}}}];
-{{{c}}}        `}
-
+{{{c}}}        return [[{{{class_name}}} alloc] {{{params.join(" ")}}}];
+{{{c}}}`}
 """
        end
 
@@ -262,21 +296,24 @@ end
                        else params.add param.name
                end
 
+               # Receiver, instance or class
+               var recv = "self"
+               if method.is_class_property then recv = method.objc_class.name
+
                var c = method.comment_str
 
                file.write """
-{{{c}}}                {{{ret}}}[self {{{params.join(" ")}}}];
-{{{c}}}        `}
-
+{{{c}}}        {{{ret}}}[{{{recv}}} {{{params.join(" ")}}}];
+{{{c}}}`}
 """
        end
 end
 
 redef class Text
        # Nit equivalent to this type
-       private fun to_nit_type: String
+       private fun objc_to_nit_type: String
        do
-               var types = sys.nit_to_java_types
+               var types = sys.objc_to_nit_types
 
                if types.has_key(self) then
                        return types[self]
@@ -286,8 +323,27 @@ redef class Text
        end
 end
 
-redef class Property
+redef class ObjcProperty
        private fun comment_str: String do if is_commented then
                return "#"
        else return ""
+
+       # Full documentation to be generated for the Nit code
+       private fun doc: String is abstract
+end
+
+redef class ObjcMethod
+       private fun indent: String do return if is_class_property then "" else "\t"
+
+       redef fun comment_str do return indent + super
+
+       redef fun doc
+       do
+               var recv = if is_class_property then objc_class.name else "self"
+               return "{indent}# Wraps: `[{recv} {params.join(" ")}]`"
+       end
+end
+
+redef class ObjcAttribute
+       redef fun doc do return "\t# Wraps: `{objc_class.name}.{name}`"
 end