contrib/objcwrapper: intro objcwrapper base code
[nit.git] / contrib / objcwrapper / src / objc_generator.nit
1 module objc_generator
2
3 import objc_model
4
5 class CodeGenerator
6 fun generator(classes: Array[nullable ObjcClass]) do
7 var init_with_alloc = true
8 for classe in classes do
9 var file = new FileWriter.open(classe.name + ".nit")
10 nit_class_generator(classe, file, init_with_alloc)
11 file.close
12 end
13 end
14
15 fun type_convertor(type_word: String): String do
16 var types = new HashMap[String, String]
17 types["char"] = "Byte"
18 types["short"] = "Int"
19 types["short int"] = "Int"
20 types["int"] = "Int"
21 types["long"] = "Int"
22 types["long int"] = "Int"
23 types["long long"] = "Int"
24 types["long long int"] = "Int"
25 types["float"] = "Float"
26 types["double"] = "Float"
27 types["long double"] = "Float"
28
29 types["NSUInteger"] = "Int"
30 types["BOOL"] = "Bool"
31 types["id"] = "NSObject"
32
33 if types.has_key(type_word) then
34 return types[type_word]
35 else
36 return type_word
37 end
38 end
39
40 fun nit_class_generator(classe: nullable ObjcClass, file: FileWriter, init_with_alloc: Bool) do
41 var commented_methods = new Array[ObjcMethod]
42 file.write "import cocoa::foundation\n\n"
43 file.write("extern class " + classe.name + """ in "ObjC" `{ """ + classe.name + """ * `}\n""")
44 for super_name in classe.super_names do
45 file.write(""" super """ + super_name + "\n")
46 end
47 if classe.super_names.is_empty then file.write(""" super NSObject\n""")
48 new_nit_generator(classe, file, init_with_alloc)
49 file.write("\n")
50 for attribute in classe.attributes do
51 nit_attribute_generator(attribute, file)
52 end
53 for method in classe.methods do
54 if method.is_commented then
55 commented_methods.add(method)
56 else
57 if init_with_alloc and method.params.first.name.has("init") then continue
58 file.write(""" """)
59 nit_method_generator(method, file, init_with_alloc)
60 file.write(""" in "ObjC" `{\n """)
61 objc_method_generator(method, file)
62 file.write(""" `}""")
63 if method != classe.methods.last then file.write("\n\n")
64 end
65 end
66 for commented_method in commented_methods do
67 if commented_method == commented_methods.first then file.write("\n")
68 file.write(""" #""")
69 nit_method_generator(commented_method, file, init_with_alloc)
70 if commented_method != commented_methods.last then file.write("\n")
71 end
72 file.write("\nend")
73 end
74
75 fun new_nit_generator(classe: nullable ObjcClass, file: FileWriter, init_with_alloc: Bool) do
76 if init_with_alloc then
77 for method in classe.methods do
78 if method.params.first.name.has("init") and not method.is_commented then
79 file.write """\n """
80 if method.params.first.name == "init" then
81 file.write "new"
82 else
83 nit_method_generator(method, file, init_with_alloc)
84 end
85 file.write """ in "ObjC" `{\n"""
86 new_alloc_init_objc_generator(classe.name, method, file)
87 file.write """ `}\n"""
88 end
89 end
90 else
91 file.write """\n new in "ObjC"`{\n"""
92 new_objc_generator(classe, file)
93 file.write """ `}\n"""
94 end
95 end
96
97 fun nit_attribute_generator(attribute: ObjcAttribute, file: FileWriter) do
98 nit_attribute_setter_generator(attribute, file)
99 file.write "\n"
100 end
101
102 fun nit_attribute_setter_generator(attribute: ObjcAttribute, file: FileWriter) do
103 file.write(""" fun """ + attribute.name.to_snake_case + ": " + type_convertor(attribute.return_type))
104 file.write """ in "ObjC" `{\n"""
105 objc_attribute_setter_generator(attribute, file)
106 file.write """ `}\n"""
107 end
108
109 fun nit_attribute_getter_generator(attribute: ObjcAttribute, file: FileWriter) do
110 file.write(""" fun """ + attribute.name.to_snake_case + "=(value: " + type_convertor(attribute.return_type) + ")")
111 file.write " in \"ObjC\" `\{\n"
112 objc_attribute_getter_generator(attribute, file)
113 file.write """ `}\n"""
114 end
115
116 fun nit_method_generator(method: ObjcMethod, file: FileWriter, init_with_alloc: Bool) do
117 var name = ""
118 for param in method.params do
119 name += param.name[0].to_upper.to_s + param.name.substring_from(1)
120 name = name.to_snake_case
121 end
122 if name.has("init") and init_with_alloc then
123 file.write "new "
124 else
125 if not init_with_alloc and name == "init" then name = "init_0"
126 file.write "fun "
127 end
128 file.write(name)
129 for param in method.params do
130 if param == method.params.first and not param.is_single then
131 file.write("(" + param.variable_name + ": " + type_convertor(param.return_type))
132 end
133 if param != method.params.first and not param.is_single then
134 file.write(", " + param.variable_name + ": " + type_convertor(param.return_type))
135 end
136 if param == method.params.last and not param.is_single then
137 file.write ")"
138 end
139 end
140 if method.return_type != "void" and not method.params.first.name.has("init") then file.write(": " + type_convertor(method.return_type))
141 end
142
143 fun new_alloc_init_objc_generator(classe_name: String, method: ObjcMethod, file: FileWriter) do
144 file.write(""" return [[""" + classe_name + " alloc] ")
145 for param in method.params do
146 if not param.is_single then
147 file.write(param.name + ":" + param.variable_name)
148 if not param == method.params.last then file.write(" ")
149 else
150 file.write param.name
151 end
152 end
153 file.write "];\n"
154 end
155
156 fun new_objc_generator(classe: nullable ObjcClass, file: FileWriter) do
157 file.write(""" return [""" + classe.name + " alloc];\n")
158 end
159
160 fun objc_attribute_setter_generator(attribute: ObjcAttribute, file: FileWriter) do
161 file.write(""" return [self """ + attribute.name + "];\n")
162 end
163
164 fun objc_attribute_getter_generator(attribute: ObjcAttribute, file: FileWriter) do
165 file.write(""" self.""" + attribute.name + " = value;\n")
166 end
167
168 fun objc_method_generator(method: ObjcMethod, file: FileWriter) do
169 if method.return_type != "void" then file.write("return ")
170 file.write "[self "
171 for param in method.params do
172 if not param.is_single then
173 file.write(param.name + ":" + param.variable_name)
174 if not param == method.params.last then file.write " "
175 else
176 file.write(param.name)
177 end
178 end
179 file.write "];\n"
180 end
181 end