1 # This file is part of NIT (http://www.nitlanguage.org).
3 # Copyright 2014 Frédéric Vachon <fredvac@gmail.com>
4 # Copyright 2015 Alexis Laferrière <alexis.laf@xymus.net>
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
18 # Services to generate extern class `in "Java"`
25 # Path to the output file
28 # Model of Java class being wrapped
31 # Comment out methods with unknown (unwrapped) types
32 var comment_unknown_types
: Bool
34 # Generate stub classes for unknown types used in the generated module
35 var stub_for_unknown_types
: Bool
38 var file_out
: Writer = new FileWriter.open
(file_name
) is lazy
, writable
40 # Name of the Nit module to generate
41 var module_name
: nullable String is lazy
do
42 if file_name
.file_extension
== "nit" then
43 # Output file ends with .nit, we expect it to be a valid name
44 return file_name
.basename
(".nit")
48 # Generate the Nit module into `file_out`
52 file_out
.write license
55 var module_name
= module_name
56 if module_name
!= null then file_out
.write
"module {module_name}\n"
60 var imports
= new HashSet[String]
61 imports
.add
"import mnit_android\n"
62 for jclass
in model
.classes
do
63 for import_
in jclass
.imports
do imports
.add
"import android::{import_}\n"
65 file_out
.write imports
.join
("\n")
67 for jclass
in model
.classes
do
69 file_out
.write gen_class_header
(jclass
.class_type
)
71 for id
, signatures
in jclass
.methods
do
73 for signature
in signatures
do
75 if c
> 0 then nid
+= c
.to_s
78 file_out
.write gen_method
(jclass
, id
, nid
, signature
.return_type
, signature
.params
)
82 file_out
.write
"end\n\n"
85 if stub_for_unknown_types
then
86 for jtype
in model
.unknown_types
do
87 file_out
.write gen_unknown_class_header
(jtype
)
93 # License for the header of the generated Nit module
95 # This file is part of NIT (http://www.nitlanguage.org).
97 # Licensed under the Apache License, Version 2.0 (the "License");
98 # you may not use this file except in compliance with the License.
99 # You may obtain a copy of the License at
101 # http://www.apache.org/licenses/LICENSE-2.0
103 # Unless required by applicable law or agreed to in writing, software
104 # distributed under the License is distributed on an "AS IS" BASIS,
105 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
106 # See the License for the specific language governing permissions and
107 # limitations under the License.
109 # This code has been generated using `jwrapper`
112 fun gen_class_header
(jtype
: JavaType): String
114 var temp
= new Array[String]
115 temp
.add
("extern class Native{jtype.id} in \"Java\
" `\{ {jtype} `\}\n")
116 temp
.add
("\tsuper JavaObject\n\n")
121 fun gen_unknown_class_header
(jtype
: JavaType): String
123 var nit_type
: NitType
124 if jtype
.extern_name
.has_generic_params
then
125 nit_type
= jtype
.extern_name
.generic_params
.first
127 nit_type
= jtype
.extern_name
130 var temp
= new Array[String]
131 temp
.add
("extern class {nit_type} in \"Java\
" `\{ {jtype.to_package_name} `\}\n")
132 temp
.add
("\tsuper JavaObject\n\nend\n")
137 fun gen_method
(java_class
: JavaClass, jmethod_id
, nmethod_id
: String, jreturn_type
: JavaType, jparam_list
: Array[JavaType]): String
143 var nit_types
= new Array[NitType]
147 for i
in [0..jparam_list
.length
[ do
148 var jparam
= jparam_list
[i
]
149 var nit_type
= jparam
.to_nit_type
151 if not nit_type
.is_complete
then
152 if jparam
.is_wrapped
then
153 java_class
.imports
.add nit_type
.mod
.as(not null)
155 model
.unknown_types
.add jparam
156 if comment_unknown_types
then
159 nit_type
= jparam
.extern_name
166 if not jparam
.is_collection
then cast
= jparam
.param_cast
168 nit_types
.add
(nit_type
)
169 nit_type
.arg_id
= "{nit_id}{nit_id_no}"
171 if i
== jparam_list
.length
- 1 then
172 java_params
+= "{cast}{nit_id}{nit_id_no}"
173 nit_params
+= "{nit_id}{nit_id_no}: {nit_type}"
175 java_params
+= "{cast}{nit_id}{nit_id_no}" + ", "
176 nit_params
+= "{nit_id}{nit_id_no}: {nit_type}, "
183 var method_id
= nmethod_id
.to_nit_method_name
184 var nit_signature
= new Array[String]
186 nit_signature
.add
"\tfun {method_id}"
188 if not jparam_list
.is_empty
then
189 nit_signature
.add
"({nit_params})"
192 var return_type
= null
194 if not jreturn_type
.is_void
then
195 return_type
= jreturn_type
.to_nit_type
197 if not return_type
.is_complete
then
198 if jreturn_type
.is_wrapped
then
199 java_class
.imports
.add return_type
.mod
.as(not null)
201 model
.unknown_types
.add jreturn_type
202 if comment_unknown_types
then
205 return_type
= jreturn_type
.extern_name
210 nit_signature
.add
": {return_type} "
213 var temp
= new Array[String]
215 temp
.add
(comment
+ nit_signature
.join
)
217 # FIXME : This huge `if` block is only necessary to copy primitive arrays as long as there's no better way to do it
218 if comment
== "#" then
219 temp
.add
(" in \"Java\
" `\{\n{comment}\t\tself.{jmethod_id}({java_params});\n{comment}\t`\}\n")
220 # Methods with return type
221 else if return_type
!= null then
222 temp
.add
(" in \"Java\
" `\{\n{comment}\t\treturn {jreturn_type.return_cast}self.{jmethod_id}({java_params});\n{comment}\t`\}\n")
223 # Methods without return type
224 else if jreturn_type
.is_void
then
225 temp
.add
(" in \"Java\
" `\{\n{comment}\t\tself.{jmethod_id}({java_params});\n{comment}\t`\}\n")
228 temp
.add
(" in \"Java\
" `\{\n{comment}\t\tself.{jmethod_id}({java_params});\n{comment}\t`\}\n")
236 # Convert the Java method name `self` to the Nit style
238 # * Converts to snake case
239 # * Strips `Get` and `Set`
240 # * Add suffix `=` to setters
241 fun to_nit_method_name
: String
243 var name
= self.to_snake_case
244 if name
.has_prefix
("get_") then
245 name
= name
.substring_from
(4)
246 else if name
.has_prefix
("set_") then
247 name
= name
.substring_from
(4) + "="