Merge: nitunit: fix running last test of a module, it was previously ignored
authorJean Privat <jean@pryen.org>
Tue, 24 Feb 2015 03:59:32 +0000 (10:59 +0700)
committerJean Privat <jean@pryen.org>
Tue, 24 Feb 2015 03:59:32 +0000 (10:59 +0700)
This is a very small commit, but it may reveal some previously ignored nitunits.

Pull-Request: #1166
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>

19 files changed:
share/libgc/android-setup-libgc.sh
src/frontend/check_annotation.nit
src/model/model.nit
src/modelize/modelize_property.nit
src/platform/android.nit
tests/base_init_autoinit2.nit
tests/base_init_autoinit3.nit [new file with mode: 0644]
tests/base_init_noinit.nit
tests/sav/base_init_autoinit2_alt1.res
tests/sav/base_init_autoinit3.res [new file with mode: 0644]
tests/sav/base_init_autoinit3_alt1.res [new file with mode: 0644]
tests/sav/base_init_autoinit3_alt2.res [new file with mode: 0644]
tests/sav/base_init_autoinit3_alt4.res [new file with mode: 0644]
tests/sav/base_init_autoinit3_alt5.res [new file with mode: 0644]
tests/sav/base_init_autoinit3_alt6.res [new file with mode: 0644]
tests/sav/base_init_autoinit3_alt7.res [new file with mode: 0644]
tests/sav/base_init_autoinit3_alt8.res [new file with mode: 0644]
tests/sav/base_init_noinit_alt5.res
tests/sav/niti/base_init_autoinit3_alt1.res [new file with mode: 0644]

index 8e20ca0..ea04856 100755 (executable)
@@ -34,18 +34,6 @@ if test -z "$ANDROID_NDK"; then
        ANDROID_NDK=`dirname $ndk_build_path`
 fi
 
-# Get the first platform available (it shouldn't change much, but it may
-# have to be adjusted)
-for platform in `echo $ANDROID_NDK/platforms/android-*/arch-arm`; do
-       SYS_ROOT=$platform
-       break
-done
-
-if test -z "$SYS_ROOT"; then
-       echo "Error: could not an Android platform in the NDK, define ANDROID_NDK to the correct path."
-       exit 1
-fi
-
 # Information on the currently targeted libgc and libatomic_ops source URL
 # These may have to be updated according to server-side changes and newer
 # versions of the Boehm GC.
@@ -82,17 +70,42 @@ mv $libatomic_ops_dir $libgc_dir/libatomic_ops || exit 1
 
 cd $libgc_dir || exit 1
 
-# Configure for Android
-path="$ANDROID_NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/"
-export CC="$path/arm-linux-androideabi-gcc --sysroot=$SYS_ROOT"
-export CXX="$path/arm-linux-androideabi-g++ --sysroot=$SYS_ROOT"
-export LD="$path/arm-linux-androideabi-ld"
-export AR="$path/arm-linux-androideabi-ar"
-export RANLIB="$path/arm-linux-androideabi-ranlib"
-export STRIP="$path/arm-linux-androideabi-strip"
-export CFLAGS="-DIGNORE_DYNAMIC_LOADING -DPLATFORM_ANDROID -I libatomic_ops/src/"
-export LIBS="-lc -lgcc"
-./configure --host=arm-linux-androideabi --enable-static --disable-shared --prefix="$install" || exit 1
-
-# Compile and install locally
-make install -j 4 || exit 1
+archs=(         arm                       x86                mips)
+tools_dirs=(    arm-linux-androideabi-4.6 x86-4.6            mipsel-linux-android-4.6)
+tools_prefixes=(arm-linux-androideabi     i686-linux-android mipsel-linux-android)
+hosts=(         arm-linux-androideabi     x86-linux-android  mips-linux-android)
+
+n_archs=$(( ${#archs[@]} - 1 ))
+for i in $(eval echo "{0..$n_archs}"); do
+       arch=${archs[i]}
+       tools_dir=${tools_dirs[i]}
+       tools_prefix=${tools_prefixes[i]}
+       host=${hosts[i]}
+
+       # Get the first platform available (it shouldn't change much, but it may
+       # have to be adjusted)
+       for platform in `echo $ANDROID_NDK/platforms/android-*/arch-$arch`; do
+               sys_root=$platform
+               break
+       done
+
+       if test -z "$sys_root"; then
+               echo "Error: could not an Android platform for $arch in the NDK, define ANDROID_NDK to the correct path."
+               exit 1
+       fi
+
+       # Configure for Android
+       path="$ANDROID_NDK/toolchains/$tools_dir/prebuilt/linux-x86_64/bin/"
+       export CC="$path/$tools_prefix-gcc --sysroot=$sys_root"
+       export CXX="$path/$tools_prefix-g++ --sysroot=$sys_root"
+       export LD="$path/$tools_prefix-ld"
+       export AR="$path/$tools_prefix-ar"
+       export RANLIB="$path/$tools_prefix-ranlib"
+       export STRIP="$path/$tools_prefix-strip"
+       export CFLAGS="-DIGNORE_DYNAMIC_LOADING -DPLATFORM_ANDROID -I libatomic_ops/src/"
+       export LIBS="-lc -lgcc"
+       ./configure --host=$host --enable-static --disable-shared --prefix="$install/$arch/" || exit 1
+
+       # Compile and install locally
+       make install -j 4 || exit 1
+done
index a51bece..9408e95 100644 (file)
@@ -83,6 +83,7 @@ noinit
 readonly
 writable
 autoinit
+noautoinit
 cached
 nosuper
 old_style_init
index 00ca5cf..f0f4ff9 100644 (file)
@@ -1757,6 +1757,9 @@ abstract class MProperty
        # The visibility of the property
        var visibility: MVisibility
 
+       # Is the property usable as an initializer?
+       var is_autoinit = false is writable
+
        init
        do
                intro_mclassdef.intro_mproperties.add(self)
index 42dee1e..ba62b6e 100644 (file)
@@ -181,6 +181,7 @@ redef class ModelBuilder
                                        mparameters.add(mparameter)
                                end
                                initializers.add(npropdef.mpropdef.mproperty)
+                               npropdef.mpropdef.mproperty.is_autoinit = true
                        end
                        if npropdef isa AAttrPropdef then
                                if npropdef.mpropdef == null then return # Skip broken attribute
@@ -190,6 +191,7 @@ redef class ModelBuilder
                                        # For autoinit attributes, call the reader to force
                                        # the lazy initialization of the attribute.
                                        initializers.add(npropdef.mreadpropdef.mproperty)
+                                       npropdef.mreadpropdef.mproperty.is_autoinit = true
                                        continue
                                end
                                if npropdef.has_value then continue
@@ -202,9 +204,11 @@ redef class ModelBuilder
                                if msetter == null then
                                        # No setter, it is a old-style attribute, so just add it
                                        initializers.add(npropdef.mpropdef.mproperty)
+                                       npropdef.mpropdef.mproperty.is_autoinit = true
                                else
                                        # Add the setter to the list
                                        initializers.add(msetter.mproperty)
+                                       msetter.mproperty.is_autoinit = true
                                end
                        end
                end
@@ -218,39 +222,99 @@ redef class ModelBuilder
                        return
                end
 
-               # Search the longest-one and checks for conflict
-               var longest = spropdefs.first
-               if spropdefs.length > 1 then
-                       # Check for conflict in the order of initializers
-                       # Each initializer list must me a prefix of the longest list
-                       # part 1. find the longest list
-                       for spd in spropdefs do
-                               if spd.initializers.length > longest.initializers.length then longest = spd
+               # Look at the autoinit class-annotation
+               var autoinit = nclassdef.get_single_annotation("autoinit", self)
+               var noautoinit = nclassdef.get_single_annotation("noautoinit", self)
+               if autoinit != null then
+                       # Just throws the collected initializers
+                       mparameters.clear
+                       initializers.clear
+
+                       if noautoinit != null then
+                               error(autoinit, "Error: `autoinit` and `noautoinit` are incompatible.")
+                       end
+
+                       if autoinit.n_args.is_empty then
+                               error(autoinit, "Syntax error: `autoinit` expects method identifiers, use `noautoinit` to clear all autoinits.")
                        end
-                       # part 2. compare
-                       for spd in spropdefs do
-                               var i = 0
-                               for p in spd.initializers do
-                                       if p != longest.initializers[i] then
-                                               self.error(nclassdef, "Error: conflict for inherited inits {spd}({spd.initializers.join(", ")}) and {longest}({longest.initializers.join(", ")})")
-                                               return
+
+                       # Get and check each argument
+                       for narg in autoinit.n_args do
+                               var id = narg.as_id
+                               if id == null then
+                                       error(narg, "Syntax error: `autoinit` expects method identifiers.")
+                                       return
+                               end
+
+                               # Search the property.
+                               # To avoid bad surprises, try to get the setter first.
+                               var p = try_get_mproperty_by_name(narg, mclassdef, id + "=")
+                               if p == null then
+                                       p = try_get_mproperty_by_name(narg, mclassdef, id)
+                               end
+                               if p == null then
+                                       error(narg, "Error: unknown method `{id}`")
+                                       return
+                               end
+                               if not p.is_autoinit then
+                                       error(narg, "Error: `{p}` is not an autoinit method")
+                                       return
+                               end
+
+                               # Register the initializer and the parameters
+                               initializers.add(p)
+                               var pd = p.intro
+                               if pd isa MMethodDef then
+                                       # Get the signature resolved for the current receiver
+                                       var sig = pd.msignature.resolve_for(mclassdef.mclass.mclass_type, mclassdef.bound_mtype, mclassdef.mmodule, false)
+                                       mparameters.add_all sig.mparameters
+                               else
+                                       # TODO attributes?
+                                       abort
+                               end
+                       end
+               else if noautoinit != null then
+                       if initializers.is_empty then
+                               warning(noautoinit, "useless-noautoinit", "Warning: the list of autoinit is already empty.")
+                       end
+                       # Just clear initializers
+                       mparameters.clear
+                       initializers.clear
+               else
+                       # Search the longest-one and checks for conflict
+                       var longest = spropdefs.first
+                       if spropdefs.length > 1 then
+                               # Check for conflict in the order of initializers
+                               # Each initializer list must me a prefix of the longest list
+                               # part 1. find the longest list
+                               for spd in spropdefs do
+                                       if spd.initializers.length > longest.initializers.length then longest = spd
+                               end
+                               # part 2. compare
+                               for spd in spropdefs do
+                                       var i = 0
+                                       for p in spd.initializers do
+                                               if p != longest.initializers[i] then
+                                                       self.error(nclassdef, "Error: conflict for inherited inits {spd}({spd.initializers.join(", ")}) and {longest}({longest.initializers.join(", ")})")
+                                                       return
+                                               end
+                                               i += 1
                                        end
-                                       i += 1
                                end
                        end
-               end
 
-               # Can we just inherit?
-               if spropdefs.length == 1 and mparameters.is_empty and defined_init == null then
-                       self.toolcontext.info("{mclassdef} inherits the basic constructor {longest}", 3)
-                       mclassdef.mclass.root_init = longest
-                       return
-               end
+                       # Can we just inherit?
+                       if spropdefs.length == 1 and mparameters.is_empty and defined_init == null then
+                               self.toolcontext.info("{mclassdef} inherits the basic constructor {longest}", 3)
+                               mclassdef.mclass.root_init = longest
+                               return
+                       end
 
-               # Combine the inherited list to what is collected
-               if longest.initializers.length > 0 then
-                       mparameters.prepend longest.new_msignature.mparameters
-                       initializers.prepend longest.initializers
+                       # Combine the inherited list to what is collected
+                       if longest.initializers.length > 0 then
+                               mparameters.prepend longest.new_msignature.mparameters
+                               initializers.prepend longest.initializers
+                       end
                end
 
                # If we already have a basic init definition, then setup its initializers
@@ -928,10 +992,11 @@ redef class AAttrPropdef
                has_value = n_expr != null or n_block != null
 
                var atnoinit = self.get_single_annotation("noinit", modelbuilder)
+               if atnoinit == null then atnoinit = self.get_single_annotation("noautoinit", modelbuilder)
                if atnoinit != null then
                        noinit = true
                        if has_value then
-                               modelbuilder.error(atnoinit, "Error: `noinit` attributes cannot have an initial value")
+                               modelbuilder.error(atnoinit, "Error: `noautoinit` attributes cannot have an initial value")
                                return
                        end
                end
index f4b04a6..c04bd28 100644 (file)
@@ -140,11 +140,17 @@ class AndroidToolchain
                        end
                end
 
-               ## Generate delegating makefile
+               ## Generate Application.mk
                dir = "{android_project_root}/jni/"
                """
+APP_ABI := armeabi armeabi-v7a x86 mips
+APP_PLATFORM := android-{{{app_target_api}}}
+""".write_to_file "{dir}/Application.mk"
+
+               ## Generate delegating makefile
+               """
 include $(call all-subdir-makefiles)
-               """.write_to_file("{dir}/Android.mk")
+""".write_to_file "{dir}/Android.mk"
 
                # Gather ldflags for Android
                var ldflags = new Array[String]
@@ -165,7 +171,7 @@ LOCAL_CFLAGS        := -D ANDROID -D WITH_LIBGC
 LOCAL_MODULE    := main
 LOCAL_SRC_FILES := \\
 {{{cfiles.join(" \\\n")}}}
-LOCAL_LDLIBS    := {{{ldflags.join(" ")}}} libgc.a
+LOCAL_LDLIBS    := {{{ldflags.join(" ")}}} $(TARGET_ARCH)/libgc.a
 LOCAL_STATIC_LIBRARIES := android_native_app_glue png
 
 include $(BUILD_SHARED_LIBRARY)
@@ -236,13 +242,20 @@ $(call import-module,android/native_app_glue)
                end
 
                # Ensure that android-setup-libgc.sh has been executed
-               if not "{share_dir}/libgc/lib".file_exists then
+               if not "{share_dir}/libgc/arm/lib".file_exists then
                        toolcontext.exec_and_check(["{share_dir}/libgc/android-setup-libgc.sh"], "Android project error")
                end
 
                # Copy GC files
-               toolcontext.exec_and_check(["cp", "{share_dir}/libgc/lib/libgc.a", "{android_project_root}/libgc.a"], "Android project error")
-               toolcontext.exec_and_check(["ln", "-s", "{share_dir}/libgc/include/gc/", "{android_project_root}/jni/nit_compile/gc"], "Android project error")
+               for arch in ["arm", "x86", "mips"] do
+                       dir = android_project_root/arch
+                       dir.mkdir
+                       toolcontext.exec_and_check(["cp", "{share_dir}/libgc/{arch}/lib/libgc.a",
+                               dir/"libgc.a"], "Android project error")
+               end
+
+               toolcontext.exec_and_check(["ln", "-s", "{share_dir}/libgc/arm/include/gc/",
+                       "{android_project_root}/jni/nit_compile/gc"], "Android project error")
 
                ### Link to assets (for mnit and others)
                # This will be accessed from `android_project_root`
@@ -285,7 +298,7 @@ $(call import-module,android/native_app_glue)
 """<?xml version="1.0" encoding="utf-8"?>
 <resources>
     <string name="app_name">{{{app_name}}}</string>
-</resources>""".write_to_file "{dir}/res/values/strings.xml"
+</resources>""".write_to_file "{android_project_root}/res/values/strings.xml"
                end
 
                # Android libs folder
index afce0f9..5930588 100644 (file)
@@ -16,9 +16,9 @@ import kernel
 
 class A
        var a: Object = get(5) is lazy
-       var b: Object is noinit
-       #alt1#var b2: Object = get(-4) is noinit
-       var c: Object is noinit
+       var b: Object is noautoinit
+       #alt1#var b2: Object = get(-4) is noautoinit
+       var c: Object is noautoinit
        var d: Object = get(2) is autoinit
        #alt2#var d2: Object = get(-2) is autoinit, lazy
        var e: Object = get(1)
diff --git a/tests/base_init_autoinit3.nit b/tests/base_init_autoinit3.nit
new file mode 100644 (file)
index 0000000..37c2cb2
--- /dev/null
@@ -0,0 +1,67 @@
+# 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 A
+       var i: Int
+end
+
+class B
+       autoinit b, i #alt2# autoinit foo #alt4# autoinit fail
+       super A
+       var b: Bool #alt5# var b: Bool is noinit
+       fun foo do end
+end
+
+class C
+       super A
+       var f: Float
+end
+
+class D
+       autoinit i, b, f
+       super B
+       super C
+end
+
+class E
+       noautoinit #alt6#
+       #alt6,7# autoinit
+       super A
+       var a: A
+end
+
+class F
+       #alt8#noautoinit
+end
+
+var a = new A(1)
+a.i.output
+
+var b = new B(false, 2)
+b.i.output
+b.b.output
+
+var c = new C(3, 3.3)
+c.i.output
+c.f.output
+
+var d = new D(4, true, 4.4)
+d.i.output
+d.b.output
+d.f.output
+
+var e = new E
+#alt1# e.a.i.output
index 87de46e..f129d53 100644 (file)
@@ -15,8 +15,8 @@
 import kernel
 
 class A
-       var x: Object is noinit #alt1,3# var x: Object
-       var y: Object is noinit #alt2,3# var y: Object
+       var x: Object is noautoinit #alt1,3# var x: Object
+       var y: Object is noautoinit #alt2,3# var y: Object
        fun work
        do
                if isset _x then x.output
index 9c9fbe0..25528d8 100644 (file)
@@ -1 +1 @@
-alt/base_init_autoinit2_alt1.nit:20,30--35: Error: `noinit` attributes cannot have an initial value
+alt/base_init_autoinit2_alt1.nit:20,30--39: Error: `noautoinit` attributes cannot have an initial value
diff --git a/tests/sav/base_init_autoinit3.res b/tests/sav/base_init_autoinit3.res
new file mode 100644 (file)
index 0000000..6851c6d
--- /dev/null
@@ -0,0 +1,8 @@
+1
+2
+false
+3
+3.300000
+4
+true
+4.400000
diff --git a/tests/sav/base_init_autoinit3_alt1.res b/tests/sav/base_init_autoinit3_alt1.res
new file mode 100644 (file)
index 0000000..92263fd
--- /dev/null
@@ -0,0 +1,9 @@
+Runtime error: Uninitialized attribute _a (alt/base_init_autoinit3_alt1.nit:43)
+1
+2
+false
+3
+3.300000
+4
+true
+4.400000
diff --git a/tests/sav/base_init_autoinit3_alt2.res b/tests/sav/base_init_autoinit3_alt2.res
new file mode 100644 (file)
index 0000000..cd95aed
--- /dev/null
@@ -0,0 +1 @@
+alt/base_init_autoinit3_alt2.nit:22,11--13: Error: `foo` is not an autoinit method
diff --git a/tests/sav/base_init_autoinit3_alt4.res b/tests/sav/base_init_autoinit3_alt4.res
new file mode 100644 (file)
index 0000000..269b2fd
--- /dev/null
@@ -0,0 +1 @@
+alt/base_init_autoinit3_alt4.nit:22,11--14: Error: unknown method `fail`
diff --git a/tests/sav/base_init_autoinit3_alt5.res b/tests/sav/base_init_autoinit3_alt5.res
new file mode 100644 (file)
index 0000000..67f272a
--- /dev/null
@@ -0,0 +1,2 @@
+alt/base_init_autoinit3_alt5.nit:22,11: Error: `b=` is not an autoinit method
+alt/base_init_autoinit3_alt5.nit:34,14: Error: `b=` is not an autoinit method
diff --git a/tests/sav/base_init_autoinit3_alt6.res b/tests/sav/base_init_autoinit3_alt6.res
new file mode 100644 (file)
index 0000000..e95f861
--- /dev/null
@@ -0,0 +1 @@
+alt/base_init_autoinit3_alt6.nit:40,2--41,9: Syntax error: `autoinit` expects method identifiers, use `noautoinit` to clear all autoinits.
diff --git a/tests/sav/base_init_autoinit3_alt7.res b/tests/sav/base_init_autoinit3_alt7.res
new file mode 100644 (file)
index 0000000..9fb22d1
--- /dev/null
@@ -0,0 +1,2 @@
+alt/base_init_autoinit3_alt7.nit:41,2--9: Error: `autoinit` and `noautoinit` are incompatible.
+alt/base_init_autoinit3_alt7.nit:41,2--9: Syntax error: `autoinit` expects method identifiers, use `noautoinit` to clear all autoinits.
diff --git a/tests/sav/base_init_autoinit3_alt8.res b/tests/sav/base_init_autoinit3_alt8.res
new file mode 100644 (file)
index 0000000..f88f100
--- /dev/null
@@ -0,0 +1,9 @@
+alt/base_init_autoinit3_alt8.nit:47,2--11: Warning: the list of autoinit is already empty.
+1
+2
+false
+3
+3.300000
+4
+true
+4.400000
index b79ac75..1f0479d 100644 (file)
@@ -1 +1 @@
-alt/base_init_noinit_alt5.nit:26,23--28: Error: `noinit` attributes cannot have an initial value
+alt/base_init_noinit_alt5.nit:26,23--28: Error: `noautoinit` attributes cannot have an initial value
diff --git a/tests/sav/niti/base_init_autoinit3_alt1.res b/tests/sav/niti/base_init_autoinit3_alt1.res
new file mode 100644 (file)
index 0000000..70e53f3
--- /dev/null
@@ -0,0 +1,9 @@
+Runtime error: Uninitialized attribute _a (alt/base_init_autoinit3_alt1.nit:67)
+1
+2
+false
+3
+3.300000
+4
+true
+4.400000