contrib/objcwrapper: add a new line at the end of the generated file
[nit.git] / contrib / objcwrapper / src / objc_generator.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Code generation
16 module objc_generator
17
18 import objc_model
19
20 class CodeGenerator
21 fun generator(classes: Array[nullable ObjcClass]) do
22 var init_with_alloc = true
23 for classe in classes do
24 var file = new FileWriter.open(classe.name + ".nit")
25 nit_class_generator(classe, file, init_with_alloc)
26 file.close
27 end
28 end
29
30 fun type_convertor(type_word: String): String do
31 var types = new HashMap[String, String]
32 types["char"] = "Byte"
33 types["short"] = "Int"
34 types["short int"] = "Int"
35 types["int"] = "Int"
36 types["long"] = "Int"
37 types["long int"] = "Int"
38 types["long long"] = "Int"
39 types["long long int"] = "Int"
40 types["float"] = "Float"
41 types["double"] = "Float"
42 types["long double"] = "Float"
43
44 types["NSUInteger"] = "Int"
45 types["BOOL"] = "Bool"
46 types["id"] = "NSObject"
47
48 if types.has_key(type_word) then
49 return types[type_word]
50 else
51 return type_word
52 end
53 end
54
55 fun nit_class_generator(classe: nullable ObjcClass, file: FileWriter, init_with_alloc: Bool) do
56 var commented_methods = new Array[ObjcMethod]
57 file.write "import cocoa::foundation\n\n"
58 file.write("extern class " + classe.name + """ in "ObjC" `{ """ + classe.name + """ * `}\n""")
59 for super_name in classe.super_names do
60 file.write(""" super """ + super_name + "\n")
61 end
62 if classe.super_names.is_empty then file.write(""" super NSObject\n""")
63 new_nit_generator(classe, file, init_with_alloc)
64 file.write("\n")
65 for attribute in classe.attributes do
66 nit_attribute_generator(attribute, file)
67 end
68 for method in classe.methods do
69 if method.is_commented then
70 commented_methods.add(method)
71 else
72 if init_with_alloc and method.params.first.name.has("init") then continue
73 file.write(""" """)
74 nit_method_generator(method, file, init_with_alloc)
75 file.write(""" in "ObjC" `{\n """)
76 objc_method_generator(method, file)
77 file.write(""" `}""")
78 if method != classe.methods.last then file.write("\n\n")
79 end
80 end
81 for commented_method in commented_methods do
82 if commented_method == commented_methods.first then file.write("\n")
83 file.write(""" #""")
84 nit_method_generator(commented_method, file, init_with_alloc)
85 if commented_method != commented_methods.last then file.write("\n")
86 end
87 file.write "\nend\n"
88 end
89
90 fun new_nit_generator(classe: nullable ObjcClass, file: FileWriter, init_with_alloc: Bool) do
91 if init_with_alloc then
92 for method in classe.methods do
93 if method.params.first.name.has("init") and not method.is_commented then
94 file.write """\n """
95 if method.params.first.name == "init" then
96 file.write "new"
97 else
98 nit_method_generator(method, file, init_with_alloc)
99 end
100 file.write """ in "ObjC" `{\n"""
101 new_alloc_init_objc_generator(classe.name, method, file)
102 file.write """ `}\n"""
103 end
104 end
105 else
106 file.write """\n new in "ObjC"`{\n"""
107 new_objc_generator(classe, file)
108 file.write """ `}\n"""
109 end
110 end
111
112 fun nit_attribute_generator(attribute: ObjcAttribute, file: FileWriter) do
113 nit_attribute_setter_generator(attribute, file)
114 file.write "\n"
115 end
116
117 fun nit_attribute_setter_generator(attribute: ObjcAttribute, file: FileWriter) do
118 file.write(""" fun """ + attribute.name.to_snake_case + ": " + type_convertor(attribute.return_type))
119 file.write """ in "ObjC" `{\n"""
120 objc_attribute_setter_generator(attribute, file)
121 file.write """ `}\n"""
122 end
123
124 fun nit_attribute_getter_generator(attribute: ObjcAttribute, file: FileWriter) do
125 file.write(""" fun """ + attribute.name.to_snake_case + "=(value: " + type_convertor(attribute.return_type) + ")")
126 file.write " in \"ObjC\" `\{\n"
127 objc_attribute_getter_generator(attribute, file)
128 file.write """ `}\n"""
129 end
130
131 fun nit_method_generator(method: ObjcMethod, file: FileWriter, init_with_alloc: Bool) do
132 var name = ""
133 for param in method.params do
134 name += param.name[0].to_upper.to_s + param.name.substring_from(1)
135 name = name.to_snake_case
136 end
137 if name.has("init") and init_with_alloc then
138 file.write "new "
139 else
140 if not init_with_alloc and name == "init" then name = "init_0"
141 file.write "fun "
142 end
143 file.write(name)
144 for param in method.params do
145 if param == method.params.first and not param.is_single then
146 file.write("(" + param.variable_name + ": " + type_convertor(param.return_type))
147 end
148 if param != method.params.first and not param.is_single then
149 file.write(", " + param.variable_name + ": " + type_convertor(param.return_type))
150 end
151 if param == method.params.last and not param.is_single then
152 file.write ")"
153 end
154 end
155 if method.return_type != "void" and not method.params.first.name.has("init") then file.write(": " + type_convertor(method.return_type))
156 end
157
158 fun new_alloc_init_objc_generator(classe_name: String, method: ObjcMethod, file: FileWriter) do
159 file.write(""" return [[""" + classe_name + " alloc] ")
160 for param in method.params do
161 if not param.is_single then
162 file.write(param.name + ":" + param.variable_name)
163 if not param == method.params.last then file.write(" ")
164 else
165 file.write param.name
166 end
167 end
168 file.write "];\n"
169 end
170
171 fun new_objc_generator(classe: nullable ObjcClass, file: FileWriter) do
172 file.write(""" return [""" + classe.name + " alloc];\n")
173 end
174
175 fun objc_attribute_setter_generator(attribute: ObjcAttribute, file: FileWriter) do
176 file.write(""" return [self """ + attribute.name + "];\n")
177 end
178
179 fun objc_attribute_getter_generator(attribute: ObjcAttribute, file: FileWriter) do
180 file.write(""" self.""" + attribute.name + " = value;\n")
181 end
182
183 fun objc_method_generator(method: ObjcMethod, file: FileWriter) do
184 if method.return_type != "void" then file.write("return ")
185 file.write "[self "
186 for param in method.params do
187 if not param.is_single then
188 file.write(param.name + ":" + param.variable_name)
189 if not param == method.params.last then file.write " "
190 else
191 file.write(param.name)
192 end
193 end
194 file.write "];\n"
195 end
196 end