Merge: check_contrib: filter-out contrib/nitc when checking Makefile of projects
authorJean Privat <jean@pryen.org>
Fri, 11 Dec 2015 00:31:31 +0000 (19:31 -0500)
committerJean Privat <jean@pryen.org>
Fri, 11 Dec 2015 00:31:31 +0000 (19:31 -0500)
src/Makefile is already executed at the begin of the tests, so a double execution is mostly useless and time-expensive.

Pull-Request: #1888
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>

55 files changed:
contrib/crazy_moles/src/moles.nit
contrib/nitiwiki/Makefile
contrib/nitiwiki/README.md
contrib/nitiwiki/src/wiki_edit.nit [new file with mode: 0644]
contrib/nitrpg/src/statistics.nit
contrib/pep8analysis/www/index.html
contrib/refund/src/refund_base.nit
contrib/tinks/src/client/client.nit
examples/mnit_ballz/src/ballz_android.nit
examples/mnit_ballz/src/ballz_linux.nit
examples/mnit_dino/src/dino.nit
lib/android/assets_and_resources.nit
lib/buffered_ropes.ini [deleted file]
lib/buffered_ropes.nit [deleted file]
lib/core/file.nit
lib/core/kernel.nit
lib/core/math.nit
lib/core/text/abstract_text.nit
lib/core/time.nit
lib/csv/csv.nit
lib/gamnit/limit_fps.nit [new file with mode: 0644]
lib/geometry/boxes.nit
lib/github/api.nit
lib/github/events.nit
lib/html/bootstrap.nit
lib/html/html.nit
lib/markdown/markdown.nit
lib/mnit/mnit_fps.nit
lib/nitcorn/examples/src/xymus_net.nit
src/compiler/abstract_compiler.nit
src/frontend/i18n_phase.nit
src/modelize/modelize_property.nit
src/parser/parser_nodes.nit
src/semantize/auto_super_init.nit
tests/base_init_auto.nit
tests/base_init_combine.nit
tests/base_init_linext2.nit
tests/base_init_simple.nit
tests/base_init_super_call2.nit
tests/sav/base_init_combine_alt1.res
tests/sav/base_init_super_call.res
tests/sav/base_init_super_call2_alt3.res
tests/sav/base_init_super_call2_alt6.res
tests/sav/base_init_super_call3.res
tests/sav/base_init_super_call_alt3.res
tests/sav/base_init_super_call_alt6.res
tests/sav/error_class_glob.res
tests/sav/nitce/fixme/base_gen_reassign_alt4.res
tests/sav/nitce/fixme/base_gen_reassign_alt5.res
tests/sav/nitce/fixme/base_gen_reassign_alt6.res
tests/sav/nituml_args3.res
tests/test_ffi_c_more_callbacks.nit
tests/test_flatrope.nit
tests/test_multi_init.nit
tests/test_text.nit

index 27ca3ad..505ce49 100644 (file)
@@ -318,7 +318,7 @@ redef class App
        do
                super
 
-               maximum_fps = 50
+               maximum_fps = 50.0
        end
 
        redef fun frame_core(display)
index 57d2cda..f040751 100644 (file)
@@ -1,9 +1,12 @@
-all: nitiwiki
+all: nitiwiki bin/nitiwiki_server
 
 nitiwiki:
        mkdir -p bin
        ../../bin/nitc src/nitiwiki.nit -o bin/nitiwiki
 
+bin/nitiwiki_server: $(shell ../../bin/nitls -M src/wiki_edit.nit)
+       ../../bin/nitc -o $@ src/wiki_edit.nit
+
 check: nitiwiki
        cd tests; make
 
index f9c7c45..757fa36 100644 (file)
@@ -250,7 +250,7 @@ Every template can access to:
 * `SUBTITLE`: Wiki description
 * `LOGO`: Wiki logo image path
 
-Additionnal macros can be used in specialized templates.
+Additional macros can be used in specialized templates.
 
 ### Main template
 
@@ -363,3 +363,17 @@ from git:
 Be sure to set `wiki.rsync_dir` in order to correctly push your changes.
 When using `--rsync`, keep in mind that the rendered output must be configured
 to work on the web server.
+
+### Serve and edit with nitiwiki_server
+
+nitiwiki_server is a lightweight web server to publish the generated files
+and accept modifications from a web form.
+
+The binary available in `bin/nitiwiki_server` is configured for simple usage or demo.
+The source of the server, at `src/wiki_edit`, can be tweaked for more advanced use.
+It is also possible to import the source and add an instance of `EditAction` to a custom nitcorn server.
+
+To launch the server, change directory to the root of the wiki and run `nitiwiki_server`.
+It uses `config.ini` from the local directory and listen on localhost:8080.
+The template should define the macro `%EDIT%` and `config.ini` should define `wiki.edit=/edit/`.
+To limit who can edit the wiki, list the md5 sum of accepted passwords (one per line) in the local file `passwords`.
diff --git a/contrib/nitiwiki/src/wiki_edit.nit b/contrib/nitiwiki/src/wiki_edit.nit
new file mode 100644 (file)
index 0000000..7dd6012
--- /dev/null
@@ -0,0 +1,200 @@
+# 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.
+
+# Web server to server generated files and modify the wiki from a web form
+module wiki_edit
+
+import nitcorn
+import markdown
+import md5
+
+intrude import wiki_html
+
+# Page for editing markdown source
+class WikiEditForm
+       super WikiArticle
+
+       # Part of the title before the name of the page
+       var title_prefix: String
+
+       # Markdown content, for previews
+       redef var md
+
+       # Custom HTML code, for forms and links
+       var html: String
+
+       init do content = (md or else "").md_to_html.to_s + html
+
+       redef fun dir_href do return "edit" / href
+
+       redef fun tpl_article
+       do
+               var s = super
+               s.title = title_prefix + title
+               return s
+       end
+
+       # Fill and return a new `HttpResponse` with this page content
+       fun to_http_response: HttpResponse
+       do
+               var resp = new HttpResponse(200)
+               resp.body = tpl_page.write_to_string
+               return resp
+       end
+end
+
+# Action to serve edit forms, show previews and apply changes
+class EditAction
+       super Action
+
+       # Full public URL for the root of this wiki
+       var root_url: String
+
+       # Path to the wiki config
+       var config_file_path: String
+
+       # Configuration of the Wiki, loaded once
+       var wiki_config = new WikiConfig(config_file_path) is lazy
+
+       # Path to the root of the wiki
+       private var wiki_root: String = config_file_path.dirname is lazy
+
+       # Path to the source files
+       private var source_dir: String = (wiki_root / wiki_config.source_dir).simplify_path + "/" is lazy
+
+       # List of acceptable password to apply modifications
+       #
+       # If `null`, no password checks are applied and all modifications are accepted.
+       var passwords: nullable Collection[String]
+
+       # Reload the wiki instance with the latest changes
+       fun wiki: Nitiwiki
+       do
+               var wiki = new Nitiwiki(wiki_config)
+               wiki.parse
+               return wiki
+       end
+
+       redef fun answer(http_request, turi)
+       do
+               var action = http_request.string_arg("action")
+               var markdown = http_request.post_args.get_or_default("content", "")
+
+               var file_path = turi.strip_leading_slash
+               file_path = wiki_root / file_path
+
+               var abs_file_path = file_path.to_absolute_path
+               var abs_source_dir = source_dir.to_absolute_path
+
+               if not abs_file_path.has_prefix(abs_source_dir) then
+                       # Attempting to access a file outside the source directory
+                       var entity = new WikiEditForm(wiki, turi.strip_leading_slash,
+                               "Access denied: ", "", "<p>Target outside of the source directory</p>")
+                       return entity.to_http_response
+               end
+
+               if action == "Submit" then
+                       var passwords = passwords
+                       var password = http_request.post_args.get_or_null("password")
+                       if passwords != null and (password == null or not passwords.has(password.md5)) then
+                               # Deny modification
+                               var entity = new WikiEditForm(wiki, turi.strip_leading_slash,
+                                       "Changes rejected: ", "", "<p>Password invalid</p>")
+                               return entity.to_http_response
+                       end
+
+                       # Save markdown source
+                       markdown = markdown.replace('\r', "")
+                       markdown.write_to_file file_path
+
+                       # Update HTML files
+                       var wiki = wiki
+                       wiki.render
+
+                       var link
+                       if turi.has_prefix("/pages/") then
+                               link = root_url / turi.substring_from(7)
+                       else link = root_url / turi
+                       link = link.strip_extension(".md") + ".html"
+
+                       # Show confirmation
+                       var body = """
+<p>Your edits were recorded and the file is updated: <a href="{{{link}}}">{{{link}}}</a></p>
+"""
+                       var entity = new WikiEditForm(wiki, turi.strip_leading_slash, "Changes saved: ", "", body)
+                       return entity.to_http_response
+               else
+                       # Show edit form, and preview when requested
+
+                       # When not in a preview, use the local content of the file
+                       if action != "Preview" then markdown = file_path.to_path.read_all
+
+                       var form = """
+<form method="POST" action="/edit{{{turi}}}">
+       You may edit the file. When you are done, click on "Submit".<br/>
+       <textarea name="content" rows="30" cols="80">{{{markdown.html_escape}}}</textarea><br/>
+"""
+                       if passwords != null then form += """
+       Password: <input type="password" name="password"><br/>
+"""
+                       form += """
+       <input type="submit" name="action" value="Preview">
+       <input type="submit" name="action" value="Submit">
+</form>
+"""
+
+                       # Show processed markdown only on preview
+                       if action != "Preview" then markdown = ""
+
+                       var entity = new WikiEditForm(wiki, turi.strip_leading_slash, "Edit source: ", markdown, form)
+                       return entity.to_http_response
+               end
+       end
+end
+
+redef class String
+       private fun strip_leading_slash: String
+       do
+               if has_prefix("/") then return substring_from(1)
+               return self
+       end
+
+       private fun to_absolute_path: String
+       do
+               return (getcwd / self).simplify_path
+       end
+end
+
+var config_file_path = "config.ini"
+var iface = "localhost:8080"
+var password_file_path = "passwords"
+
+# Load passwords for file
+var passwords = if password_file_path.file_exists then
+               password_file_path.to_path.read_lines
+       else null
+
+var vh = new VirtualHost(iface)
+
+# Serve Markdown editing form
+var action = new EditAction("http://" + iface, config_file_path, passwords)
+vh.routes.add new Route("/edit", action)
+
+# Serve the static (and generated) content
+var path_to_public_files = config_file_path.dirname / action.wiki_config.out_dir
+vh.routes.add new Route(null, new FileServer(path_to_public_files))
+
+var factory = new HttpFactory.and_libevent
+factory.config.virtual_hosts.add vh
+factory.run
index 0bdb421..2827ae9 100644 (file)
@@ -166,6 +166,7 @@ class GameStats
 
        # Load `self` from saved data.
        init from_json(game: Game, period: String, owner: GameEntity, json: JsonObject) do
+               init(game, period, owner)
                var values = json.get_or_null("values")
                if not values isa JsonObject then return
                for k, v in values do self[k] = v.as(Int)
index 6f7598a..46b62be 100644 (file)
     <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
       <ul class="nav navbar-nav">
         <li><a href="http://xymus.net/ens/">Enseignement</a></li>
-        <li class="active"><a href="http://pep8.xymus.net/">Pep/8 Analysis</a></li>
+        <li><a href="http://xymus.net/opportunity/">Opportunité</a></li>
         <li><a href="http://tnitter.xymus.net/">Tnitter</a></li>
+        <li class="active"><a href="http://pep8.xymus.net/">Pep/8 Analysis</a></li>
         <li><a href="http://benitlux.xymus.net/">Benitlux</a></li>
-               <li><a href="http://xymus.net/opportunity/">Opportunité</a></li>
-        <li><a href="http://nitlanguage.org/">Nit</a></li>
       </ul>
 
       <ul class="nav navbar-nav pull-right">
index ec1de5a..48e1833 100644 (file)
@@ -352,7 +352,7 @@ class UniqCare
        # * `max`: max amount refunded for this `Care` in a reclamation sheet.
        # * `month_max`: max amount refunded by month.
        init with_vals(id: Int, cover: Float, max, month_max: nullable Dollar) do
-               self.id = id
+               init(id)
                self.cover = cover
                self.max = max
                self.month_max = month_max
@@ -382,7 +382,7 @@ class RangeCare
        # * `max`: max amount refunded for this `Care` in a reclamation sheet.
        # * `month_max`: max amount refunded by month.
        init with_vals(id: Range[Int], cover: Float, max, month_max: nullable Dollar) do
-               self.id = id
+               init(id)
                self.cover = cover
                self.max = max
                self.month_max = month_max
index 8dad5eb..6975ed7 100644 (file)
@@ -80,7 +80,7 @@ redef class App
        redef fun on_create
        do
                super
-               maximum_fps = 60
+               maximum_fps = 60.0
                assets.assign_images_to_story context.game.story
        end
 
@@ -127,7 +127,7 @@ redef class App
                        return new LocalServerContext
                else
                        print "Connecting to:{address}:{port}"
-                       maximum_fps = 0
+                       maximum_fps = 0.0
 
                        # Args are: tinks server_address {port}
                        #var address = "riph" # args[0]
index dc934e7..0f46bfc 100644 (file)
@@ -38,7 +38,7 @@ redef class App
                gyroscope.enabled = true
                light.enabled = true
                proximity.enabled = true
-               maximum_fps = 50
+               maximum_fps = 50.0
                sensors_support_enabled = true
                super
        end
index 6f089a8..bd2e563 100644 (file)
@@ -29,7 +29,7 @@ redef class App
 
        redef fun run
        do
-               maximum_fps = 50
+               maximum_fps = 50.0
                super
        end
 
index df97ad5..27ced99 100644 (file)
@@ -39,7 +39,7 @@ redef class App
        do
                super
 
-               maximum_fps = 80
+               maximum_fps = 80.0
 
                var display = display
                assert display != null
index 624a03d..8bbc7da 100644 (file)
@@ -218,8 +218,7 @@ class ResourcesManager
 
        private init native(res: NativeResources, app_package: String)
        do
-               self.android_resources = res.new_global_ref
-               self.app_package = app_package
+               init(res.new_global_ref, app_package)
        end
 
        # Get a color from resources
diff --git a/lib/buffered_ropes.ini b/lib/buffered_ropes.ini
deleted file mode 100644 (file)
index 280bea6..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-[package]
-name=buffered_ropes
-tags=algo,text,lib
-maintainer=Lucas Bajolet <r4pass@hotmail.com>
-license=Apache-2.0
-[upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/buffered_ropes.nit
-git=https://github.com/nitlang/nit.git
-git.directory=lib/buffered_ropes.nit
-homepage=http://nitlanguage.org
-issues=https://github.com/nitlang/nit/issues
diff --git a/lib/buffered_ropes.nit b/lib/buffered_ropes.nit
deleted file mode 100644 (file)
index fcc90c7..0000000
+++ /dev/null
@@ -1,346 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT.  This software is
-# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without  even  the implied warranty of  MERCHANTABILITY or  FITNESS FOR A
-# PARTICULAR PURPOSE.  You can modify it is you want,  provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You  are  allowed  to  redistribute it and sell it, alone or is a part of
-# another product.
-
-# Ropes with a special kind of Leaves that act similar to a `Buffer`
-#
-# When using this module, re-allocations are limited by the introduction
-# of a larger-than-necessary buffered area for the native part of a `String`
-# in an append-only fashion.
-#
-# Concretely, when concatenating two small strings of length `n` + `m` < `maxlen`
-# What happens is that a `maxlen` byte buffer is allocated, ready to receive more
-# bytes a posteriori without necessarily reallocating a new byte array.
-#
-# Theoretically, this should lower the number of concatenations
-# and reallocations when concatenating `String` objects.
-module buffered_ropes
-
-intrude import core::text::ropes
-
-# Hidden buffer, used to simulate a `FlatBuffer` on a short string.
-#
-# This is to be used by low-level APIs because of its lack of
-# safety, if you use it, make sure you know what you are doing !
-#
-# Practically, it is the underlying representation of a `Leaf` in
-# the `Rope` block, its advantage is that it saves a bit more space
-# for future concatenations, without risking to overwrite previously
-# used space, making it suitable for Strings.
-#
-# Note for future use : Should there be parallel capacity in Nit at
-# some point, this is NOT thread safe !
-private class ManualBuffer
-       var ns: NativeString is noinit
-       # Current position in the `NativeString`
-       #
-       # It is used by the clients of `ManualBuffer` as a guard
-       # to detect if the concatenation in the `ManualBuffer`
-       # is safe or not.
-       #
-       # i.e. :
-       # Say we have two strings `x` and `y` referencing the
-       # same `ManualBuffer` `b`, `y` is the concatenation of
-       # `x` and another string.
-       #
-       # If we try to concatenate a `String` `z` to `x`, a new
-       # `ManualBuffer` will be created since `pos` and `x.length`
-       # do not match.
-       #
-       # However, if we concatenate the same `String` to `y`,
-       # the contents of `z` will be copied to the `ManualBuffer`.
-       var pos = 0
-
-       init do ns = new NativeString(maxlen)
-
-       fun [](i: Int): Byte do return ns[i]
-end
-
-# Simple implementation of the iterator on Substrings for `Leaf`
-#
-# Basically just returns `self` encapsulated in a `FlatString`.
-private class LeafSubstrings
-       super IndexedIterator[FlatText]
-
-       var leaf: Leaf
-       var str: FlatString is noinit
-       var avail = true
-
-       init do
-               str = new FlatString.with_infos(leaf.buf.ns, leaf.length, 0, leaf.length - 1)
-       end
-
-       redef fun is_ok do return avail
-
-       redef fun next do avail = false
-
-       redef fun index do return 0
-
-       redef fun item do return str
-end
-
-# Leaf of a `Rope`, used as a buffered area for speedy concatenation.
-private class Leaf
-       super String
-       super Rope
-
-       var buf: ManualBuffer
-       var bns: NativeString is noinit
-       redef var length is noinit
-
-       # Unsafe, but since it is an experiment, don't mind
-       redef fun bytelen do return length
-
-       redef fun empty do return new Leaf(new ManualBuffer)
-
-       redef fun to_cstring do
-               var len = length
-               var ns = new NativeString(len + 1)
-               ns[len] = 0u8
-               buf.ns.copy_to(ns, len, 0, 0)
-               return ns
-       end
-
-       redef fun substrings do return new LeafSubstrings(self)
-
-       redef fun [](i) do return buf[i].to_i.code_point
-
-       init do
-               bns = buf.ns
-               length = buf.pos
-       end
-
-       redef fun output do new FlatString.with_infos(buf.ns, length, 0, length - 1).output
-
-       redef fun to_upper do
-               var x = new FlatBuffer
-               for i in chars do x.add(i.to_upper)
-               return x.to_s
-       end
-
-       redef fun to_lower do
-               var x = new FlatBuffer
-               for i in chars do x.add(i.to_lower)
-               return x.to_s
-       end
-
-       redef fun reversed do
-               var x = new ManualBuffer
-               var nns = x.ns
-               var ns = bns
-               var mlen = length
-               var j = mlen - 1
-               for i in [0 .. mlen[ do
-                       nns[j] = ns[i]
-                       j -= 1
-               end
-               x.pos = mlen - 1
-               return new Leaf(x)
-       end
-
-       redef fun substring(from, len) do
-               return new FlatString.with_infos(buf.ns, len, from, from + len - 1)
-       end
-
-       redef fun insert_at(s, pos) do
-               var l = substring(0, pos)
-               var r = substring_from(pos)
-               return l + s + r
-       end
-
-       redef fun +(o) do
-               var s = o.to_s
-               var slen = s.bytelen
-               var mlen = bytelen
-               if slen == 0 then return self
-               if mlen == 0 then return s
-               var nlen = mlen + slen
-               if nlen > maxlen then return new Concat(self, s)
-               if s isa FlatString then
-                       var bpos = buf.pos
-                       var sits = s.items
-                       if bpos == mlen then
-                               sits.copy_to(buf.ns, slen, s.first_byte, bpos)
-                               buf.pos = bpos + slen
-                               return new Leaf(buf)
-                       else
-                               var b = new ManualBuffer
-                               var nbns = b.ns
-                               bns.copy_to(nbns, mlen, 0, 0)
-                               sits.copy_to(nbns, slen, s.first_byte, mlen)
-                               b.pos = nlen
-                               return new Leaf(b)
-                       end
-               else if s isa Leaf then
-                       var bpos = buf.pos
-                       var sbns = s.bns
-                       if bpos == mlen then
-                               sbns.copy_to(bns, slen, 0, bpos)
-                               buf.pos += slen
-                               return new Leaf(buf)
-                       else
-                               var b = new ManualBuffer
-                               var nbns = b.ns
-                               bns.copy_to(nbns, mlen, 0, 0)
-                               sbns.copy_to(nbns, slen, 0, mlen)
-                               b.pos = nlen
-                               return new Leaf(b)
-                       end
-               else if s isa Concat then
-                       if not s.left isa Concat then
-                               return new Concat(self + s.left, s.right)
-                       end
-                       return new Concat(self, s)
-               else
-                       var bpos = buf.pos
-                       var b = buf
-                       if bpos != mlen then
-                               b = new ManualBuffer
-                               bns.copy_to(b.ns, mlen, 0, 0)
-                       end
-                       for i in s.bytes do
-                               bns[bpos] = i
-                               bpos += 1
-                       end
-                       return new Leaf(b)
-               end
-       end
-end
-
-redef class Concat
-       redef fun to_cstring do
-               var len = length
-               var ns = new NativeString(len + 1)
-               ns[len] = 0u8
-               var off = 0
-               for i in substrings do
-                       var ilen = i.length
-                       if i isa FlatString then
-                               i.items.copy_to(ns, ilen, i.first_byte, off)
-                       else if i isa Leaf then
-                               i.buf.ns.copy_to(ns, ilen, 0, off)
-                       else
-                               abort
-                       end
-                       off += ilen
-               end
-               return ns
-       end
-
-       redef fun +(o) do
-               var s = o.to_s
-               var slen = s.length
-               if s isa FlatString then
-                       var r = right
-                       var rlen = r.length
-                       if rlen + slen > maxlen then return new Concat(left, new Concat(r, s))
-                       return new Concat(left, r + s)
-               else if s isa Concat then
-                       return new Concat(self, s)
-               else if s isa Leaf then
-                       var r = right
-                       var rlen = r.length
-                       if rlen + slen > maxlen then return new Concat(left, new Concat(r, s))
-                       return new Concat(left, r + s)
-               else
-                       abort
-               end
-       end
-end
-
-redef class FlatString
-       redef fun +(o) do
-               var s = o.to_s
-               var slen = s.length
-               var mlen = length
-               if slen == 0 then return self
-               if mlen == 0 then return s
-               if s isa FlatString then
-                       if slen + mlen > maxlen then return new Concat(self, s)
-                       var mits = items
-                       var sifrom = s.first_byte
-                       var mifrom = first_byte
-                       var sits = s.items
-                       var b = new ManualBuffer
-                       var bns = b.ns
-                       mits.copy_to(bns, mlen, mifrom, 0)
-                       sits.copy_to(bns, slen, sifrom, mlen)
-                       b.pos = mlen + slen
-                       return new Leaf(b)
-               else if s isa Concat then
-                       var sl = s.left
-                       var sllen = sl.length
-                       if sllen + mlen > maxlen then return new Concat(self, s)
-                       return new Concat(sl + self, s.right)
-               else if s isa Leaf then
-                       if slen + mlen > maxlen then return new Concat(self, s)
-                       var mifrom = first_byte
-                       var sb = s.buf
-                       var b = new ManualBuffer
-                       var bns = b.ns
-                       items.copy_to(bns, mlen, mifrom, 0)
-                       sb.ns.copy_to(bns, slen, 0, mlen)
-                       b.pos = mlen + slen
-                       return new Leaf(b)
-               else
-                       abort
-               end
-       end
-end
-
-redef class Array[E]
-
-       # Fast implementation
-       redef fun to_s do
-               var l = length
-               if l == 0 then return ""
-               if l == 1 then if self[0] == null then return "" else return self[0].to_s
-               var its = _items
-               var na = new NativeArray[String](l)
-               var i = 0
-               var sl = 0
-               var mypos = 0
-               while i < l do
-                       var itsi = its[i]
-                       if itsi == null then
-                               i += 1
-                               continue
-                       end
-                       var tmp = itsi.to_s
-                       sl += tmp.length
-                       na[mypos] = tmp
-                       i += 1
-                       mypos += 1
-               end
-               var ns = new NativeString(sl + 1)
-               ns[sl] = 0u8
-               i = 0
-               var off = 0
-               while i < mypos do
-                       var tmp = na[i]
-                       var tpl = tmp.length
-                       if tmp isa FlatString then
-                               tmp.items.copy_to(ns, tpl, tmp.first_byte, off)
-                               off += tpl
-                       else
-                               for j in tmp.substrings do
-                                       var slen = j.length
-                                       if j isa FlatString then
-                                               j.items.copy_to(ns, slen, j.first_byte, off)
-                                       else if j isa Leaf then
-                                               j.buf.ns.copy_to(ns, slen, 0, off)
-                                       end
-                                       off += slen
-                               end
-                       end
-                       i += 1
-               end
-               return ns.to_s_with_length(sl)
-       end
-end
index 03955eb..fd848e1 100644 (file)
@@ -959,10 +959,13 @@ redef class String
        end
 
        # Return the canonicalized absolute pathname (see POSIX function `realpath`)
+       #
+       # Require: `file_exists`
        fun realpath: String do
                var cs = to_cstring.file_realpath
+               assert file_exists
                var res = cs.to_s_with_copy
-               # cs.free_malloc # FIXME memory leak
+               cs.free
                return res
        end
 
index 84bd844..125e95f 100644 (file)
@@ -644,17 +644,23 @@ universal Byte
        # `i` bits shift fo the left
        #
        #     assert 5u8 << 1    == 10u8
-       fun <<(i: Int): Byte `{ return self << i; `}
+       fun <<(i: Int): Byte is intern do return lsh(i)
+
+       private fun lsh(i: Int): Byte `{ return self << i; `}
 
        # `i` bits shift fo the right
        #
        #     assert 5u8 >> 1    == 2u8
-       fun >>(i: Int): Byte `{ return self >> i; `}
+       fun >>(i: Int): Byte is intern do return rsh(i)
+
+       private fun rsh(i: Int): Byte `{ return self >> i; `}
 
        # Returns the character equivalent of `self`
        #
        # REQUIRE: `self <= 127u8`
-       fun ascii: Char `{ return (uint32_t)self; `}
+       fun ascii: Char is intern do return ffi_ascii
+
+       private fun ffi_ascii: Char `{ return (uint32_t)self; `}
 
        redef fun to_i is intern
        redef fun to_f is intern
@@ -743,12 +749,16 @@ universal Int
        # `i` bits shift fo the left
        #
        #     assert 5 << 1    == 10
-       fun <<(i: Int): Int `{ return self << i; `}
+       fun <<(i: Int): Int is intern do return lsh(i)
+
+       private fun lsh(i: Int): Int `{ return self << i; `}
 
        # `i` bits shift fo the right
        #
        #     assert 5 >> 1    == 2
-       fun >>(i: Int): Int `{ return self >> i; `}
+       fun >>(i: Int): Int is intern do return rsh(i)
+
+       private fun rsh(i: Int): Int `{ return self >> i; `}
 
        redef fun to_i do return self
        redef fun to_f is intern
@@ -807,7 +817,9 @@ universal Int
        #     assert 65.code_point == 'A'
        #     assert 10.code_point == '\n'
        #     assert 0x220B.code_point == '∋'
-       fun code_point: Char `{ return (uint32_t)self; `}
+       fun code_point: Char is intern do return cp
+
+       private fun cp: Char `{ return (uint32_t)self; `}
 
        # Number of digits of an integer in base `b` (plus one if negative)
        #
@@ -878,15 +890,7 @@ universal Int
        #     assert (-10).abs   == 10
        #     assert 10.abs    == 10
        #     assert 0.abs     == 0
-       fun abs: Int
-       do
-           if self >= 0
-           then
-               return self
-           else
-               return -1 * self
-           end
-       end
+       fun abs: Int do return if self >= 0 then self else -self
 end
 
 # Native characters.
@@ -961,7 +965,9 @@ universal Char
        #     assert 'A'.code_point == 65
        #     assert '\n'.code_point == 10
        #     assert '∋'.code_point == 0x220B
-       fun code_point: Int `{ return (long)self; `}
+       fun code_point: Int is intern do return cp
+
+       private fun cp: Int `{ return (long)self; `}
 
        # Is `self` an ASCII character ?
        #
index c08c735..f2a3f99 100644 (file)
@@ -67,12 +67,16 @@ redef class Int
        # Returns the result of a binary AND operation on `self` and `i`
        #
        #     assert 0x10 & 0x01 == 0
-       fun &(i: Int): Int `{ return self & i; `}
+       fun &(i: Int): Int is intern do return band(i)
+
+       private fun band(i: Int): Int `{ return self & i; `}
 
        # Returns the result of a binary OR operation on `self` and `i`
        #
        #     assert 0x10 | 0x01 == 0x11
-       fun |(i: Int): Int `{ return self | i; `}
+       fun |(i: Int): Int is intern do return bor(i)
+
+       private fun bor(i: Int): Int `{ return self | i; `}
 
        # Returns the result of a binary XOR operation on `self` and `i`
        #
@@ -175,7 +179,9 @@ redef class Byte
        # Returns the result of a binary AND operation on `self` and `i`
        #
        #     assert 0x10u8 & 0x01u8 == 0u8
-       fun &(i: Byte): Byte `{ return self & i; `}
+       fun &(i: Byte): Byte is intern do return band(i)
+
+       private fun band(i: Byte): Byte `{ return self & i; `}
 
        # Returns the result of a binary OR operation on `self` and `i`
        #
index 76823e2..cacee99 100644 (file)
@@ -1709,6 +1709,16 @@ redef class Char
                return (self >= 'a' and self <= 'z') or (self >= 'A' and self <= 'Z')
        end
 
+       # Is `self` an hexadecimal digit ?
+       #
+       #     assert 'A'.is_hexdigit
+       #     assert not 'G'.is_hexdigit
+       #     assert 'a'.is_hexdigit
+       #     assert not 'g'.is_hexdigit
+       #     assert '5'.is_hexdigit
+       fun is_hexdigit: Bool do return (self >= '0' and self <= '9') or (self >= 'A' and self <= 'F') or
+                                       (self >= 'a' and self <= 'f')
+
        # Returns true if the char is an alpha or a numeric digit
        #
        #     assert 'a'.is_alphanumeric
index 6c99016..5fc37f2 100644 (file)
@@ -32,6 +32,16 @@ redef class Sys
        `}
 end
 
+redef class Float
+       # Sleep approximately `self` seconds
+       fun sleep `{
+               time_t s = self;
+               long ns = (self-s) * 1000000000.0;
+               const struct timespec req = {s, ns};
+               nanosleep(&req, NULL);
+       `}
+end
+
 # Time since epoch
 extern class TimeT `{time_t`}
 
index f76d41c..57590ad 100644 (file)
@@ -169,7 +169,7 @@ class CsvWriter
 
        # Create a new writer with the specified format.
        init with_format(ostream:Writer, format: CsvFormat) do
-               self.ostream = ostream
+               init(ostream)
                self.format = format
        end
 
@@ -260,7 +260,7 @@ class CsvReader
 
        # Create a new reader with the specified format.
        init with_format(istream:Reader, format: CsvFormat) do
-               self.istream = istream
+               init(istream)
                self.format = format
        end
 
diff --git a/lib/gamnit/limit_fps.nit b/lib/gamnit/limit_fps.nit
new file mode 100644 (file)
index 0000000..a300b54
--- /dev/null
@@ -0,0 +1,78 @@
+# 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.
+
+# Frame-rate control for applications
+module limit_fps
+
+import gamnit
+private import realtime
+
+redef class App
+       # Limit the frame-rate to a given frequency
+       #
+       # This basically limits how much `frame_core` is called per second.
+       # Zero (or a negative value) means no limit.
+       #
+       # Applications can modify this value even during the main-loop.
+       var maximum_fps = 60.0 is writable
+
+       # Current frame-rate
+       #
+       # Updated each 5 seconds.
+       var current_fps = 0.0
+
+       redef fun frame_full
+       do
+               super
+               limit_fps
+       end
+
+       # The clock for limit_fps
+       private var clock = new Clock
+
+       # Number of frames since the last deadline
+       #
+       # Used to compute `current_fps`.
+       private var frame_count = 0
+
+       # Deadline used to compute `current_fps`
+       private var frame_count_deadline = 0
+
+       # Check and sleep to maintain a frame-rate bellow `maximum_fps`
+       #
+       # Also periodically update `current_fps`
+       # Is automatically called at the end of `full_frame`.
+       fun limit_fps
+       do
+               var t = clock.total.sec
+               if t >= frame_count_deadline then
+                       var cfps = frame_count.to_f / 5.0
+                       self.current_fps = cfps
+                       frame_count = 0
+                       frame_count_deadline = t + 5
+               end
+               frame_count += 1
+
+               var mfps = maximum_fps
+               if mfps <= 0.0 then return
+               var lapse = clock.lapse
+               var dt = lapse.to_f
+               var target_dt = 1.0 / mfps
+               if dt < target_dt then
+                       var sleep_t = target_dt - dt
+                       sleep_t.sleep
+                       clock.lapse
+               end
+       end
+end
index 0e2d4b5..6ecf483 100644 (file)
@@ -215,6 +215,8 @@ class Box3d[N: Numeric]
        #     assert box.right == 4 and box.top == 4
        init around(boxed: Boxed3d[N]...)
        do
+               super
+
                assert not boxed.is_empty
 
                var left: nullable N = null
index 18880ec..59917c5 100644 (file)
@@ -557,8 +557,7 @@ abstract class RepoEntity
 
        # Init `self` from a `json` object.
        init from_json(api: GithubAPI, repo: Repo, json: JsonObject) do
-               self.api = api
-               self.repo = repo
+               init(api, repo)
                self.json = json
        end
 end
@@ -1572,8 +1571,7 @@ class ContributorStats
 
        # Init `self` from a `json` object.
        init from_json(api: GithubAPI, json: JsonObject) do
-               self.api = api
-               self.json = json
+               init(api, json)
        end
 
        # User these statistics are about.
index 543a786..33c637f 100644 (file)
@@ -34,7 +34,7 @@ class GithubEvent
 
        # Init `self` from a `json` object.
        init from_json(api: GithubAPI, json: JsonObject) do
-               self.api = api
+               init(api)
                self.json = json
        end
 
index 66befa3..d7960e3 100644 (file)
@@ -70,8 +70,7 @@ class Link
 
        # Creates a link with a `title` attribute.
        init with_title(href: String, text: Writable, title: nullable String) do
-               self.href = href
-               self.text = text
+               init(href, text)
                self.title = title
        end
 
@@ -112,8 +111,7 @@ class Header
 
        # Creates a link with a `title` attribute.
        init with_subtext(level: Int, text: Writable, subtext: String) do
-               self.level = level
-               self.text = text
+               init(level, text)
                self.subtext = subtext
        end
 
index 6cb192b..b5f5529 100644 (file)
@@ -123,7 +123,7 @@ class HTMLTag
 
        # Create a HTML elements with the specifed type and attributes.
        init with_attrs(tag: String, attrs: Map[String, String]) do
-               self.tag = tag
+               init(tag)
                self.attrs = attrs
        end
 
index 7907409..4c2428f 100644 (file)
@@ -168,6 +168,7 @@ class MarkdownProcessor
                                var c = input[i]
                                if c == '\n' then
                                        eol = true
+                               else if c == '\r' then
                                else if c == '\t' then
                                        var np = pos + (4 - (pos & 3))
                                        while pos < np do
@@ -634,7 +635,7 @@ class LinkRef
 
        # Create a link with a title.
        init with_title(link: String, title: nullable String) do
-               self.link = link
+               init(link)
                self.title = title
        end
 end
index 2b2abf1..3841bc6 100644 (file)
@@ -24,7 +24,7 @@ redef class App
        # Zero (or a negative value) means no limit.
        #
        # Applications can modify this value even during the main-loop.
-       var maximum_fps = 60 is writable
+       var maximum_fps = 60.0 is writable
 
        # Current frame-rate
        # Updated each 5 seconds.
@@ -53,7 +53,7 @@ redef class App
        do
                var t = clock.total.sec
                if t >= frame_count_deadline then
-                       var cfps = frame_count_deadline.to_f / 5.0
+                       var cfps = frame_count.to_f / 5.0
                        self.current_fps = cfps
                        frame_count = 0
                        frame_count_deadline = t + 5
@@ -61,15 +61,14 @@ redef class App
                frame_count += 1
 
                var mfps = maximum_fps
-               if mfps <= 0 then return
-               var dt = clock.lapse
-               var target_dt = 1000000000 / mfps
-               var sec = dt.sec
-               var nanosec = dt.nanosec
-               if sec == 0 and nanosec < target_dt then
-                       var sleep_t = target_dt - nanosec
-                       sys.nanosleep(0, sleep_t)
-                       dt = clock.lapse
+               if mfps <= 0.0 then return
+               var lapse = clock.lapse
+               var dt = lapse.to_f
+               var target_dt = 1.0 / mfps
+               if dt < target_dt then
+                       var sleep_t = target_dt - dt
+                       sleep_t.sleep
+                       clock.lapse
                end
        end
 end
index e0a4a10..07c830b 100644 (file)
@@ -24,6 +24,7 @@ import privileges
 import tnitter
 import benitlux::benitlux_controller
 import opportunity::opportunity_controller
+import nitiwiki::wiki_edit
 
 # Header for the whole site
 class MasterHeader
@@ -57,11 +58,10 @@ class MasterHeader
     <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
       <ul class="nav navbar-nav">
         <li{{{actives.get_or_default("ens", "")}}}><a href="http://xymus.net/ens/">Enseignement</a></li>
-        <li><a href="http://pep8.xymus.net/">Pep/8 Analysis</a></li>
+        <li{{{actives.get_or_default("opportunity", "")}}}><a href="http://xymus.net/opportunity/">Opportunité</a></li>
         <li{{{actives.get_or_default("tnitter", "")}}}><a href="http://tnitter.xymus.net/">Tnitter</a></li>
+        <li><a href="http://pep8.xymus.net/">Pep/8 Analysis</a></li>
         <li{{{actives.get_or_default("benitlux", "")}}}><a href="http://benitlux.xymus.net/">Benitlux</a></li>
-        <li{{{actives.get_or_default("opportunity", "")}}}><a href="http://xymus.net/opportunity/">Opportunité</a></li>
-        <li><a href="http://nitlanguage.org/">Nit</a></li>
       </ul>
 
       <ul class="nav navbar-nav pull-right">
@@ -169,7 +169,6 @@ tnitter_vh.routes.add new Route("/rest/", new TnitterREST)
 tnitter_vh.routes.add new Route("/push/", new TnitterPush)
 tnitter_vh.routes.add new Route(null, tnitter)
 
-
 # Pep/8 Analysis is only a file server. It is available at `pep8.xymus.net`
 # and through the global/default file server at `xymus.net/pep8/`
 #
@@ -187,11 +186,17 @@ default_vh.routes.add new Route("/benitlux/", benitlux_sub)
 benitlux_vh.routes.add new Route("/rest/", benitlux_rest)
 benitlux_vh.routes.add new Route(null, benitlux_sub)
 
+# Opportunity service
 var opportunity = new OpportunityWelcome
 var opportunity_rest = new OpportunityRESTAction
 default_vh.routes.add new Route("/opportunity/rest/", opportunity_rest)
 default_vh.routes.add new Route("/opportunity/", opportunity)
 
+# Nitiwiki modification form
+var passwords = "nitiwiki_passwords".to_path.read_lines
+assert passwords.not_empty
+default_vh.routes.add new Route("/edit", new EditAction("http://xymus.net/", "/home/xymus/projects/wiki/config.ini", passwords))
+
 # We use a special file server for the path `xymus.net/ens` only to display
 # a different header.
 var file_server_ens = new FileServer("/var/www/ens/")
index 1308e29..02fa9a6 100644 (file)
@@ -2249,6 +2249,21 @@ redef class AMethPropdef
                        else if pname == "to_b" then
                                v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
                                return true
+                       else if pname == "code_point" then
+                               v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
+                               return true
+                       else if pname == "&" then
+                               v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == "|" then
+                               v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == ">>" then
+                               v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == "<<" then
+                               v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
+                               return true
                        end
                else if cname == "Char" then
                        if pname == "object_id" then
@@ -2282,6 +2297,9 @@ redef class AMethPropdef
                        else if pname == "to_i" then
                                v.ret(v.new_expr("{arguments[0]}-'0'", ret.as(not null)))
                                return true
+                       else if pname == "code_point" then
+                               v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
+                               return true
                        end
                else if cname == "Byte" then
                        if pname == "output" then
@@ -2330,6 +2348,15 @@ redef class AMethPropdef
                        else if pname == ">=" then
                                v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
                                return true
+                       else if pname == ">>" then
+                               v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == "<<" then
+                               v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == "&" then
+                               v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
+                               return true
                        else if pname == "to_i" then
                                v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
                                return true
@@ -2351,6 +2378,9 @@ redef class AMethPropdef
                        else if pname == "to_u32" then
                                v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
                                return true
+                       else if pname == "ascii" then
+                               v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
+                               return true
                        end
                else if cname == "Bool" then
                        if pname == "output" then
index fac760c..0550caf 100644 (file)
@@ -58,7 +58,7 @@ private class I18NPhase
 
                var pot_path = locale_dir / module_name
                var arr = vi.strings.values.to_a
-               var po = new POFile.with_strings(arr)
+               var po = new POFile(arr)
                po.write_template(pot_path)
 
                if lang != null then
@@ -191,12 +191,6 @@ class POFile
        # Read from a PO file
        var strings: Array[PObject]
 
-       # Creates a PO file with strings built-in
-       init with_strings(sm: Array[PObject])do
-               strings = new Array[PObject].with_capacity(sm.length)
-               strings.add_all sm
-       end
-
        redef fun write_to_file(path) do
                if not path.has_suffix(".po") then path += ".po"
                super path
index afd299f..b00c7f4 100644 (file)
@@ -1355,6 +1355,8 @@ redef class AAttrPropdef
                        if nexpr != null then
                                if nexpr isa ANewExpr then
                                        mtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, nexpr.n_type, true)
+                               else if nexpr isa AAsCastExpr then
+                                       mtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, nexpr.n_type, true)
                                else if nexpr isa AIntegerExpr then
                                        var cla: nullable MClass = null
                                        if nexpr.value isa Int then
index df01109..472e289 100644 (file)
@@ -1126,7 +1126,7 @@ end
 class APublicVisibility
        super AVisibility
        # The `public` keyword, if any
-       var n_kwpublic: nullable TKwpublic is writable
+       var n_kwpublic: nullable TKwpublic = null is writable
 end
 # An explicit private visibility modifier
 class APrivateVisibility
index 30b1f27..55263bd 100644 (file)
@@ -101,43 +101,9 @@ redef class AMethPropdef
                # Still here? So it means that we must determine what super inits need to be automatically invoked
                # The code that follow is required to deal with complex cases with old-style and new-style inits
 
-               # Look for old-style super constructors
                var auto_super_inits = new Array[CallSite]
-               for msupertype in mclassdef.supertypes do
-                       # FIXME: the order is quite arbitrary
-                       if not msupertype.mclass.kind.need_init then continue
-                       msupertype = msupertype.anchor_to(mmodule, mclassdef.bound_mtype)
-                       var candidate = modelbuilder.try_get_mproperty_by_name2(self, mmodule, msupertype, mpropdef.mproperty.name)
-                       if candidate == null then
-                               candidate = modelbuilder.try_get_mproperty_by_name2(self, mmodule, msupertype, "init")
-                       end
-                       if candidate == null then
-                               modelbuilder.error(self, "Error: cannot do an implicit constructor call in `{mpropdef}`; there is no constructor named `{mpropdef.mproperty.name}` in `{msupertype}`.")
-                               return
-                       end
-                       assert candidate isa MMethod
-
-                       # Skip new-style init
-                       if candidate.is_root_init then continue
-
-                       var candidatedefs = candidate.lookup_definitions(mmodule, anchor)
-                       if candidatedefs.is_empty then
-                               # skip broken
-                               is_broken = true
-                               return
-                       end
-                       var candidatedef = candidatedefs.first
-                       # TODO, we drop the others propdefs in the callsite, that is not great :(
-
-                       var msignature = candidatedef.new_msignature or else candidatedef.msignature
-                       msignature = msignature.resolve_for(recvtype, anchor, mmodule, true)
-
-                       var callsite = new CallSite(hot_location, recvtype, mmodule, anchor, true, candidate, candidatedef, msignature, false)
-                       auto_super_inits.add(callsite)
-                       modelbuilder.toolcontext.info("Old-style auto-super init for {mpropdef} to {candidate.full_name}", 4)
-               end
 
-               # No old style? The look for new-style super constructors (called from a old style constructor)
+               # The look for new-style super constructors (called from a old style constructor)
                var the_root_init_mmethod = modelbuilder.the_root_init_mmethod
                if the_root_init_mmethod != null and auto_super_inits.is_empty then
                        var candidatedefs = the_root_init_mmethod.lookup_definitions(mmodule, anchor)
@@ -147,31 +113,23 @@ redef class AMethPropdef
                                return
                        end
 
-                       # Search the longest-one and checks for conflict
                        var candidatedef = candidatedefs.first
                        if candidatedefs.length > 1 then
-                               # Check for conflict in the order of initializers
-                               # Each initializer list must me a prefix of the longest list
-                               # part 1. find the longest list
-                               for spd in candidatedefs do
-                                       if spd.initializers.length > candidatedef.initializers.length then candidatedef = spd
-                               end
-                               # compare
-                               for spd in candidatedefs do
-                                       var i = 0
-                                       for p in spd.initializers do
-                                               if p != candidatedef.initializers[i] then
-                                                       modelbuilder.error(self, "Error: cannot do an implicit constructor call to conflicting inherited inits `{spd}({spd.initializers.join(", ")}`) and `{candidatedef}({candidatedef.initializers.join(", ")}`). NOTE: Do not mix old-style and new-style init!")
-                                                       return
-                                               end
-                                               i += 1
-                                       end
-                               end
+                               var cd2 = candidatedefs[1]
+                               modelbuilder.error(self, "Error: cannot do an implicit constructor call to conflicting inherited inits `{cd2}({cd2.initializers.join(", ")}`) and `{candidatedef}({candidatedef.initializers.join(", ")}`). NOTE: Do not mix old-style and new-style init!")
+                               is_broken = true
+                               return
                        end
 
                        var msignature = candidatedef.new_msignature or else candidatedef.msignature
                        msignature = msignature.resolve_for(recvtype, anchor, mmodule, true)
 
+                       if msignature.arity > 0 then
+                               modelbuilder.error(self, "Error: cannot do an implicit constructor call to `{candidatedef}{msignature}`. Expected at least `{msignature.arity}` arguments.")
+                               is_broken = true
+                               return
+                       end
+
                        var callsite = new CallSite(hot_location, recvtype, mmodule, anchor, true, the_root_init_mmethod, candidatedef, msignature, false)
                        auto_super_inits.add(callsite)
                        modelbuilder.toolcontext.info("Auto-super init for {mpropdef} to {the_root_init_mmethod.full_name}", 4)
@@ -181,27 +139,6 @@ redef class AMethPropdef
                        return
                end
 
-               # Can the super-constructors be called?
-               for auto_super_init in auto_super_inits do
-                       var auto_super_init_def = auto_super_init.mpropdef
-                       var msig = mpropdef.msignature.as(not null)
-                       var supermsig = auto_super_init.msignature
-                       if supermsig.arity > msig.arity then
-                               modelbuilder.error(self, "Error: cannot do an implicit constructor call to `{auto_super_init_def}{supermsig}`. Expected at least `{supermsig.arity}` arguments, got `{msig.arity}`.")
-                               continue
-                       end
-                       var i = 0
-                       for sp in supermsig.mparameters do
-                               var p = msig.mparameters[i]
-                               var sub = p.mtype
-                               var sup = sp.mtype
-                               if not sub.is_subtype(mmodule, anchor, sup) then
-                                       modelbuilder.error(self, "Error: cannot do an implicit constructor call to `{auto_super_init_def}{supermsig}`. Expected argument #{i} of type `{sp.mtype}`, got implicit argument `{p.name}` of type `{p.mtype}`.")
-                                       break
-                               end
-                               i += 1
-                       end
-               end
                self.auto_super_inits = auto_super_inits
        end
 
index 963dc12..f82dfc9 100644 (file)
@@ -22,7 +22,7 @@ class A
        var y: Int = -2 #alt2#
        #alt2#var y: Int
        #alt3#init (xx: Int) do x = xx
-       #alt4#init foo(xx: Int) do x = xx
+       #alt4#init foo(xx: Int) do init(xx)
        fun work
        do
                x.output
index e30298f..20d9609 100644 (file)
@@ -41,8 +41,7 @@ class E
        super B
 
        var i: Int
-       init(i: Int) do
-               self.i = i
+       init do
                i.output
        end
 end
index aa032c0..00ab7ef 100644 (file)
@@ -73,14 +73,14 @@ class C
                '2'.output
                ' '.output
        end
-       init init_par(c: Char)
+       redef init init_par(c: Char)
        do
                'C'.output
                '3'.output
                c.output
                ' '.output
        end
-       init init_par3(c: Char)
+       redef init init_par3(c: Char)
        do
                'C'.output
                '4'.output
index a5cdb89..d1f8f3f 100644 (file)
@@ -11,7 +11,7 @@ class B
        #alt1#redef init do '1'.output
        init do '1'.output #alt1#
        #alt1#redef init init2 do '2'.output
-       init init2 do '2'.output #alt1#
+       redef init init2 do '2'.output #alt1#
        #alt1#redef init init3 do '3'.output
        init init3 do '3'.output #alt1#
 end
index 1211acf..be64735 100644 (file)
@@ -89,6 +89,7 @@ end
 class C3
        super A
        init(j: Int) do
+               super(j)#alt6#
                j.output
        end
 end
@@ -96,6 +97,7 @@ end
 class D3
        super A
        init(j: Int) do
+               super(j)#alt6#
                j.output
        end
 end
@@ -119,6 +121,7 @@ end
 class F2
        super A
        init(j: Int, k: Bool) do
+               super(j)#alt6#
                j.output
        end
 end
index d210e23..23bd9f9 100644 (file)
@@ -1,13 +1 @@
-1
-2
-1
-2
-3
-1
-2
-1
-2
-5
-1
-2
-6
+alt/base_init_combine_alt1.nit:59,9--11: Error: expected 2 argument(s) for `init(i: Int, z: Int)`; got 1. See introduction at `core::Object::init`.
index 0f283aa..596139a 100644 (file)
@@ -16,12 +16,9 @@ true
 11
 true
 12
-12
-13
 13
 14
 true
 15
 15
 16
-16
index 8cdfe03..f52de9b 100644 (file)
@@ -1 +1 @@
-alt/base_init_super_call2_alt3.nit:38,2--5: Error: cannot do an implicit constructor call to `base_init_super_call2_alt3#A#init(i: Int)`. Expected at least `1` arguments, got `0`.
+alt/base_init_super_call2_alt3.nit:38,2--5: Error: cannot do an implicit constructor call to `base_init_super_call2_alt3#A#init(i: Int)`. Expected at least `1` arguments.
index a03aff9..3c79f1c 100644 (file)
@@ -1 +1,4 @@
-alt/base_init_super_call2_alt6.nit:105,2--5: Error: cannot do an implicit constructor call to `base_init_super_call2_alt6#A#init(i: Int)`. Expected argument #0 of type `Int`, got implicit argument `j` of type `Bool`.
+alt/base_init_super_call2_alt6.nit:91,2--5: Error: cannot do an implicit constructor call to `base_init_super_call2_alt6#A#init(i: Int)`. Expected at least `1` arguments.
+alt/base_init_super_call2_alt6.nit:99,2--5: Error: cannot do an implicit constructor call to `base_init_super_call2_alt6#A#init(i: Int)`. Expected at least `1` arguments.
+alt/base_init_super_call2_alt6.nit:107,2--5: Error: cannot do an implicit constructor call to `base_init_super_call2_alt6#A#init(i: Int)`. Expected at least `1` arguments.
+alt/base_init_super_call2_alt6.nit:123,2--5: Error: cannot do an implicit constructor call to `base_init_super_call2_alt6#A#init(i: Int)`. Expected at least `1` arguments.
index 921fd8f..138108b 100644 (file)
@@ -1 +1,23 @@
-alt/base_init_super_call_alt3.nit:38,2--5: Error: cannot do an implicit constructor call to `base_init_super_call_alt3#A#init(i: Int)`. Expected at least `1` arguments, got `0`.
+1
+2
+3
+4
+6
+6
+7
+7
+8
+true
+9
+9
+10
+10
+11
+true
+12
+13
+14
+true
+15
+15
+16
index 724de84..2863a59 100644 (file)
@@ -1 +1,23 @@
-alt/base_init_super_call_alt6.nit:105,2--5: Error: cannot do an implicit constructor call to `base_init_super_call_alt6#A#init(i: Int)`. Expected argument #0 of type `Int`, got implicit argument `j` of type `Bool`.
+1
+2
+3
+4
+5
+6
+6
+7
+7
+8
+true
+9
+9
+10
+10
+11
+true
+12
+13
+true
+15
+15
+16
index 08a096b..2a3b9a8 100644 (file)
@@ -6,8 +6,8 @@
 ../lib/core/kernel.nit:431,1--486,3: Error: `kernel#Numeric` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
 ../lib/core/kernel.nit:492,1--515,3: Error: `kernel#Bool` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
 ../lib/core/kernel.nit:517,1--599,3: Error: `kernel#Float` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
-../lib/core/kernel.nit:601,1--702,3: Error: `kernel#Byte` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
-../lib/core/kernel.nit:704,1--890,3: Error: `kernel#Int` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
-../lib/core/kernel.nit:892,1--1060,3: Error: `kernel#Char` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
-../lib/core/kernel.nit:1062,1--1069,3: Error: `kernel#Pointer` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
-../lib/core/kernel.nit:1071,1--1080,3: Error: `kernel#Task` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:601,1--708,3: Error: `kernel#Byte` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:710,1--894,3: Error: `kernel#Int` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:896,1--1066,3: Error: `kernel#Char` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:1068,1--1075,3: Error: `kernel#Pointer` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:1077,1--1086,3: Error: `kernel#Task` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
index d556892..90983e4 100644 (file)
@@ -1,4 +1,4 @@
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:725)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:731)
 11
 21
 31
index d556892..90983e4 100644 (file)
@@ -1,4 +1,4 @@
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:725)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:731)
 11
 21
 31
index d556892..90983e4 100644 (file)
@@ -1,4 +1,4 @@
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:725)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:731)
 11
 21
 31
index 9f86235..7d2fd76 100644 (file)
@@ -51,19 +51,19 @@ Float [
 Numeric -> Float [dir=back arrowtail=open style=dashed];
 
 Byte [
- label = "{Byte||+ %(i: Byte): Byte\l+ \<\<(i: Int): Byte\l+ \>\>(i: Int): Byte\l+ ascii(): Char\l}"
+ label = "{Byte||+ %(i: Byte): Byte\l+ \<\<(i: Int): Byte\l- lsh(i: Int): Byte\l+ \>\>(i: Int): Byte\l- rsh(i: Int): Byte\l+ ascii(): Char\l- ffi_ascii(): Char\l}"
 ]
 Discrete -> Byte [dir=back arrowtail=open style=dashed];
 Numeric -> Byte [dir=back arrowtail=open style=dashed];
 
 Int [
- label = "{Int||+ %(i: Int): Int\l+ \<\<(i: Int): Int\l+ \>\>(i: Int): Int\l+ code_point(): Char\l+ digit_count(b: Int): Int\l+ digit_count_base_10(): Int\l+ to_c(): Char\l+ abs(): Int\l}"
+ label = "{Int||+ %(i: Int): Int\l+ \<\<(i: Int): Int\l- lsh(i: Int): Int\l+ \>\>(i: Int): Int\l- rsh(i: Int): Int\l+ code_point(): Char\l- cp(): Char\l+ digit_count(b: Int): Int\l+ digit_count_base_10(): Int\l+ to_c(): Char\l+ abs(): Int\l}"
 ]
 Discrete -> Int [dir=back arrowtail=open style=dashed];
 Numeric -> Int [dir=back arrowtail=open style=dashed];
 
 Char [
- label = "{Char||+ to_i(): Int\l+ ascii(): Byte\l+ code_point(): Int\l+ is_ascii(): Bool\l+ to_lower(): Char\l+ to_upper(): Char\l+ is_digit(): Bool\l+ is_lower(): Bool\l+ is_upper(): Bool\l+ is_letter(): Bool\l+ is_whitespace(): Bool\l}"
+ label = "{Char||+ to_i(): Int\l+ ascii(): Byte\l+ code_point(): Int\l- cp(): Int\l+ is_ascii(): Bool\l+ to_lower(): Char\l+ to_upper(): Char\l+ is_digit(): Bool\l+ is_lower(): Bool\l+ is_upper(): Bool\l+ is_letter(): Bool\l+ is_whitespace(): Bool\l}"
 ]
 Discrete -> Char [dir=back arrowtail=open style=dashed];
 
index 1b927aa..9c1e991 100644 (file)
@@ -22,7 +22,7 @@ module test_ffi_c_more_callbacks
 `}
 
 class A
-       var a: Int
+       var a: Int is noautoinit
        init do a = 1234
        init alt(i: Int) do a = i
        fun to_i: Int do return a
index 8b1d6bc..19e550c 100644 (file)
@@ -13,7 +13,6 @@
 # limitations under the License.
 
 #alt1 import core
-#alt1 import buffered_ropes
 
 var st = "quick brown fox over the lazy dog"
 
index d818431..63c62d7 100644 (file)
@@ -1,12 +1,12 @@
 
 class A
        var s : String
-       init a( s : String ) do self.s = s
+       init a( s : String ) do init(s)
 end
 
 class B
        var i : Int
-       init b( i : Int ) do self.i = i
+       init b( i : Int ) do init(i)
 end
 
 class C
index ea3db1e..820b5c3 100644 (file)
@@ -13,7 +13,6 @@
 # limitations under the License.
 
 #alt2 import core
-#alt2 import buffered_ropes
 
 var str = "Woe to you, oh earth and sea for the Devil sends the beast with wrath because he knows the time is short. Let him who hath understanding reckon the number of the beast, for it is a human number, its number is Six Hundred and Sixty-Six."
 var spaces = "           "