Merge: nitmetrics: fix typo in usage text
authorJean Privat <jean@pryen.org>
Tue, 22 Jul 2014 19:49:14 +0000 (15:49 -0400)
committerJean Privat <jean@pryen.org>
Tue, 22 Jul 2014 19:49:14 +0000 (15:49 -0400)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

Pull-Request: #607
Reviewed-by: Jean Privat <jean@pryen.org>

21 files changed:
lib/android/assets_and_resources.nit
lib/android/audio.nit
lib/android/bundle/bundle.nit
lib/android/java_io.nit
lib/android/shared_preferences/shared_preferences_api10.nit
lib/standard/string.nit
lib/standard/string_nit.c
lib/standard/string_nit.h
src/abstract_compiler.nit
src/common_ffi/java.nit
src/modelize_property.nit
src/naive_interpreter.nit
src/nitni/nitni_base.nit
tests/base_attr_lazy.nit [new file with mode: 0644]
tests/base_attr_lazy_int.nit [new file with mode: 0644]
tests/base_attr_lazy_nullable.nit [new file with mode: 0644]
tests/sav/base_attr_lazy.res [new file with mode: 0644]
tests/sav/base_attr_lazy_alt1.res [new file with mode: 0644]
tests/sav/base_attr_lazy_int.res [new file with mode: 0644]
tests/sav/base_attr_lazy_nullable.res [new file with mode: 0644]
tests/test_ffi_java_types.nit

index ef78d72..d654641 100644 (file)
@@ -175,17 +175,17 @@ extern class NativeResources in "Java" `{ android.content.res.Resources `}
        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
@@ -284,7 +284,7 @@ extern class NativeBitmap in "Java" `{ android.graphics.Bitmap `}
 
        # 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
index b46a660..7a19756 100644 (file)
@@ -41,7 +41,7 @@ extern class NativeAudioManager in "Java" `{ android.media.AudioManager `}
        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(); `}
@@ -74,7 +74,7 @@ extern class NativeMediaPlayer in "Java" `{ android.media.MediaPlayer `}
                }
        `}
 
-       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(); `}
@@ -84,7 +84,7 @@ extern class NativeMediaPlayer in "Java" `{ android.media.MediaPlayer `}
        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);
@@ -110,24 +110,24 @@ extern class NativeSoundPool in "Java" `{ android.media.SoundPool `}
        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
 
 
index b8b8390..7a84d4b 100644 (file)
@@ -85,7 +85,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        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));
@@ -94,7 +94,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        `}
        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));
@@ -104,7 +104,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        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));
@@ -113,7 +113,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        `}
        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);
@@ -122,7 +122,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        `}
        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);
@@ -131,7 +131,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        `}
        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);
@@ -140,7 +140,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        `}
        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);
@@ -149,7 +149,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        `}
        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);
@@ -158,7 +158,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        `}
        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);
@@ -167,7 +167,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        `}
        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);
@@ -176,7 +176,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        `}
        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);
@@ -185,7 +185,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        `}
        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);
@@ -194,7 +194,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        `}
        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);
@@ -222,13 +222,11 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
        `}
        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); 
@@ -305,7 +303,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
                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;
        `}
@@ -317,7 +315,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
                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;
        `}
@@ -354,7 +352,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `}
                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;
        `}
index 7b67cb3..bcd70dc 100644 (file)
@@ -128,7 +128,7 @@ extern class NativeFileOutputStream in "Java" `{ java.io.FileOutputStream `}
        `}
        fun write(one_byte: Int) in "Java" `{
                try {
-                       recv.write(one_byte);
+                       recv.write((byte)one_byte);
                }catch(IOException e){
                        e.printStackTrace();
                }
index 577d0d2..81ababc 100644 (file)
@@ -75,14 +75,13 @@ extern class NativeSharedPreferences in "Java" `{ android.content.SharedPreferen
        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 {
@@ -118,7 +117,7 @@ extern class NativeSharedPreferencesEditor in "Java" `{ android.content.SharedPr
                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); 
@@ -169,9 +168,9 @@ class SharedPreferences
 
                // 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();
index 74ec7a2..9dbb38c 100644 (file)
@@ -1524,15 +1524,14 @@ redef class Int
        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
index 15979dc..0159249 100644 (file)
@@ -12,8 +12,9 @@
 #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;
 }
index a6cf69a..311041d 100644 (file)
@@ -13,6 +13,6 @@
  * another product.
  */
 
-char* native_int_to_s(int recv, int len);
+char* native_int_to_s(long recv);
 
 #endif
index 8015a5a..fb376ac 100644 (file)
@@ -2121,18 +2121,55 @@ end
 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
index 2e499d3..eefb5c6 100644 (file)
@@ -468,7 +468,7 @@ redef class MClassType
                        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
@@ -479,7 +479,7 @@ redef class MClassType
                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
@@ -510,7 +510,7 @@ redef class MClassType
                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
@@ -521,7 +521,7 @@ redef class MClassType
                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
index 96ec598..fb21a65 100644 (file)
@@ -645,10 +645,20 @@ redef class AAttrPropdef
        # 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
@@ -718,6 +728,17 @@ redef class AAttrPropdef
                        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
@@ -840,7 +861,7 @@ redef class AAttrPropdef
                        mreadpropdef.msignature = msignature
                end
 
-               var msritepropdef = self.mwritepropdef
+               var mwritepropdef = self.mwritepropdef
                if mwritepropdef != null then
                        var name: String
                        if n_id != null then
@@ -852,6 +873,11 @@ redef class AAttrPropdef
                        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)
index ba2fb39..138c7e2 100644 (file)
@@ -441,6 +441,13 @@ private class NaiveInterpreter
                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
@@ -982,28 +989,26 @@ redef class AAttrPropdef
                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)
@@ -1012,6 +1017,21 @@ redef class AAttrPropdef
                        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
@@ -1669,8 +1689,7 @@ redef class AIssetAttrExpr
                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
 
index dd2fe10..cc0ffa2 100644 (file)
@@ -90,7 +90,7 @@ redef class MClassType
                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
@@ -105,7 +105,7 @@ redef class MClassType
                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 *"
diff --git a/tests/base_attr_lazy.nit b/tests/base_attr_lazy.nit
new file mode 100644 (file)
index 0000000..d271411
--- /dev/null
@@ -0,0 +1,48 @@
+# 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
diff --git a/tests/base_attr_lazy_int.nit b/tests/base_attr_lazy_int.nit
new file mode 100644 (file)
index 0000000..5197740
--- /dev/null
@@ -0,0 +1,47 @@
+# 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
diff --git a/tests/base_attr_lazy_nullable.nit b/tests/base_attr_lazy_nullable.nit
new file mode 100644 (file)
index 0000000..ba3b404
--- /dev/null
@@ -0,0 +1,57 @@
+# 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
diff --git a/tests/sav/base_attr_lazy.res b/tests/sav/base_attr_lazy.res
new file mode 100644 (file)
index 0000000..540f9b8
--- /dev/null
@@ -0,0 +1,16 @@
+1
+10
+10
+2
+20
+20
+
+2
+20
+1
+10
+20
+10
+
+100
+100
diff --git a/tests/sav/base_attr_lazy_alt1.res b/tests/sav/base_attr_lazy_alt1.res
new file mode 100644 (file)
index 0000000..d628b21
--- /dev/null
@@ -0,0 +1 @@
+alt/base_attr_lazy_alt1.nit:28,20--23: Error: a lazy attribute needs a value
diff --git a/tests/sav/base_attr_lazy_int.res b/tests/sav/base_attr_lazy_int.res
new file mode 100644 (file)
index 0000000..540f9b8
--- /dev/null
@@ -0,0 +1,16 @@
+1
+10
+10
+2
+20
+20
+
+2
+20
+1
+10
+20
+10
+
+100
+100
diff --git a/tests/sav/base_attr_lazy_nullable.res b/tests/sav/base_attr_lazy_nullable.res
new file mode 100644 (file)
index 0000000..540f9b8
--- /dev/null
@@ -0,0 +1,16 @@
+1
+10
+10
+2
+20
+20
+
+2
+20
+1
+10
+20
+10
+
+100
+100
index a7c057c..642abeb 100644 (file)
@@ -31,7 +31,7 @@ extern class JavaArrayList in "Java" `{ java.util.ArrayList `}
 
        redef fun output in "Java" `{
                for (Object i: recv) {
-                       System.out.println((int)i);
+                       System.out.println((long)i);
                }
        `}