module objc_generator
import opts
+import gen_nit
import objc_model
types["long double"] = "Float"
types["NSUInteger"] = "Int"
+ types["NSInteger"] = "Int"
+ types["CGFloat"] = "Float"
types["BOOL"] = "Bool"
+
types["id"] = "NSObject"
types["constid"] = "NSObject"
types["SEL"] = "NSObject"
end
# Generate code
- file.write "import cocoa::foundation\n\n"
+ file.write """
+# File generated by objcwrapper with the following command:
+# {{{program_name}}} {{{args.join(" ")}}}
+
+"""
+
+ file.write "import cocoa::foundation\n"
for classe in classes do
write_class(classe, file)
end
super NSObject
"""
- file.write "\n"
-
# Constructor or constructors
write_constructors(classe, file)
if opt_init_as_methods.value then
# A single constructor for `alloc`
file.write """
+
new in "ObjC" `{
return [{{{classe.name}}} alloc];
`}
-
"""
return
end
write_method_signature(method, file)
- write_objc_init_call(classe.name, method, file)
+ write_objc_init_call(classe.name, method, file)
end
end
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
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
if name == "init" then name = ""
+ name = name.to_nit_name(property=true, pointer=true)
+
# If class method, prefix with class name
if method.is_class_property then name = "{method.objc_class.name.to_snake_case}_{name}"
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.objc_to_nit_type}"
+ params.add "{param.nit_variable_name}: {param.return_type.objc_to_nit_type}"
end
var params_with_par = ""
end
file.write """
+
+{{{method.doc}}}
{{{c}}}{{{fun_keyword}}} {{{name}}}{{{params_with_par}}}{{{ret}}} in "ObjC" `{
"""
end
var params = new Array[String]
for param in method.params do
if not param.is_single then
- params.add "{param.name}: {param.variable_name}"
+ params.add "{param.name}: {param.nit_variable_name}"
else params.add param.name
end
file.write """
{{{c}}} return [[{{{class_name}}} alloc] {{{params.join(" ")}}}];
{{{c}}}`}
-
"""
end
var params = new Array[String]
for param in method.params do
if not param.is_single then
- params.add "{param.name}: {param.variable_name}"
+ params.add "{param.name}: {param.nit_variable_name}"
else params.add param.name
end
file.write """
{{{c}}} {{{ret}}}[{{{recv}}} {{{params.join(" ")}}}];
{{{c}}}`}
-
"""
end
end
return to_s
end
end
+
+ # Convert to a safe Nit name for a `property`, a property in a subclass of `pointer` or a variable
+ private fun to_nit_name(property, pointer: nullable Bool): String
+ do
+ var name = to_s
+ name = name.to_snake_case
+
+ while not name.is_empty and name.chars.first == '_' do name = name.substring_from(1)
+
+ if keywords.has(name) then name = name + "0"
+
+ if property == true then
+ if methods_in_object.has(name) then name = name + "0"
+ if pointer == true and methods_in_pointer.has(name) then name = name + "0"
+ end
+
+ return name.to_s
+ end
end
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
+
+redef class ObjcParam
+ # `variable_name` mangled for the Nit language
+ private fun nit_variable_name: String do return variable_name.to_nit_name
end