Merge: names and concerns in model
authorJean Privat <jean@pryen.org>
Thu, 26 Jun 2014 01:10:11 +0000 (21:10 -0400)
committerJean Privat <jean@pryen.org>
Thu, 26 Jun 2014 01:10:11 +0000 (21:10 -0400)
First commit adapt the MEntity implementation to it's documentation by moving up the `name` property.

Second commit introduce a new kind of MEntity: MConcern that will be used in documentation tools as a common interface for MProject, MGroup and MModule.

Pull-Request: #522
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Jean Privat <jean@pryen.org>

26 files changed:
.mailmap
benchmarks/bench_common.sh [new file with mode: 0644]
benchmarks/bench_engines.sh
benchmarks/bench_languages.sh
c_src/Makefile
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/global_compiler.nit
src/mkcsrc
src/model_utils.nit
src/nit.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/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 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 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 b2c741b..be3fd4d 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
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
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?)
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"