Merge: Markdown Extended
authorJean Privat <jean@pryen.org>
Tue, 25 Nov 2014 01:04:59 +0000 (20:04 -0500)
committerJean Privat <jean@pryen.org>
Tue, 25 Nov 2014 01:04:59 +0000 (20:04 -0500)
Added extrended mode to the markdown parser.

Features:
* fences and meta
* super span
* strike span

Pull-Request: #784
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>

40 files changed:
lib/android/assets_and_resources.nit
lib/android/audio.nit
lib/android/bundle/bundle.nit
lib/android/intent/intent_api10.nit
lib/android/platform.nit
lib/android/shared_preferences/shared_preferences_api10.nit
lib/android/vibration.nit
lib/app/data_store.nit
lib/c.nit
lib/java/io.nit
lib/java/java.nit
lib/mnit_android/android_app.nit
lib/pthreads/extra.nit [new file with mode: 0644]
lib/pthreads/pthreads.nit
lib/standard/kernel.nit
lib/standard/math.nit
lib/trees/abstract_tree.nit
lib/trees/bintree.nit
lib/trees/rbtree.nit
src/compiler/android_annotations.nit
src/compiler/android_platform.nit
src/interpreter/naive_interpreter.nit
src/modelize/modelize_property.nit
tests/base_self_type.nit [new file with mode: 0644]
tests/sav/base_self_type.res [new file with mode: 0644]
tests/sav/base_self_type_alt1.res [new file with mode: 0644]
tests/sav/base_self_type_alt2.res [new file with mode: 0644]
tests/sav/base_self_type_alt3.res [new file with mode: 0644]
tests/sav/error_class_glob.res
tests/sav/nitg-e/base_self_type.res [new file with mode: 0644]
tests/sav/nitg-e/base_self_type_alt2.res [new file with mode: 0644]
tests/sav/nitg-e/fixme/base_gen_reassign_alt4.res
tests/sav/nitg-e/fixme/base_gen_reassign_alt5.res
tests/sav/nitg-e/fixme/base_gen_reassign_alt6.res
tests/sav/nituml_args3.res
tests/sav/nituml_args4.res
tests/sav/test_c_alt1.res
tests/sav/test_c_alt2.res
tests/sav/test_c_alt3.res
tests/sav/test_c_alt4.res

index 9470dd8..82ae3d1 100644 (file)
@@ -46,7 +46,6 @@ in "Java" `{
 # This is a low-level class, use `AssetManager` instead
 extern class NativeAssetManager in "Java" `{ android.content.res.AssetManager `}
        super JavaObject
-       redef type SELF: NativeAssetManager
 
        fun close in "Java" `{ recv.close(); `}
 
@@ -172,7 +171,6 @@ end
 # This is a low-level class, use `ResourcesManager` instead
 extern class NativeResources in "Java" `{ android.content.res.Resources `}
        super JavaObject
-       redef type SELF: NativeResources
 
        fun get_assets:NativeAssetManager in "Java" `{ return recv.getAssets(); `}
        fun get_color(id: Int): Int in "Java" `{ return recv.getColor((int)id); `}
@@ -283,7 +281,6 @@ end
 # An android Bitmap, get an instance using the AssetManager or the ResourceManager
 extern class NativeBitmap in "Java" `{ android.graphics.Bitmap `}
        super JavaObject
-       redef type SELF: NativeBitmap
 
        # Create a NativeBitmap from a NativeInputStream retrieved with `open` function of the AssetManager
        # Called by the AssetManager
@@ -299,7 +296,6 @@ end
 # Android AssetFileDescriptor, can be retrieve by AssetManager and used to load a sound in a SoundPool
 extern class NativeAssetFileDescriptor in "Java" `{ android.content.res.AssetFileDescriptor `}
        super JavaObject
-       redef type SELF: NativeAssetFileDescriptor
 
        fun close in "Java" `{
                try {
index e640621..366c7d4 100644 (file)
@@ -38,7 +38,6 @@ in "Java" `{
 # AudioManager of the application, used to manage the audio mode
 extern class NativeAudioManager in "Java" `{ android.media.AudioManager `}
        super JavaObject
-       redef type SELF: NativeAudioManager
 
        fun mode: Int in "Java" `{ return recv.getMode(); `}
        fun mode=(i: Int) in "Java" `{ recv.setMode((int)i); `}
@@ -61,7 +60,6 @@ end
 # This is a low-level class, use `MediaPlater` instead
 extern class NativeMediaPlayer in "Java" `{ android.media.MediaPlayer `}
        super JavaObject
-       redef type SELF: NativeMediaPlayer
 
        new in "Java" `{ return new MediaPlayer(); `}
        fun start in "Java" `{ recv.start(); `}
@@ -108,7 +106,6 @@ end
 # This is a low-level class, use `SoundPool`instead
 extern class NativeSoundPool in "Java" `{ android.media.SoundPool `}
        super JavaObject
-       redef type SELF: NativeSoundPool
 
        new(max_streams, stream_type, src_quality: Int) in "Java" `{
                return new SoundPool((int)max_streams, (int)stream_type, (int)src_quality);
index 9528e05..5a083d2 100644 (file)
@@ -31,7 +31,6 @@ in "Java" `{
 
 extern class NativeBundle in "Java" `{ android.os.Bundle `}
        super JavaObject
-       redef type SELF: NativeBundle
 
        fun clone: JavaObject in "Java" `{ return recv.clone(); `}
        fun size: Int in "Java" `{ return recv.size(); `}
index d07a817..20c85dc 100644 (file)
@@ -33,7 +33,6 @@ in "Java" `{
 
 extern class NativeIntent in "Java" `{ android.content.Intent `}
        super JavaObject
-       redef type SELF: NativeIntent
 
        fun add_category(category: JavaString) in "Java" `{ recv.addCategory(category); `}
        fun add_flags(flags: Int) in "Java" `{ recv.addFlags((int)flags); `}
index dab001d..fca03e0 100644 (file)
@@ -21,6 +21,8 @@ module platform is
        new_annotation max_api_version
        new_annotation target_api_version
        new_annotation android_manifest
+       new_annotation android_manifest_application
+       new_annotation android_manifest_activity
 end
 
 import java
index 8635f86..404aaea 100644 (file)
@@ -33,7 +33,6 @@ in "Java" `{
 
 extern class NativeSharedPreferences in "Java" `{ android.content.SharedPreferences `}
        super JavaObject
-       redef type SELF: NativeSharedPreferences
        
        fun contains(key: JavaString): Bool in "Java" `{ return recv.contains(key); `}
        fun get_all: HashMap[JavaString, JavaObject] import HashMap[JavaString, JavaObject],
@@ -113,7 +112,6 @@ end
 
 extern class NativeSharedPreferencesEditor in "Java" `{ android.content.SharedPreferences$Editor `}
        super JavaObject
-       redef type SELF: NativeSharedPreferencesEditor
 
        fun clear: NativeSharedPreferencesEditor in "Java" `{ return recv.clear(); `}
        fun commit: Bool in "Java" `{ return recv.commit(); `}
index 6226285..f56dbef 100644 (file)
@@ -26,7 +26,6 @@ import native_app_glue
 # Handle to an Android vibrator
 extern class Vibrator in "Java" `{ android.os.Vibrator `}
        super JavaObject
-       redef type SELF: Vibrator
 
        # Vibrate for `n` miliseconds
        fun vibrate(n: Int) in "Java" `{ recv.vibrate(n); `}
index afb6a1d..13891fc 100644 (file)
@@ -34,5 +34,5 @@ interface DataStore
        fun [](key: String): nullable Object is abstract
 
        # Store `value` at `key`
-       fun []=(key: String, value: Serializable) is abstract
+       fun []=(key: String, value: nullable Serializable) is abstract
 end
index fdc7e99..6c843f3 100644 (file)
--- a/lib/c.nit
+++ b/lib/c.nit
@@ -29,7 +29,6 @@ end
 # A native C array, as in a pointer to the first element of the array
 extern class NativeCArray `{ void * `}
        type E: nullable Object
-       type SELF: NativeCArray
 
        fun [](index: E): E is abstract
        fun []=(index: E, val: E) is abstract
@@ -79,7 +78,6 @@ end
 extern class NativeCIntArray `{ int* `}
        super NativeCArray
        redef type E: Int
-       redef type SELF: NativeCIntArray
 
        new(size: Int) `{ return calloc(size, sizeof(int)); `}
        redef fun [](index) `{ return recv[index]; `}
@@ -91,7 +89,6 @@ end
 redef class NativeString
        super NativeCArray
        redef type E: Char
-       redef type SELF: NativeString
 
        redef fun +(offset) `{ return recv + offset; `}
 end
index 04245a5..4ab4eab 100644 (file)
@@ -32,7 +32,6 @@ in "Java" `{
 
 extern class NativeFile in "Java" `{ java.io.File `}
        super JavaObject
-       redef type SELF: NativeFile
 
        fun can_execute: Bool in "Java" `{ return recv.canExecute(); `}
        fun can_read: Bool in "Java" `{ return recv.canRead(); `}
@@ -77,7 +76,6 @@ end
 
 extern class NativeFileInputStream in "Java" `{ java.io.FileInputStream `}
        super JavaObject
-       redef type SELF: NativeFileInputStream
 
        fun available: Int in "Java" `{
                try {
@@ -114,7 +112,6 @@ end
 
 extern class NativeFileOutputStream in "Java" `{ java.io.FileOutputStream `}
        super JavaObject
-       redef type SELF: NativeFileOutputStream
 
        fun close in "Java" `{
                try {
@@ -141,7 +138,7 @@ end
 
 extern class NativeFileDescriptor in "Java" `{ java.io.FileDescriptor `}
        super JavaObject
-       redef type SELF: NativeFileDescriptor
+
        fun sync in "Java" `{
                try{
                        recv.sync();
@@ -154,7 +151,6 @@ end
 
 extern class NativeInputStream in "Java" `{ java.io.InputStream `}
        super JavaObject
-       redef type SELF: NativeInputStream
 
        fun available: Int in "Java" `{
                try {
index 0b6a652..c3db430 100644 (file)
@@ -98,8 +98,6 @@ end
 extern class JavaString in "Java" `{ java.lang.String `}
        super JavaObject
 
-       redef type SELF: JavaString
-
        # Get the string from Java and copy it to Nit memory
        fun to_cstring: NativeString import sys, Sys.jni_env `{
                Sys sys = JavaString_sys(recv);
@@ -140,7 +138,6 @@ redef class Text
 end
 
 redef extern class JavaObject
-       type SELF: JavaObject
 
        # Returns a global reference to the Java object behind this reference
        #
index 725c612..87afb4a 100644 (file)
 # limitations under the License.
 
 # Impements the services of `mnit:app` using the API from the Android ndk
-module android_app
+module android_app is
+       android_manifest_activity """
+               android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+               android:configChanges="orientation|keyboardHidden"
+               android:screenOrientation="portrait""""
+end
 
 import mnit
 import android
diff --git a/lib/pthreads/extra.nit b/lib/pthreads/extra.nit
new file mode 100644 (file)
index 0000000..416b174
--- /dev/null
@@ -0,0 +1,62 @@
+# This file is part of NIT (http://www.nitlanguage.org).
+#
+# Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
+#
+# 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.
+
+# Offers some POSIX threads services that are not available on all platforms
+module extra is
+       c_compiler_option("-pthread")
+       c_linker_option("-pthread")
+end
+
+intrude import pthreads
+
+in "C" `{
+       // TODO protect with: #ifdef WITH_LIBGC
+       #ifndef ANDROID
+               #define GC_THREADS
+               #include <gc.h>
+       #endif
+`}
+
+redef extern class NativePthread
+       fun cancel: Bool `{
+               return pthread_cancel(*recv);
+       `}
+end
+
+redef class Thread
+       # Cancel the execution of the thread
+       fun cancel
+       do
+               if native == null then return
+               native.cancel
+               native = null
+       end
+end
+
+# Does not return if the running thread is to be cancelled
+fun test_cancel `{ pthread_testcancel(); `}
+
+private extern class NativePthreadBarrier in "C" `{ pthread_barrier_t * `}
+       new(count: Int) `{
+               pthread_barrier_t *barrier = malloc(sizeof(pthread_barrier_t));
+               int res = pthread_barrier_init(barrier, NULL, count);
+               return barrier;
+       `}
+
+       fun destroy `{ pthread_barrier_destroy(recv); `}
+
+       fun wait `{ pthread_barrier_wait(recv); `}
+end
index 1e76e28..94cf078 100644 (file)
@@ -34,9 +34,10 @@ in "C" `{
        // TODO protect with: #ifdef WITH_LIBGC
        // We might have to add the next line to gc_chooser.c too, especially
        // if we get an error like "thread not registered with GC".
+       #ifndef ANDROID
                #define GC_THREADS
                #include <gc.h>
-       //#endif
+       #endif
 `}
 
 redef class Sys
@@ -114,10 +115,6 @@ private extern class NativePthread in "C" `{ pthread_t * `}
                return (nullable_Object)thread_return;
        `}
 
-       fun cancel: Bool `{
-               return pthread_cancel(*recv);
-       `}
-
        fun attr: NativePthreadAttr `{
                pthread_attr_t *pattr = malloc(sizeof(pthread_attr_t));
                pthread_getattr_np(*recv, pattr);
@@ -192,18 +189,6 @@ private extern class NativePthreadMutexAttr in "C" `{ pthread_mutexattr_t * `}
        # pthread_mutexattr_setrobust_np
 end
 
-private extern class NativePthreadBarrier in "C" `{ pthread_barrier_t * `}
-       new(count: Int) `{
-               pthread_barrier_t *barrier = malloc(sizeof(pthread_barrier_t));
-               int res = pthread_barrier_init(barrier, NULL, count);
-               return barrier;
-       `}
-
-       fun destroy `{ pthread_barrier_destroy(recv); `}
-
-       fun wait `{ pthread_barrier_wait(recv); `}
-end
-
 private extern class NativePthreadKey in "C" `{ pthread_key_t * `}
        new `{
                pthread_key_t *key = malloc(sizeof(pthread_key_t));
@@ -222,6 +207,27 @@ private extern class NativePthreadKey in "C" `{ pthread_key_t * `}
        `}
 end
 
+private extern class NativePthreadCond in "C" `{ pthread_cond_t * `}
+       new `{
+               pthread_cond_t cond;
+               int r = pthread_cond_init(&cond, NULL);
+               if (r == 0) {
+                       pthread_cond_t *pcond = malloc(sizeof(pthread_cond_t));
+                       memmove(pcond, &cond, sizeof(pthread_cond_t));
+                       return pcond;
+               }
+               return NULL;
+       `}
+
+       fun destroy `{ pthread_cond_destroy(recv); `}
+
+       fun signal `{ pthread_cond_signal(recv); `}
+
+       fun broadcast `{ pthread_cond_broadcast(recv);  `}
+
+       fun wait(mutex: NativePthreadMutex) `{ pthread_cond_wait(recv, mutex); `}
+end
+
 #
 ## Nity part
 #
@@ -272,14 +278,6 @@ abstract class Thread
                return r
        end
 
-       # Cancel the execution of the thread
-       fun cancel
-       do
-               if native == null then return
-               native.cancel
-               native = null
-       end
-
        redef fun finalize
        do
                if native == null then return
@@ -298,9 +296,6 @@ end
 # Exit current thread and return `value` to caller of `Thread::join`
 fun exit_thread(value: nullable Object) `{ pthread_exit(value); `}
 
-# Does not return if the running thread is to be cancelled
-fun test_cancel `{ pthread_testcancel(); `}
-
 # Returns the handle to the running `Thread`
 fun thread: Thread
 do
@@ -364,24 +359,36 @@ end
 class Barrier
        super Finalizable
 
+       private var mutex = new Mutex
+       private var cond: nullable NativePthreadCond = new NativePthreadCond
+
        # Number of threads that must be waiting for `wait` to unblock
        var count: Int
 
-       private var native: nullable NativePthreadBarrier is noinit
-
-       init do native = new NativePthreadBarrier(count)
+       private var threads_waiting = 0
 
        # Wait at this barrier and block until there are a `count` threads waiting
-       fun wait do native.wait
+       fun wait
+       do
+               mutex.lock
+               threads_waiting += 1
+               if threads_waiting == count then
+                       threads_waiting = 0
+                       cond.broadcast
+               else
+                       cond.wait(mutex.native.as(not null))
+               end
+               mutex.unlock
+       end
 
        redef fun finalize
        do
-               var native = self.native
-               if native != null then
-                       native.destroy
-                       native.free
+               var cond = self.cond
+               if cond != null then
+                       cond.destroy
+                       cond.free
                end
-               self.native = null
+               self.cond = null
        end
 end
 
index 2e9c9ae..a179e9a 100644 (file)
@@ -30,6 +30,28 @@ import end # Mark this module is a top level one. (must be only one)
 #
 # Currently, Object is also used to collect all top-level methods.
 interface Object
+       # Type of this instance, automatically specialized in every class
+       #
+       # A common use case of the virtual type `SELF` is to type an attribute and
+       # store another instance of the same type as `self`. It can also be used as as
+       # return type to a method producing a copy of `self` or returning an instance
+       # expected to be the exact same type as self.
+       #
+       # This virtual type must be used with caution as it can hinder specialization.
+       # In fact, it imposes strict restrictions on all sub-classes and their usage.
+       # For example, using `SELF` as a return type of a method `foo`
+       # forces all subclasses to ensure that `foo` returns the correct and updated
+       # type.
+       # A dangerous usage take the form of a method typed by `SELF` which creates
+       # and returns a new instance.
+       # If not correctly specialized, this method would break when invoked on a
+       # sub-class.
+       #
+       # A general rule for safe usage of `SELF` is to ensure that inputs typed
+       # `SELF` are stored in attributes typed `SELF` and returned by methods typed
+       # `SELF`, pretty much the same things as you would do with parameter types.
+       type SELF: Object
+
        # The unique object identifier in the class.
        # Unless specific code, you should not use this method.
        # The identifier is used internally to provide a hash value.
@@ -331,6 +353,21 @@ universal Float
                end
        end
 
+       # Compare float numbers with a given precision.
+       #
+       # Because of the loss of precision in floating numbers,
+       # the `==` method is often not the best way to compare them.
+       #
+       # ~~~
+       # assert 0.01.is_approx(0.02, 0.1)   == true
+       # assert 0.01.is_approx(0.02, 0.001) == false
+       # ~~~
+       fun is_approx(other, precision: Float): Bool
+       do
+               assert precision >= 0.0
+               return self <= other + precision and self >= other - precision
+       end
+
        redef fun max(other)
        do
                if self < other then
index 2bbb6aa..6214a65 100644 (file)
@@ -138,6 +138,14 @@ redef class Float
        #     assert 2.0.floor == 2.0
        #     assert (-1.5).floor == -2.0
        fun floor: Float `{ return floor(recv); `}
+
+       # Rounds the value of a float to its nearest integer value
+       #
+       #     assert 1.67.round == 2.0
+       #     assert 1.34.round == 1.0
+       #     assert -1.34.round == -1.0
+       #     assert -1.67.round == -2.0
+       fun round: Float is extern "round"
        
        # Returns a random `Float` in `[0.0 .. self[`.
        fun rand: Float is extern "kernel_Float_Float_rand_0"
index d05663e..6626036 100644 (file)
@@ -42,7 +42,7 @@ end
 class TreeNode[K: Comparable, E]
 
        # TreeNode type
-       type SELF: TreeNode[K, E]
+       type N: TreeNode[K, E]
 
        # `key` for this node
        var key: K
@@ -51,7 +51,7 @@ class TreeNode[K: Comparable, E]
        var value: E
 
        # Direct parent of this node (null if the node is root)
-       var parent: nullable SELF = null is writable
+       var parent: nullable N = null is writable
 
        redef fun to_s do return "\{{value or else ""}\}"
 
index b689700..4c647b3 100644 (file)
@@ -370,38 +370,38 @@ class BinTreeNode[K: Comparable, E]
        private var prev: nullable BinTreeNode[K, E]
        private var next: nullable BinTreeNode[K, E]
 
-       redef type SELF: BinTreeNode[K, E]
+       redef type N: BinTreeNode[K, E]
 
        init(key: K, item: E) do
                super(key, item)
        end
 
-       private var left_node: nullable SELF = null
+       private var left_node: nullable N = null
 
        # `left` tree node child (null if node has no left child)
-       fun left: nullable SELF do return left_node
+       fun left: nullable N do return left_node
 
        # set `left` child for this node (or null if left no child)
        # ENSURE: node.key < key (only if node != null)
-       fun left=(node: nullable SELF) do
+       fun left=(node: nullable N) do
                #assert node != null implies node.key < key
                left_node = node
        end
 
-       private var right_node: nullable SELF = null
+       private var right_node: nullable N = null
 
        # `right` tree node child (null if node has no right child)
-       fun right: nullable SELF do return right_node
+       fun right: nullable N do return right_node
 
        # set `right` child for this node (or null if right no child)
        # ENSURE: node.key < key (only if node != null)
-       fun right=(node: nullable SELF) do
+       fun right=(node: nullable N) do
                #assert node != null implies node.key > key
                right_node = node
        end
 
        # `parent` of the `parent` of this node (null if root)
-       fun grandparent: nullable SELF do
+       fun grandparent: nullable N do
                if parent == null then
                        return null
                else
@@ -411,7 +411,7 @@ class BinTreeNode[K: Comparable, E]
 
        # Other child of the `grandparent`
        # `left` or `right` depends on the position of the current node against its parent
-       fun uncle: nullable SELF do
+       fun uncle: nullable N do
                var g = grandparent
                if g == null then
                        return null
@@ -426,7 +426,7 @@ class BinTreeNode[K: Comparable, E]
 
        # Other child of the parent
        # `left` or `right` depends on the position of the current node against its parent
-       fun sibling: nullable SELF do
+       fun sibling: nullable N do
                if parent == null then
                        return null
                else if self == parent.left then
index ce17feb..e1fe413 100644 (file)
@@ -130,7 +130,7 @@ end
 class RBTreeNode[K: Comparable, E]
        super BinTreeNode[K, E]
 
-       redef type SELF: RBTreeNode[K, E]
+       redef type N: RBTreeNode[K, E]
 
        # Is the node red?
        private var is_red = true
index cc24d6e..ad34b9a 100644 (file)
@@ -44,6 +44,9 @@ class AndroidProject
        # Custom lines to add to the AndroidManifest.xml in the <application> node
        var manifest_application_lines = new Array[String]
 
+       # Custom lines to add to AndroidManifest.xml as attributes inside the <activity> node
+       var manifest_activity_attributes = new Array[String]
+
        # Minimum API level required for the application to run
        var min_api: nullable Int = null
 
@@ -107,6 +110,9 @@ redef class ModelBuilder
                annots = collect_annotations_on_modules("android_manifest_application", mmodule)
                for an in annots do project.manifest_application_lines.add an.arg_as_string(self) or else ""
 
+               annots = collect_annotations_on_modules("android_manifest_activity", mmodule)
+               for an in annots do project.manifest_activity_attributes.add an.arg_as_string(self) or else ""
+
                # Get the date and time (down to the minute) as string
                var local_time = new Tm.localtime
                var local_time_s = local_time.strftime("%y%m%d%H%M")
index 55468fd..1cf6ba8 100644 (file)
@@ -124,10 +124,12 @@ class AndroidToolchain
 
                # Also copy over the java files
                dir = "{android_project_root}/src/"
-               var extra_java_files = compiler.mainmodule.extra_java_files
-               if extra_java_files != null then for file in extra_java_files do
-                       var path = file.filename
-                       path.file_copy_to("{dir}/{path.basename("")}")
+               for mmodule in compiler.mainmodule.in_importation.greaters do
+                       var extra_java_files = mmodule.extra_java_files
+                       if extra_java_files != null then for file in extra_java_files do
+                               var path = file.filename
+                               path.file_copy_to(dir/path.basename(""))
+                       end
                end
 
                ## Generate delagating makefile
@@ -178,13 +180,11 @@ $(call import-module,android/native_app_glue)
              This will take care of integrating with our NDK code. -->
         <activity android:name="android.app.NativeActivity"
                 android:label="@string/app_name"
-                android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
-                android:configChanges="orientation|keyboardHidden"
-                android:screenOrientation="portrait"
+                {{{project.manifest_activity_attributes.join("\n")}}}
                 {{{icon_declaration}}}>
-            <!-- Tell NativeActivity the name of or .so -->
-            <meta-data android:name=\"{{{app_package}}}\"
-                    android:value=\"{{{app_name}}}\" />
+            <!-- Tell NativeActivity the name of our .so -->
+            <meta-data android:name=\"android.app.lib_name\"
+                    android:value=\"main\" />
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
index 2879ac9..476608c 100644 (file)
@@ -901,6 +901,8 @@ redef class AMethPropdef
                                return v.bool_instance(args[0].to_f.is_nan)
                        else if pname == "is_inf_extern" then
                                return v.bool_instance(args[0].to_f.is_inf != 0)
+                       else if pname == "round" then
+                               return v.float_instance(args[0].to_f.round)
                        end
                else if cname == "NativeString" then
                        if pname == "new" then
index cb56d38..81b3245 100644 (file)
@@ -54,6 +54,7 @@ redef class ModelBuilder
                        build_properties(mclassdef2nclassdef[superclassdef])
                end
 
+               mclassdef.build_self_type(self, nclassdef)
                for nclassdef2 in nclassdef.all_defs do
                        for npropdef in nclassdef2.n_propdefs do
                                npropdef.build_property(self, mclassdef)
@@ -310,6 +311,50 @@ redef class MClassDef
        # What is the `APropdef` associated to a `MProperty`?
        # Used to check multiple definition of a property.
        var mprop2npropdef: Map[MProperty, APropdef] = new HashMap[MProperty, APropdef]
+
+       # Build the virtual type `SELF` only for introduction `MClassDef`
+       fun build_self_type(modelbuilder: ModelBuilder, nclassdef: AClassdef)
+       do
+               if not is_intro then return
+
+               var name = "SELF"
+               var mprop = modelbuilder.try_get_mproperty_by_name(nclassdef, self, name)
+
+               # If SELF type is declared nowherer?
+               if mprop == null then return
+
+               # SELF is not a virtual type? it is weird but we ignore it
+               if not mprop isa MVirtualTypeProp then return
+
+               # Is this the intro of SELF in the library?
+               var intro = mprop.intro
+               var intro_mclassdef = intro.mclassdef
+               if intro_mclassdef == self then
+                       var nintro = modelbuilder.mpropdef2npropdef[intro]
+
+                       # SELF must be declared in Object, otherwise this will create conflicts
+                       if intro_mclassdef.mclass.name != "Object" then
+                               modelbuilder.error(nintro, "Error: the virtual type SELF must be declared in Object.")
+                       end
+
+                       # SELF must be public
+                       if mprop.visibility != public_visibility then
+                               modelbuilder.error(nintro, "Error: the virtual type SELF must be public.")
+                       end
+
+                       # SELF must not be fixed
+                       if intro.is_fixed then
+                               modelbuilder.error(nintro, "Error: the virtual type SELF cannot be fixed.")
+                       end
+
+                       return
+               end
+
+               # This class introduction inherits a SELF
+               # We insert an artificial property to update it
+               var mpropdef = new MVirtualTypeDef(self, mprop, self.location)
+               mpropdef.bound = mclass.mclass_type
+       end
 end
 
 redef class APropdef
diff --git a/tests/base_self_type.nit b/tests/base_self_type.nit
new file mode 100644 (file)
index 0000000..7c5d204
--- /dev/null
@@ -0,0 +1,58 @@
+# 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 X
+       fun foo: SELF do return self
+       fun bar(o: SELF) do o.output_class_name
+end
+
+class Y
+       super X
+
+#alt1# redef fun foo do return new X
+#alt2# redef fun foo do return new Y
+end
+
+class A[E]
+       fun foo: Object do return new G[SELF]
+end
+
+class B[F]
+       super A[F]
+end
+
+class G[E:A[nullable Object]]
+end
+
+var x = new X
+x.output_class_name
+x.foo.output_class_name
+x.bar x
+
+var y = new Y
+y.output_class_name
+y.foo.output_class_name
+x.bar y
+y.bar y
+#alt3# y.bar x
+
+var a = new A[Int]
+a.output_class_name
+a.foo.output_class_name
+
+var b = new B[Bool]
+b.output_class_name
+b.foo.output_class_name
diff --git a/tests/sav/base_self_type.res b/tests/sav/base_self_type.res
new file mode 100644 (file)
index 0000000..4c75853
--- /dev/null
@@ -0,0 +1,11 @@
+X
+X
+X
+Y
+Y
+Y
+Y
+A[Int]
+G[A[Int]]
+B[Bool]
+G[B[Bool]]
diff --git a/tests/sav/base_self_type_alt1.res b/tests/sav/base_self_type_alt1.res
new file mode 100644 (file)
index 0000000..467d315
--- /dev/null
@@ -0,0 +1 @@
+alt/base_self_type_alt1.nit:25,25--29: Type error: expected SELF, got X
diff --git a/tests/sav/base_self_type_alt2.res b/tests/sav/base_self_type_alt2.res
new file mode 100644 (file)
index 0000000..4c75853
--- /dev/null
@@ -0,0 +1,11 @@
+X
+X
+X
+Y
+Y
+Y
+Y
+A[Int]
+G[A[Int]]
+B[Bool]
+G[B[Bool]]
diff --git a/tests/sav/base_self_type_alt3.res b/tests/sav/base_self_type_alt3.res
new file mode 100644 (file)
index 0000000..78888be
--- /dev/null
@@ -0,0 +1 @@
+alt/base_self_type_alt3.nit:50,7: Type error: expected Y, got X
index 30a32a5..695948f 100644 (file)
@@ -1 +1 @@
-../lib/standard/kernel.nit:79,1--95,3: Fatal error: kernel#Sys does not specialize module_0#Object. Possible duplication of the root class `Object`?
+../lib/standard/kernel.nit:101,1--117,3: Fatal error: kernel#Sys does not specialize module_0#Object. Possible duplication of the root class `Object`?
diff --git a/tests/sav/nitg-e/base_self_type.res b/tests/sav/nitg-e/base_self_type.res
new file mode 100644 (file)
index 0000000..3c20b42
--- /dev/null
@@ -0,0 +1,11 @@
+X
+X
+X
+Y
+Y
+Y
+Y
+A
+G
+B
+G
diff --git a/tests/sav/nitg-e/base_self_type_alt2.res b/tests/sav/nitg-e/base_self_type_alt2.res
new file mode 100644 (file)
index 0000000..3c20b42
--- /dev/null
@@ -0,0 +1,11 @@
+X
+X
+X
+Y
+Y
+Y
+Y
+A
+G
+B
+G
index 56621b6..980ce17 100644 (file)
@@ -1,4 +1,4 @@
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:374)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:411)
 11
 21
 31
index 56621b6..980ce17 100644 (file)
@@ -1,4 +1,4 @@
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:374)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:411)
 11
 21
 31
index 56621b6..980ce17 100644 (file)
@@ -1,4 +1,4 @@
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:374)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:411)
 11
 21
 31
index af28f14..e248df6 100644 (file)
@@ -41,7 +41,7 @@ Bool [
 Object -> Bool [dir=back arrowtail=open style=dashed];
 
 Float [
- label = "{Float||}"
+ label = "{Float||+ is_approx(other: Float, precision: Float): Bool\l}"
 ]
 Numeric -> Float [dir=back arrowtail=open style=dashed];
 
index 6189897..9a7b30f 100644 (file)
@@ -41,7 +41,7 @@ Bool [
 Object -> Bool [dir=back arrowtail=open style=dashed];
 
 Float [
- label = "{Float||}"
+ label = "{Float||+ is_approx(other: Float, precision: Float): Bool\l}"
 ]
 Numeric -> Float [dir=back arrowtail=open style=dashed];
 
index aa38be4..9533b69 100644 (file)
@@ -1 +1 @@
-Runtime error: Assert failed (../lib/c.nit:64)
+Runtime error: Assert failed (../lib/c.nit:63)
index 95d7a74..17a3dc5 100644 (file)
@@ -1,2 +1,2 @@
-Runtime error: Assert failed (../lib/c.nit:57)
+Runtime error: Assert failed (../lib/c.nit:56)
 0
index 95d7a74..17a3dc5 100644 (file)
@@ -1,2 +1,2 @@
-Runtime error: Assert failed (../lib/c.nit:57)
+Runtime error: Assert failed (../lib/c.nit:56)
 0
index 3bb984c..fdc9a45 100644 (file)
@@ -1,4 +1,4 @@
-Runtime error: Assert failed (../lib/c.nit:56)
+Runtime error: Assert failed (../lib/c.nit:55)
 0
 0
 1