The `auto_serializable` implies `super Serializable` part is up for discussion. It cleans up the code, but the code could no more be compatible with engines that do not handle the annotation.
Next there will be a tool (and/or a phase) to generate support to deserialize generic types.
Pull-Request: #608
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Jean Privat <jean@pryen.org>
android:
mkdir -p bin
- ../../bin/nitg -o bin/simple.apk src/simple_android.nit
+ ../../bin/nitg -o bin/simple.apk src/complete_simple_android.nit
clean:
rm -rf bin
--- /dev/null
+#FIXME: Improper way of resolving unjustified metadata conflict
+module complete_simple_android is
+ app_name("test all")
+ java_package("org.nitlanguage.test_all")
+ app_version(1, 0)
+end
+
+import test_bundle
+import test_audio
+import test_shared_preferences
+import test_assets_and_resources
+import test_target_api
import simple
import mnit_android
-import android::bundle
-import android::shared_preferences
-import android::assets_and_resources
-import android::audio
+import serialization
in "Java" `{
import android.content.Context;
`}
redef class App
- var soundsp: Sound
- var soundmp: Sound
-
- redef fun init_window
- do
- super
- manage_audio_mode
- # retrieve sound
- soundsp = load_sound("sound.ogg")
- soundmp = load_music("xylofon.ogg")
- default_mediaplayer.looping = true
- default_mediaplayer.prepare
- soundmp.play
- end
-
redef fun input( ie )
do
if ie isa PointerEvent and ie.depressed then
- do_java_stuff
- test_bundle
- test_shared_preferences
- soundsp.play
- test_assets
- test_resources
+ test_java_ffi
end
return super
end
- #testing the assets manager
- fun test_assets
- do
- assert asset_manager.bitmap("fighter.png") != null
- end
-
- #testing the resources manager
- fun test_resources do
- assert resource_manager.string("string_test") == "string test"
- assert resource_manager.boolean("test_bool") == true
- assert resource_manager.dimension("test_dimen_1") != null
- assert resource_manager.dimension("test_dimen_2") != null
- end
-
- fun test_bundle
- do
- var bundle = new Bundle(self)
-
- bundle["anInt"] = 1
- bundle["aFloat"] = 1.1
- bundle["aString"] = "A string"
- bundle["aBool"] = true
-
- var int_array = new Array[Int]
- var bool_array = new Array[Bool]
-
- var value = true
-
- for i in [0..5] do
- int_array.add(i)
- bool_array.add(value)
- value = not value
- end
-
- bundle["anArrayOfInt"] = int_array
- bundle["anArrayOfBool"] = bool_array
-
- assert bundle.int("anInt", 0) == 1
- assert bundle.int("wrongInt", 0) == 0
- assert bundle.float("aFloat", 0.0) == 1.1
- assert bundle.float("wrongFloat", 0.0) == 0.0
- assert bundle.string("aString") == "A string"
- assert bundle.string("wrongString") == null
- assert bundle.bool("aBool", false)
- assert bundle.bool("wrongBool", false) == false
-
- var int_array_test = bundle.array_of_int("anArrayOfInt")
- var bool_array_test = bundle.array_of_bool("anArrayOfBool")
-
- value = true
-
- for i in [0..5] do
- assert int_array_test[i] == i
- assert bool_array_test[i] == value
- value = not value
- end
-
- assert bundle.size == 6
- assert bundle.has("aBool")
- assert not bundle.is_empty
-
- bundle.remove("aString")
- bundle.remove("anArrayOfBool")
-
- assert bundle.string("aString") == null
- assert bundle.array_of_bool("anArrayOfBool") == null
-
- # Serializable tests
- var p1 = new Point(10, 10)
- bundle["aPoint"] = p1
- var p2 = bundle.deserialize("aPoint")
-
- assert p1.to_s == p2.to_s
-
- var point_array = new Array[Point]
-
- for i in [0..5] do point_array.add(new Point(i, i))
-
- bundle["anArrayOfPoint"] = point_array
-
- var deserialized_point_array = bundle.deserialize_array("anArrayOfPoint")
-
- for i in [0..5] do
- var point = new Point(i, i)
- assert deserialized_point_array[i].to_s == point.to_s
- end
-
- bundle.clear
-
- assert bundle.keys.is_empty
- assert bundle.is_empty
- end
-
- fun test_shared_preferences
- do
- # Private mode tests
- var sp = new SharedPreferences.privately(self, "test")
- sp.add_bool("a_boolean", true)
- sp.add_float("a_float", 66.6)
- sp.add_int("an_int", 666)
- sp.add_int("a_second_int", 666777)
- sp.add_long("a_long", 6666666666)
- sp.add_string("a_string", "A string")
- sp["another_int"] = 85
- sp["yet_another_string"] = "Another string"
- sp.remove("a_second_int")
-
- # Serialized object test
- var my_point = new Point(10, 10)
- sp["a_point"] = my_point
- var my_deserialized_point = sp["a_point"]
- assert my_point.to_s == my_deserialized_point.to_s
-
- assert sp.bool("a_boolean", false) == true
- assert sp.bool("wrong_boolean", false) == false
- assert sp.float("a_float", 0.0) != 0.0
- assert sp.float("wrong_float", 0.0) == 0.0
- assert sp.int("an_int", 0) == 666
- assert sp.int("a_second_int", 0) == 0
- assert sp.long("a_long", 0) == 6666666666
- assert sp.long("wrong_long", 0) == 0
- assert sp.string("a_string", "ERROR!") == "A string"
- assert sp.string("wrong_string", "ERROR!") == "ERROR!"
- assert sp.long("another_int", 0) == 85
- assert sp.string("yet_another_string", "ERROR!") == "Another string"
- assert sp.has("an_int") == true
- assert sp.has("a_second_int") == false
-
- sp.clear
- assert sp.all == null
-
- sp.destroy
- end
-
- fun do_java_stuff import native_activity in "Java" `{
+ fun test_java_ffi import native_activity in "Java" `{
// + Log (no context needed)
android.util.Log.d("mnit_simple", "Java within NIT!!!");
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2014 Romain Chanoir <romain.chanoir@viacesi.fr>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Test for the asserts_and_resources module of App.nit framework
+module test_assets_and_resources
+
+import simple_android
+import android::assets_and_resources
+
+redef class App
+ redef fun input( ie )
+ do
+ if ie isa PointerEvent and ie.depressed then
+ test_assets
+ test_resources
+ end
+ return super
+ end
+
+ # Testing the assets manager
+ fun test_assets
+ do
+ assert asset_manager.bitmap("fighter.png") != null
+ end
+
+ # Testing the resources manager
+ fun test_resources do
+ assert resource_manager.string("string_test") == "string test"
+ assert resource_manager.boolean("test_bool") == true
+ assert resource_manager.dimension("test_dimen_1") != null
+ assert resource_manager.dimension("test_dimen_2") != null
+ end
+end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2014 Romain Chanoir <romain.chanoir@viacesi.fr>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Test for the audio module of App.nit framework
+module test_audio
+
+import simple_android
+import android::audio
+
+redef class App
+ var soundsp: Sound
+ var soundmp: Sound
+
+ redef fun init_window
+ do
+ super
+ manage_audio_mode
+
+ # Retrieve sound
+ soundsp = load_sound("sound.ogg")
+ soundmp = load_music("xylofon.ogg")
+ default_mediaplayer.looping = true
+ default_mediaplayer.prepare
+ soundmp.play
+ end
+
+ redef fun input( ie )
+ do
+ if ie isa PointerEvent and ie.depressed then
+ soundsp.play
+ end
+ return super
+ end
+end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2014 Frédéric Vachon <fredvac@gmail.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Test for the bundle module of App.nit framework
+module test_bundle
+
+import simple_android
+import android::bundle
+
+redef class App
+ redef fun input ( ie )
+ do
+ if ie isa PointerEvent and ie.depressed then
+ test_bundle
+ end
+ return super
+ end
+
+ fun test_bundle
+ do
+ var bundle = new Bundle(self)
+
+ bundle["anInt"] = 1
+ bundle["aFloat"] = 1.1
+ bundle["aString"] = "A string"
+ bundle["aBool"] = true
+
+ var int_array = new Array[Int]
+ var bool_array = new Array[Bool]
+
+ var value = true
+
+ for i in [0..5] do
+ int_array.add(i)
+ bool_array.add(value)
+ value = not value
+ end
+
+ bundle["anArrayOfInt"] = int_array
+ bundle["anArrayOfBool"] = bool_array
+
+ assert bundle.int("anInt", 0) == 1
+ assert bundle.int("wrongInt", 0) == 0
+ assert bundle.float("aFloat", 0.0) == 1.1
+ assert bundle.float("wrongFloat", 0.0) == 0.0
+ assert bundle.string("aString") == "A string"
+ assert bundle.string("wrongString") == null
+ assert bundle.bool("aBool", false)
+ assert bundle.bool("wrongBool", false) == false
+
+ var int_array_test = bundle.array_of_int("anArrayOfInt")
+ var bool_array_test = bundle.array_of_bool("anArrayOfBool")
+
+ value = true
+
+ for i in [0..5] do
+ assert int_array_test[i] == i
+ assert bool_array_test[i] == value
+ value = not value
+ end
+
+ assert bundle.size == 6
+ assert bundle.has("aBool")
+ assert not bundle.is_empty
+
+ bundle.remove("aString")
+ bundle.remove("anArrayOfBool")
+
+ assert bundle.string("aString") == null
+ assert bundle.array_of_bool("anArrayOfBool") == null
+
+ # Serializable tests
+ var p1 = new Point(10, 10)
+ bundle["aPoint"] = p1
+ var p2 = bundle.deserialize("aPoint")
+
+ assert p1.to_s == p2.to_s
+
+ var point_array = new Array[Point]
+
+ for i in [0..5] do point_array.add(new Point(i, i))
+
+ bundle["anArrayOfPoint"] = point_array
+
+ var deserialized_point_array = bundle.deserialize_array("anArrayOfPoint")
+
+ for i in [0..5] do
+ var point = new Point(i, i)
+ assert deserialized_point_array[i].to_s == point.to_s
+ end
+
+ bundle.clear
+
+ assert bundle.keys.is_empty
+ assert bundle.is_empty
+ end
+end
+
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2014 Frédéric Vachon <fredvac@gmail.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Test for the shared_preferences module of App.nit framework
+module test_shared_preferences
+
+import simple_android
+import android::shared_preferences
+
+redef class App
+ redef fun input ( ie )
+ do
+ if ie isa PointerEvent and ie.depressed then
+ test_shared_preferences
+ end
+ return super
+ end
+
+ fun test_shared_preferences
+ do
+ # Private mode tests
+ var sp = new SharedPreferences.privately(self, "test")
+ sp.add_bool("a_boolean", true)
+ sp.add_float("a_float", 66.6)
+ sp.add_int("an_int", 666)
+ sp.add_int("a_second_int", 666777)
+ sp.add_long("a_long", 6666666666)
+ sp.add_string("a_string", "A string")
+ sp["another_int"] = 85
+ sp["yet_another_string"] = "Another string"
+ sp.remove("a_second_int")
+
+ # Serialized object test
+ var my_point = new Point(10, 10)
+ sp["a_point"] = my_point
+ var my_deserialized_point = sp["a_point"]
+ assert my_point.to_s == my_deserialized_point.to_s
+
+ assert sp.bool("a_boolean", false) == true
+ assert sp.bool("wrong_boolean", false) == false
+ assert sp.float("a_float", 0.0) != 0.0
+ assert sp.float("wrong_float", 0.0) == 0.0
+ assert sp.int("an_int", 0) == 666
+ assert sp.int("a_second_int", 0) == 0
+ assert sp.long("a_long", 0) == 6666666666
+ assert sp.long("wrong_long", 0) == 0
+ assert sp.string("a_string", "ERROR!") == "A string"
+ assert sp.string("wrong_string", "ERROR!") == "ERROR!"
+ assert sp["another_int"] == 85
+ assert sp["yet_another_string"] == "Another string"
+ assert sp.has("an_int") == true
+ assert sp.has("a_second_int") == false
+
+ sp.clear
+ assert sp.all == null
+
+ sp.destroy
+ end
+end
# Test for the API level related annotations
module test_target_api is
- min_sdk_version(10)
- max_sdk_version(19)
- target_sdk_version(11)
+ min_api_version(10)
+ max_api_version(19)
+ target_api_version(11)
end
import simple_android
redef type SELF: NativeResources
fun get_assets:NativeAssetManager in "Java" `{ return recv.getAssets(); `}
- fun get_color(id: Int): Int in "Java" `{ return recv.getColor(id); `}
- fun get_boolean(id: Int): Bool in "Java" `{ return recv.getBoolean(id); `}
- fun get_dimension(id: Int): Int in "Java" `{ return (int)recv.getDimension(id); `}
- fun get_drawable(id: Int): NativeDrawable in "Java" `{ return recv.getDrawable(id); `}
+ fun get_color(id: Int): Int in "Java" `{ return recv.getColor((int)id); `}
+ fun get_boolean(id: Int): Bool in "Java" `{ return recv.getBoolean((int)id); `}
+ fun get_dimension(id: Int): Int in "Java" `{ return (int)recv.getDimension((int)id); `}
+ fun get_drawable(id: Int): NativeDrawable in "Java" `{ return recv.getDrawable((int)id); `}
fun get_identifier(name, def_type, def_package: JavaString): Int in "Java" `{ return recv.getIdentifier(name, def_type, def_package); `}
- fun get_integer(id: Int): Int in "Java" `{ return recv.getInteger(id); `}
- fun get_string(id: Int): JavaString in "Java" `{ return recv.getString(id); `}
- fun get_resource_entry_name(resid: Int): JavaString in "Java" `{ return recv.getResourceEntryName(resid); `}
- fun get_resource_name(resid: Int): JavaString in "Java" `{ return recv.getResourceName(resid); `}
- fun get_resource_pakage_name(resid: Int): JavaString in "Java" `{ return recv.getResourcePackageName(resid); `}
- fun get_resource_type_name(resid: Int): JavaString in "Java" `{ return recv.getResourceTypeName(resid); `}
+ fun get_integer(id: Int): Int in "Java" `{ return recv.getInteger((int)id); `}
+ fun get_string(id: Int): JavaString in "Java" `{ return recv.getString((int)id); `}
+ fun get_resource_entry_name(resid: Int): JavaString in "Java" `{ return recv.getResourceEntryName((int)resid); `}
+ fun get_resource_name(resid: Int): JavaString in "Java" `{ return recv.getResourceName((int)resid); `}
+ fun get_resource_pakage_name(resid: Int): JavaString in "Java" `{ return recv.getResourcePackageName((int)resid); `}
+ fun get_resource_type_name(resid: Int): JavaString in "Java" `{ return recv.getResourceTypeName((int)resid); `}
end
# Resource manager for android resources placed in the `res` folder of your app
# Create a NativeBitmap using a resource ID and the NativeResources
# Called by the ResourceManager
- new from_resources(res: NativeResources, id: Int) in "Java" `{ return BitmapFactory.decodeResource(res, id); `}
+ new from_resources(res: NativeResources, id: Int) in "Java" `{ return BitmapFactory.decodeResource(res, (int)id); `}
fun width: Int in "Java" `{ return recv.getWidth(); `}
fun height: Int in "Java" `{ return recv.getHeight(); `}
end
redef type SELF: NativeAudioManager
fun mode: Int in "Java" `{ return recv.getMode(); `}
- fun mode=(i: Int) in "Java" `{ recv.setMode(i); `}
+ fun mode=(i: Int) in "Java" `{ recv.setMode((int)i); `}
fun wired_headset_on: Bool in "Java" `{ return recv.isWiredHeadsetOn(); `}
fun wired_headset_on=(b: Bool) in "Java" `{ recv.setWiredHeadsetOn(b); `}
fun speakerphone_on: Bool in "Java" `{ return recv.isSpeakerphoneOn(); `}
}
`}
- fun create(context: NativeActivity, id: Int): NativeMediaPlayer in "Java" `{ return recv.create(context, id); `}
+ fun create(context: NativeActivity, id: Int): NativeMediaPlayer in "Java" `{ return recv.create(context, (int)id); `}
fun pause in "Java" `{ recv.pause(); `}
fun stop in "Java" `{ recv.stop(); `}
fun playing: Bool in "Java" `{ return recv.isPlaying(); `}
fun looping=(b: Bool) in "Java" `{ recv.setLooping(b); `}
fun volume=(vol: Float) in "Java" `{ recv.setVolume((float)vol, (float)vol); `}
fun both_volume(left_volume, right_volume: Float) in "Java" `{ recv.setVolume((float)left_volume, (float)right_volume); `}
- fun stream_type=(stream_type: Int) in "Java" `{ recv.setAudioStreamType(stream_type); `}
+ fun stream_type=(stream_type: Int) in "Java" `{ recv.setAudioStreamType((int)stream_type); `}
fun data_source_fd(fd: NativeFileDescriptor, start_offset, length: Int) in "Java" `{
try {
recv.setDataSource(fd, start_offset, length);
redef type SELF: NativeSoundPool
new(max_streams, stream_type, src_quality: Int) in "Java" `{
- return new SoundPool(max_streams, stream_type, src_quality);
+ return new SoundPool((int)max_streams, (int)stream_type, (int)src_quality);
`}
- fun load_asset_fd(afd: NativeAssetFileDescriptor, priority: Int): Int in "Java" `{ return recv.load(afd, priority); `}
- fun load_id(context: NativeActivity, resid, priority: Int): Int in "Java" `{ return recv.load(context, resid, priority); `}
- fun load_path(path: JavaString, priority: Int): Int in "Java" `{ return recv.load(path, priority); `}
+ fun load_asset_fd(afd: NativeAssetFileDescriptor, priority: Int): Int in "Java" `{ return recv.load(afd, (int)priority); `}
+ fun load_id(context: NativeActivity, resid, priority: Int): Int in "Java" `{ return recv.load(context, (int)resid, (int)priority); `}
+ fun load_path(path: JavaString, priority: Int): Int in "Java" `{ return recv.load(path, (int)priority); `}
fun play(sound_id: Int, left_volume, right_volume: Float, priority, l: Int, rate: Float): Int in "Java" `{
- return recv.play(sound_id, (float)left_volume, (float)right_volume, priority, l, (float)rate);
+ return recv.play((int)sound_id, (float)left_volume, (float)right_volume, (int)priority, (int)l, (float)rate);
`}
- fun pause(stream_id: Int) in "Java" `{ recv.pause(stream_id); `}
+ fun pause(stream_id: Int) in "Java" `{ recv.pause((int)stream_id); `}
fun auto_pause in "Java" `{ recv.autoPause(); `}
fun auto_resume in "Java" `{ recv.autoResume(); `}
- fun resume(stream_id: Int) in "Java" `{ recv.resume(stream_id); `}
- fun set_loop(stream_id, l: Int) in "Java" `{ recv.setLoop(stream_id, l); `}
- fun set_priority(stream_id, priority: Int) in "Java" `{ recv.setPriority(stream_id, priority); `}
- fun set_rate(stream_id: Int, rate: Float) in "Java" `{ recv.setRate(stream_id, (float)rate); `}
- fun set_volume(stream_id: Int, left_volume, right_volume: Float) in "Java" `{ recv.setVolume(stream_id, (float)left_volume, (float)right_volume); `}
- fun stop(stream_id: Int) in "Java" `{ recv.stop(stream_id); `}
- fun unload(sound_id: Int): Bool in "Java" `{ return recv.unload(sound_id); `}
+ fun resume(stream_id: Int) in "Java" `{ recv.resume((int)stream_id); `}
+ fun set_loop(stream_id, l: Int) in "Java" `{ recv.setLoop((int)stream_id, (int)l); `}
+ fun set_priority(stream_id, priority: Int) in "Java" `{ recv.setPriority((int)stream_id, (int)priority); `}
+ fun set_rate(stream_id: Int, rate: Float) in "Java" `{ recv.setRate((int)stream_id, (float)rate); `}
+ fun set_volume(stream_id: Int, left_volume, right_volume: Float) in "Java" `{ recv.setVolume((int)stream_id, (float)left_volume, (float)right_volume); `}
+ fun stop(stream_id: Int) in "Java" `{ recv.stop((int)stream_id); `}
+ fun unload(sound_id: Int): Bool in "Java" `{ return recv.unload((int)sound_id); `}
end
fun put_integer_array_list(key: JavaString, value: Array[Int])
import Array[Int].length, Array[Int].[] in "Java" `{
ArrayList<Integer> java_array =
- new ArrayList<Integer>(Array_of_Int_length(value));
+ new ArrayList<Integer>((int) Array_of_Int_length(value));
for(int i=0; i < java_array.size(); ++i)
java_array.add((int) Array_of_Int__index(value, i));
`}
fun put_string_array_list(key: JavaString, value: Array[JavaString])
import Array[JavaString].length, Array[JavaString].[] in "Java" `{
- ArrayList<String> java_array = new ArrayList<String>(Array_of_JavaString_length(value));
+ ArrayList<String> java_array = new ArrayList<String>((int)Array_of_JavaString_length(value));
for(int i=0; i < java_array.size(); ++i)
java_array.add(Array_of_JavaString__index(value, i));
fun put_char_sequence_array_list(key: JavaString, value: Array[JavaString])
import Array[JavaString].length, Array[JavaString].[] in "Java" `{
ArrayList<CharSequence> java_array =
- new ArrayList<CharSequence>(Array_of_JavaString_length(value));
+ new ArrayList<CharSequence>((int)Array_of_JavaString_length(value));
for(int i=0; i < java_array.size(); ++i)
java_array.add(Array_of_JavaString__index(value, i));
`}
fun put_boolean_array(key: JavaString, value: Array[Bool])
import Array[Bool].length, Array[Bool].[] in "Java" `{
- boolean[] java_array = new boolean[Array_of_Bool_length(value)];
+ boolean[] java_array = new boolean[(int)Array_of_Bool_length(value)];
for(int i=0; i < java_array.length; ++i)
java_array[i] = Array_of_Bool__index(value, i);
`}
fun put_byte_array(key: JavaString, value: Array[Int])
import Array[Int].length, Array[Int].[] in "Java" `{
- byte[] java_array = new byte[Array_of_Int_length(value)];
+ byte[] java_array = new byte[(int)Array_of_Int_length(value)];
for(int i=0; i < java_array.length; ++i)
java_array[i] = (byte) Array_of_Int__index(value, i);
`}
fun put_short_array(key: JavaString, value: Array[Int])
import Array[Int].length, Array[Int].[] in "Java" `{
- short[] java_array = new short[Array_of_Int_length(value)];
+ short[] java_array = new short[(int)Array_of_Int_length(value)];
for(int i=0; i < java_array.length; ++i)
java_array[i] = (short) Array_of_Int__index(value, i);
`}
fun put_char_array(key: JavaString, value: Array[Char])
import Array[Char].length, Array[Char].[] in "Java" `{
- char[] java_array = new char[Array_of_Char_length(value)];
+ char[] java_array = new char[(int)Array_of_Char_length(value)];
for(int i=0; i < java_array.length; ++i)
java_array[i] = Array_of_Char__index(value, i);
`}
fun put_int_array(key: JavaString, value: Array[Int])
import Array[Int].length, Array[Int].[] in "Java" `{
- int[] java_array = new int[Array_of_Int_length(value)];
+ int[] java_array = new int[(int)Array_of_Int_length(value)];
for(int i=0; i < java_array.length; ++i)
java_array[i] = (int) Array_of_Int__index(value, i);
`}
fun put_long_array(key: JavaString, value: Array[Int])
import Array[Int].length, Array[Int].[] in "Java" `{
- long[] java_array = new long[Array_of_Int_length(value)];
+ long[] java_array = new long[(int)Array_of_Int_length(value)];
for(int i=0; i < java_array.length; ++i)
java_array[i] = Array_of_Int__index(value, i);
`}
fun put_float_array(key: JavaString, value: Array[Float])
import Array[Float].length, Array[Float].[] in "Java" `{
- float[] java_array = new float[Array_of_Float_length(value)];
+ float[] java_array = new float[(int)Array_of_Float_length(value)];
for(int i=0; i < java_array.length; ++i)
java_array[i] = (float) Array_of_Float__index(value, i);
`}
fun put_double_array(key: JavaString, value: Array[Float])
import Array[Float].length, Array[Float].[] in "Java" `{
- double[] java_array = new double[Array_of_Float_length(value)];
+ double[] java_array = new double[(int)Array_of_Float_length(value)];
for(int i=0; i < java_array.length; ++i)
java_array[i] = Array_of_Float__index(value, i);
`}
fun put_string_array(key: JavaString, value: Array[JavaString])
import Array[JavaString].length, Array[JavaString].[] in "Java" `{
- String[] java_array = new String[Array_of_JavaString_length(value)];
+ String[] java_array = new String[(int)Array_of_JavaString_length(value)];
for(int i=0; i < java_array.length; ++i)
java_array[i] = Array_of_JavaString__index(value, i);
`}
fun put_char_sequence_array(key: JavaString, value: Array[JavaString])
import Array[JavaString].length, Array[JavaString].[] in "Java" `{
- CharSequence[] java_array = new CharSequence[Array_of_JavaString_length(value)];
+ CharSequence[] java_array = new CharSequence[(int)Array_of_JavaString_length(value)];
for(int i=0; i < java_array.length; ++i)
java_array[i] = Array_of_JavaString__index(value, i);
`}
fun get_int(key: JavaString): Int in "Java" `{ return recv.getInt(key); `}
fun get_int_with_def_value(key: JavaString, def_value: Int): Int in "Java" `{
- return (int) recv.getInt(key, (int) def_value);
+ return recv.getInt(key, (int) def_value);
`}
- # FIXME: Get rid of the int cast as soon as the ffi is fixed
- fun get_long(key: JavaString): Int in "Java" `{ return (int) recv.getLong(key); `}
- # FIXME: Get rid of the int cast as soon as the ffi is fixed
+ fun get_long(key: JavaString): Int in "Java" `{ return recv.getLong(key); `}
fun get_long_with_def_value(key: JavaString, def_value: Int): Int in "Java" `{
- return (int) recv.getLong(key);
+ return recv.getLong(key);
`}
fun get_float(key: JavaString): Float in "Java" `{
return (float) recv.getFloat(key);
if (java_array == null) return nit_array;
for(int i=0; i < java_array.length; ++i)
- Array_of_Int_add(nit_array, (int) java_array[i]);
+ Array_of_Int_add(nit_array, java_array[i]);
return nit_array;
`}
if (java_array == null) return nit_array;
for(int i=0; i < java_array.length; ++i)
- Array_of_Int_add(nit_array, (int) java_array[i]);
+ Array_of_Int_add(nit_array, java_array[i]);
return nit_array;
`}
if (java_array == null) return nit_array;
for(int i=0; i < java_array.length; ++i)
- Array_of_Int_add(nit_array, (int) java_array[i]);
+ Array_of_Int_add(nit_array, java_array[i]);
return nit_array;
`}
`}
fun write(one_byte: Int) in "Java" `{
try {
- recv.write(one_byte);
+ recv.write((byte)one_byte);
}catch(IOException e){
e.printStackTrace();
}
fun get_int(key: JavaString, def_value: Int): Int in "Java" `{
int return_value;
try {
- return_value = recv.getInt(key, def_value);
+ return_value = recv.getInt(key, (int)def_value);
} catch (ClassCastException e) {
return def_value;
}
return return_value;
`}
- #FIXME: Get rid of the `int` cast when the ffi is fixed
fun get_long(key: JavaString, def_value: Int): Int in "Java" `{
long return_value;
try {
return recv.putFloat(key, (float) value);
`}
fun put_int(key: JavaString, value: Int): NativeSharedPreferencesEditor in "Java" `{
- return recv.putInt(key, value);
+ return recv.putInt(key, (int)value);
`}
fun put_long(key: JavaString, value: Int): NativeSharedPreferencesEditor in "Java" `{
return recv.putLong(key, value);
// Uses default SharedPreferences if file_name is an empty String
if (file_name.equals("")) {
- sp = context.getPreferences( mode);
+ sp = context.getPreferences((int)mode);
} else {
- sp = context.getSharedPreferences(file_name, mode);
+ sp = context.getSharedPreferences(file_name, (int)mode);
}
SharedPreferences.Editor editor = sp.edit();
end
# C function to convert an nit Int to a NativeString (char*)
- private fun native_int_to_s(len: Int): NativeString is extern "native_int_to_s"
+ private fun native_int_to_s: NativeString is extern "native_int_to_s"
# return displayable int in base 10 and signed
#
# assert 1.to_s == "1"
# assert (-123).to_s == "-123"
redef fun to_s do
- var len = digit_count(10)
- return native_int_to_s(len).to_s_with_length(len)
+ return native_int_to_s.to_s
end
# return displayable int in hexadecimal
#include "string_nit.h"
// Integer to NativeString method
-char* native_int_to_s(int recv, int len){
- char* str = malloc(len + 1);
- sprintf(str, "%d", recv);
+char* native_int_to_s(long recv){
+ int len = snprintf(NULL, 0, "%ld", recv);
+ char* str = malloc(len);
+ sprintf(str, "%ld", recv);
return str;
}
* another product.
*/
-char* native_int_to_s(int recv, int len);
+char* native_int_to_s(long recv);
#endif
redef class AAttrPropdef
redef fun compile_to_c(v, mpropdef, arguments)
do
- if arguments.length == 1 then
- var res = v.read_attribute(self.mpropdef.mproperty, arguments.first)
+ if mpropdef == mreadpropdef then
+ assert arguments.length == 1
+ var res
+ if is_lazy then
+ var nexpr = n_expr
+ assert nexpr != null
+ var set
+ var ret = self.mpropdef.static_mtype
+ var useiset = ret.ctype == "val*" and not ret isa MNullableType
+ var guard = self.mlazypropdef.mproperty
+ if useiset then
+ set = v.isset_attribute(self.mpropdef.mproperty, arguments.first)
+ else
+ set = v.read_attribute(guard, arguments.first)
+ end
+ v.add("if(likely({set})) \{")
+ res = v.read_attribute(self.mpropdef.mproperty, arguments.first)
+ v.add("\} else \{")
+ var value = v.expr(nexpr, self.mpropdef.static_mtype)
+ v.write_attribute(self.mpropdef.mproperty, arguments.first, value)
+ v.assign(res, value)
+ if not useiset then
+ var true_v = v.new_expr("1", v.bool_type)
+ v.write_attribute(guard, arguments.first, true_v)
+ end
+ v.add("\}")
+ else
+ res = v.read_attribute(self.mpropdef.mproperty, arguments.first)
+ end
v.assign(v.frame.returnvar.as(not null), res)
- else
+ else if mpropdef == mwritepropdef then
+ assert arguments.length == 2
v.write_attribute(self.mpropdef.mproperty, arguments.first, arguments[1])
+ if is_lazy then
+ var ret = self.mpropdef.static_mtype
+ var useiset = ret.ctype == "val*" and not ret isa MNullableType
+ if not useiset then
+ v.write_attribute(self.mlazypropdef.mproperty, arguments.first, v.new_expr("1", v.bool_type))
+ end
+ end
+ else
+ abort
end
end
fun init_expr(v: AbstractCompilerVisitor, recv: RuntimeVariable)
do
var nexpr = self.n_expr
- if nexpr != null then
+ if nexpr != null and not is_lazy then
var oldnode = v.current_node
v.current_node = self
var old_frame = v.frame
replace('/', ".").replace('$', ".").replace(' ', "").replace('\n',"")
if mclass.name == "Bool" then return "boolean"
if mclass.name == "Char" then return "char"
- if mclass.name == "Int" then return "int"
+ if mclass.name == "Int" then return "long"
if mclass.name == "Float" then return "double"
return super
end
if ftype isa ForeignJavaType then return "jobject"
if mclass.name == "Bool" then return "jboolean"
if mclass.name == "Char" then return "jchar"
- if mclass.name == "Int" then return "jint"
+ if mclass.name == "Int" then return "jlong"
if mclass.name == "Float" then return "jdouble"
return super
end
end
if mclass.name == "Bool" then return "Z"
if mclass.name == "Char" then return "C"
- if mclass.name == "Int" then return "I"
+ if mclass.name == "Int" then return "J"
if mclass.name == "Float" then return "D"
return super
end
if ftype isa ForeignJavaType then return "Object"
if mclass.name == "Bool" then return "Boolean"
if mclass.name == "Char" then return "Char"
- if mclass.name == "Int" then return "Int"
+ if mclass.name == "Int" then return "Long"
if mclass.name == "Float" then return "Double"
return super
end
# Is the node tagged `noinit`?
var noinit = false
+ # Is the node taggeg lazy?
+ var is_lazy = false
+
+ # The guard associated to a lasy attribute.
+ # Because some engines does not have a working `isset`,
+ # this additionnal attribute is used to guard the lazy initialization.
+ # TODO: to remove once isset is correctly implemented
+ var mlazypropdef: nullable MAttributeDef
+
# The associated getter (read accessor) if any
var mreadpropdef: nullable MMethodDef writable
# The associated setter (write accessor) if any
var mwritepropdef: nullable MMethodDef writable
+
redef fun build_property(modelbuilder, mclassdef)
do
var mclass = mclassdef.mclass
modelbuilder.mpropdef2npropdef[mreadpropdef] = self
mreadpropdef.mdoc = mpropdef.mdoc
+ var atlazy = self.get_single_annotation("lazy", modelbuilder)
+ if atlazy != null then
+ if n_expr == null then
+ modelbuilder.error(atlazy, "Error: a lazy attribute needs a value")
+ end
+ is_lazy = true
+ var mlazyprop = new MAttribute(mclassdef, "lazy _" + name, none_visibility)
+ var mlazypropdef = new MAttributeDef(mclassdef, mlazyprop, self.location)
+ self.mlazypropdef = mlazypropdef
+ end
+
var atreadonly = self.get_single_annotation("readonly", modelbuilder)
if atreadonly != null then
if n_expr == null then
mreadpropdef.msignature = msignature
end
- var msritepropdef = self.mwritepropdef
+ var mwritepropdef = self.mwritepropdef
if mwritepropdef != null then
var name: String
if n_id != null then
var msignature = new MSignature([mparameter], null)
mwritepropdef.msignature = msignature
end
+
+ var mlazypropdef = self.mlazypropdef
+ if mlazypropdef != null then
+ mlazypropdef.static_mtype = modelbuilder.model.get_mclasses_by_name("Bool").first.mclass_type
+ end
end
redef fun check_signature(modelbuilder)
recv.attributes[mproperty] = value
end
+ # Is the attribute `mproperty` initialized the instance `recv`?
+ fun isset_attribute(mproperty: MAttribute, recv: Instance): Bool
+ do
+ assert recv isa MutableInstance
+ return recv.attributes.has_key(mproperty)
+ end
+
# Collect attributes of a type in the order of their init
fun collect_attr_propdef(mtype: MType): Array[AAttrPropdef]
do
var recv = args.first
assert recv isa MutableInstance
var attr = self.mpropdef.mproperty
- if args.length == 1 then
- return v.read_attribute(attr, recv)
- else
+ if mpropdef == mreadpropdef then
+ assert args.length == 1
+ if not is_lazy or v.isset_attribute(attr, recv) then return v.read_attribute(attr, recv)
+ return evaluate_expr(v, recv)
+ else if mpropdef == mwritepropdef then
assert args.length == 2
v.write_attribute(attr, recv, args[1])
return null
+ else
+ abort
end
end
# Evaluate and set the default value of the attribute in `recv`
private fun init_expr(v: NaiveInterpreter, recv: Instance)
do
- assert recv isa MutableInstance
+ if is_lazy then return
var nexpr = self.n_expr
if nexpr != null then
- var f = new Frame(self, self.mpropdef.as(not null), [recv])
- v.frames.unshift(f)
- var val = v.expr(nexpr)
- assert val != null
- v.frames.shift
- assert not v.is_escaping
- v.write_attribute(self.mpropdef.mproperty, recv, val)
+ evaluate_expr(v, recv)
return
end
var mtype = self.mpropdef.static_mtype.as(not null)
v.write_attribute(self.mpropdef.mproperty, recv, v.null_instance)
end
end
+
+ private fun evaluate_expr(v: NaiveInterpreter, recv: Instance): Instance
+ do
+ assert recv isa MutableInstance
+ var nexpr = self.n_expr
+ assert nexpr != null
+ var f = new Frame(self, self.mpropdef.as(not null), [recv])
+ v.frames.unshift(f)
+ var val = v.expr(nexpr)
+ assert val != null
+ v.frames.shift
+ assert not v.is_escaping
+ v.write_attribute(self.mpropdef.mproperty, recv, val)
+ return val
+ end
end
redef class AClassdef
if recv == null then return null
if recv.mtype isa MNullType then fatal(v, "Receiver is null")
var mproperty = self.mproperty.as(not null)
- assert recv isa MutableInstance
- return v.bool_instance(recv.attributes.has_key(mproperty))
+ return v.bool_instance(v.isset_attribute(mproperty, recv))
end
end
# Create a tool context to handle options and paths
var toolcontext = new ToolContext
-toolcontext.tooldescription = "Usage: nitmetrics [OPTION]... <file.nit>...\mComputes various metrics on Nit programs."
+toolcontext.tooldescription = "Usage: nitmetrics [OPTION]... <file.nit>...\nComputes various metrics on Nit programs."
# We do not add other options, so process them now!
toolcontext.process_options(args)
if name == "Bool" then return "int"
if name == "Char" then return "char"
if name == "Float" then return "double"
- if name == "Int" then return "int"
+ if name == "Int" then return "long"
if name == "NativeString" then return "char*"
if mclass.kind == extern_kind then
var ctype = mclass.ctype
if name == "Bool" then return "int"
if name == "Char" then return "char"
if name == "Float" then return "double"
- if name == "Int" then return "int"
+ if name == "Int" then return "long"
if name == "NativeString" then return "char*"
if mclass.kind == extern_kind then return "void*"
return "struct nitni_instance *"
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import kernel
+
+class Foo
+ var a1: Object = fa1 is lazy
+ var a2: Object = fa2 is lazy
+ fun fa1: Object do
+ 1.output
+ return 10
+ end
+ fun fa2: Object do
+ 2.output
+ return 20
+ end
+ #alt1#var a3: Object is lazy
+end
+
+var f = new Foo
+f.a1.output
+f.a1.output
+f.a2.output
+f.a2.output
+'\n'.output
+
+var g = new Foo
+g.a2.output
+g.a1.output
+g.a2.output
+g.a1.output
+'\n'.output
+
+var h = new Foo
+h.a1 = 100
+h.a1.output
+h.a1.output
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import kernel
+
+class Foo
+ var a1: Int = fa1 is lazy
+ var a2: Int = fa2 is lazy
+ fun fa1: Int do
+ 1.output
+ return 10
+ end
+ fun fa2: Int do
+ 2.output
+ return 20
+ end
+end
+
+var f = new Foo
+f.a1.output
+f.a1.output
+f.a2.output
+f.a2.output
+'\n'.output
+
+var g = new Foo
+g.a2.output
+g.a1.output
+g.a2.output
+g.a1.output
+'\n'.output
+
+var h = new Foo
+h.a1 = 100
+h.a1.output
+h.a1.output
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import kernel
+
+class Foo
+ var a1: nullable Object = fa1 is lazy
+ var a2: nullable Object = fa2 is lazy
+ fun fa1: nullable Object do
+ 1.output
+ return 10
+ end
+ fun fa2: nullable Object do
+ 2.output
+ return 20
+ end
+end
+
+fun o(o: nullable Object)
+do
+ if o == null then
+ 'n'.output
+ '\n'.output
+ else
+ o.output
+ end
+end
+
+var f = new Foo
+o f.a1
+o f.a1
+o f.a2
+o f.a2
+'\n'.output
+
+var g = new Foo
+o g.a2
+o g.a1
+o g.a2
+o g.a1
+'\n'.output
+
+var h = new Foo
+h.a1 = 100
+h.a1.output
+h.a1.output
--- /dev/null
+1
+10
+10
+2
+20
+20
+
+2
+20
+1
+10
+20
+10
+
+100
+100
--- /dev/null
+alt/base_attr_lazy_alt1.nit:28,20--23: Error: a lazy attribute needs a value
--- /dev/null
+1
+10
+10
+2
+20
+20
+
+2
+20
+1
+10
+20
+10
+
+100
+100
--- /dev/null
+1
+10
+10
+2
+20
+20
+
+2
+20
+1
+10
+20
+10
+
+100
+100
--- /dev/null
+Not executable (platform?)
-Usage: nitmetrics [OPTION]... <file.nit>...mComputes various metrics on Nit programs.
+Usage: nitmetrics [OPTION]... <file.nit>...
+Computes various metrics on Nit programs.
Use --help for help
redef fun output in "Java" `{
for (Object i: recv) {
- System.out.println((int)i);
+ System.out.println((long)i);
}
`}