Merge: PNaCl: Added 'create_thread' function in the pnacl lib.
authorJean Privat <jean@pryen.org>
Thu, 26 Jun 2014 17:16:00 +0000 (13:16 -0400)
committerJean Privat <jean@pryen.org>
Thu, 26 Jun 2014 17:16:00 +0000 (13:16 -0400)
Added 'create_thread' function to enable thread creation after a exit.

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

37 files changed:
.mailmap
benchmarks/bench_common.sh [new file with mode: 0644]
benchmarks/bench_engines.sh
benchmarks/bench_languages.sh
c_src/Makefile
lib/ordered_tree.nit
lib/ropes_debug.nit
lib/standard/ropes.nit
src/Makefile
src/abstract_compiler.nit
src/debugger.nit
src/debugger_socket.nit [new file with mode: 0644]
src/doc/doc_pages.nit
src/global_compiler.nit
src/mkcsrc
src/model/mmodule.nit
src/model/model.nit
src/model/model_base.nit
src/model/mproject.nit
src/model_utils.nit
src/nit.nit
src/nitx.nit
tests/emscripten.skip [new file with mode: 0644]
tests/emscripten_nodejs.nit [new file with mode: 0644]
tests/sav/emscripten/emscripten_nodejs.res [new file with mode: 0644]
tests/sav/emscripten/fixme/base_attr_gen_alt1.res [new file with mode: 0644]
tests/sav/emscripten/fixme/base_conflict_submodule_name.res [new file with mode: 0644]
tests/sav/emscripten/fixme/base_conflict_submodule_name_alt1.res [new file with mode: 0644]
tests/sav/emscripten/fixme/base_conflict_submodule_name_alt2.res [new file with mode: 0644]
tests/sav/emscripten_nodejs.res [new file with mode: 0644]
tests/sav/nitg-s/fixme/base_attr_gen_alt1.res
tests/sav/nitg-sg/fixme/base_attr_gen_alt1.res
tests/sav/test_ordered_tree.res [new file with mode: 0644]
tests/sav/test_ordered_tree2.res [new file with mode: 0644]
tests/test_ordered_tree.nit [new file with mode: 0644]
tests/test_ordered_tree2.nit [new file with mode: 0644]
tests/tests.sh

index a3e389c..695a4ce 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -23,3 +23,5 @@ Romain Chanoir <romain.chanoir@viacesi.fr>
 Clement de Figueiredo <clement.defigueiredo@gmail.com>
 
 Christophe Gigax <christophe.gigax@viacesi.fr>
+
+Julien Pagès <julien.projet@gmail.com>
diff --git a/benchmarks/bench_common.sh b/benchmarks/bench_common.sh
new file mode 100644 (file)
index 0000000..c600732
--- /dev/null
@@ -0,0 +1,87 @@
+#!/bin/bash
+# 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.
+
+# Common functions for all the bench scripts
+
+# Run a single command multiple time and store the execution times
+# in the current $res file.
+#
+#  $1: title of the command
+#  $2: long desription of the command
+#  rest: the command to execute
+function bench_command()
+{
+       if [ "$dry_run" = "true" ]; then return; fi
+       local title="$1"
+       local desc="$2"
+       shift
+       shift
+       if test "$verbose" = true; then outputopts="/dev/stdout"; else outputopts="/dev/null"; fi
+       timeout="time.out"
+       echo "$title" > "$timeout"
+       echo "# $desc" >> "$timeout"
+       echo "\$ $@" >> "$timeout"
+       echo
+       echo "** [$title] $desc **"
+       echo " $ $@"
+
+       # Execute the commands $count times
+       for i in `seq 1 "$count"`; do
+               /usr/bin/time -f "%U" -o "$timeout" -a "$@" > $outputopts 2>&1 || die "$1: failed"
+               echo -n "$i. "
+               tail -n 1 "$timeout"
+       done
+
+       line=`compute_stats "$timeout"`
+       echo "$line ($res)"
+       echo $line >> "$res"
+}
+
+# Run a simble command witout storing the execution time
+# Used to display command on verbose and skip long executions when dry_run is given
+# $@ command to execute
+function run_command()
+{
+       if [ "$dry_run" = "true" ]; then return; fi
+       echo " $ $@"
+       "$@" || die "$@: failed"
+}
+
+# Check if the test should be skiped according to its name
+# $1: name of the test
+# $2: description of the test
+# $NOTSKIPED: arguments
+function skip_test()
+{
+       if test -z "$NOTSKIPED"; then
+               echo "* $1"
+               return 0
+       fi
+       if test "$NOTSKIPED" = "all"; then
+               : # Execute anyway
+       elif echo "$1" | egrep "$NOTSKIPED" >/dev/null 2>&1; then
+               : # Found one to execute
+       else
+               return 0
+       fi
+       if test -n "$html"; then
+               echo >>"$html" "<h2>$1</h2>"
+       fi
+       echo "*"
+       echo "* $1 *****"
+       echo "*"
+       return 1
+}
+
index 55db63e..abc65e3 100755 (executable)
@@ -17,6 +17,7 @@
 
 # TODO: cleanup and libify the helper-parts
 
+source ./bench_common.sh
 source ./bench_plot.sh
 
 ## CONFIGURATION OPTIONS ##
@@ -35,76 +36,6 @@ function die()
        died=1
 }
 
-# Run a single command multiple time and store the execution times
-# in the current $res file.
-#
-#  $1: title of the command
-#  $2: long desription of the command
-#  rest: the command to execute
-function bench_command()
-{
-       if [ "$dry_run" = "true" ]; then return; fi
-       local title="$1"
-       local desc="$2"
-       shift
-       shift
-       if test "$verbose" = true; then outputopts="/dev/stdout"; else outputopts="/dev/null"; fi
-       timeout="time.out"
-       echo "$title" > "$timeout"
-       echo "# $desc" >> "$timeout"
-       echo "\$ $@" >> "$timeout"
-       echo
-       echo "** [$title] $desc **"
-       echo " $ $@"
-
-       # Execute the commands $count times
-       for i in `seq 1 "$count"`; do
-               /usr/bin/time -f "%U" -o "$timeout" -a "$@" > $outputopts 2>&1 || die "$1: failed"
-               echo -n "$i. "
-               tail -n 1 "$timeout"
-       done
-
-       line=`compute_stats "$timeout"`
-       echo "$line ($res)"
-       echo $line >> "$res"
-}
-
-# Run a simble command witout storing the execution time
-# Used to display command on verbose and skip long executions when dry_run is given
-# $@ command to execute
-function run_command()
-{
-       if [ "$dry_run" = "true" ]; then return; fi
-       echo " $ $@"
-       "$@" || die "$@: failed"
-}
-
-# Check if the test should be skiped according to its name
-# $1: name of the test
-# $2: description of the test
-# $NOTSKIPED: arguments
-function skip_test()
-{
-       if test -z "$NOTSKIPED"; then
-               echo "* $1"
-               return 0
-       fi
-       if test "$NOTSKIPED" = "all"; then
-               : # Execute anyway
-       elif echo "$1" | egrep "$NOTSKIPED" >/dev/null 2>&1; then
-               : # Found one to execute
-       else
-               return 0
-       fi
-       if test -n "$html"; then
-               echo >>"$html" "<h2>$1</h2>"
-       fi
-       echo "*"
-       echo "* $1 *****"
-       echo "*"
-       return 1
-}
-
 # HELPER FOR NIT #
 
 # Run standards benchs on a compiler command
index d9db525..fea39ff 100755 (executable)
@@ -17,6 +17,7 @@
 
 # TODO: cleanup and libify the helper-parts
 
+source ./bench_common.sh
 source ./bench_plot.sh
 
 ## CONFIGURATION OPTIONS ##
@@ -33,74 +34,6 @@ function die()
        died=1
 }
 
-# Run a single command multiple time and store the execution times
-# in the current $res file.
-#
-#  $1: title of the command
-#  $2: long desription of the command
-#  rest: the command to execute
-function bench_command()
-{
-       if [ "$dry_run" = "true" ]; then return; fi
-       local title="$1"
-       local desc="$2"
-       shift
-       shift
-       if test "$verbose" = true; then outputopts="/dev/stdout"; else outputopts="/dev/null"; fi
-       timeout="time.out"
-       echo "$title" > "$timeout"
-       echo "# $desc" >> "$timeout"
-       echo "\$ $@" >> "$timeout"
-       echo
-       echo "** [$title] $desc **"
-       echo " $ $@"
-
-       # Execute the commands $count times
-       for i in `seq 1 "$count"`; do
-               (ulimit -t 300; /usr/bin/time -f "%U" -o "$timeout" -a "$@") > $outputopts 2>&1 || die "$1: failed"
-               echo -n "$i. "
-               tail -n 1 "$timeout"
-       done
-
-       line=`compute_stats "$timeout"`
-       echo "$line ($res)"
-       echo $line >> "$res"
-       rm $timeout
-}
-
-# Run a simple command witout storing the execution time
-# Used to display command on verbose and skip long executions when dry_run is given
-# $@ command to execute
-function run_command()
-{
-       if [ "$dry_run" = "true" ]; then return; fi
-       echo " $ $@"
-       (ulimit -t 180; "$@") || die "$@: failed"
-}
-
-# Check if the test should be skiped according to its name
-# $1: name of the test
-# $2: description of the test
-# $NOTSKIPED: arguments
-function skip_test()
-{
-       if test -z "$NOTSKIPED"; then
-               echo "* $1"
-               return 0
-       fi
-       if test "$NOTSKIPED" = "all"; then
-               : # Execute anyway
-       elif echo "$1" | egrep "$NOTSKIPED" >/dev/null 2>&1; then
-               : # Found one to execute
-       else
-               return 0
-       fi
-       echo "*"
-       echo "* $1 *****"
-       echo "*"
-       return 1
-}
-
 ## HANDLE OPTIONS ##
 
 function usage()
index 1453943..d94866c 100644 (file)
@@ -1,8 +1,22 @@
 CC = ccache cc
-CFLAGS = -g -O2
+CFLAGS = -g -O2 -Wno-unused-value -Wno-switch
 CINCL =  -I "clib"
 LDFLAGS ?= 
-LDLIBS  ?= -lm -lgc  -lunwind
+LDLIBS  ?= -lm -lgc
+
+NEED_LIBUNWIND := YesPlease
+uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
+ifeq ($(uname_S),Darwin)
+       NEED_LIBUNWIND :=
+endif
+
+clang_check := $(shell sh -c '$(CC) -v 2>&1 | grep -q clang; echo $$?')
+ifeq ($(clang_check), 0)
+       CFLAGS += -Qunused-arguments
+endif
+ifdef NEED_LIBUNWIND
+       LDLIBS += -lunwind
+endif
 
 all: nitg
 
index 7e45aef..f6cd69a 100644 (file)
@@ -25,6 +25,7 @@ module ordered_tree
 # The class can also be specialized to provide more specific behavior.
 class OrderedTree[E: Object]
        super Streamable
+       super Collection[E]
 
        # Sequence
        var roots = new Array[E]
@@ -92,4 +93,100 @@ class OrderedTree[E: Object]
        #
        # Subclasses should redefine this method to provide a specific output
        fun display(e: E): String do return e.to_s
+
+       # Get an array of the contained elements
+       # Order is preserved
+       #
+       #     var tree = new OrderedTree[Int]
+       #     tree.add(null, 1)
+       #     tree.add(1, 11)
+       #     tree.add(11, 111)
+       #     tree.add(11, 112)
+       #     tree.add(1, 12)
+       #     tree.add(12, 121)
+       #     tree.add(12, 122)
+       #     tree.add(null, 2)
+       #     tree.add(2, 21)
+       #     tree.add(2, 22)
+       #     assert tree.to_a == [1, 11, 111, 112, 12, 121, 122, 2, 21, 22]
+       redef fun to_a: Array[E] do
+               var res = new Array[E]
+               for r in roots do sub_to_a(r, res)
+               return res
+       end
+
+       private fun sub_to_a(e: E, res: Array[E]) do
+               res.add e
+               if sub.has_key(e) then for e2 in sub[e] do sub_to_a(e2, res)
+       end
+
+       #     var tree = new OrderedTree[Int]
+       #     assert tree.is_empty
+       #     tree.add(null, 1)
+       #     assert not tree.is_empty
+       redef fun is_empty: Bool do return roots.is_empty
+
+       #     var tree = new OrderedTree[Int]
+       #     tree.add(null, 1)
+       #     tree.add(1, 11)
+       #     assert tree.first == 1
+       redef fun first do return roots.first
+
+       #     var tree = new OrderedTree[Int]
+       #     tree.add(null, 1)
+       #     tree.add(1, 11)
+       #     tree.add(11, 111)
+       #     tree.add(11, 112)
+       #     tree.add(1, 12)
+       #     tree.add(12, 121)
+       #     tree.add(12, 122)
+       #     tree.add(null, 2)
+       #     tree.add(2, 21)
+       #     tree.add(2, 22)
+       #     var order = [1, 11, 111, 112, 12, 121, 122, 2, 21, 22]
+       #     var res = new Array[Int]
+       #     for i in tree do res.add(i)
+       #     assert res == order
+       redef fun iterator do return new OrderedTreeIterator[E](self)
+end
+
+# An Iterator over an OrderedTree
+private class OrderedTreeIterator[E: Object]
+       super Iterator[E]
+
+       var tree: OrderedTree[E]
+
+       var iterators = new Array[Iterator[E]]
+
+       init(tree: OrderedTree[E]) do
+               self.tree = tree
+
+               if not tree.is_empty then
+                       iterators.add tree.roots.iterator
+               end
+       end
+
+       redef fun is_ok do return not iterators.is_empty
+
+       redef fun item do
+               assert is_ok
+               return iterators.last.item
+       end
+
+       redef fun next do
+               assert is_ok
+               if tree.sub.has_key(item) then
+                       iterators.add tree.sub[item].iterator
+               else
+                       iterators.last.next
+                       while is_ok and not iterators.last.is_ok do
+                               iterators.pop
+                               if is_ok and iterators.last.is_ok then
+                                       iterators.last.next
+                               end
+                       end
+               end
+       end
+
+       redef fun iterator do return new OrderedTreeIterator[E](tree)
 end
index b9ba5ab..a122a02 100644 (file)
@@ -53,13 +53,24 @@ redef class Concat
        end
 end
 
+redef class FlatText
+       fun to_dot(s: String): String is abstract
+end
+
 redef class FlatString
-       fun to_dot(s: String): String
+       redef fun to_dot(s: String): String
        do
                return s + "n{object_id} [label=\"FlatString\\nindex_from = {index_from}\\nindex_to = {index_to}\\nNativeString = {items.to_s_with_length(items.cstring_length)}\"];\n"
        end
 end
 
+redef class FlatBuffer
+       redef fun to_dot(s: String): String
+       do
+               return s + "n{object_id} [label=\"FlatBuffer\\length = {length}\\ncapacity = {capacity}\\nitems = {items.to_s_with_length(items.cstring_length)}\"];\n"
+       end
+end
+
 redef class RopeString
        redef fun to_dot(filepath: String)
        do
index 45c1cbd..7bc4154 100644 (file)
@@ -44,6 +44,11 @@ end
 private abstract class RopeNode
        # Length of the node
        var length = 0
+
+       # Transforms the current node to a Leaf.
+       # This might be costly to invoke since this produces a FlatString concatenation.
+       # Can be used internally to limit the growth of the Rope when working with small leaves.
+       fun to_leaf: Leaf is abstract
 end
 
 # Node that represents a concatenation between two nodes (of any RopeNode type)
@@ -51,40 +56,47 @@ private class Concat
        super RopeNode
 
        # Left child of the node
-       var _left: nullable RopeNode = null
+       var left: nullable RopeNode
        # Right child of the node
-       var _right: nullable RopeNode = null
-
-       fun left: nullable RopeNode do return _left
-       fun right: nullable RopeNode do return _right
+       var right: nullable RopeNode
 
-       fun left=(l: RopeNode)
+       init(l: nullable RopeNode, r: nullable RopeNode)
        do
-               _left = l
-               length = l.length
-               if _right != null then length += _right.length
+               left = l
+               right = r
+               if l != null then length += l.length
+               if r != null then length += r.length
        end
 
-       fun right=(r: RopeNode)
+       redef fun to_leaf
        do
-               _right = r
-               length = r.length
-               if _left != null then length += _left.length
+               if left == null then
+                       if right == null then return new StringLeaf("".as(FlatString))
+                       return right.to_leaf
+               end
+               if right == null then return left.as(not null).to_leaf
+               return new StringLeaf((left.to_leaf.str.as(FlatString) + right.to_leaf.str.as(FlatString)).as(FlatString))
        end
 end
 
 # Leaf of a Rope, contains a FlatString
-private class Leaf
+private abstract class Leaf
        super RopeNode
 
        # Encapsulated FlatString in the leaf node
-       var str: FlatString
+       var str: FlatText
+
+end
+
+private class StringLeaf
+       super Leaf
 
        init(val: FlatString) do
                self.str = val
                length = str.length
        end
 
+       redef fun to_leaf do return self
 end
 
 # Basic structure, binary tree with a root node.
@@ -104,7 +116,7 @@ abstract class Rope
 
        # Creates a new Rope with `s` as root
        init from(s: String) do
-               if s isa RopeString then root = s.root else root = new Leaf(s.as(FlatString))
+               if s isa RopeString then root = s.root else root = new StringLeaf(s.as(FlatString))
        end
 
        private init from_root(r: RopeNode)
@@ -276,36 +288,40 @@ class RopeString
 
                var path = node_at(pos)
 
-               var last_concat = new Concat
+               var last_concat: Concat
 
                if path.offset == 0 then
-                       last_concat.right = path.leaf
-                       if str isa FlatString then last_concat.left = new Leaf(str) else last_concat.left = str.as(RopeString).root
+                       if str isa FlatString then
+                               last_concat = new Concat(new StringLeaf(str), path.leaf)
+                       else
+                               last_concat = new Concat(str.as(RopeString).root, path.leaf)
+                       end
                else if path.offset == path.leaf.length then
-                       if str isa FlatString then last_concat.right = new Leaf(str) else last_concat.right = str.as(RopeString).root
-                       last_concat.left = path.leaf
+                       if str isa FlatString then
+                               last_concat = new Concat(path.leaf, new StringLeaf(str))
+                       else
+                               last_concat = new Concat(path.leaf, str.as(RopeString).root)
+                       end
                else
                        var s = path.leaf.str
                        var l_half = s.substring(0, s.length - path.offset)
                        var r_half = s.substring_from(s.length - path.offset)
-                       var cct = new Concat
-                       cct.right = new Leaf(r_half.as(FlatString))
-                       last_concat.left = new Leaf(l_half.as(FlatString))
-                       if str isa FlatString then last_concat.right = new Leaf(str) else last_concat.right = str.as(RopeString).root
-                       cct.left = last_concat
-                       last_concat = cct
+                       var cct: Concat
+                       var ll = new StringLeaf(l_half.as(FlatString))
+                       if str isa FlatString then
+                               cct = new Concat(ll, new StringLeaf(str))
+                       else
+                               cct = new Concat(ll, str.as(RopeString).root)
+                       end
+                       last_concat = new Concat(cct, new StringLeaf(r_half.as(FlatString)))
                end
 
                for i in path.stack.reverse_iterator do
-                       var nod = new Concat
                        if i.left then
-                               nod.right = i.node.right.as(not null)
-                               nod.left = last_concat
+                               last_concat = new Concat(last_concat, i.node.right)
                        else
-                               nod.left = i.node.left.as(not null)
-                               nod.right = last_concat
+                               last_concat = new Concat(i.node.left, last_concat)
                        end
-                       last_concat = nod
                end
 
                return new RopeString.from_root(last_concat)
@@ -324,17 +340,25 @@ class RopeString
        # Builds a new path from root to the rightmost node with s appended
        private fun append_to_path(node: RopeNode, s: String): RopeNode
        do
-               var cct = new Concat
+               var cct: Concat
                if node isa Leaf then
-                       cct.left = node
-                       if s isa FlatString then cct.right = new Leaf(s) else cct.right = s.as(RopeString).root
-               else if node isa Concat then
-                       var right = node.right
-                       if node.left != null then cct.left = node.left.as(not null)
+                       if s isa FlatString then
+                               cct = new Concat(node, new StringLeaf(s))
+                       else
+                               cct = new Concat(node, s.as(RopeString).root)
+                       end
+               else
+                       var n = node.as(Concat)
+                       var right = n.right
+                       var lft = n.left.as(not null)
                        if right == null then
-                               if s isa FlatString then cct.right = new Leaf(s) else cct.right = s.as(RopeString).root
+                               if s isa FlatString then
+                                       cct = new Concat(lft, new StringLeaf(s))
+                               else
+                                       cct = new Concat(lft, s.as(RopeString).root)
+                               end
                        else
-                               cct.right = append_to_path(right, s)
+                               cct = new Concat(lft, append_to_path(right, s))
                        end
                end
                return cct
@@ -364,17 +388,13 @@ class RopeString
                var lf = path.leaf
                var offset = path.offset
 
-               if path.leaf.str.length - offset > len then lf = new Leaf(lf.str.substring(offset,len).as(FlatString)) else lf = new Leaf(lf.str.substring_from(offset).as(FlatString))
+               if path.leaf.str.length - offset > len then lf = new StringLeaf(lf.str.substring(offset,len).as(FlatString)) else lf = new StringLeaf(lf.str.substring_from(offset).as(FlatString))
 
                var nod: RopeNode = lf
 
                for i in path.stack.reverse_iterator do
                        if i.right then continue
-                       var tmp = new Concat
-                       tmp.left = nod
-                       var r = i.node.right
-                       if r != null then tmp.right = r
-                       nod = tmp
+                       nod = new Concat(nod, i.node.right)
                end
 
                var ret = new RopeString
@@ -383,15 +403,11 @@ class RopeString
                path = ret.node_at(len-1)
 
                offset = path.offset
-               nod = new Leaf(path.leaf.str.substring(0, offset+1).as(FlatString))
+               nod = new StringLeaf(path.leaf.str.substring(0, offset+1).as(FlatString))
 
                for i in path.stack.reverse_iterator do
                        if i.left then continue
-                       var tmp = new Concat
-                       tmp.right = nod
-                       var l = i.node.left
-                       if l != null then tmp.left = l
-                       nod = tmp
+                       nod = new Concat(i.node.left, nod)
                end
 
                ret.root = nod
index 211287d..2ca0fb7 100644 (file)
@@ -15,6 +15,7 @@
 # limitations under the License.
 
 NITCOPT=
+OLDNITCOPT= --no-stacktrace
 
 all: ../bin/nitdoc ../bin/nitmetrics ../bin/nitg ../bin/nit ../bin/nitx ../bin/nitunit ../bin/nitlight ../bin/nitls ../bin/nitdbg_client
 
@@ -23,7 +24,7 @@ nitg_0: ../c_src/nitg parser/parser.nit
        @echo '* Compile nitg_0 from NIT source files                          *'
        @echo '***************************************************************'
        ./git-gen-version.sh
-       ../c_src/nitg ${NITCOPT} -o nitg_0 -v nitg.nit
+       ../c_src/nitg ${OLDNITCOPT} -o nitg_0 -v nitg.nit
 
 ../bin/nitg: nitg_0 parser/parser.nit
        @echo '***************************************************************'
index 99b84be..e8d0179 100644 (file)
@@ -320,10 +320,28 @@ class MakefileToolchain
                        if libs != null then linker_options.add_all(libs)
                end
 
+               makefile.write("CC = ccache cc\nCFLAGS = -g -O2 -Wno-unused-value -Wno-switch\nCINCL = {cc_includes}\nLDFLAGS ?= \nLDLIBS  ?= -lm -lgc {linker_options.join(" ")}\n\n")
+
                var ost = toolcontext.opt_stacktrace.value
-               if ost == "libunwind" or ost == "nitstack" then linker_options.add("-lunwind")
+               if ost == "libunwind" or ost == "nitstack" then makefile.write("NEED_LIBUNWIND := YesPlease\n")
+
+               # Dynamic adaptations
+               # While `platform` enable complex toolchains, they are statically applied
+               # For a dynamic adaptsation of the compilation, the generated Makefile should check and adapt things itself
+
+               # Check and adapt the targeted system
+               makefile.write("uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')\n")
+               makefile.write("ifeq ($(uname_S),Darwin)\n")
+               # remove -lunwind since it is already included on macosx
+               makefile.write("\tNEED_LIBUNWIND :=\n")
+               makefile.write("endif\n\n")
+
+               # Check and adapt for the compiler used
+               # clang need an additionnal `-Qunused-arguments`
+               makefile.write("clang_check := $(shell sh -c '$(CC) -v 2>&1 | grep -q clang; echo $$?')\nifeq ($(clang_check), 0)\n\tCFLAGS += -Qunused-arguments\nendif\n")
+
+               makefile.write("ifdef NEED_LIBUNWIND\n\tLDLIBS += -lunwind\nendif\n")
 
-               makefile.write("CC = ccache cc\nCFLAGS = -g -O2\nCINCL = {cc_includes}\nLDFLAGS ?= \nLDLIBS  ?= -lm -lgc {linker_options.join(" ")}\n\n")
                makefile.write("all: {outpath}\n\n")
 
                var ofiles = new Array[String]
index 697f86b..75486cb 100644 (file)
@@ -23,7 +23,6 @@ import nitx
 intrude import local_var_init
 intrude import scope
 intrude import toolcontext
-import websocket
 
 redef class Model
        # Cleans the model to remove a module and what it defines when semantic analysis fails on injected code
@@ -124,23 +123,11 @@ redef class ToolContext
        # -c
        var opt_debugger_autorun: OptionBool = new OptionBool("Launches the target program with the interpreter, such as when the program fails, the debugging prompt is summoned", "-c")
 
-       # --socket
-       var opt_socket_mode = new OptionBool("Launches the target program with raw output on the network via sockets", "--socket")
-
-       # --websocket
-       var opt_websocket_mode = new OptionBool("Launches the target program with output on the network via websockets", "--websocket")
-
-       # --port
-       var opt_debug_port: OptionInt = new OptionInt("Sets the debug port (Defaults to 22125) - Must be contained between 0 and 65535", 22125, "--port")
-
        redef init
        do
                super
                self.option_context.add_option(self.opt_debugger_mode)
                self.option_context.add_option(self.opt_debugger_autorun)
-               self.option_context.add_option(self.opt_socket_mode)
-               self.option_context.add_option(self.opt_websocket_mode)
-               self.option_context.add_option(self.opt_debug_port)
        end
 end
 
@@ -158,12 +145,8 @@ redef class ModelBuilder
 
                var interpreter = new Debugger(self, mainmodule, arguments)
 
-               set_stdstreams
-
                init_naive_interpreter(interpreter, mainmodule)
 
-               close_stdstreams
-
                var time1 = get_time
                self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
        end
@@ -176,53 +159,11 @@ redef class ModelBuilder
                var interpreter = new Debugger(self, mainmodule, arguments)
                interpreter.autocontinue = true
 
-               set_stdstreams
-
                init_naive_interpreter(interpreter, mainmodule)
 
-               close_stdstreams
-
                var time1 = get_time
                self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
        end
-
-       redef fun run_naive_interpreter(mmod, args)
-       do
-               set_stdstreams
-               super
-       end
-
-       fun set_stdstreams
-       do
-               if self.toolcontext.opt_socket_mode.value then
-                       var sock = new Socket.server(toolcontext.opt_debug_port.value, 1)
-                       var ns = sock.accept
-                       sock.close
-                       sys.set_io(ns,ns,ns)
-               else if self.toolcontext.opt_websocket_mode.value then
-                       var websock = new WebSocket(toolcontext.opt_debug_port.value, 1)
-                       websock.accept
-                       sys.set_io(websock,websock,websock)
-               end
-       end
-
-       fun close_stdstreams
-       do
-               if sys.stdin isa WebSocket or sys.stdin isa Socket then
-                       sys.stdin.close
-                       sys.stdout.close
-                       sys.stderr.close
-               end
-       end
-end
-
-redef class Sys
-       private fun set_io(istream: PollableIStream, ostream: OStream, errstream: OStream)
-       do
-               self.stdin = istream
-               self.stdout = ostream
-               self.stderr = ostream
-       end
 end
 
 # The class extending `NaiveInterpreter` by adding debugging methods
diff --git a/src/debugger_socket.nit b/src/debugger_socket.nit
new file mode 100644 (file)
index 0000000..07cf16d
--- /dev/null
@@ -0,0 +1,121 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2014 Johan Kayser <kayser.johan@gmail.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Debugging of a nit program using sockets.
+module debugger_socket
+
+intrude import debugger
+import websocket
+
+redef class ToolContext
+       # --socket
+       var opt_socket_mode = new OptionBool("Launches the target program with raw output on the network via sockets", "--socket")
+
+       # --websocket
+       var opt_websocket_mode = new OptionBool("Launches the target program with output on the network via websockets", "--websocket")
+
+       # --port
+       var opt_debug_port: OptionInt = new OptionInt("Sets the debug port (Defaults to 22125) - Must be contained between 0 and 65535", 22125, "--port")
+
+       redef init
+       do
+               super
+               self.option_context.add_option(self.opt_socket_mode)
+               self.option_context.add_option(self.opt_websocket_mode)
+               self.option_context.add_option(self.opt_debug_port)
+       end
+end
+
+redef class ModelBuilder
+       # Execute the program from the entry point (Sys::main) of the `mainmodule`
+       # `arguments` are the command-line arguments in order
+       # REQUIRE that:
+       #   1. the AST is fully loaded.
+       #   2. the model is fully built.
+       #   3. the instructions are fully analysed.
+       redef fun run_debugger(mainmodule: MModule, arguments: Array[String])
+       do
+               var time0 = get_time
+               self.toolcontext.info("*** START INTERPRETING ***", 1)
+
+               var interpreter = new Debugger(self, mainmodule, arguments)
+
+               set_stdstreams
+
+               init_naive_interpreter(interpreter, mainmodule)
+
+               close_stdstreams
+
+               var time1 = get_time
+               self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
+       end
+
+       redef fun run_debugger_autorun(mainmodule: MModule, arguments: Array[String])
+       do
+               var time0 = get_time
+               self.toolcontext.info("*** START INTERPRETING ***", 1)
+
+               var interpreter = new Debugger(self, mainmodule, arguments)
+               interpreter.autocontinue = true
+
+               set_stdstreams
+
+               init_naive_interpreter(interpreter, mainmodule)
+
+               close_stdstreams
+
+               var time1 = get_time
+               self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
+       end
+
+       redef fun run_naive_interpreter(mmod, args)
+       do
+               set_stdstreams
+               super
+       end
+
+       fun set_stdstreams
+       do
+               if self.toolcontext.opt_socket_mode.value then
+                       var sock = new Socket.server(toolcontext.opt_debug_port.value, 1)
+                       var ns = sock.accept
+                       sock.close
+                       sys.set_io(ns,ns,ns)
+               else if self.toolcontext.opt_websocket_mode.value then
+                       var websock = new WebSocket(toolcontext.opt_debug_port.value, 1)
+                       websock.accept
+                       sys.set_io(websock,websock,websock)
+               end
+       end
+
+       fun close_stdstreams
+       do
+               if sys.stdin isa WebSocket or sys.stdin isa Socket then
+                       sys.stdin.close
+                       sys.stdout.close
+                       sys.stderr.close
+               end
+       end
+end
+
+redef class Sys
+       private fun set_io(istream: PollableIStream, ostream: OStream, errstream: OStream)
+       do
+               self.stdin = istream
+               self.stdout = ostream
+               self.stderr = ostream
+       end
+end
index e41cae2..bb379e5 100644 (file)
@@ -230,6 +230,7 @@ abstract class NitdocPage
 
        private var ctx: NitdocContext
        private var model: Model
+       private var name_sorter = new MEntityNameSorter
 
        init(ctx: NitdocContext) do
                self.ctx = ctx
@@ -533,8 +534,7 @@ class NitdocSearch
                        if mmodule.name == "<main>" then continue
                        sorted.add mmodule
                end
-               var sorter = new MModuleNameSorter
-               sorter.sort(sorted)
+               name_sorter.sort(sorted)
                return sorted
        end
 
@@ -545,8 +545,7 @@ class NitdocSearch
                        if mclass.visibility < ctx.min_visibility then continue
                        sorted.add mclass
                end
-               var sorter = new MClassNameSorter
-               sorter.sort(sorted)
+               name_sorter.sort(sorted)
                return sorted
        end
 
@@ -558,8 +557,7 @@ class NitdocSearch
                        if mproperty isa MAttribute then continue
                        sorted.add mproperty
                end
-               var sorter = new MPropertyNameSorter
-               sorter.sort(sorted)
+               name_sorter.sort(sorted)
                return sorted
        end
 end
@@ -616,7 +614,6 @@ class NitdocModule
                if clients.length > 10 then clients = mmodule.in_importation.direct_smallers
 
                # Display lists
-               var sorter = new MModuleNameSorter
                var section = new TplSection.with_title("inheritance", "Inheritance")
 
                # Graph
@@ -631,7 +628,7 @@ class NitdocModule
                # nested modules
                if not nested.is_empty then
                        var lst = nested.to_a
-                       sorter.sort lst
+                       name_sorter.sort lst
                        section.add_child tpl_list("nesting", "Nested modules", lst)
                end
 
@@ -643,7 +640,7 @@ class NitdocModule
                        lst.add(dep)
                end
                if not lst.is_empty then
-                       sorter.sort lst
+                       name_sorter.sort lst
                        section.add_child tpl_list("imports", "Imports", lst)
                end
 
@@ -655,7 +652,7 @@ class NitdocModule
                        lst.add(dep)
                end
                if not lst.is_empty then
-                       sorter.sort lst
+                       name_sorter.sort lst
                        section.add_child tpl_list("clients", "Clients", lst)
                end
 
@@ -671,19 +668,18 @@ class NitdocModule
        end
 
        private fun tpl_mclasses(parent: TplSection) do
-               var sorter = new MClassNameSorter
                var mclassdefs = new HashSet[MClassDef]
                mclassdefs.add_all mmodule.in_nesting_intro_mclassdefs(ctx.min_visibility)
                mclassdefs.add_all mmodule.in_nesting_redef_mclassdefs(ctx.min_visibility)
                var mclasses2mdefs = sort_by_mclass(mclassdefs)
                var sorted_mclasses = mclasses2mdefs.keys.to_a
-               sorter.sort sorted_mclasses
+               name_sorter.sort sorted_mclasses
 
                # intros
                var section = new TplSection.with_title("intros", "Introductions")
                var intros = mmodule.in_nesting_intro_mclasses(ctx.min_visibility)
                var sorted_intros = intros.to_a
-               sorter.sort(sorted_intros)
+               name_sorter.sort(sorted_intros)
                for mclass in sorted_intros do
                        if not mclasses2mdefs.has_key(mclass) then continue
                        section.add_child tpl_mclass_article(mclass, mclasses2mdefs[mclass].to_a)
@@ -693,7 +689,7 @@ class NitdocModule
                # redefs
                section = new TplSection.with_title("redefs", "Refinements")
                var redefs = mmodule.in_nesting_redef_mclasses(ctx.min_visibility).to_a
-               sorter.sort(redefs)
+               name_sorter.sort(redefs)
                for mclass in redefs do
                        if intros.has(mclass) then continue
                        if not mclasses2mdefs.has_key(mclass) then continue
@@ -803,11 +799,9 @@ class NitdocClass
                tpl_sidebar.boxes.add new TplSideBox.with_content("All properties", summary)
        end
 
-       var mprop_sorter = new MPropertyNameSorter
-
        private fun tpl_sidebar_list(name: String, mprops: Array[MProperty], summary: TplList) do
                if mprops.is_empty then return
-               mprop_sorter.sort(mprops)
+               name_sorter.sort(mprops)
                var entry = new TplListItem.with_content(name)
                var list = new TplList.with_classes(["list-unstyled", "list-labeled"])
                for mprop in mprops do
@@ -858,8 +852,7 @@ class NitdocClass
 
                if not owners.is_empty then
                        var article = new TplArticle.with_title("concerns", "Concerns")
-                       var module_sorter = new MModuleNameSorter
-                       module_sorter.sort owners
+                       name_sorter.sort owners
                        var list = new TplList.with_classes(["list-unstyled", "list-definition"])
                        for owner in owners do
                                var li = new Template
@@ -871,7 +864,7 @@ class NitdocClass
                                var smmodules = owner_map[owner].to_a
                                #if not smmodules.length >= 1 then
                                        var slist = new TplList.with_classes(["list-unstyled", "list-definition"])
-                                       module_sorter.sort smmodules
+                                       name_sorter.sort smmodules
                                        for mmodule in smmodules do
                                                if mmodule == owner then continue
                                                var sli = new Template
@@ -925,7 +918,6 @@ class NitdocClass
                end
 
                # Display lists
-               var sorter = new MClassNameSorter
                var section = new TplSection.with_title("inheritance", "Inheritance")
 
                # Graph
@@ -941,28 +933,28 @@ class NitdocClass
                # parents
                if not hparents.is_empty then
                        var lst = hparents.to_a
-                       sorter.sort lst
+                       name_sorter.sort lst
                        section.add_child tpl_list("parents", "Parents", lst)
                end
 
                # ancestors
                if not hancestors.is_empty then
                        var lst = hancestors.to_a
-                       sorter.sort lst
+                       name_sorter.sort lst
                        section.add_child tpl_list("ancestors", "Ancestors", lst)
                end
 
                # children
                if not hchildren.is_empty and hchildren.length < 15 then
                        var lst = hchildren.to_a
-                       sorter.sort lst
+                       name_sorter.sort lst
                        section.add_child tpl_list("children", "Children", lst)
                end
 
                # descendants
                if not hdescendants.is_empty and hchildren.length < 15 then
                        var lst = hdescendants.to_a
-                       sorter.sort lst
+                       name_sorter.sort lst
                        section.add_child tpl_list("descendants", "Descendants", lst)
                end
 
@@ -992,12 +984,11 @@ class NitdocClass
                        for mmodule in owner_map[owner] do
                                # properties
                                var mprops = mod_map[mmodule]
-                               var sorter = new MPropertyNameSorter
                                var kind_map = sort_by_kind(mprops)
 
                                # virtual types
                                var elts = kind_map["type"].to_a
-                               sorter.sort(elts)
+                               name_sorter.sort(elts)
                                for elt in elts do
                                        var defs = mprops2mdefs[elt].to_a
                                        section.add_child tpl_mprop_article(elt, defs)
@@ -1005,7 +996,7 @@ class NitdocClass
 
                                # constructors
                                elts = kind_map["init"].to_a
-                               sorter.sort(elts)
+                               name_sorter.sort(elts)
                                for elt in elts do
                                        var defs = mprops2mdefs[elt].to_a
                                        section.add_child tpl_mprop_article(elt, defs)
@@ -1013,7 +1004,7 @@ class NitdocClass
 
                                # methods
                                elts = kind_map["fun"].to_a
-                               sorter.sort(elts)
+                               name_sorter.sort(elts)
                                for elt in elts do
                                        var defs = mprops2mdefs[elt].to_a
                                        section.add_child tpl_mprop_article(elt, defs)
index 8c6ac6c..9e79281 100644 (file)
@@ -124,8 +124,8 @@ class GlobalCompiler
        # Compile class names (for the class_name and output_class_name methods)
        protected fun compile_class_names do
                var v = new_visitor
-               self.header.add_decl("extern const char const * class_names[];")
-               v.add("const char const * class_names[] = \{")
+               self.header.add_decl("extern const char *class_names[];")
+               v.add("const char *class_names[] = \{")
                for t in self.runtime_type_analysis.live_types do
                        v.add("\"{t}\", /* {self.classid(t)} */")
                end
index a408697..7ba4466 100755 (executable)
@@ -21,3 +21,6 @@ done
 perl -i -npe 's#"\.\./.*?([^/]*.h)"#"\1"#' "$out"/*.[ch]
 perl -i -npe 's#\S*/([^/]*.[ch])#\1#' "$out/Makefile"
 perl -i -npe 's#\.\./clib#.#' "$out/Makefile"
+
+# Remove old compilation flags
+sed -i -e 's/OLDNITCOPT=.*/OLDNITCOPT=/' src/Makefile
index 60a7c92..18e835d 100644 (file)
@@ -69,7 +69,7 @@ end
 
 # A Nit module is usually associated with a Nit source file.
 class MModule
-       super MEntity
+       super MConcern
 
        # The model considered
        var model: Model
@@ -84,7 +84,7 @@ class MModule
        var mgroup: nullable MGroup
 
        # The short name of the module
-       var name: String
+       redef var name: String
 
        # The origin of the definition
        var location: Location
@@ -221,4 +221,6 @@ class MModule
                        abort
                end
        end
+
+       redef fun parent_concern do return mgroup
 end
index 6732a16..7481338 100644 (file)
@@ -33,6 +33,7 @@ import poset
 import location
 import mmodule
 import mdoc
+import ordered_tree
 private import more_collections
 
 redef class Model
@@ -106,6 +107,35 @@ redef class Model
 
        # The only null type
        var null_type: MNullType = new MNullType(self)
+
+       # Build an ordered tree with from `concerns`
+       fun concerns_tree(mconcerns: Collection[MConcern]): ConcernsTree do
+               var seen = new HashSet[MConcern]
+               var res = new ConcernsTree
+
+               var todo = new Array[MConcern]
+               todo.add_all mconcerns
+
+               while not todo.is_empty do
+                       var c = todo.pop
+                       if seen.has(c) then continue
+                       var pc = c.parent_concern
+                       if pc == null then
+                               res.add(null, c)
+                       else
+                               res.add(pc, c)
+                               todo.add(pc)
+                       end
+                       seen.add(c)
+               end
+
+               return res
+       end
+end
+
+# An OrderedTree that can be easily refined for display purposes
+class ConcernsTree
+       super OrderedTree[MConcern]
 end
 
 redef class MModule
@@ -302,7 +332,7 @@ class MClass
 
        # The short name of the class
        # In Nit, the name of a class cannot evolve in refinements
-       var name: String
+       redef var name: String
 
        # The canonical name of the class
        # Example: `"owner::module::MyClass"`
@@ -463,6 +493,9 @@ class MClassDef
                self.to_s = "{mmodule}#{mclass}"
        end
 
+       # Actually the name of the `mclass`
+       redef fun name do return mclass.name
+
        # All declared super-types
        # FIXME: quite ugly but not better idea yet
        var supertypes: Array[MClassType] = new Array[MClassType]
@@ -1514,7 +1547,7 @@ abstract class MProperty
        var intro_mclassdef: MClassDef
 
        # The (short) name of the property
-       var name: String
+       redef var name: String
 
        # The canonical name of the property
        # Example: "owner::my_module::MyClass::my_method"
@@ -1799,6 +1832,9 @@ abstract class MPropDef
                self.to_s = "{mclassdef}#{mproperty}"
        end
 
+       # Actually the name of the `mproperty`
+       redef fun name do return mproperty.name
+
        # Internal name combining the module, the class and the property
        # Example: "mymodule#MyClass#mymethod"
        redef var to_s: String
index 39df50b..666ce8e 100644 (file)
@@ -25,6 +25,15 @@ end
 # A named and possibly documented entity in the model.
 # This class is usefull to generalize presentation of entities to the human.
 abstract class MEntity
+       # The short (unqualified) name of this model entity
+       fun name: String is abstract
+end
+
+# Something that represents a concern
+abstract class MConcern
+       super MEntity
+       # The concern that contains `self` or null if `self` is the root of the concern hierarchy
+       fun parent_concern: nullable MConcern is abstract
 end
 
 # A visibility (for modules, class and properties)
index cad2e39..7bd502e 100644 (file)
@@ -21,10 +21,10 @@ import poset
 
 # A Nit project, thas encompass a product
 class MProject
-       super MEntity
+       super MConcern
 
        # The name of the project
-       var name: String
+       redef var name: String
 
        # The model of the project
        var model: Model
@@ -44,15 +44,18 @@ class MProject
                model.mprojects.add(self)
                model.mproject_by_name.add_one(name, self)
        end
+
+       # MProject are always roots of the concerns hierarchy
+       redef fun parent_concern do return null
 end
 
 # A group of modules in a project
 class MGroup
-       super MEntity
+       super MConcern
 
        # The name of the group
        # empty name for a default group in a single-module project
-       var name: String
+       redef var name: String
 
        # The englobing project
        var mproject: MProject
@@ -74,6 +77,9 @@ class MGroup
        # nesting group (see `parent`) is bigger
        var in_nesting: POSetElement[MGroup]
 
+       # Is `self` the root of its project?
+       fun is_root: Bool do return mproject.root == self
+
        # The filepath (usualy a directory) of the group, if any
        var filepath: nullable String writable
 
@@ -89,6 +95,11 @@ class MGroup
                end
        end
 
+       redef fun parent_concern do
+               if not is_root then return parent
+               return mproject
+       end
+
        redef fun to_s do return name
 end
 
index b2c741b..6decb0f 100644 (file)
@@ -19,6 +19,50 @@ module model_utils
 
 import modelbuilder
 
+redef class MGroup
+       fun in_nesting_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
+               var res = new HashSet[MClass]
+               var lst = in_nesting.direct_smallers
+               for mmodule in mmodules do res.add_all mmodule.filter_intro_mclasses(min_visibility)
+               for mgrp in lst do res.add_all mgrp.in_nesting_intro_mclasses(min_visibility)
+               return res
+       end
+
+       fun in_nesting_redef_mclasses(min_visibility: MVisibility): Set[MClass] do
+               var res = new HashSet[MClass]
+               var lst = in_nesting.direct_smallers
+               for mmodule in mmodules do res.add_all mmodule.filter_redef_mclasses(min_visibility)
+               for mgrp in lst do res.add_all mgrp.in_nesting_redef_mclasses(min_visibility)
+               return res
+       end
+
+       fun in_nesting_intro_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
+               var res = new HashSet[MClassDef]
+               var lst = in_nesting.direct_smallers
+               for mmodule in mmodules do res.add_all mmodule.intro_mclassdefs(min_visibility)
+               for mgrp in lst do res.add_all mgrp.in_nesting_intro_mclassdefs(min_visibility)
+               return res
+       end
+
+       fun in_nesting_redef_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
+               var res = new HashSet[MClassDef]
+               var lst = in_nesting.direct_smallers
+               for mmodule in mmodules do res.add_all mmodule.redef_mclassdefs(min_visibility)
+               for mgrp in lst do res.add_all mgrp.in_nesting_redef_mclassdefs(min_visibility)
+               return res
+       end
+
+       # Collect nested modules
+       fun collect_mmodules: Set[MModule] do
+               var res = new HashSet[MModule]
+               res.add_all mmodules
+               for mgroup in in_nesting.direct_smallers do
+                       res.add_all mgroup.collect_mmodules
+               end
+               return res
+       end
+end
+
 redef class MModule
 
        # The list of intro mclassdef in the module.
@@ -45,6 +89,17 @@ redef class MModule
                return res
        end
 
+       # The list of intro mclass in the module.
+       # with visibility >= to min_visibility
+       fun filter_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
+               var res = new HashSet[MClass]
+               for mclass in intro_mclasses do
+                       if mclass.visibility < min_visibility then continue
+                       res.add mclass
+               end
+               return res
+       end
+
        # Get the list of mclasses refined in 'self'.
        fun redef_mclasses: Set[MClass] do
                var mclasses = new HashSet[MClass]
@@ -54,6 +109,16 @@ redef class MModule
                return mclasses
        end
 
+       # Get the list of mclasses refined in 'self'.
+       fun filter_redef_mclasses(min_visibility: MVisibility): Set[MClass] do
+               var mclasses = new HashSet[MClass]
+               for c in mclassdefs do
+                       if c.mclass.visibility < min_visibility then continue
+                       if not c.is_intro then mclasses.add(c.mclass)
+               end
+               return mclasses
+       end
+
        # Get the list of all mclasses imported by 'self'.
        fun imported_mclasses: Set[MClass] do
                var mclasses = new HashSet[MClass]
@@ -67,7 +132,7 @@ redef class MModule
        fun in_nesting_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
                var res = new HashSet[MClass]
                for mmodule in in_nesting.greaters do
-                       for mclass in mmodule.intro_mclasses do
+                       for mclass in mmodule.filter_intro_mclasses(min_visibility) do
                                if mclass.visibility < min_visibility then continue
                                res.add mclass
                        end
@@ -78,7 +143,7 @@ redef class MModule
        fun in_nesting_redef_mclasses(min_visibility: MVisibility): Set[MClass] do
                var res = new HashSet[MClass]
                for mmodule in self.in_nesting.greaters do
-                       for mclass in mmodule.redef_mclasses do
+                       for mclass in mmodule.filter_redef_mclasses(min_visibility) do
                                if mclass.visibility < min_visibility then continue
                                res.add mclass
                        end
@@ -397,37 +462,10 @@ end
 
 # Sorters
 
-# Sort mmodules by their name
-class MModuleNameSorter
-       super AbstractSorter[MModule]
+# Sort mentities by their name
+class MEntityNameSorter
+       super AbstractSorter[MEntity]
        redef fun compare(a, b) do return a.name <=> b.name
        init do end
 end
 
-# Sort mclasses by their name
-class MClassNameSorter
-       super AbstractSorter[MClass]
-       redef fun compare(a, b) do return a.name <=> b.name
-       init do end
-end
-
-# Sort mclassdefs by their name
-class MClassDefNameSorter
-       super AbstractSorter[MClassDef]
-       redef fun compare(a, b) do return a.mclass.name <=> b.mclass.name
-       init do end
-end
-
-# Sort mproperties by their name
-class MPropertyNameSorter
-       super AbstractSorter[MProperty]
-       redef fun compare(a, b) do return a.name <=> b.name
-       init do end
-end
-
-# Sort mpropdefs by their name
-class MPropDefNameSorter
-       super AbstractSorter[MPropDef]
-       redef fun compare(a, b) do return a.mproperty.name <=> b.mproperty.name
-       init do end
-end
index 36c3815..dc48db8 100644 (file)
@@ -19,6 +19,7 @@ module nit
 
 import naive_interpreter
 import debugger
+import debugger_socket
 
 # Create a tool context to handle options and paths
 var toolcontext = new ToolContext
index 0e0d345..29be82b 100644 (file)
@@ -79,7 +79,7 @@ class NitIndex
                print "Loaded modules:"
                var mmodules = new Array[MModule]
                mmodules.add_all(model.mmodules)
-               var sorter = new MModuleNameSorter
+               var sorter = new MEntityNameSorter
                sorter.sort(mmodules)
                for m in mmodules do
                        print "\t{m.name}"
@@ -330,7 +330,7 @@ private class PagerMatchesRenderer
                        cats[key].add(mprop)
                end
                #sort groups
-               var sorter = new MModuleNameSorter
+               var sorter = new MEntityNameSorter
                var sorted = new Array[MModule]
                sorted.add_all(cats.keys)
                sorter.sort(sorted)
@@ -338,8 +338,7 @@ private class PagerMatchesRenderer
                for mmodule in sorted do
                        var mprops = cats[mmodule]
                        pager.add("# matches in module {mmodule.namespace.bold}")
-                       var sorterp = new MPropertyNameSorter
-                       sorterp.sort(mprops)
+                       sorter.sort(mprops)
                        for mprop in mprops do
 
                        end
@@ -394,7 +393,7 @@ redef class MModule
                pager.add(prototype)
                pager.add("{namespace}".bold.gray + " (lines {location.lines})".gray)
                pager.indent = pager.indent + 1
-               var sorter = new MModuleNameSorter
+               var sorter = new MEntityNameSorter
                # imported modules
                var imports = new Array[MModule]
                for mmodule in in_importation.direct_greaters.to_a do
@@ -412,7 +411,6 @@ redef class MModule
                        pager.indent = pager.indent - 1
                end
                # mclassdefs
-               var csorter = new MClassDefNameSorter
                var intros = new Array[MClassDef]
                var redefs = new Array[MClassDef]
                for mclassdef in mclassdefs do
@@ -424,7 +422,7 @@ redef class MModule
                end
                # introductions
                if not intros.is_empty then
-                       csorter.sort(intros)
+                       sorter.sort(intros)
                        pager.add("")
                        pager.add("== introduced classes".bold)
                        pager.indent = pager.indent + 1
@@ -436,7 +434,7 @@ redef class MModule
                end
                # refinements
                if not redefs.is_empty then
-                       csorter.sort(redefs)
+                       sorter.sort(redefs)
                        pager.add("")
                        pager.add("== refined classes".bold)
                        pager.indent = pager.indent + 1
@@ -489,6 +487,7 @@ redef class MClass
 
        redef fun content(index, pager) do
                # intro comment
+               var sorter = new MEntityNameSorter
                var mdoc = intro.mdoc
                if mdoc != null then
                        for comment in mdoc.content do pager.add(comment.green)
@@ -499,8 +498,7 @@ redef class MClass
                # parents
                var supers = self.in_hierarchy(index.mainmodule).direct_greaters.to_a
                if not supers.is_empty then
-                       var csorter = new MClassNameSorter
-                       csorter.sort(supers)
+                       sorter.sort(supers)
                        pager.add("")
                        pager.add("== supers".bold)
                        pager.indent = pager.indent + 1
@@ -522,13 +520,12 @@ redef class MClass
                        pager.indent = pager.indent - 1
                end
                # intro mproperties
-               var psorter = new MPropDefNameSorter
                var mpropdefs = intro.mpropdefs
                index.mainmodule.linearize_mpropdefs(mpropdefs)
                for cat in intro.cats2mpropdefs.keys do
                        var defs = intro.cats2mpropdefs[cat].to_a
                        if defs.is_empty then continue
-                       psorter.sort(defs)
+                       sorter.sort(defs)
                        pager.add("")
                        pager.add("== {cat}".bold)
                        pager.indent = pager.indent + 1
@@ -589,11 +586,11 @@ redef class MClassDef
                pager.add("{namespace}".bold.gray + " (lines {location.lines})".gray)
                pager.indent = pager.indent + 1
                var mpropdefs = self.mpropdefs
-               var psorter = new MPropDefNameSorter
+               var sorter = new MEntityNameSorter
                index.mainmodule.linearize_mpropdefs(mpropdefs)
                for cat in cats2mpropdefs.keys do
                        var defs = cats2mpropdefs[cat].to_a
-                       psorter.sort(defs)
+                       sorter.sort(defs)
                        if defs.is_empty then continue
                        pager.add("")
                        pager.add("== {cat}".bold)
diff --git a/tests/emscripten.skip b/tests/emscripten.skip
new file mode 100644 (file)
index 0000000..c782ec0
--- /dev/null
@@ -0,0 +1,2 @@
+init_inherit
+init_linext
diff --git a/tests/emscripten_nodejs.nit b/tests/emscripten_nodejs.nit
new file mode 100644 (file)
index 0000000..5ada70d
--- /dev/null
@@ -0,0 +1,13 @@
+import emscripten
+redef class IFStream
+       redef fun fill_buffer
+       do
+               print "NOT YET IMPLEMENTED"
+               abort
+       end
+       redef init open(f)
+       do
+               print "NOT YET IMPLEMENTED"
+               abort
+       end
+end
diff --git a/tests/sav/emscripten/emscripten_nodejs.res b/tests/sav/emscripten/emscripten_nodejs.res
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/sav/emscripten/fixme/base_attr_gen_alt1.res b/tests/sav/emscripten/fixme/base_attr_gen_alt1.res
new file mode 100644 (file)
index 0000000..b4de394
--- /dev/null
@@ -0,0 +1 @@
+11
diff --git a/tests/sav/emscripten/fixme/base_conflict_submodule_name.res b/tests/sav/emscripten/fixme/base_conflict_submodule_name.res
new file mode 100644 (file)
index 0000000..4ad3dc3
--- /dev/null
@@ -0,0 +1 @@
+UNDEFINED
diff --git a/tests/sav/emscripten/fixme/base_conflict_submodule_name_alt1.res b/tests/sav/emscripten/fixme/base_conflict_submodule_name_alt1.res
new file mode 100644 (file)
index 0000000..4ad3dc3
--- /dev/null
@@ -0,0 +1 @@
+UNDEFINED
diff --git a/tests/sav/emscripten/fixme/base_conflict_submodule_name_alt2.res b/tests/sav/emscripten/fixme/base_conflict_submodule_name_alt2.res
new file mode 100644 (file)
index 0000000..4ad3dc3
--- /dev/null
@@ -0,0 +1 @@
+UNDEFINED
diff --git a/tests/sav/emscripten_nodejs.res b/tests/sav/emscripten_nodejs.res
new file mode 100644 (file)
index 0000000..174d681
--- /dev/null
@@ -0,0 +1 @@
+Not executable (platform?)
diff --git a/tests/sav/test_ordered_tree.res b/tests/sav/test_ordered_tree.res
new file mode 100644 (file)
index 0000000..c009bd0
--- /dev/null
@@ -0,0 +1,21 @@
+1
+11
+111
+112
+12
+121
+122
+2
+21
+22
+--
+22
+21
+2
+122
+121
+12
+112
+111
+11
+1
diff --git a/tests/sav/test_ordered_tree2.res b/tests/sav/test_ordered_tree2.res
new file mode 100644 (file)
index 0000000..ee5edcf
--- /dev/null
@@ -0,0 +1,10 @@
+1
+|--11
+|  |--111
+|  `--112
+`--12
+   |--121
+   `--122
+2
+|--21
+`--22
diff --git a/tests/test_ordered_tree.nit b/tests/test_ordered_tree.nit
new file mode 100644 (file)
index 0000000..f759742
--- /dev/null
@@ -0,0 +1,31 @@
+# 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 ordered_tree
+
+var tree = new OrderedTree[Int]
+tree.add(null, 1)
+tree.add(1, 11)
+tree.add(11, 111)
+tree.add(11, 112)
+tree.add(1, 12)
+tree.add(12, 121)
+tree.add(12, 122)
+tree.add(null, 2)
+tree.add(2, 21)
+tree.add(2, 22)
+
+for i in tree do print i
+print "--"
+for i in tree.to_a.reversed do print i
diff --git a/tests/test_ordered_tree2.nit b/tests/test_ordered_tree2.nit
new file mode 100644 (file)
index 0000000..40e848a
--- /dev/null
@@ -0,0 +1,29 @@
+# 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 ordered_tree
+
+var tree = new OrderedTree[Int]
+tree.add(null, 1)
+tree.add(1, 11)
+tree.add(11, 111)
+tree.add(11, 112)
+tree.add(1, 12)
+tree.add(12, 121)
+tree.add(12, 122)
+tree.add(null, 2)
+tree.add(2, 21)
+tree.add(2, 22)
+
+tree.write_to(stdout)
index b8ecd0a..6cfb9be 100755 (executable)
@@ -19,6 +19,7 @@
 
 # Set lang do default to avoid failed tests because of locale
 export LANG=C
+export LC_ALL=C
 export NIT_TESTING=true
 
 unset NIT_DIR
@@ -318,6 +319,11 @@ case $engine in
        niti)
                enginebinname=nit
                ;;
+       emscripten)
+               enginebinname=nitg
+               OPT="-m emscripten_nodejs.nit --semi-global $OPT"
+               savdirs="sav/nitg-sg/"
+               ;;
        nitc)
                echo "disabled engine $engine"
                exit 0
@@ -409,6 +415,11 @@ for ii in "$@"; do
                        inputs=/dev/null
                fi
 
+               ffout="$ff.bin"
+               if [ "$engine" = "emscripten" ]; then
+                       ffout="$ff.bin.js"
+               fi
+
                if [ "$engine" = "niti" ]; then
                        cat > "./$ff.bin" <<END
 exec $NITC --no-color $OPT "$i" $includes -- "\$@"
@@ -426,16 +437,25 @@ END
                        # Compile
                        if [ "x$verbose" = "xtrue" ]; then
                                echo ""
-                               echo $NITC --no-color $OPT -o "$ff.bin" "$i" "$includes" $nocc
+                               echo $NITC --no-color $OPT -o "$ffout" "$i" "$includes" $nocc
                        fi
                        NIT_NO_STACK=1 JNI_LIB_PATH=$JNI_LIB_PATH JAVA_HOME=$JAVA_HOME \
-                               $TIMEOUT $NITC --no-color $OPT -o "$ff.bin" "$i" $includes $nocc 2> "$ff.cmp.err" > "$ff.compile.log"
+                               $TIMEOUT $NITC --no-color $OPT -o "$ffout" "$i" $includes $nocc 2> "$ff.cmp.err" > "$ff.compile.log"
                        ERR=$?
                        if [ "x$verbose" = "xtrue" ]; then
                                cat "$ff.compile.log"
                                cat >&2 "$ff.cmp.err"
                        fi
                fi
+               if [ "$engine" = "emscripten" ]; then
+                       echo > "./$ff.bin" "nodejs $ffout \"\$@\""
+                       chmod +x "$ff.bin"
+                       if grep "Fatal Error: more than one primitive class" "$ff.compile.log" > /dev/null; then
+                               echo " [skip] do no not imports kernel"
+                               echo >>$xml "<testcase classname='$pack' name='$bf'><skipped/></testcase>"
+                               continue
+                       fi
+               fi
                if [ "$ERR" != 0 ]; then
                        echo -n "! "
                        cat "$ff.compile.log" "$ff.cmp.err" > "$ff.res"