Merge: android: click event on button release, better errors and safer `JavaString...
authorJean Privat <jean@pryen.org>
Fri, 7 Oct 2016 19:40:27 +0000 (15:40 -0400)
committerJean Privat <jean@pryen.org>
Fri, 7 Oct 2016 19:40:27 +0000 (15:40 -0400)
Some small tweaks to the Android support:

* `JavaString::to_s` used to crash (at the JNI level) if the associated Java string was null. This was a counterintuitive behavior when the Nit object is non-nullable. This PR prevents this error by returning something similar to the default `Object::to_s` when the underlying Java value is null (for `JavaString` and others). This makes it crash proof, but one should still check if `JavaString::is_java_null` before using the value returned by `to_s` when an actual string is expected.

* Some Java exceptions raised by the Android implementation of `http_get` do not have a message. This PR looks through the causes of such exceptions to find the first available message.

* Also, fix `on_click & ButtonPressEvent` to be raised only when a button is released (instead of at the initial touch).

Pull-Request: #2319
Reviewed-by: Romain Chanoir <romain.chanoir@viacesi.fr>
Reviewed-by: Ait younes Mehdi Adel <overpex@gmail.com>

107 files changed:
benchmarks/json/scripts/nitcc_parser.nit
contrib/benitlux/Makefile
contrib/benitlux/src/client/base.nit
contrib/benitlux/src/server/benitlux_controller.nit
contrib/neo_doxygen/src/model/descriptions.nit
contrib/neo_doxygen/src/model/graph.nit
contrib/neo_doxygen/src/model/location.nit
contrib/neo_doxygen/src/tests/neo_doxygen_descriptions.nit [deleted file]
contrib/neo_doxygen/src/tests/neo_doxygen_member_resolve_introducer.nit [deleted file]
contrib/nitrpg/src/achievements.nit
contrib/nitrpg/src/events.nit
contrib/nitrpg/src/game.nit
contrib/nitrpg/src/statistics.nit
contrib/nitrpg/src/test_achievements.nit
contrib/nitrpg/src/test_events.nit
contrib/nitrpg/src/test_game.nit
contrib/refund/src/refund_json.nit
contrib/refund/tests/res/json_error1.res
contrib/refund/tests/res/json_error3.res
contrib/shibuqam/examples/shibuqamoauth.nit
contrib/tinks/src/client/linux_client.nit
contrib/tnitter/src/action.nit
contrib/tnitter/src/push.nit
contrib/tnitter/src/tnitter_app.nit
examples/rosettacode/json_output.nit
lib/android/bundle/bundle.nit
lib/android/intent/intent_api10.nit
lib/android/shared_preferences/shared_preferences_api10.nit
lib/app/http_request.nit
lib/github/api.nit
lib/github/events.nit
lib/github/github_curl.nit
lib/ios/data_store.nit
lib/json/README.md [new file with mode: 0644]
lib/json/error.nit
lib/json/json.nit
lib/json/serialization.nit [deleted file]
lib/json/serialization_read.nit [new file with mode: 0644]
lib/json/serialization_write.nit [new file with mode: 0644]
lib/json/static.nit
lib/json/store.nit
lib/json/string_parser.nit
lib/linux/data_store.nit
lib/md5.nit
lib/mongodb/mongodb.nit
lib/mpi/mpi.nit
lib/neo4j/curl_json.nit
lib/neo4j/error.nit
lib/neo4j/graph/json_graph_store.nit
lib/nitcc_runtime.nit
lib/nitcorn/restful.nit
lib/parser_base.nit
lib/popcorn/pop_handlers.nit
lib/popcorn/pop_repos.nit
lib/popcorn/pop_validation.nit
lib/pthreads/pthreads.nit
lib/serialization/README.md
src/doc/doc_phases/doc_indexing.nit
src/doc/html_templates/html_components.nit
src/examples/nitwebcrawl.nit
src/model/model_json.nit
src/platform/ios.nit
src/toolcontext.nit
src/web/api_catalog.nit
src/web/api_feedback.nit
src/web/api_metrics.nit
src/web/web_base.nit
tests/Darwin.skip
tests/sav/hello_ios.res
tests/sav/json_output.res
tests/sav/neo_doxygen_descriptions.res [deleted file]
tests/sav/neo_doxygen_member_resolve_introducer.res [deleted file]
tests/sav/nitce/test_json_deserialization_alt1.res
tests/sav/nitce/test_json_deserialization_alt3.res
tests/sav/nitce/test_serialization.res
tests/sav/nitce/test_serialization_alt2.res
tests/sav/nitce/test_serialization_alt3.res
tests/sav/nitce/test_serialization_alt4.res
tests/sav/nitce/test_serialization_alt5.res
tests/sav/nitce/test_serialization_redef.res
tests/sav/nitce/test_serialization_redef_alt0.res
tests/sav/nitce/test_serialization_redef_alt1.res
tests/sav/nitce/test_serialization_redef_alt2.res
tests/sav/test_adhoc_json_parse_args1.res
tests/sav/test_json_deserialization.res
tests/sav/test_json_deserialization_alt1.res
tests/sav/test_json_deserialization_alt2.res
tests/sav/test_json_deserialization_alt3.res
tests/sav/test_json_deserialization_alt4.res
tests/sav/test_json_deserialization_plain.res
tests/sav/test_json_unicode.res
tests/sav/test_platform_ios.res
tests/sav/test_serialization.res
tests/sav/test_serialization_alt1.res
tests/sav/test_serialization_alt2.res
tests/sav/test_serialization_alt3.res
tests/sav/test_serialization_alt4.res
tests/sav/test_serialization_alt5.res
tests/sav/test_serialization_redef.res
tests/sav/test_serialization_redef_alt0.res
tests/sav/test_serialization_redef_alt1.res
tests/sav/test_serialization_redef_alt2.res
tests/test_json_deserialization.nit
tests/test_json_deserialization_heuristic.nit
tests/test_json_deserialization_plain.nit
tests/test_json_unicode.nit
tests/test_serialization.nit

index f09b746..627ae39 100644 (file)
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import json
+import json::static
 
 var text = args.first.to_path.read_all
 var json = text.parse_json
index 4ae4000..af250c1 100644 (file)
@@ -79,7 +79,9 @@ bin/proto.app: $(shell nitls -M src/client/ios_proto.nit) ios/AppIcon.appiconset
 
 ios-release: $(shell nitls -M src/client/ios.nit) ios/AppIcon.appiconset/Contents.json
        mkdir -p bin/
-       nitc -o bin/benitlux.app src/client/ios.nit -D benitlux_rest_server_uri=http://$(SERVER)/
+       nitc -o bin/benitlux.app src/client/ios.nit \
+               -D benitlux_rest_server_uri=http://xymus.net/benitlux/ --release \
+               --compile-dir nit_compile
 
 ios/AppIcon.appiconset/Contents.json: art/icon.svg
        mkdir -p ios
index 7cfde72..28b4c88 100644 (file)
@@ -19,7 +19,7 @@ import app::ui
 import app::data_store
 import app::http_request
 import android::aware
-import json::serialization
+import json
 
 import benitlux_model
 import translations
index 5649345..a2ab392 100644 (file)
@@ -19,7 +19,7 @@ module benitlux_controller
 
 import nitcorn
 import nitcorn::restful
-private import json::serialization
+private import json
 
 import benitlux_model
 import benitlux_db
index 1f504ef..58ef0e6 100644 (file)
@@ -16,6 +16,7 @@
 module model::descriptions
 
 import json::static
+import json
 
 # Documentation associated to an entity.
 #
@@ -106,8 +107,8 @@ class Documentation
        # Is the documentation empty?
        fun is_empty: Bool do return content.is_empty
 
-       redef fun to_json do return content.to_json
-       redef fun append_json(b) do content.append_json(b)
+       redef fun serialize_to(v) do content.serialize_to v
+       redef fun accept_json_serializer(v) do content.serialize_to v
 end
 
 # A `Jsonable` array of strings.
index 74a81b5..26c8e66 100644 (file)
@@ -221,7 +221,7 @@ end
 abstract class Compound
        super Entity
 
-       # Set the declared visibility (the proctection) of the compound.
+       # Set the declared visibility (the protection) of the compound.
        fun visibility=(visibility: String) do
                self["visibility"] = visibility
        end
@@ -233,7 +233,7 @@ abstract class Compound
 
        # Declare an inner namespace.
        #
-       # Note: Althought Doxygen indicates that the name is optional,
+       # Note: Although Doxygen indicates that the name is optional,
        # declarations with an empty name are not supported yet, except for the root
        # namespace. For the root namespace, both arguments are empty.
        #
@@ -246,7 +246,7 @@ abstract class Compound
 
        # Declare an inner class.
        #
-       # Note: Althought Doxygen indicates that both arguments are optional,
+       # Note: Although Doxygen indicates that both arguments are optional,
        # declarations with an empty ID are not supported yet.
        #
        # Parameters:
@@ -292,7 +292,7 @@ class Namespace
                self.labels.add("MGroup")
        end
 
-       redef fun declare_namespace(id: String, full_name: String) do
+       redef fun declare_namespace(id, full_name) do
                inner_namespaces.add new NamespaceRef(id, full_name)
        end
 
index b78a2ef..d5f3727 100644 (file)
@@ -16,6 +16,7 @@
 module location
 
 import json::static
+import json
 
 # A location inside a source file.
 class Location
@@ -36,11 +37,13 @@ class Location
        # The one-based column index of the last character.
        var column_end: Int = 1 is writable
 
-       redef fun to_s: String do
+       redef fun to_s do
+               var path = path
                var file_part = "/dev/null:"
-               if path != null and path.length > 0 then file_part = "{path.as(not null)}:"
+               if path != null and path.length > 0 then file_part = "{path}:"
                return "{file_part}{line_start},{column_start}--{line_end},{column_end}"
        end
 
-       redef fun to_json do return to_s.to_json
+       redef fun serialize_to(v) do to_s.serialize_to v
+       redef fun accept_json_serializer(v) do to_s.serialize_to v
 end
diff --git a/contrib/neo_doxygen/src/tests/neo_doxygen_descriptions.nit b/contrib/neo_doxygen/src/tests/neo_doxygen_descriptions.nit
deleted file mode 100644 (file)
index d277be7..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import model::descriptions
-
-# Copied from the documentation of `Documentation`.
-
-var doc = new Documentation
-
-doc.brief_description = "Do something."
-doc.detailed_description = ["Do not lunch a rocket."]
-assert doc.brief_description == "Do something."
-assert doc.detailed_description == ["Do not lunch a rocket."]
-assert doc.to_json == """["Do something.","Do not lunch a rocket."]"""
-
-doc.brief_description = ""
-doc.detailed_description = ["The answer is `42`."]
-assert doc.brief_description == "The answer is `42`."
-assert doc.detailed_description == ["The answer is `42`."]
-assert doc.to_json == """["The answer is `42`."]"""
-
-doc.detailed_description = ["The answer is `42`."]
-doc.brief_description = ""
-assert doc.brief_description == "The answer is `42`."
-assert doc.detailed_description == ["The answer is `42`."]
-assert doc.to_json == """["The answer is `42`."]"""
-
-doc.detailed_description = new Array[String]
-doc.brief_description = ""
-assert doc.is_empty
-assert doc.brief_description == ""
-assert doc.detailed_description == new Array[String]
-assert doc.to_json == "[]"
diff --git a/contrib/neo_doxygen/src/tests/neo_doxygen_member_resolve_introducer.nit b/contrib/neo_doxygen/src/tests/neo_doxygen_member_resolve_introducer.nit
deleted file mode 100644 (file)
index 4909e9d..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import model::member
-
-# Copied from the documentation of `Member::resolve_introducer`.
-
-var g = new ProjectGraph("foo")
-var m1 = new Attribute(g)
-var m2 = new Attribute(g)
-var m3 = new Attribute(g)
-
-m1.model_id = "1"
-m1.put_in_graph
-m2.reimplement("1")
-m2.put_in_graph
-assert m1.resolve_introducer == m1.introducer
-assert m2.resolve_introducer == m1.introducer
-
-m3.model_id = "3"
-m3.reimplement("3")
-m3.put_in_graph
-assert m3.resolve_introducer == null
index 9055b22..2097ec3 100644 (file)
@@ -120,7 +120,7 @@ class Achievement
                        json["reward"].as(Int))
        end
 
-       redef fun to_json do
+       redef fun to_json_object do
                var json = super
                json["id"] = id
                json["name"] = name
index c540dc5..08d387d 100644 (file)
@@ -104,7 +104,7 @@ class GameEvent
                time = new ISODate.from_string(json["time"].as(String))
        end
 
-       redef fun to_json do
+       redef fun to_json_object do
                var json = new JsonObject
                json["internal_id"] = internal_id.to_s
                json["kind"] = kind
index 504c445..b1d8916 100644 (file)
@@ -42,10 +42,10 @@ interface GameEntity
        fun key: String is abstract
 
        # Saves `self` in db.
-       fun save do game.db.collection(collection_name).save(to_json)
+       fun save do game.db.collection(collection_name).save(to_json_object)
 
        # Json representation of `self`.
-       fun to_json: JsonObject do
+       fun to_json_object: JsonObject do
                var json = new JsonObject
                json["_id"] = key
                return json
@@ -102,7 +102,7 @@ class Game
        # Used to load entities from saved data.
        fun from_json(json: JsonObject) do end
 
-       redef fun to_json do
+       redef fun to_json_object do
                var json = super
                json["name"] = name
                return json
@@ -166,7 +166,7 @@ class Game
        end
 
        # Erase all saved data for this game.
-       fun clear do db.collection(collection_name).remove(to_json)
+       fun clear do db.collection(collection_name).remove(to_json_object)
 
        # Verbosity level used fo stdout.
        #
@@ -236,7 +236,7 @@ class Player
                nitcoins = json["nitcoins"].as(Int)
        end
 
-       redef fun to_json do
+       redef fun to_json_object do
                var json = super
                json["game"] = game.key
                json["name"] = name
index cde6816..764616f 100644 (file)
@@ -172,7 +172,7 @@ class GameStats
                for k, v in values do self[k] = v.as(Int)
        end
 
-       redef fun to_json do
+       redef fun to_json_object do
                var obj = super
                obj["period"] = period
                obj["owner"] = owner.key
index 033832f..c210c60 100644 (file)
@@ -51,7 +51,7 @@ class TestGame
                var a3 = new Achievement(game, "test_id3", "test_name", "test_desc", 15)
                game.add_achievement(a1)
                game.add_achievement(a2)
-               game.db.collection("achievements").insert(a3.to_json)
+               game.db.collection("achievements").insert(a3.to_json_object)
                var ok = [a1.id, a2.id]
                var res = game.load_achievements
                assert res.length == 2
index b960501..640e8dc 100644 (file)
@@ -51,7 +51,7 @@ class TestGame
                var event3 = new GameEvent(game, "test_kind", new JsonObject)
                game.add_event(event1)
                game.add_event(event2)
-               game.db.collection("events").insert(event3.to_json)
+               game.db.collection("events").insert(event3.to_json_object)
                var ok = [event1.internal_id, event2.internal_id]
                var res = game.load_events
                assert res.length == 2
@@ -115,7 +115,7 @@ class TestGameEvent
                var db = gen_test_db
                var game = load_game("Morriar/nit", db)
                var event = new GameEvent(game, "test_kind", new JsonObject)
-               assert event.to_json["kind"] == "test_kind"
+               assert event.to_json_object["kind"] == "test_kind"
        end
 
        fun test_init_from_json do
index fceafb9..25ddcad 100644 (file)
@@ -43,8 +43,8 @@ class TestGame
 
                var player1 = new Player(game, "Morriar")
                var player2 = new Player(ogame, "privat")
-               game.db.collection("players").insert(player1.to_json)
-               ogame.db.collection("players").insert(player2.to_json)
+               game.db.collection("players").insert(player1.to_json_object)
+               ogame.db.collection("players").insert(player2.to_json_object)
 
                assert game.load_player("privat") == null
                assert game.load_player("Morriar").name == "Morriar"
@@ -60,9 +60,9 @@ class TestGame
                var player1 = new Player(game, "Morriar")
                var player2 = new Player(ogame, "privat")
                var player3 = new Player(game, "xymus")
-               game.db.collection("players").insert(player1.to_json)
-               ogame.db.collection("players").insert(player2.to_json)
-               game.db.collection("players").insert(player3.to_json)
+               game.db.collection("players").insert(player1.to_json_object)
+               ogame.db.collection("players").insert(player2.to_json_object)
+               game.db.collection("players").insert(player3.to_json_object)
 
                var players = game.load_players
                var ok = ["Morriar", "xymus"]
index 4da71f5..f670f9d 100644 (file)
@@ -19,6 +19,7 @@ module refund_json
 
 import refund_base
 import json::static
+import json
 
 redef class RefundProcessor
 
@@ -89,6 +90,7 @@ redef class RefundProcessor
        fun write_output(str: String, file: String) do
                var ofs = new FileWriter.open(file)
                ofs.write(str)
+               ofs.write("\n")
                ofs.close
        end
 
@@ -118,7 +120,7 @@ redef class RefundProcessor
                exit 1
        end
 
-       redef fun show_stats do print load_stats.to_json.to_pretty_json
+       redef fun show_stats do print load_stats.to_json_object.to_pretty_json
 
        redef fun load_stats do
                # If no stats found, return a new object
@@ -134,7 +136,7 @@ redef class RefundProcessor
        end
 
        redef fun save_stats(stats) do
-               write_output(stats.to_json.to_pretty_json, stats_file)
+               write_output(stats.to_json_object.to_pretty_json, stats_file)
        end
 end
 
@@ -146,7 +148,7 @@ redef class RefundStats
        end
 
        # Outputs `self` as a JSON string.
-       fun to_json: JsonObject do
+       fun to_json_object: JsonObject do
                var obj = new JsonObject
                for k, v in self do obj[k] = v
                return obj
index 958aa8d..e7eb308 100644 (file)
@@ -1,3 +1,3 @@
 {
-       "message": "Wrong input file (Unexpected Eof; is acceptable instead: value)"
+       "message": "Wrong input file (Empty JSON)"
 }
index d35b982..83de0af 100644 (file)
@@ -1,3 +1,3 @@
 {
-       "message": "Wrong input file (Unexpected Eof; is acceptable instead: members, pair)"
+       "message": "Wrong input file (Malformed JSON object)"
 }
index 2a52be9..bda76a3 100644 (file)
@@ -172,7 +172,7 @@ module shibuqamoauth
 
 import popcorn
 import shibuqam
-import json::serialization
+import json
 
 redef class HttpRequest
        # percent decoded get or post parameter.
@@ -304,7 +304,6 @@ end
 
 redef class User
        super Jsonable
-       redef fun to_json do return serialize_to_json(plain=true)
 end
 
 # Information about an authenticated used stored on the server to be given to the client.
index bd60702..5e7cca4 100644 (file)
@@ -17,7 +17,7 @@ module linux_client
 
 import mnit::linux
 import linux::audio
-import json::serialization
+import json
 
 import client
 
index 60ee384..f567294 100644 (file)
@@ -18,7 +18,7 @@
 module action
 
 import nitcorn
-import json::serialization
+import json
 
 import model
 import database
index bc47789..9900cfa 100644 (file)
@@ -16,7 +16,7 @@
 module push
 
 import nitcorn
-import json::serialization
+import json
 
 import model
 import database
index cf1d162..8218004 100644 (file)
@@ -31,7 +31,7 @@ import app::ui
 import app::http_request
 import app::data_store
 import android::aware
-import json::serialization
+import json
 
 import model
 
index 59fb72b..800a310 100644 (file)
@@ -7,6 +7,7 @@
 # SEE: <http://rosettacode.org/wiki/JSON>
 module json_output
 
+import json::static
 import json
 
 var str = """{
index 82acbec..e02702a 100644 (file)
@@ -19,7 +19,7 @@
 module bundle
 
 import serialization
-import json::serialization
+import json
 
 import platform
 import activities
index 746c0c4..f9e6c3b 100644 (file)
@@ -21,7 +21,7 @@ module intent_api10
 import dalvik
 import android::bundle
 import serialization
-private import json::serialization
+private import json
 
 in "Java" `{
        import android.content.Intent;
index b268087..f17661f 100644 (file)
@@ -19,7 +19,7 @@ module shared_preferences_api10
 
 import dalvik
 import serialization
-private import json::serialization
+private import json
 
 in "Java" `{
        import android.content.SharedPreferences;
index 3fc48c6..0260cab 100644 (file)
@@ -17,7 +17,7 @@ module http_request
 
 import app_base
 import pthreads
-import json::serialization
+import json
 
 import linux::http_request is conditional(linux)
 import android::http_request is conditional(android)
index 7c85422..8bd1ee3 100644 (file)
@@ -20,7 +20,7 @@
 module api
 
 import github_curl
-intrude import json::serialization
+intrude import json::serialization_read
 
 # Client to Github API
 #
@@ -512,8 +512,6 @@ abstract class GithubEntity
 
        # Github page url.
        var html_url: nullable String is writable
-
-       redef fun to_json do return serialize_to_json
 end
 
 # A Github user
@@ -1062,8 +1060,6 @@ end
 redef class ISODate
        super Jsonable
        serialize
-
-       redef fun to_json do return serialize_to_json
 end
 
 # JsonDeserializer specific for Github objects.
index 2dc0af7..3417de2 100644 (file)
@@ -18,7 +18,7 @@
 module events
 
 import api
-intrude import json::serialization
+intrude import json
 
 # Github event stub.
 class GithubEvent
@@ -33,8 +33,6 @@ class GithubEvent
 
        # Repo where this event occured.
        var repo: Repo is writable
-
-       redef fun to_json do return serialize_to_json
 end
 
 # Triggered when a commit comment is created.
index b5874f3..f2d5737 100644 (file)
@@ -18,6 +18,7 @@ module github_curl
 
 import curl
 import json::static
+import json
 
 # Specific Curl that know hot to talk to the github API
 class GithubCurl
@@ -127,9 +128,7 @@ class GithubError
                json["message"] = message.to_json
        end
 
-       redef fun to_json do
-               return json.to_json
-       end
+       redef fun serialize_to(v) do json.serialize_to v
 
        redef fun to_s do return "[{name}] {super}"
 end
index 6d1579d..a06586c 100644 (file)
@@ -17,7 +17,7 @@ module data_store
 
 import app::data_store
 import cocoa::foundation
-private import json::serialization
+private import json
 
 redef class App
        redef var data_store = new UserDefaultView
diff --git a/lib/json/README.md b/lib/json/README.md
new file mode 100644 (file)
index 0000000..b964d1c
--- /dev/null
@@ -0,0 +1,239 @@
+read and write JSON formatted text
+
+These services can be useful to communicate with a remote server or client,
+save data locally or even debug and understand the structure of a Nit object.
+There is a single API to write JSON, and three API to read depending on the use case.
+
+# Write JSON
+
+Writing Nit objects to JSON format can be useful to communicate with a remote service,
+save data locally or even debug and understand the structure of an object.
+There is two related services to write JSON object, the method
+`serialize_to_json` and the object `JsonSerializer`.
+The method `serialize_to_json` is actually a shortcut to `JsonSerializer`, both
+share the same features.
+
+## Write plain JSON
+
+Passing the argument `plain=true` to `serialize_to_json` generates plain and clean JSON.
+This format is non-Nit program, it cannot be fully deserialized back to Nit objects.
+The argument `pretty=true` generates JSON for humans, with more spaces and line breaks.
+
+The Nit objects to write must subclass `Serializable` and implement its services.
+Most classes from the `core` library are already supported, including collections, numeric values, etc.
+For your local objects, you can annotate them with `serialize` to automate subclassing
+`Serializable` and the implementation of its services.
+
+### Example
+
+~~~
+class Person
+    serialize
+
+    var name: String
+    var year_of_birth: Int
+    var next_of_kin: nullable Person
+end
+
+var bob = new Person("Bob", 1986)
+assert bob.serialize_to_json(pretty=true, plain=true) == """
+{
+       "name": "Bob",
+       "year_of_birth": 1986,
+       "next_of_kin": null
+}"""
+
+var alice = new Person("Alice", 1978, bob)
+assert alice.serialize_to_json(pretty=true, plain=true) == """
+{
+       "name": "Alice",
+       "year_of_birth": 1978,
+       "next_of_kin": {
+               "name": "Bob",
+               "year_of_birth": 1986,
+               "next_of_kin": null
+       }
+}"""
+
+# You can also build JSON objects as a `Map`
+var charlie = new Map[String, nullable Serializable]
+charlie["name"] = "Charlie"
+charlie["year_of_birth"] = 1968
+charlie["next_of_kin"] = alice
+assert charlie.serialize_to_json(pretty=true, plain=true) == """
+{
+       "name": "Charlie",
+       "year_of_birth": 1968,
+       "next_of_kin": {
+               "name": "Alice",
+               "year_of_birth": 1978,
+               "next_of_kin": {
+                       "name": "Bob",
+                       "year_of_birth": 1986,
+                       "next_of_kin": null
+               }
+       }
+}"""
+~~~
+
+## Write JSON with metadata
+
+By default, `serialize_to_json` and `JsonSerializer` include metadate in the generated JSON.
+This metadata is used by `JsonDeserializer` when reading the JSON code to recreate
+the Nit object with the exact original type.
+The metadata allows to avoid repeating an object and its resolves cycles in the serialized objects.
+
+For more information on Nit serialization, see: ../serialization/README.md
+
+
+# Read JSON
+
+There are a total of 3 API to read JSON:
+* `JsonDeserializer` reads JSON to recreate complex Nit objects (discussed here),
+* the module `json::dynamic` provides an easy API to explore JSON objects,
+* the module `json::static` offers a low-level service to parse JSON and create basic Nit objects.
+
+The class `JsonDeserializer` reads JSON code to recreate objects.
+It can use the metadata in the JSON code, to recreate precise Nit objects.
+Otherwise, JSON objects are recreated to simple Nit types: `Map`, `Array`, etc.
+Errors are reported to the attribute `JsonDeserializer::errors`.
+
+The type to recreate is either declared or inferred:
+
+1. The JSON object defines a `__class` key with the name of the Nit class as value.
+   This attribute is generated by the `JsonSerializer` with other metadata,
+   it can also be specified by other external tools.
+2. A refinement of `JsonDeserializer::class_name_heuristic` identifies the Nit class.
+3. If all else fails, `JsonDeserializer` uses the static type of the attribute,
+   or the type name passed to `deserialize`.
+
+The method `from_json_string` is a shortcut to `JsonDeserializer` which prints
+errors to the console. It is fit only for small scripts and other quick and dirty usage.
+
+### Example
+
+~~~
+class Triangle
+    serialize
+
+    var corners = new Array[Point]
+    redef var to_s is serialize_as("name")
+end
+
+class Point
+    serialize
+
+    var x: Int
+    var y: Int
+end
+
+# Metadata on each JSON object tells the deserializer what is its Nit type,
+# and it supports special types such as generic collections.
+var json_with_metadata = """{
+    "__class": "Triangle",
+    "corners": {"__class": "Array[Point]",
+                "__items": [{"__class": "Point", "x": 0, "y": 0},
+                            {"__class": "Point", "x": 3, "y": 0},
+                            {"__class": "Point", "x": 2, "y": 2}]},
+    "name": "some triangle"
+}"""
+
+var deserializer = new JsonDeserializer(json_with_metadata)
+var object = deserializer.deserialize
+assert deserializer.errors.is_empty
+assert object != null
+
+# However most non-Nit services won't add the metadata and instead produce plain JSON.
+# Without a "__class", the deserializer relies on `class_name_heuristic` and the static type.
+# The type of the root object to deserialize can be specified by an argument passed to `deserialize`.
+var plain_json = """{
+    "corners": [{"x": 0, "y": 0},
+                {"x": 3, "y": 0},
+                {"x": 2, "y": 2}],
+    "name": "the same triangle"
+}"""
+
+deserializer = new JsonDeserializer(plain_json)
+object = deserializer.deserialize("Triangle")
+assert deserializer.errors.is_empty # If false, `object` is invalid
+~~~
+
+### Missing attributes and default values
+
+When reading JSON, some attributes expected by Nit classes may be missing.
+The JSON object may come from an external API using optional attributes or
+from a previous version of your program without the attributes.
+When an attribute is not found, the deserialization engine acts in one of three ways:
+
+1. If the attribute has a default value or if it is annotated by `lazy`,
+   the engine leave the attribute to the default value. No error is raised.
+2. If the static type of the attribute is nullable, the engine sets
+   the attribute to `null`. No error is raised.
+3. Otherwise, the engine raises an error and does not set the attribute.
+   The caller must check for `errors` and must not read from the attribute.
+
+~~~
+class MyConfig
+    serialize
+
+    var width: Int # Must be in JSON or an error is raised
+    var height = 4
+    var volume_level = 8 is lazy
+    var player_name: nullable String
+    var tmp_dir: nullable String = "/tmp" is lazy
+end
+
+# ---
+# JSON object with all expected attributes -> OK
+var plain_json = """
+{
+    "width": 11,
+    "height": 22,
+    "volume_level": 33,
+    "player_name": "Alice",
+    "tmp_dir": null
+}"""
+var deserializer = new JsonDeserializer(plain_json)
+var obj = deserializer.deserialize("MyConfig")
+
+assert deserializer.errors.is_empty
+assert obj isa MyConfig
+assert obj.width == 11
+assert obj.height == 22
+assert obj.volume_level == 33
+assert obj.player_name == "Alice"
+assert obj.tmp_dir == null
+
+# ---
+# JSON object missing optional attributes -> OK
+plain_json = """
+{
+    "width": 11
+}"""
+deserializer = new JsonDeserializer(plain_json)
+obj = deserializer.deserialize("MyConfig")
+
+assert deserializer.errors.is_empty
+assert obj isa MyConfig
+assert obj.width == 11
+assert obj.height == 4
+assert obj.volume_level == 8
+assert obj.player_name == null
+assert obj.tmp_dir == "/tmp"
+
+# ---
+# JSON object missing the mandatory attribute -> Error
+plain_json = """
+{
+    "player_name": "Bob",
+}"""
+deserializer = new JsonDeserializer(plain_json)
+obj = deserializer.deserialize("MyConfig")
+
+# There's an error, `obj` is partial
+assert deserializer.errors.length == 1
+
+# Still, we can access valid attributes
+assert obj isa MyConfig
+assert obj.player_name == "Bob"
+~~~
index 85e6154..26a9952 100644 (file)
@@ -16,6 +16,7 @@ import nitcc_runtime
 # Ill-formed JSON.
 class JsonParseError
        super Error
+       serialize
 
        # The location of the error in the original text.
        var position: nullable Position
index 7df7e82..391f746 100644 (file)
@@ -1,8 +1,5 @@
 # This file is part of NIT ( http://www.nitlanguage.org ).
 #
-# Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
-# Copyright 2014 Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.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
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Libraries to manipulate JSON strings.
-#
-# Both `dynamic` and `static` modules provide at least a method to parse a
-# value written in JSON, but only `static` provide a method to translate a
-# value into JSON.
-#
-# The `dynamic` module provides a simple interface to get information
-# from a JSON document. You must be careful as all services are provided on
-# each nodes and a wrongful use can `abort`.
-#
-# The `static` module provides a common interface for anything that can be
-# translated into a JSON document. The provided parsing method return a
-# nullable Nit object that must then be type-checked before it can be used.
+# Read and write JSON formatted text using the standard serialization services
 module json
 
-import static
-import dynamic
+import serialization_write
+import serialization_read
diff --git a/lib/json/serialization.nit b/lib/json/serialization.nit
deleted file mode 100644 (file)
index 983f50b..0000000
+++ /dev/null
@@ -1,968 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Handles serialization and deserialization of objects to/from JSON
-#
-# ## Writing JSON with metadata
-#
-# `JsonSerializer` write Nit objects that subclass `Serializable` to JSON,
-# and `JsonDeserializer` can read them. They both use metadata added to the
-# generated JSON to recreate the Nit instances with the exact original type.
-#
-# For more information on Nit serialization, see: ../serialization/README.md
-#
-# ## Writing plain JSON
-#
-# The attribute `JsonSerializer::plain_json` triggers generating plain and
-# clean JSON. This format is easier to read for an human and a non-Nit program,
-# but it cannot be fully deserialized. It can still be read by services from
-# `json::static` and `json::dynamic`.
-#
-# A shortcut to these writing services is provided by `Serializable::serialize_to_json`.
-#
-# ### Usage Example
-#
-# ~~~nitish
-# import json::serialization
-#
-# class Person
-#     serialize
-#
-#     var name: String
-#     var year_of_birth: Int
-#     var next_of_kin: nullable Person
-# end
-#
-# var bob = new Person("Bob", 1986)
-# var alice = new Person("Alice", 1978, bob)
-#
-# assert bob.serialize_to_json(pretty=true, plain=true) == """
-#{
-#      "name": "Bob",
-#      "year_of_birth": 1986,
-#      "next_of_kin": null
-#}"""
-#
-# assert alice.serialize_to_json(pretty=true, plain=true) == """
-#{
-#      "name": "Alice",
-#      "year_of_birth": 1978,
-#      "next_of_kin": {
-#              "name": "Bob",
-#              "year_of_birth": 1986,
-#              "next_of_kin": null
-#      }
-#}"""
-# ~~~
-#
-# ## Read JSON to create Nit objects
-#
-# The `JsonDeserializer` supports reading JSON code with or without metadata.
-# It can create Nit objects from a remote service returning JSON data
-# or to read local configuration files as Nit objects.
-# However, it needs to know which Nit class to recreate from each JSON object.
-# The class is either declared or inferred:
-#
-# 1. The JSON object defines a `__class` key with the name of the Nit class as value.
-#    This attribute is generated by the `JsonSerializer` with other metadata,
-#    it can also be specified by other external tools.
-# 2. A refinement of `JsonDeserializer::class_name_heuristic` identifies the Nit class.
-# 3. If all else fails, `JsonDeserializer` uses the static type of the attribute.
-#
-# ### Usage Example
-#
-# ~~~nitish
-# import json::serialization
-#
-# class Triangle
-#     serialize
-#
-#     var corners = new Array[Point]
-#     redef var to_s is serialize_as("name")
-# end
-#
-# class Point
-#     serialize
-#
-#     var x: Int
-#     var y: Int
-# end
-#
-# # Metadata on each JSON object tells the deserializer what is its Nit type,
-# # and it supports special types such as generic collections.
-# var json_with_metadata = """{
-#     "__class": "Triangle",
-#     "corners": {"__class": "Array[Point]",
-#                 "__items": [{"__class": "Point", "x": 0, "y": 0},
-#                             {"__class": "Point", "x": 3, "y": 0},
-#                             {"__class": "Point", "x": 2, "y": 2}]},
-#     "name": "some triangle"
-# }"""
-#
-# var deserializer = new JsonDeserializer(json_with_metadata)
-# var object = deserializer.deserialize
-# assert deserializer.errors.is_empty
-# assert object != null
-# print object
-#
-# # However most non-Nit services won't add the metadata and instead produce plain JSON.
-# # Without a "__class", the deserializer relies on `class_name_heuristic` and the static type.
-# # The type of the root object to deserialize can be specified by calling
-# # its deserialization constructor `from_deserializer`.
-# var plain_json = """{
-#     "corners": [{"x": 0, "y": 0},
-#                 {"x": 3, "y": 0},
-#                 {"x": 2, "y": 2}],
-#     "name": "the same triangle"
-# }"""
-#
-# deserializer = new JsonDeserializer(plain_json)
-# object = new Triangle.from_deserializer(deserializer)
-# assert deserializer.errors.is_empty # If false, `obj` is invalid
-# print object
-# ~~~
-#
-# ### Missing attributes and default values
-#
-# When reading JSON, some attributes expected by Nit classes may be missing.
-# The JSON object may come from an external API using optional attributes or
-# from a previous version of your program without the attributes.
-# When an attribute is not found, the deserialization engine acts in one of three ways:
-#
-# 1. If the attribute has a default value or if it is annotated by `lazy`,
-#    the engine leave the attribute to the default value. No error is raised.
-# 2. If the static type of the attribute is nullable, the engine sets
-#    the attribute to `null`. No error is raised.
-# 3. Otherwise, the engine raises an error and does not set the attribute.
-#    The caller must check for `errors` and must not read from the attribute.
-#
-# ~~~nitish
-# import json::serialization
-#
-# class MyConfig
-#     serialize
-#
-#     var width: Int # Must be in JSON or an error is raised
-#     var height = 4
-#     var volume_level = 8 is lazy
-#     var player_name: nullable String
-#     var tmp_dir: nullable String = "/tmp" is lazy
-# end
-#
-# # ---
-# # JSON object with all expected attributes -> OK
-# var plain_json = """
-# {
-#     "width": 11,
-#     "height": 22,
-#     "volume_level": 33,
-#     "player_name": "Alice",
-#     "tmp_dir": null
-# }"""
-# var deserializer = new JsonDeserializer(plain_json)
-# var obj = new MyConfig.from_deserializer(deserializer)
-#
-# assert deserializer.errors.is_empty
-# assert obj.width == 11
-# assert obj.height == 22
-# assert obj.volume_level == 33
-# assert obj.player_name == "Alice"
-# assert obj.tmp_dir == null
-#
-# # ---
-# # JSON object missing optional attributes -> OK
-# plain_json = """
-# {
-#     "width": 11
-# }"""
-# deserializer = new JsonDeserializer(plain_json)
-# obj = new MyConfig.from_deserializer(deserializer)
-#
-# assert deserializer.errors.is_empty
-# assert obj.width == 11
-# assert obj.height == 4
-# assert obj.volume_level == 8
-# assert obj.player_name == null
-# assert obj.tmp_dir == "/tmp"
-#
-# # ---
-# # JSON object missing the mandatory attribute -> Error
-# plain_json = """
-# {
-#     "player_name": "Bob",
-# }"""
-# deserializer = new JsonDeserializer(plain_json)
-# obj = new MyConfig.from_deserializer(deserializer)
-#
-# # There's an error, `obj` is partial
-# assert deserializer.errors.length == 1
-#
-# # Still, we can access valid attributes
-# assert obj.player_name == "Bob"
-# ~~~
-module serialization
-
-import ::serialization::caching
-private import ::serialization::engine_tools
-private import static
-private import string_parser
-
-# Serializer of Nit objects to Json string.
-class JsonSerializer
-       super CachingSerializer
-
-       # Target writing stream
-       var stream: Writer
-
-       # Write plain JSON? Standard JSON without metadata for deserialization
-       #
-       # If `false`, the default, serialize to support deserialization:
-       #
-       # * Write metadata, including the types of the serialized objects so they can
-       #   be deserialized to their original form using `JsonDeserializer`.
-       # * Use references when an object has already been serialized so to not duplicate it.
-       # * Support cycles in references.
-       # * Preserve the Nit `Char` type as an object because it does not exist in JSON.
-       # * The generated JSON is standard and can be read by non-Nit programs.
-       #   However, some Nit types are not represented by the simplest possible JSON representation.
-       #   With the added metadata, it can be complex to read.
-       #
-       # If `true`, serialize for other programs:
-       #
-       # * Nit objects are serialized to pure and standard JSON so they can
-       #   be easily read by non-Nit programs and humans.
-       # * Nit objects are serialized for every references, so they can be duplicated.
-       #   It is easier to read but it creates a larger output.
-       # * Does not support cycles, will replace the problematic references by `null`.
-       # * Does not serialize the metadata needed to deserialize the objects
-       #   back to regular Nit objects.
-       # * Keys of Nit `HashMap` are converted to their string representation using `to_s`.
-       var plain_json = false is writable
-
-       # Write pretty JSON for human eyes?
-       #
-       # Toggles skipping lines between attributes of an object and
-       # properly indent the written JSON.
-       var pretty_json = false is writable
-
-       # Current indentation level used for writing `pretty_json`
-       private var indent_level = 0
-
-       # List of the current open objects, the first is the main target of the serialization
-       #
-       # Used only when `plain_json == true` to detect cycles in serialization.
-       private var open_objects = new Array[Object]
-
-       # Has the first attribute of the current object already been serialized?
-       #
-       # Used only when `plain_json == true`.
-       private var first_attribute = false
-
-       redef fun serialize(object)
-       do
-               if object == null then
-                       stream.write "null"
-               else
-                       if plain_json then
-                               for o in open_objects do
-                                       if object.is_same_serialized(o) then
-                                               # Cycle, can't be managed in plain json
-                                               warn "Cycle detected in serialized object, replacing reference with 'null'."
-                                               stream.write "null"
-                                               return
-                                       end
-                               end
-
-                               open_objects.add object
-                       end
-
-                       first_attribute = true
-                       object.accept_json_serializer self
-                       first_attribute = false
-
-                       if plain_json then open_objects.pop
-               end
-       end
-
-       redef fun serialize_attribute(name, value)
-       do
-               if not plain_json or not first_attribute then
-                       stream.write ","
-                       first_attribute = false
-               end
-
-               new_line_and_indent
-               stream.write "\""
-               stream.write name
-               stream.write "\": "
-               super
-       end
-
-       redef fun serialize_reference(object)
-       do
-               if not plain_json and cache.has_object(object) then
-                       # if already serialized, add local reference
-                       var id = cache.id_for(object)
-                       stream.write "\{"
-                       indent_level += 1
-                       new_line_and_indent
-                       stream.write "\"__kind\": \"ref\", \"__id\": "
-                       stream.write id.to_s
-                       indent_level -= 1
-                       new_line_and_indent
-                       stream.write "\}"
-               else
-                       # serialize here
-                       serialize object
-               end
-       end
-
-       # Write a new line and indent it, only if `pretty_json`
-       private fun new_line_and_indent
-       do
-               if pretty_json then
-                       stream.write "\n"
-                       for i in indent_level.times do stream.write "\t"
-               end
-       end
-end
-
-# Deserializer from a Json string.
-class JsonDeserializer
-       super CachingDeserializer
-
-       # Json text to deserialize from.
-       private var text: Text
-
-       # Root json object parsed from input text.
-       private var root: nullable Object is noinit
-
-       # Depth-first path in the serialized object tree.
-       private var path = new Array[Map[String, nullable Object]]
-
-       # Names of the attributes from the root to the object currently being deserialized
-       var attributes_path = new Array[String]
-
-       # Last encountered object reference id.
-       #
-       # See `id_to_object`.
-       var just_opened_id: nullable Int = null
-
-       init do
-               var root = text.parse_json
-               if root isa Map[String, nullable Object] then path.add(root)
-               self.root = root
-       end
-
-       redef fun deserialize_attribute(name, static_type)
-       do
-               if path.is_empty then
-                       # The was a parsing error or the root is not an object
-                       if not root isa Error then
-                               errors.add new Error("Deserialization Error: parsed JSON value is not an object.")
-                       end
-                       deserialize_attribute_missing = false
-                       return null
-               end
-
-               var current = path.last
-
-               if not current.keys.has(name) then
-                       # Let the generated code / caller of `deserialize_attribute` raise the missing attribute error
-                       deserialize_attribute_missing = true
-                       return null
-               end
-
-               var value = current[name]
-
-               attributes_path.add name
-               var res = convert_object(value, static_type)
-               attributes_path.pop
-
-               deserialize_attribute_missing = false
-               return res
-       end
-
-       # This may be called multiple times by the same object from constructors
-       # in different nclassdef
-       redef fun notify_of_creation(new_object)
-       do
-               var id = just_opened_id
-               if id == null then return # Register `new_object` only once
-               cache[id] = new_object
-       end
-
-       # Convert the simple JSON `object` to a Nit object
-       private fun convert_object(object: nullable Object, static_type: nullable String): nullable Object
-       do
-               if object isa JsonParseError then
-                       errors.add object
-                       return null
-               end
-
-               if object isa Map[String, nullable Object] then
-                       var kind = null
-                       if object.keys.has("__kind") then
-                               kind = object["__kind"]
-                       end
-
-                       # ref?
-                       if kind == "ref" then
-                               if not object.keys.has("__id") then
-                                       errors.add new Error("Serialization Error: JSON object reference does not declare a `__id`.")
-                                       return object
-                               end
-
-                               var id = object["__id"]
-                               if not id isa Int then
-                                       errors.add new Error("Serialization Error: JSON object reference declares a non-integer `__id`.")
-                                       return object
-                               end
-
-                               if not cache.has_id(id) then
-                                       errors.add new Error("Serialization Error: JSON object reference has an unknown `__id`.")
-                                       return object
-                               end
-
-                               return cache.object_for(id)
-                       end
-
-                       # obj?
-                       if kind == "obj" or kind == null then
-                               var id = null
-                               if object.keys.has("__id") then
-                                       id = object["__id"]
-
-                                       if not id isa Int then
-                                               errors.add new Error("Serialization Error: JSON object declaration declares a non-integer `__id`.")
-                                               return object
-                                       end
-
-                                       if cache.has_id(id) then
-                                               errors.add new Error("Serialization Error: JSON object with `__id` {id} is deserialized twice.")
-                                               # Keep going
-                                       end
-                               end
-
-                               var class_name = object.get_or_null("__class")
-                               if class_name == null then
-                                       # Fallback to custom heuristic
-                                       class_name = class_name_heuristic(object)
-
-                                       if class_name == null and static_type != null then
-                                               # Fallack to the static type, strip the `nullable` prefix
-                                               var prefix = "nullable "
-                                               if static_type.has(prefix) then
-                                                       class_name = static_type.substring_from(prefix.length)
-                                               else class_name = static_type
-                                       end
-                               end
-
-                               if class_name == null then
-                                       errors.add new Error("Serialization Error: JSON object declaration does not declare a `__class`.")
-                                       return object
-                               end
-
-                               if not class_name isa String then
-                                       errors.add new Error("Serialization Error: JSON object declaration declares a non-string `__class`.")
-                                       return object
-                               end
-
-                               # advance on path
-                               path.push object
-
-                               just_opened_id = id
-                               var value = deserialize_class(class_name)
-                               just_opened_id = null
-
-                               # revert on path
-                               path.pop
-
-                               return value
-                       end
-
-                       # char?
-                       if kind == "char" then
-                               if not object.keys.has("__val") then
-                                       errors.add new Error("Serialization Error: JSON `char` object does not declare a `__val`.")
-                                       return object
-                               end
-
-                               var val = object["__val"]
-
-                               if not val isa String or val.is_empty then
-                                       errors.add new Error("Serialization Error: JSON `char` object does not declare a single char in `__val`.")
-                                       return object
-                               end
-
-                               return val.chars.first
-                       end
-
-                       errors.add new Error("Serialization Error: JSON object has an unknown `__kind`.")
-                       return object
-               end
-
-               # Simple JSON array without serialization metadata
-               if object isa Array[nullable Object] then
-                       # Can we use the static type?
-                       if static_type != null then
-                               var prefix = "nullable "
-                               var class_name = if static_type.has(prefix) then
-                                               static_type.substring_from(prefix.length)
-                                       else static_type
-
-                               opened_array = object
-                               var value = deserialize_class(class_name)
-                               opened_array = null
-                               return value
-                       end
-
-                       # This branch should rarely be used:
-                       # when an array is the root object which is accepted but illegal in standard JSON,
-                       # or in strange custom deserialization hacks.
-
-                       var array = new Array[nullable Object]
-                       var types = new HashSet[String]
-                       var has_nullable = false
-                       for e in object do
-                               var res = convert_object(e)
-                               array.add res
-
-                               if res != null then
-                                       types.add res.class_name
-                               else has_nullable = true
-                       end
-
-                       if types.length == 1 then
-                               var array_type = types.first
-
-                               var typed_array
-                               if array_type == "ASCIIFlatString" or array_type == "UnicodeFlatString" then
-                                       if has_nullable then
-                                               typed_array = new Array[nullable FlatString]
-                                       else typed_array = new Array[FlatString]
-                               else if array_type == "Int" then
-                                       if has_nullable then
-                                               typed_array = new Array[nullable Int]
-                                       else typed_array = new Array[Int]
-                               else if array_type == "Float" then
-                                       if has_nullable then
-                                               typed_array = new Array[nullable Float]
-                                       else typed_array = new Array[Float]
-                               else
-                                       # TODO support all array types when we separate the constructor
-                                       # `from_deserializer` from the filling of the items.
-
-                                       if not has_nullable then
-                                               typed_array = new Array[Object]
-                                       else
-                                               # Unsupported array type, return as `Array[nullable Object]`
-                                               return array
-                                       end
-                               end
-
-                               assert typed_array isa Array[nullable Object]
-
-                               # Copy item to the new array
-                               for e in array do typed_array.add e
-                               return typed_array
-                       end
-
-                       # Uninferrable type, return as `Array[nullable Object]`
-                       return array
-               end
-
-               return object
-       end
-
-       # Current array open for deserialization, used by `SimpleCollection::from_deserializer`
-       private var opened_array: nullable Array[nullable Object] = null
-
-       redef fun deserialize
-       do
-               errors.clear
-               return convert_object(root)
-       end
-
-       # User customizable heuristic to infer the name of the Nit class to deserialize `json_object`
-       #
-       # This method is called only when deserializing an object without the metadata `__class`.
-       # Use the content of `json_object` to identify what Nit class it should be deserialized into.
-       # Or use `self.attributes_path` indicating where the deserialized object will be stored,
-       # is is less reliable as some objects don't have an associated attribute:
-       # the root/first deserialized object and collection elements.
-       #
-       # Return the class name as a `String` when it can be inferred,
-       # or `null` when the class name cannot be found.
-       #
-       # If a valid class name is returned, `json_object` will then be deserialized normally.
-       # So it must contain the attributes of the corresponding class, as usual.
-       #
-       # ~~~nitish
-       # class MyData
-       #     serialize
-       #
-       #     var data: String
-       # end
-       #
-       # class MyError
-       #     serialize
-       #
-       #     var error: String
-       #     var related_data: MyData
-       # end
-       #
-       # class MyJsonDeserializer
-       #     super JsonDeserializer
-       #
-       #     redef fun class_name_heuristic(json_object)
-       #     do
-       #         # Infer the Nit class from the content of the JSON object.
-       #         if json_object.keys.has("error") then return "MyError"
-       #         if json_object.keys.has("data") then return "MyData"
-       #
-       #         # Infer the Nit class from the attribute where it will be stored.
-       #         # This line duplicates a previous line, and would only apply when
-       #         # `MyData` is within a `MyError`.
-       #         if attributes_path.not_empty and attributes_path.last == "related_data" then return "MyData"
-       #
-       #         return null
-       #     end
-       # end
-       #
-       # var json = """{"data": "some data"}"""
-       # var deserializer = new MyJsonDeserializer(json)
-       # var deserialized = deserializer.deserialize
-       # assert deserialized isa MyData
-       #
-       # json = """{"error": "some error message",
-       #            "related_data": {"data": "some other data"}"""
-       # deserializer = new MyJsonDeserializer(json)
-       # deserialized = deserializer.deserialize
-       # assert deserialized isa MyError
-       # ~~~
-       protected fun class_name_heuristic(json_object: Map[String, nullable Object]): nullable String
-       do
-               return null
-       end
-end
-
-redef class Text
-
-       # Deserialize a `nullable Object` from this JSON formatted string
-       #
-       # Warning: Deserialization errors are reported with `print_error` and
-       # may be returned as a partial object or as `null`.
-       #
-       # This method is not appropriate when errors need to be handled programmatically,
-       # manually use a `JsonDeserializer` in such cases.
-       fun from_json_string: nullable Object
-       do
-               var deserializer = new JsonDeserializer(self)
-               var res = deserializer.deserialize
-               if deserializer.errors.not_empty then
-                       print_error "Deserialization Errors: {deserializer.errors.join(", ")}"
-               end
-               return res
-       end
-
-       redef fun accept_json_serializer(v) do v.stream.write(to_json)
-end
-
-redef class Serializable
-
-       # Serialize `self` to JSON
-       #
-       # Set `plain = true` to generate standard JSON, without deserialization metadata.
-       # Use this option if the generated JSON will be read by other programs or humans.
-       # Use the default, `plain = false`, if the JSON is to be deserialized by a Nit program.
-       #
-       # Set `pretty = true` to generate pretty JSON for human eyes.
-       # Use the default, `pretty = false`, to generate minified JSON.
-       #
-       # This method should not be refined by subclasses,
-       # instead `accept_json_serializer` can customize the serialization of an object.
-       #
-       # See: `JsonSerializer`
-       fun serialize_to_json(plain, pretty: nullable Bool): String
-       do
-               var stream = new StringWriter
-               var serializer = new JsonSerializer(stream)
-               serializer.plain_json = plain or else false
-               serializer.pretty_json = pretty or else false
-               serializer.serialize self
-               stream.close
-               return stream.to_s
-       end
-
-       # Refinable service to customize the serialization of this class to JSON
-       #
-       # This method can be refined to customize the serialization by either
-       # writing pure JSON directly on the stream `v.stream` or
-       # by using other services of `JsonSerializer`.
-       #
-       # Most of the time, it is preferable to refine the method `core_serialize_to`
-       # which is used by all the serialization engines, not just JSON.
-       protected fun accept_json_serializer(v: JsonSerializer)
-       do
-               var id = v.cache.new_id_for(self)
-               v.stream.write "\{"
-               v.indent_level += 1
-               if not v.plain_json then
-                       v.new_line_and_indent
-                       v.stream.write "\"__kind\": \"obj\", \"__id\": "
-                       v.stream.write id.to_s
-                       v.stream.write ", \"__class\": \""
-                       v.stream.write class_name
-                       v.stream.write "\""
-               end
-               core_serialize_to(v)
-
-               v.indent_level -= 1
-               v.new_line_and_indent
-               v.stream.write "\}"
-       end
-end
-
-redef class Int
-       redef fun accept_json_serializer(v) do v.stream.write to_s
-end
-
-redef class Float
-       redef fun accept_json_serializer(v) do v.stream.write to_s
-end
-
-redef class Bool
-       redef fun accept_json_serializer(v) do v.stream.write to_s
-end
-
-redef class Char
-       redef fun accept_json_serializer(v)
-       do
-               if v.plain_json then
-                       to_s.accept_json_serializer v
-               else
-                       v.stream.write "\{\"__kind\": \"char\", \"__val\": "
-                       to_s.accept_json_serializer v
-                       v.stream.write "\}"
-               end
-       end
-end
-
-redef class NativeString
-       redef fun accept_json_serializer(v) do to_s.accept_json_serializer(v)
-end
-
-redef class Collection[E]
-       # Utility to serialize a normal Json array
-       private fun serialize_to_pure_json(v: JsonSerializer)
-       do
-               v.stream.write "["
-               v.indent_level += 1
-               var is_first = true
-               for e in self do
-                       if is_first then
-                               is_first = false
-                       else v.stream.write ","
-                       v.new_line_and_indent
-
-                       if not v.try_to_serialize(e) then
-                               assert e != null # null would have been serialized
-                               v.warn("element of type {e.class_name} is not serializable.")
-                       end
-               end
-               v.indent_level -= 1
-               v.new_line_and_indent
-               v.stream.write "]"
-       end
-end
-
-redef class SimpleCollection[E]
-       redef fun accept_json_serializer(v)
-       do
-               # Register as pseudo object
-               if not v.plain_json then
-                       var id = v.cache.new_id_for(self)
-                       v.stream.write """{"""
-                       v.indent_level += 1
-                       v.new_line_and_indent
-                       v.stream.write """"__kind": "obj", "__id": """
-                       v.stream.write id.to_s
-                       v.stream.write """, "__class": """"
-                       v.stream.write class_name
-                       v.stream.write """","""
-                       v.new_line_and_indent
-                       v.stream.write """"__items": """
-
-                       core_serialize_to v
-               end
-
-               serialize_to_pure_json v
-
-               if not v.plain_json then
-                       v.indent_level -= 1
-                       v.new_line_and_indent
-                       v.stream.write "\}"
-               end
-       end
-
-       redef init from_deserializer(v)
-       do
-               super
-               if v isa JsonDeserializer then
-                       v.notify_of_creation self
-                       init
-
-                       var open_array: nullable SequenceRead[nullable Object] = v.opened_array
-                       if open_array == null then
-                               # With metadata
-                               var arr = v.path.last.get_or_null("__items")
-                               if not arr isa SequenceRead[nullable Object] then
-                                       # If there is nothing, we consider that it is an empty collection.
-                                       if arr != null then v.errors.add new Error("Deserialization Error: invalid format in {self.class_name}")
-                                       return
-                               end
-                               open_array = arr
-                       end
-
-                       # Try to get the name of the single parameter type assuming it is E.
-                       # This does not work in non-generic subclasses,
-                       # when the first parameter is not E, or
-                       # when there is more than one parameter. (The last one could be fixed)
-                       var class_name = class_name
-                       var items_type = null
-                       var bracket_index = class_name.index_of('[')
-                       if bracket_index != -1 then
-                               var start = bracket_index + 1
-                               var ending = class_name.last_index_of(']')
-                               items_type = class_name.substring(start, ending-start)
-                       end
-
-                       # Fill array
-                       for o in open_array do
-                               var obj = v.convert_object(o, items_type)
-                               if obj isa E then
-                                       add obj
-                               else v.errors.add new AttributeTypeError(self, "items", obj, "E")
-                       end
-               end
-       end
-end
-
-redef class Map[K, V]
-       redef fun accept_json_serializer(v)
-       do
-               # Register as pseudo object
-               var id = v.cache.new_id_for(self)
-
-               v.stream.write "\{"
-               v.indent_level += 1
-
-               if v.plain_json then
-                       var first = true
-                       for key, val in self do
-                               if not first then
-                                       v.stream.write ","
-                               else first = false
-                               v.new_line_and_indent
-
-                               var k = key or else "null"
-                               k.to_s.accept_json_serializer v
-                               v.stream.write ": "
-                               if not v.try_to_serialize(val) then
-                                       assert val != null # null would have been serialized
-                                       v.warn("element of type {val.class_name} is not serializable.")
-                                       v.stream.write "null"
-                               end
-                       end
-               else
-                       v.new_line_and_indent
-                       v.stream.write """"__kind": "obj", "__id": """
-                       v.stream.write id.to_s
-                       v.stream.write """, "__class": """"
-                       v.stream.write class_name
-                       v.stream.write """", "__length": """
-                       v.stream.write length.to_s
-
-                       v.stream.write ","
-                       v.new_line_and_indent
-                       v.stream.write """"__keys": """
-                       keys.serialize_to_pure_json v
-
-                       v.stream.write ","
-                       v.new_line_and_indent
-                       v.stream.write """"__values": """
-                       values.serialize_to_pure_json v
-
-                       core_serialize_to v
-               end
-
-               v.indent_level -= 1
-               v.new_line_and_indent
-               v.stream.write "\}"
-       end
-
-       redef init from_deserializer(v)
-       do
-               super
-
-               if v isa JsonDeserializer then
-                       v.notify_of_creation self
-                       init
-
-                       var length = v.deserialize_attribute("__length")
-                       var keys = v.path.last.get_or_null("__keys")
-                       var values = v.path.last.get_or_null("__values")
-
-                       # Length is optional
-                       if length == null and keys isa SequenceRead[nullable Object] then length = keys.length
-
-                       # Consistency check
-                       if not length isa Int or length < 0 or
-                          not keys isa SequenceRead[nullable Object] or
-                          not values isa SequenceRead[nullable Object] or
-                          keys.length != values.length or length != keys.length then
-
-                               # If there is nothing or length == 0, we consider that it is an empty Map.
-                               if (length != null and length != 0) or keys != null or values != null then
-                                       v.errors.add new Error("Deserialization Error: invalid format in {self.class_name}")
-                               end
-                               return
-                       end
-
-                       for i in length.times do
-                               var key = v.convert_object(keys[i])
-                               var value = v.convert_object(values[i])
-
-                               if not key isa K then
-                                       v.errors.add new AttributeTypeError(self, "keys", key, "K")
-                                       continue
-                               end
-
-                               if not value isa V then
-                                       v.errors.add new AttributeTypeError(self, "values", value, "V")
-                                       continue
-                               end
-
-                               if has_key(key) then
-                                       v.errors.add new Error("Deserialization Error: duplicated key '{key or else "null"}' in {self.class_name}, previous value overwritten")
-                               end
-
-                               self[key] = value
-                       end
-               end
-       end
-end
diff --git a/lib/json/serialization_read.nit b/lib/json/serialization_read.nit
new file mode 100644 (file)
index 0000000..e29f5bd
--- /dev/null
@@ -0,0 +1,460 @@
+# 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.
+
+# Services to read JSON: `from_json_string` and `JsonDeserializer`
+module serialization_read
+
+import ::serialization::caching
+private import ::serialization::engine_tools
+private import static
+private import string_parser
+
+# Deserializer from a Json string.
+class JsonDeserializer
+       super CachingDeserializer
+
+       # Json text to deserialize from.
+       private var text: Text
+
+       # Root json object parsed from input text.
+       private var root: nullable Object is noinit
+
+       # Depth-first path in the serialized object tree.
+       private var path = new Array[Map[String, nullable Object]]
+
+       # Names of the attributes from the root to the object currently being deserialized
+       var attributes_path = new Array[String]
+
+       # Last encountered object reference id.
+       #
+       # See `id_to_object`.
+       var just_opened_id: nullable Int = null
+
+       init do
+               var root = text.parse_json
+               if root isa Map[String, nullable Object] then path.add(root)
+               self.root = root
+       end
+
+       redef fun deserialize_attribute(name, static_type)
+       do
+               if path.is_empty then
+                       # The was a parsing error or the root is not an object
+                       if not root isa Error then
+                               errors.add new Error("Deserialization Error: parsed JSON value is not an object.")
+                       end
+                       deserialize_attribute_missing = false
+                       return null
+               end
+
+               var current = path.last
+
+               if not current.keys.has(name) then
+                       # Let the generated code / caller of `deserialize_attribute` raise the missing attribute error
+                       deserialize_attribute_missing = true
+                       return null
+               end
+
+               var value = current[name]
+
+               attributes_path.add name
+               var res = convert_object(value, static_type)
+               attributes_path.pop
+
+               deserialize_attribute_missing = false
+               return res
+       end
+
+       # This may be called multiple times by the same object from constructors
+       # in different nclassdef
+       redef fun notify_of_creation(new_object)
+       do
+               var id = just_opened_id
+               if id == null then return # Register `new_object` only once
+               cache[id] = new_object
+       end
+
+       # Convert the simple JSON `object` to a Nit object
+       private fun convert_object(object: nullable Object, static_type: nullable String): nullable Object
+       do
+               if object isa JsonParseError then
+                       errors.add object
+                       return null
+               end
+
+               if object isa Map[String, nullable Object] then
+                       var kind = null
+                       if object.keys.has("__kind") then
+                               kind = object["__kind"]
+                       end
+
+                       # ref?
+                       if kind == "ref" then
+                               if not object.keys.has("__id") then
+                                       errors.add new Error("Serialization Error: JSON object reference does not declare a `__id`.")
+                                       return object
+                               end
+
+                               var id = object["__id"]
+                               if not id isa Int then
+                                       errors.add new Error("Serialization Error: JSON object reference declares a non-integer `__id`.")
+                                       return object
+                               end
+
+                               if not cache.has_id(id) then
+                                       errors.add new Error("Serialization Error: JSON object reference has an unknown `__id`.")
+                                       return object
+                               end
+
+                               return cache.object_for(id)
+                       end
+
+                       # obj?
+                       if kind == "obj" or kind == null then
+                               var id = null
+                               if object.keys.has("__id") then
+                                       id = object["__id"]
+
+                                       if not id isa Int then
+                                               errors.add new Error("Serialization Error: JSON object declaration declares a non-integer `__id`.")
+                                               return object
+                                       end
+
+                                       if cache.has_id(id) then
+                                               errors.add new Error("Serialization Error: JSON object with `__id` {id} is deserialized twice.")
+                                               # Keep going
+                                       end
+                               end
+
+                               var class_name = object.get_or_null("__class")
+                               if class_name == null then
+                                       # Fallback to custom heuristic
+                                       class_name = class_name_heuristic(object)
+
+                                       if class_name == null and static_type != null then
+                                               # Fallack to the static type, strip the `nullable` prefix
+                                               var prefix = "nullable "
+                                               if static_type.has(prefix) then
+                                                       class_name = static_type.substring_from(prefix.length)
+                                               else class_name = static_type
+                                       end
+                               end
+
+                               if class_name == null then
+                                       errors.add new Error("Serialization Error: JSON object declaration does not declare a `__class`.")
+                                       return object
+                               end
+
+                               if not class_name isa String then
+                                       errors.add new Error("Serialization Error: JSON object declaration declares a non-string `__class`.")
+                                       return object
+                               end
+
+                               # advance on path
+                               path.push object
+
+                               just_opened_id = id
+                               var value = deserialize_class(class_name)
+                               just_opened_id = null
+
+                               # revert on path
+                               path.pop
+
+                               return value
+                       end
+
+                       # char?
+                       if kind == "char" then
+                               if not object.keys.has("__val") then
+                                       errors.add new Error("Serialization Error: JSON `char` object does not declare a `__val`.")
+                                       return object
+                               end
+
+                               var val = object["__val"]
+
+                               if not val isa String or val.is_empty then
+                                       errors.add new Error("Serialization Error: JSON `char` object does not declare a single char in `__val`.")
+                                       return object
+                               end
+
+                               return val.chars.first
+                       end
+
+                       errors.add new Error("Serialization Error: JSON object has an unknown `__kind`.")
+                       return object
+               end
+
+               # Simple JSON array without serialization metadata
+               if object isa Array[nullable Object] then
+                       # Can we use the static type?
+                       if static_type != null then
+                               var prefix = "nullable "
+                               var class_name = if static_type.has(prefix) then
+                                               static_type.substring_from(prefix.length)
+                                       else static_type
+
+                               opened_array = object
+                               var value = deserialize_class(class_name)
+                               opened_array = null
+                               return value
+                       end
+
+                       # This branch should rarely be used:
+                       # when an array is the root object which is accepted but illegal in standard JSON,
+                       # or in strange custom deserialization hacks.
+
+                       var array = new Array[nullable Object]
+                       var types = new HashSet[String]
+                       var has_nullable = false
+                       for e in object do
+                               var res = convert_object(e)
+                               array.add res
+
+                               if res != null then
+                                       types.add res.class_name
+                               else has_nullable = true
+                       end
+
+                       if types.length == 1 then
+                               var array_type = types.first
+
+                               var typed_array
+                               if array_type == "ASCIIFlatString" or array_type == "UnicodeFlatString" then
+                                       if has_nullable then
+                                               typed_array = new Array[nullable FlatString]
+                                       else typed_array = new Array[FlatString]
+                               else if array_type == "Int" then
+                                       if has_nullable then
+                                               typed_array = new Array[nullable Int]
+                                       else typed_array = new Array[Int]
+                               else if array_type == "Float" then
+                                       if has_nullable then
+                                               typed_array = new Array[nullable Float]
+                                       else typed_array = new Array[Float]
+                               else
+                                       # TODO support all array types when we separate the constructor
+                                       # `from_deserializer` from the filling of the items.
+
+                                       if not has_nullable then
+                                               typed_array = new Array[Object]
+                                       else
+                                               # Unsupported array type, return as `Array[nullable Object]`
+                                               return array
+                                       end
+                               end
+
+                               assert typed_array isa Array[nullable Object]
+
+                               # Copy item to the new array
+                               for e in array do typed_array.add e
+                               return typed_array
+                       end
+
+                       # Uninferrable type, return as `Array[nullable Object]`
+                       return array
+               end
+
+               return object
+       end
+
+       # Current array open for deserialization, used by `SimpleCollection::from_deserializer`
+       private var opened_array: nullable Array[nullable Object] = null
+
+       redef fun deserialize
+       do
+               errors.clear
+               return convert_object(root)
+       end
+
+       # User customizable heuristic to infer the name of the Nit class to deserialize `json_object`
+       #
+       # This method is called only when deserializing an object without the metadata `__class`.
+       # Use the content of `json_object` to identify what Nit class it should be deserialized into.
+       # Or use `self.attributes_path` indicating where the deserialized object will be stored,
+       # is is less reliable as some objects don't have an associated attribute:
+       # the root/first deserialized object and collection elements.
+       #
+       # Return the class name as a `String` when it can be inferred,
+       # or `null` when the class name cannot be found.
+       #
+       # If a valid class name is returned, `json_object` will then be deserialized normally.
+       # So it must contain the attributes of the corresponding class, as usual.
+       #
+       # ~~~
+       # class MyData
+       #     serialize
+       #
+       #     var data: String
+       # end
+       #
+       # class MyError
+       #     serialize
+       #
+       #     var error: String
+       #     var related_data: MyData
+       # end
+       #
+       # class MyJsonDeserializer
+       #     super JsonDeserializer
+       #
+       #     redef fun class_name_heuristic(json_object)
+       #     do
+       #         # Infer the Nit class from the content of the JSON object.
+       #         if json_object.keys.has("error") then return "MyError"
+       #         if json_object.keys.has("data") then return "MyData"
+       #
+       #         # Infer the Nit class from the attribute where it will be stored.
+       #         # This line duplicates a previous line, and would only apply when
+       #         # `MyData` is within a `MyError`.
+       #         if attributes_path.not_empty and attributes_path.last == "related_data" then return "MyData"
+       #
+       #         return null
+       #     end
+       # end
+       #
+       # var json = """{"data": "some data"}"""
+       # var deserializer = new MyJsonDeserializer(json)
+       # var deserialized = deserializer.deserialize
+       # assert deserializer.errors.is_empty
+       # assert deserialized isa MyData
+       #
+       # json = """{"error": "some error message",
+       #            "related_data": {"data": "some other data"}}"""
+       # deserializer = new MyJsonDeserializer(json)
+       # deserialized = deserializer.deserialize
+       # assert deserializer.errors.is_empty
+       # assert deserialized isa MyError
+       # ~~~
+       protected fun class_name_heuristic(json_object: Map[String, nullable Object]): nullable String
+       do
+               return null
+       end
+end
+
+redef class Text
+
+       # Deserialize a `nullable Object` from this JSON formatted string
+       #
+       # Warning: Deserialization errors are reported with `print_error` and
+       # may be returned as a partial object or as `null`.
+       #
+       # This method is not appropriate when errors need to be handled programmatically,
+       # manually use a `JsonDeserializer` in such cases.
+       fun from_json_string: nullable Object
+       do
+               var deserializer = new JsonDeserializer(self)
+               var res = deserializer.deserialize
+               if deserializer.errors.not_empty then
+                       print_error "Deserialization Errors: {deserializer.errors.join(", ")}"
+               end
+               return res
+       end
+end
+
+redef class SimpleCollection[E]
+       redef init from_deserializer(v)
+       do
+               super
+               if v isa JsonDeserializer then
+                       v.notify_of_creation self
+                       init
+
+                       var open_array: nullable SequenceRead[nullable Object] = v.opened_array
+                       if open_array == null then
+                               # With metadata
+                               var arr = v.path.last.get_or_null("__items")
+                               if not arr isa SequenceRead[nullable Object] then
+                                       # If there is nothing, we consider that it is an empty collection.
+                                       if arr != null then v.errors.add new Error("Deserialization Error: invalid format in {self.class_name}")
+                                       return
+                               end
+                               open_array = arr
+                       end
+
+                       # Try to get the name of the single parameter type assuming it is E.
+                       # This does not work in non-generic subclasses,
+                       # when the first parameter is not E, or
+                       # when there is more than one parameter. (The last one could be fixed)
+                       var class_name = class_name
+                       var items_type = null
+                       var bracket_index = class_name.index_of('[')
+                       if bracket_index != -1 then
+                               var start = bracket_index + 1
+                               var ending = class_name.last_index_of(']')
+                               items_type = class_name.substring(start, ending-start)
+                       end
+
+                       # Fill array
+                       for o in open_array do
+                               var obj = v.convert_object(o, items_type)
+                               if obj isa E then
+                                       add obj
+                               else v.errors.add new AttributeTypeError(self, "items", obj, "E")
+                       end
+               end
+       end
+end
+
+redef class Map[K, V]
+       redef init from_deserializer(v)
+       do
+               super
+
+               if v isa JsonDeserializer then
+                       v.notify_of_creation self
+                       init
+
+                       var length = v.deserialize_attribute("__length")
+                       var keys = v.path.last.get_or_null("__keys")
+                       var values = v.path.last.get_or_null("__values")
+
+                       # Length is optional
+                       if length == null and keys isa SequenceRead[nullable Object] then length = keys.length
+
+                       # Consistency check
+                       if not length isa Int or length < 0 or
+                          not keys isa SequenceRead[nullable Object] or
+                          not values isa SequenceRead[nullable Object] or
+                          keys.length != values.length or length != keys.length then
+
+                               # If there is nothing or length == 0, we consider that it is an empty Map.
+                               if (length != null and length != 0) or keys != null or values != null then
+                                       v.errors.add new Error("Deserialization Error: invalid format in {self.class_name}")
+                               end
+                               return
+                       end
+
+                       for i in length.times do
+                               var key = v.convert_object(keys[i])
+                               var value = v.convert_object(values[i])
+
+                               if not key isa K then
+                                       v.errors.add new AttributeTypeError(self, "keys", key, "K")
+                                       continue
+                               end
+
+                               if not value isa V then
+                                       v.errors.add new AttributeTypeError(self, "values", value, "V")
+                                       continue
+                               end
+
+                               if has_key(key) then
+                                       v.errors.add new Error("Deserialization Error: duplicated key '{key or else "null"}' in {self.class_name}, previous value overwritten")
+                               end
+
+                               self[key] = value
+                       end
+               end
+       end
+end
diff --git a/lib/json/serialization_write.nit b/lib/json/serialization_write.nit
new file mode 100644 (file)
index 0000000..e26236c
--- /dev/null
@@ -0,0 +1,371 @@
+# 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.
+
+# Services to write Nit objects to JSON strings: `serialize_to_json` and `JsonSerializer`
+module serialization_write
+
+import ::serialization::caching
+private import ::serialization::engine_tools
+
+# Serializer of Nit objects to Json string.
+class JsonSerializer
+       super CachingSerializer
+
+       # Target writing stream
+       var stream: Writer
+
+       # Write plain JSON? Standard JSON without metadata for deserialization
+       #
+       # If `false`, the default, serialize to support deserialization:
+       #
+       # * Write metadata, including the types of the serialized objects so they can
+       #   be deserialized to their original form using `JsonDeserializer`.
+       # * Use references when an object has already been serialized so to not duplicate it.
+       # * Support cycles in references.
+       # * Preserve the Nit `Char` type as an object because it does not exist in JSON.
+       # * The generated JSON is standard and can be read by non-Nit programs.
+       #   However, some Nit types are not represented by the simplest possible JSON representation.
+       #   With the added metadata, it can be complex to read.
+       #
+       # If `true`, serialize for other programs:
+       #
+       # * Nit objects are serialized to pure and standard JSON so they can
+       #   be easily read by non-Nit programs and humans.
+       # * Nit objects are serialized for every references, so they can be duplicated.
+       #   It is easier to read but it creates a larger output.
+       # * Does not support cycles, will replace the problematic references by `null`.
+       # * Does not serialize the metadata needed to deserialize the objects
+       #   back to regular Nit objects.
+       # * Keys of Nit `HashMap` are converted to their string representation using `to_s`.
+       var plain_json = false is writable
+
+       # Write pretty JSON for human eyes?
+       #
+       # Toggles skipping lines between attributes of an object and
+       # properly indent the written JSON.
+       var pretty_json = false is writable
+
+       # Current indentation level used for writing `pretty_json`
+       private var indent_level = 0
+
+       # List of the current open objects, the first is the main target of the serialization
+       #
+       # Used only when `plain_json == true` to detect cycles in serialization.
+       private var open_objects = new Array[Object]
+
+       # Has the first attribute of the current object already been serialized?
+       #
+       # Used only when `plain_json == true`.
+       private var first_attribute = false
+
+       redef fun serialize(object)
+       do
+               if object == null then
+                       stream.write "null"
+               else
+                       if plain_json then
+                               for o in open_objects do
+                                       if object.is_same_serialized(o) then
+                                               # Cycle, can't be managed in plain json
+                                               warn "Cycle detected in serialized object, replacing reference with 'null'."
+                                               stream.write "null"
+                                               return
+                                       end
+                               end
+
+                               open_objects.add object
+                       end
+
+                       first_attribute = true
+                       object.accept_json_serializer self
+                       first_attribute = false
+
+                       if plain_json then open_objects.pop
+               end
+       end
+
+       redef fun serialize_attribute(name, value)
+       do
+               if not plain_json or not first_attribute then
+                       stream.write ","
+                       first_attribute = false
+               end
+
+               new_line_and_indent
+               stream.write "\""
+               stream.write name
+               stream.write "\":"
+               if pretty_json then stream.write " "
+               super
+       end
+
+       redef fun serialize_reference(object)
+       do
+               if not plain_json and cache.has_object(object) then
+                       # if already serialized, add local reference
+                       var id = cache.id_for(object)
+                       stream.write "\{"
+                       indent_level += 1
+                       new_line_and_indent
+                       stream.write "\"__kind\": \"ref\", \"__id\": "
+                       stream.write id.to_s
+                       indent_level -= 1
+                       new_line_and_indent
+                       stream.write "\}"
+               else
+                       # serialize here
+                       serialize object
+               end
+       end
+
+       # Write a new line and indent it, only if `pretty_json`
+       private fun new_line_and_indent
+       do
+               if pretty_json then
+                       stream.write "\n"
+                       for i in indent_level.times do stream.write "\t"
+               end
+       end
+end
+
+redef class Text
+
+       redef fun accept_json_serializer(v)
+       do
+               v.stream.write "\""
+               for i in [0 .. self.length[ do
+                       var char = self[i]
+                       if char == '\\' then
+                               v.stream.write "\\\\"
+                       else if char == '\"' then
+                               v.stream.write "\\\""
+                       else if char < ' ' then
+                               if char == '\n' then
+                                       v.stream.write "\\n"
+                               else if char == '\r' then
+                                       v.stream.write "\\r"
+                               else if char == '\t' then
+                                       v.stream.write "\\t"
+                               else
+                                       v.stream.write char.escape_to_utf16
+                               end
+                       else
+                               v.stream.write char.to_s
+                       end
+               end
+               v.stream.write "\""
+       end
+end
+
+redef class Serializable
+
+       # Serialize `self` to JSON
+       #
+       # Set `plain = true` to generate standard JSON, without deserialization metadata.
+       # Use this option if the generated JSON will be read by other programs or humans.
+       # Use the default, `plain = false`, if the JSON is to be deserialized by a Nit program.
+       #
+       # Set `pretty = true` to generate pretty JSON for human eyes.
+       # Use the default, `pretty = false`, to generate minified JSON.
+       #
+       # This method should not be refined by subclasses,
+       # instead `accept_json_serializer` can customize the serialization of an object.
+       #
+       # See: `JsonSerializer`
+       fun serialize_to_json(plain, pretty: nullable Bool): String
+       do
+               var stream = new StringWriter
+               var serializer = new JsonSerializer(stream)
+               serializer.plain_json = plain or else false
+               serializer.pretty_json = pretty or else false
+               serializer.serialize self
+               stream.close
+               return stream.to_s
+       end
+
+       # Serialize `self` to plain JSON
+       #
+       # Compatibility alias for `serialize_to_json(plain=true)`.
+       fun to_json: String do return serialize_to_json(plain=true)
+
+       # Serialize `self` to plain pretty JSON
+       #
+       # Compatibility alias for `serialize_to_json(plain=true, pretty=true)`.
+       fun to_pretty_json: String do return serialize_to_json(plain=true, pretty=true)
+
+       # Refinable service to customize the serialization of this class to JSON
+       #
+       # This method can be refined to customize the serialization by either
+       # writing pure JSON directly on the stream `v.stream` or
+       # by using other services of `JsonSerializer`.
+       #
+       # Most of the time, it is preferable to refine the method `core_serialize_to`
+       # which is used by all the serialization engines, not just JSON.
+       protected fun accept_json_serializer(v: JsonSerializer)
+       do
+               var id = v.cache.new_id_for(self)
+               v.stream.write "\{"
+               v.indent_level += 1
+               if not v.plain_json then
+                       v.new_line_and_indent
+                       v.stream.write "\"__kind\": \"obj\", \"__id\": "
+                       v.stream.write id.to_s
+                       v.stream.write ", \"__class\": \""
+                       v.stream.write class_name
+                       v.stream.write "\""
+               end
+               core_serialize_to(v)
+
+               v.indent_level -= 1
+               v.new_line_and_indent
+               v.stream.write "\}"
+       end
+end
+
+redef class Int
+       redef fun accept_json_serializer(v) do v.stream.write to_s
+end
+
+redef class Float
+       redef fun accept_json_serializer(v) do v.stream.write to_s
+end
+
+redef class Bool
+       redef fun accept_json_serializer(v) do v.stream.write to_s
+end
+
+redef class Char
+       redef fun accept_json_serializer(v)
+       do
+               if v.plain_json then
+                       to_s.accept_json_serializer v
+               else
+                       v.stream.write "\{\"__kind\": \"char\", \"__val\": "
+                       to_s.accept_json_serializer v
+                       v.stream.write "\}"
+               end
+       end
+end
+
+redef class NativeString
+       redef fun accept_json_serializer(v) do to_s.accept_json_serializer(v)
+end
+
+redef class Collection[E]
+       # Utility to serialize a normal Json array
+       private fun serialize_to_pure_json(v: JsonSerializer)
+       do
+               v.stream.write "["
+               var is_first = true
+               for e in self do
+                       if is_first then
+                               is_first = false
+                       else
+                               v.stream.write ","
+                               if v.pretty_json then v.stream.write " "
+                       end
+
+                       if not v.try_to_serialize(e) then
+                               assert e != null # null would have been serialized
+                               v.warn("element of type {e.class_name} is not serializable.")
+                       end
+               end
+               v.stream.write "]"
+       end
+end
+
+redef class SimpleCollection[E]
+       redef fun accept_json_serializer(v)
+       do
+               # Register as pseudo object
+               if not v.plain_json then
+                       var id = v.cache.new_id_for(self)
+                       v.stream.write """{"""
+                       v.indent_level += 1
+                       v.new_line_and_indent
+                       v.stream.write """"__kind": "obj", "__id": """
+                       v.stream.write id.to_s
+                       v.stream.write """, "__class": """"
+                       v.stream.write class_name
+                       v.stream.write """","""
+                       v.new_line_and_indent
+                       v.stream.write """"__items": """
+
+                       core_serialize_to v
+               end
+
+               serialize_to_pure_json v
+
+               if not v.plain_json then
+                       v.indent_level -= 1
+                       v.new_line_and_indent
+                       v.stream.write "\}"
+               end
+       end
+end
+
+redef class Map[K, V]
+       redef fun accept_json_serializer(v)
+       do
+               # Register as pseudo object
+               var id = v.cache.new_id_for(self)
+
+               v.stream.write "\{"
+               v.indent_level += 1
+
+               if v.plain_json then
+                       var first = true
+                       for key, val in self do
+                               if not first then
+                                       v.stream.write ","
+                               else first = false
+                               v.new_line_and_indent
+
+                               var k = key or else "null"
+                               k.to_s.accept_json_serializer v
+                               v.stream.write ":"
+                               if v.pretty_json then v.stream.write " "
+                               if not v.try_to_serialize(val) then
+                                       assert val != null # null would have been serialized
+                                       v.warn("element of type {val.class_name} is not serializable.")
+                                       v.stream.write "null"
+                               end
+                       end
+               else
+                       v.new_line_and_indent
+                       v.stream.write """"__kind": "obj", "__id": """
+                       v.stream.write id.to_s
+                       v.stream.write """, "__class": """"
+                       v.stream.write class_name
+                       v.stream.write """", "__length": """
+                       v.stream.write length.to_s
+
+                       v.stream.write ","
+                       v.new_line_and_indent
+                       v.stream.write """"__keys": """
+                       keys.serialize_to_pure_json v
+
+                       v.stream.write ","
+                       v.new_line_and_indent
+                       v.stream.write """"__values": """
+                       values.serialize_to_pure_json v
+
+                       core_serialize_to v
+               end
+
+               v.indent_level -= 1
+               v.new_line_and_indent
+               v.stream.write "\}"
+       end
+end
index dd1cc85..f3107cc 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Static interface to get Nit objects from a Json string.
+# Static interface to read Nit objects from JSON strings
 #
-# `Text::parse_json` returns an equivalent Nit object from
-# the Json source. This object can then be type checked by the usual
-# languages features (`isa` and `as`).
+# `Text::parse_json` returns a simple Nit object from the JSON source.
+# This object can then be type checked as usual with `isa` and `as`.
 module static
 
 import error
@@ -29,64 +28,7 @@ private import json_lexer
 
 # Something that can be translated to JSON.
 interface Jsonable
-       # Encode `self` in JSON.
-       #
-       # This is a recursive method which can be refined by any subclasses.
-       # To write any `Serializable` object to JSON, see `serialize_to_json`.
-       #
-       # SEE: `append_json`
-       fun to_json: String is abstract
-
-       # Use `append_json` to implement `to_json`.
-       #
-       # Therefore, one that redefine `append_json` may use the following
-       # redefinition to link `to_json` and `append_json`:
-       #
-       # ~~~nitish
-       # redef fun to_json do return to_json_by_append
-       # ~~~
-       #
-       # Note: This is not the default implementation of `to_json` in order to
-       # avoid cyclic references between `append_json` and `to_json` when none are
-       # implemented.
-       protected fun to_json_by_append: String do
-               var buffer = new FlatBuffer
-               append_json(buffer)
-               return buffer.to_s
-       end
-
-       # Append the JSON representation of `self` to the specified buffer.
-       #
-       # SEE: `to_json`
-       fun append_json(buffer: Buffer) do buffer.append(to_json)
-
-       # Pretty print JSON string.
-       #
-       # ~~~
-       # var obj = new JsonObject
-       # obj["foo"] = 1
-       # obj["bar"] = true
-       # var arr = new JsonArray
-       # arr.add 2
-       # arr.add false
-       # arr.add "baz"
-       # obj["baz"] = arr
-       # var res = obj.to_pretty_json
-       # var exp = """{
-       # \t"foo": 1,
-       # \t"bar": true,
-       # \t"baz": [2, false, "baz"]
-       # }\n"""
-       # assert res == exp
-       # ~~~
-       fun to_pretty_json: String do
-               var res = new FlatBuffer
-               pretty_json_visit(res, 0)
-               res.add '\n'
-               return res.to_s
-       end
-
-       private fun pretty_json_visit(buffer: FlatBuffer, indent: Int) is abstract
+       super Serializable
 end
 
 redef class Text
@@ -108,31 +50,6 @@ redef class Text
        #     assert "\\\"string\\\"".json_need_escape
        protected fun json_need_escape: Bool do return has('\\')
 
-       redef fun append_json(buffer) do
-               buffer.add '\"'
-               for i in [0 .. self.length[ do
-                       var char = self[i]
-                       if char == '\\' then
-                               buffer.append "\\\\"
-                       else if char == '\"' then
-                               buffer.append "\\\""
-                       else if char < ' ' then
-                               if char == '\n' then
-                                       buffer.append "\\n"
-                               else if char == '\r' then
-                                       buffer.append "\\r"
-                               else if char == '\t' then
-                                       buffer.append "\\t"
-                               else
-                                       buffer.append char.escape_to_utf16
-                               end
-                       else
-                               buffer.add char
-                       end
-               end
-               buffer.add '\"'
-       end
-
        # Escapes `self` from a JSON string to a Nit string
        #
        #     assert "\\\"string\\\"".json_to_nit_string == "\"string\""
@@ -180,19 +97,6 @@ redef class Text
                return res.to_s
        end
 
-
-       # Encode `self` in JSON.
-       #
-       # ~~~
-       # assert "\t\"http://example.com\"\r\n\0\\".to_json ==
-       #     "\"\\t\\\"http://example.com\\\"\\r\\n\\u0000\\\\\""
-       # ~~~
-       redef fun to_json do
-               var b = new FlatBuffer.with_capacity(byte_length)
-               append_json(b)
-               return b.to_s
-       end
-
        # Parse `self` as JSON.
        #
        # If `self` is not a valid JSON document or contains an unsupported escape
@@ -248,116 +152,22 @@ redef class FlatText
        end
 end
 
-redef class Buffer
-
-       # Append the JSON representation of `jsonable` to `self`.
-       #
-       # Append `"null"` for `null`.
-       private fun append_json_of(jsonable: nullable Jsonable) do
-               if jsonable isa Jsonable then
-                       append jsonable.to_json
-               else
-                       append "null"
-               end
-       end
-end
-
 redef class Int
        super Jsonable
-
-       # Encode `self` in JSON.
-       #
-       #     assert 0.to_json == "0"
-       #     assert (-42).to_json == "-42"
-       redef fun to_json do return self.to_s
 end
 
 redef class Float
        super Jsonable
-
-       # Encode `self` in JSON.
-       #
-       # Note: Because this method use `to_s`, it may lose precision.
-       #
-       # ~~~
-       # # Will not work as expected.
-       # # assert (-0.0).to_json == "-0.0"
-       #
-       # assert (.5).to_json == "0.5"
-       # assert (0.0).to_json == "0.0"
-       # ~~~
-       redef fun to_json do return self.to_s
 end
 
 redef class Bool
        super Jsonable
-
-       # Encode `self` in JSON.
-       #
-       #     assert true.to_json == "true"
-       #     assert false.to_json == "false"
-       redef fun to_json do return self.to_s
 end
 
 # A map that can be translated into a JSON object.
 interface JsonMapRead[K: String, V: nullable Jsonable]
        super MapRead[K, V]
        super Jsonable
-
-       redef fun append_json(buffer) do
-               buffer.append "\{"
-               var it = iterator
-               if it.is_ok then
-                       append_json_entry(it, buffer)
-                       while it.is_ok do
-                               buffer.append ","
-                               append_json_entry(it, buffer)
-                       end
-               end
-               it.finish
-               buffer.append "\}"
-       end
-
-       # Encode `self` in JSON.
-       #
-       #     var obj = new JsonObject
-       #     obj["foo"] = "bar"
-       #     assert obj.to_json == "\{\"foo\":\"bar\"\}"
-       #     obj = new JsonObject
-       #     obj["baz"] = null
-       #     assert obj.to_json == "\{\"baz\":null\}"
-       redef fun to_json do return to_json_by_append
-
-       redef fun pretty_json_visit(buffer, indent) do
-               buffer.append "\{\n"
-               indent += 1
-               var i = 0
-               for k, v in self do
-                       buffer.append "\t" * indent
-                       buffer.append "\"{k}\": "
-                       if v isa JsonObject or v isa JsonArray then
-                               v.pretty_json_visit(buffer, indent)
-                       else
-                               buffer.append v.to_json
-                       end
-                       if i < length - 1 then
-                               buffer.append ","
-                       end
-                       buffer.append "\n"
-                       i += 1
-               end
-               indent -= 1
-               buffer.append "\t" * indent
-               buffer.append "\}"
-       end
-
-       private fun append_json_entry(iterator: MapIterator[String, nullable Jsonable],
-                       buffer: Buffer) do
-               buffer.append iterator.key.to_json
-               buffer.append ":"
-               buffer.append_json_of(iterator.item)
-               iterator.next
-       end
 end
 
 # A JSON Object.
@@ -370,51 +180,6 @@ end
 class JsonSequenceRead[E: nullable Jsonable]
        super Jsonable
        super SequenceRead[E]
-
-       redef fun append_json(buffer) do
-               buffer.append "["
-               var it = iterator
-               if it.is_ok then
-                       append_json_entry(it, buffer)
-                       while it.is_ok do
-                               buffer.append ","
-                               append_json_entry(it, buffer)
-                       end
-               end
-               it.finish
-               buffer.append "]"
-       end
-
-       # Encode `self` in JSON.
-       #
-       #     var arr = new JsonArray.with_items("foo", null)
-       #     assert arr.to_json == "[\"foo\",null]"
-       #     arr.pop
-       #     assert arr.to_json =="[\"foo\"]"
-       #     arr.pop
-       #     assert arr.to_json =="[]"
-       redef fun to_json do return to_json_by_append
-
-       redef fun pretty_json_visit(buffer, indent) do
-               buffer.append "\["
-               var i = 0
-               for v in self do
-                       if v isa JsonObject or v isa JsonArray then
-                               v.pretty_json_visit(buffer, indent)
-                       else
-                               buffer.append v.to_json
-                       end
-                       if i < length - 1 then buffer.append ", "
-                       i += 1
-               end
-               buffer.append "\]"
-       end
-
-       private fun append_json_entry(iterator: Iterator[nullable Jsonable],
-                       buffer: Buffer) do
-               buffer.append_json_of(iterator.item)
-               iterator.next
-       end
 end
 
 # A JSON array.
@@ -425,48 +190,10 @@ end
 
 redef class JsonParseError
        super Jsonable
-
-       # Get the JSON representation of `self`.
-       #
-       # ~~~
-       # var err = new JsonParseError("foo", new Position(1, 2, 3, 4, 5, 6))
-       # assert err.to_json == "\{\"error\":\"JsonParseError\"," +
-       #               "\"position\":\{" +
-       #                       "\"pos_start\":1,\"pos_end\":2," +
-       #                       "\"line_start\":3,\"line_end\":4," +
-       #                       "\"col_start\":5,\"col_end\":6" +
-       #               "\},\"message\":\"foo\"\}"
-       # ~~~
-       redef fun to_json do
-               return "\{\"error\":\"JsonParseError\"," +
-                               "\"position\":{position.to_json}," +
-                               "\"message\":{message.to_json}\}"
-       end
-
-       redef fun pretty_json_visit(buf, indents) do
-               buf.clear
-               buf.append(to_json)
-       end
 end
 
 redef class Position
        super Jsonable
-
-       # Get the JSON representation of `self`.
-       #
-       # ~~~
-       # var pos = new Position(1, 2, 3, 4, 5, 6)
-       # assert pos.to_json == "\{" +
-       #                       "\"pos_start\":1,\"pos_end\":2," +
-       #                       "\"line_start\":3,\"line_end\":4," +
-       #                       "\"col_start\":5,\"col_end\":6" +
-       #               "\}"
-       # ~~~
-       redef fun to_json do
-               return "\{\"pos_start\":{pos_start},\"pos_end\":{pos_end}," +
-                               "\"line_start\":{line_start},\"line_end\":{line_end}," +
-                               "\"col_start\":{col_start},\"col_end\":{col_end}\}"
-       end
 end
 
 ################################################################################
index 42a04df..b8ce0f9 100644 (file)
@@ -90,6 +90,7 @@
 module store
 
 import static
+import json
 
 # A JsonStore can save and load json data from file system.
 class JsonStore
index 51d302e..19c8fd1 100644 (file)
@@ -344,21 +344,8 @@ redef class Text
 end
 
 redef class JsonParseError
+       serialize
 
        # Location of the error in source
        var location: nullable Location = null
-
-       # Get the JSON representation of `self`.
-       #
-       # ~~~
-       # var err = new JsonParseError("foo", new Position(1, 2, 3, 4, 5, 6))
-       # assert err.to_json == "Parsing error: foo"
-       # ~~~
-       redef fun to_json do
-               var l = location
-               var m = message
-               return if l == null then "Parsing error: {m}" else "Parsing error at {l}: {m}"
-       end
-
-       redef fun to_s do return to_json
 end
index 4d7ff2b..5924822 100644 (file)
@@ -20,7 +20,7 @@ module data_store
 import app::data_store
 private import xdg_basedir
 private import sqlite3
-private import json::serialization
+private import json
 
 redef class App
        redef var data_store = new LinuxStore
index 3fee2f8..2b6b85d 100644 (file)
@@ -508,7 +508,7 @@ redef class NativeString
                int di;
 
                md5_init(&state);
-               md5_append(&state, (const md5_byte_t *)self, strlen(self));
+               md5_append(&state, (const md5_byte_t *)self, (int)strlen(self));
                md5_finish(&state, digest);
 
                for (di = 0; di < 16; ++di)
index 80c4d4c..17b137f 100644 (file)
@@ -42,6 +42,7 @@
 # ~~~
 module mongodb
 
+import json::static
 import json
 private import native_mongodb
 
index bc47997..5ea6596 100644 (file)
@@ -33,7 +33,7 @@ end
 import c
 intrude import core::text::flat
 import serialization
-private import json::serialization
+private import json
 
 in "C Header" `{
        #include <mpi.h>
index 03a7ca4..f2a541f 100644 (file)
@@ -16,6 +16,7 @@
 module curl_json
 
 import json::static
+import json
 intrude import curl
 
 # An abstract request that defines most of the standard options for Neo4j REST API
index f9df000..58068ad 100644 (file)
 module neo4j::error
 
 import json::static
+import json
 
 # An error thrown by the `neo4j` API.
 #
 #     var error = new NeoError("ErrorMessage", "ErrorName")
-#     assert error.to_json == "\{\"error\":\"ErrorName\",\"message\":\"ErrorMessage\"\}"
+#     assert error.to_json == """{"message":"ErrorMessage","cause":null,"error":"ErrorName"}"""
 class NeoError
        super Error
        super Jsonable
+       serialize
 
        # The name of the error.
        #
        # Used to programmatically distinguish this kind of error from others.
-       var name: String
-
-       redef fun to_json do
-               return "\{\"error\":{name.to_json},\"message\":{message.to_json}\}"
-       end
+       var name: String is serialize_as "error"
 
        redef fun to_s do return "[{name}] {super}"
 end
index 618a1d3..d924bd9 100644 (file)
@@ -191,35 +191,25 @@ redef class NeoGraph
                end
        end
 
-       redef fun to_json do return to_json_by_append
-
-       # Append the JSON representation of `self` to the specified buffer.
-       #
-       # For a description of the format, see `JsonGraphStore`.
-       #
-       # SEE: `to_json`
-       redef fun append_json(b) do
-               b.append "\{\"nodes\":["
-               append_entities_json(nodes, b)
-               b.append "],\"edges\":["
-               append_entities_json(edges, b)
-               b.append "]\}"
+       redef fun accept_json_serializer(v) do
+               v.stream.write "\{\"nodes\":["
+               append_entities_json(nodes, v)
+               v.stream.write "],\"edges\":["
+               append_entities_json(edges, v)
+               v.stream.write "]\}"
        end
 
        # Encode `self` in JSON.
        #
        # For a description of the format, see `JsonGraphStore`.
-       #
-       # SEE: `append_json`
-       private fun append_entities_json(entities: Collection[NeoEntity],
-                       b: Buffer) do
+       private fun append_entities_json(entities: Collection[NeoEntity], v: JsonSerializer) do
                var i = entities.iterator
                if i.is_ok then
-                       i.item.append_json_for(self, b)
+                       i.item.append_json_for(self, v)
                        i.next
                        for entity in i do
-                               b.add ','
-                               entity.append_json_for(self, b)
+                               v.stream.write ","
+                               entity.append_json_for(self, v)
                        end
                end
        end
@@ -233,7 +223,7 @@ end
 redef class NeoEntity
 
        # Append the JSON representation of the entity to the specified buffer.
-       fun append_json_for(graph: NeoGraph, buffer: Buffer) is abstract
+       fun append_json_for(graph: NeoGraph, v: JsonSerializer) is abstract
 end
 
 # Make `NeoNode` `Jsonable`.
@@ -273,32 +263,27 @@ redef class NeoNode
                properties.add_all(json_properties)
        end
 
-       redef fun to_json do return to_json_by_append
-
-       # Append the JSON representation of the node to the specified buffer.
-       #
-       # SEE: `JsonGraph`
-       redef fun append_json(b) do
-               b.append "\{\"labels\":["
+       redef fun accept_json_serializer(v) do
+               v.stream.write "\{\"labels\":["
                var i = labels.iterator
                if i.is_ok then
-                       i.item.append_json(b)
+                       i.item.serialize_to v
                        i.next
                        for lab in i do
-                               b.add ','
-                               lab.append_json(b)
+                               v.stream.write ","
+                               lab.serialize_to v
                        end
                end
-               b.append "],\"properties\":"
-               properties.append_json(b)
-               b.add '}'
+               v.stream.write "],\"properties\":"
+               properties.serialize_to v
+               v.stream.write "}"
        end
 
        redef fun to_s do return to_json
 
        # Append the JSON representation of the node to the specified buffer.
-       redef fun append_json_for(graph, buffer) do
-               append_json(buffer)
+       redef fun append_json_for(graph, v) do
+               accept_json_serializer v
        end
 end
 
@@ -307,15 +292,15 @@ redef class NeoEdge
        # Append the JSON representation of the relationship to the specified buffer.
        #
        # Use the IDs specfied by `graph.nodes`.
-       redef fun append_json_for(graph, buffer) do
-               buffer.append "\{\"type\":"
-               rel_type.as(not null).append_json(buffer)
-               buffer.append ",\"properties\":"
-               properties.append_json(buffer)
-               buffer.append ",\"from\":"
-               graph.nodes.id_of(from).append_json(buffer)
-               buffer.append ",\"to\":"
-               graph.nodes.id_of(to).append_json(buffer)
-               buffer.append "}"
+       redef fun append_json_for(graph, v) do
+               v.stream.write "\{\"type\":"
+               rel_type.as(not null).serialize_to(v)
+               v.stream.write ",\"properties\":"
+               properties.serialize_to(v)
+               v.stream.write ",\"from\":"
+               graph.nodes.id_of(from).serialize_to(v)
+               v.stream.write ",\"to\":"
+               graph.nodes.id_of(to).serialize_to(v)
+               v.stream.write "}"
        end
 end
index a09bc3c..cfddec3 100644 (file)
@@ -15,6 +15,8 @@
 # Runtime library required by parsers and lexers generated by nitcc
 module nitcc_runtime
 
+import serialization
+
 # A abstract parser engine generated by nitcc
 abstract class Parser
        # The list of tokens
@@ -303,6 +305,8 @@ end
 # A position into a input stream
 # Used to give position to tokens
 class Position
+       serialize
+
        var pos_start: Int
        var pos_end: Int
        var line_start: Int
index 158643a..4342a11 100644 (file)
@@ -16,7 +16,7 @@
 module restful is new_annotation(restful)
 
 import nitcorn
-import json::serialization
+import json
 
 # Action with `restful` methods
 class RestfulAction
index f97fbf0..b623137 100644 (file)
@@ -11,6 +11,8 @@
 # Simple base for hand-made parsers of all kinds
 module parser_base
 
+import serialization
+
 # Basic facilities for common parser operations on String sources
 class StringProcessor
        # Source document to parse
@@ -114,6 +116,8 @@ end
 
 # Information about the location of an entity in a source document
 class Location
+       serialize
+
        # Line in which the element is described
        var line: Int
        # Offset in the line at which the element is positioned
index e4da4a5..8d66cc9 100644 (file)
@@ -18,6 +18,7 @@
 module pop_handlers
 
 import pop_routes
+import json::static
 import json
 
 # Class handler for a route.
index 4c3ea14..7b02c35 100644 (file)
@@ -54,7 +54,6 @@
 #      redef fun to_s do return title
 #      redef fun ==(o) do return o isa SELF and id == o.id
 #      redef fun hash do return id.hash
-#      redef fun to_json do return serialize_to_json
 # end
 #
 # # We then need to subclass the `MongoRepository` to provide Book specific services.
@@ -121,7 +120,7 @@ module pop_repos
 
 import popcorn::pop_config
 import serialization
-import json::serialization
+import json
 import mongodb::queries
 
 redef class AppConfig
@@ -436,7 +435,6 @@ abstract class RepoObject
 
        redef fun hash do return id.hash
        redef fun to_s do return id
-       redef fun to_json do return serialize_to_json
 end
 
 # JsonObject can be used as a `RepositoryQuery`.
index 386bb24..b1464b8 100644 (file)
@@ -70,7 +70,7 @@
 # ~~~
 module pop_validation
 
-import json
+import json::static
 
 # The base class of all validators
 abstract class DocumentValidator
@@ -152,7 +152,7 @@ class ValidationResult
                return obj
        end
 
-       redef fun to_json do return json.to_json
+       redef fun serialize_to(v) do json.serialize_to(v)
 
        # Returns the validation result as a pretty formated string
        fun to_pretty_string: String do
index 1db10b2..8fed1bb 100644 (file)
@@ -128,7 +128,7 @@ private extern class NativePthread in "C" `{ pthread_t * `}
 
        fun equal(other: NativePthread): Bool `{ return pthread_equal(*self, *other); `}
 
-       fun kill(signal: Int) `{ pthread_kill(*self, signal); `}
+       fun kill(signal: Int) `{ pthread_kill(*self, (int)signal); `}
 end
 
 private extern class NativePthreadAttr in "C" `{ pthread_attr_t * `}
index 47eef73..3f6ac6c 100644 (file)
@@ -234,7 +234,7 @@ The main implementations of these services are `JsonSerializer` and `JsonDeseria
 from the `json_serialization` module.
 
 ~~~
-import json_serialization
+import json
 import user_credentials
 
 # Data to be serialized and deserialized
index d532d9c..066f8ab 100644 (file)
@@ -18,6 +18,7 @@ module doc_indexing
 import doc_base
 import html_templates::html_model # FIXME maybe this phase should depend on `html_render`
 private import json::static
+private import json
 
 # Generate the index for then Nitdoc QuickSearch field.
 #
@@ -67,7 +68,7 @@ class IndexingPhase
                var buffer = new Buffer
                tpl.add buffer
                buffer.append "var nitdocQuickSearchRawList="
-               table.append_json buffer
+               buffer.append table.to_json
                buffer.append ";"
                return tpl
        end
@@ -95,14 +96,11 @@ end
 # A QuickSearch result.
 private class QuickSearchResult
        super Jsonable
+       serialize
 
        # The text of the link.
        var txt: String
 
        # The destination of the link.
        var url: String
-
-       redef fun to_json do
-               return "\{\"txt\":{txt.to_json},\"url\":{url.to_json}\}"
-       end
 end
index 630d28e..a0f1399 100644 (file)
@@ -18,7 +18,7 @@ module html_components
 
 import doc_base
 import html::bootstrap
-import json::static
+import json
 
 # A label with a text content.
 class DocHTMLLabel
index 1187476..e981ac6 100644 (file)
@@ -15,7 +15,7 @@
 # Crawler on the nitweb web API
 module nitwebcrawl
 
-import json
+import json::static
 
 # Download a HTTP resource
 fun curl(url: String): String do
index 2c5cd04..1d8483c 100644 (file)
@@ -25,6 +25,7 @@
 module model_json
 
 import model::model_collect
+import json::static
 import json
 import loader
 
@@ -68,7 +69,7 @@ redef class MEntity
                return obj
        end
 
-       redef fun to_json do return json.to_json
+       redef fun serialize_to(v) do json.serialize_to(v)
 
        # Return `self` as a JsonObject with references.
        #
@@ -95,7 +96,7 @@ redef class MDoc
                return obj
        end
 
-       redef fun to_json do return json.to_json
+       redef fun serialize_to(v) do json.serialize_to(v)
 end
 
 redef class Location
@@ -115,13 +116,13 @@ redef class Location
                return obj
        end
 
-       redef fun to_json do return json.to_json
+       redef fun serialize_to(v) do json.serialize_to(v)
 end
 
 redef class MVisibility
        super Jsonable
 
-       redef fun to_json do return to_s.to_json
+       redef fun serialize_to(v) do to_s.serialize_to(v)
 end
 
 redef class MPackage
index 76fefea..0cb1ce0 100644 (file)
@@ -166,17 +166,25 @@ private class IOSToolchain
                # Compile with `xcodebuild`
                #
                # TODO support more than the iPhone and the simulator.
+               var compile_mode = if release then "Release" else "Debug"
                var args = ["sh", "-c", "cd {ios_project_root}; " +
-                       "xcodebuild -target '{project_name}' " +
+                       "xcodebuild -quiet -target '{project_name}' " +
                        "-destination 'platform=iOS Simulator,name=iPhone' " +
-                       "-configuration {if release then "Release" else "Debug"} " +
+                       "-configuration {compile_mode} " +
                         "ONLY_ACTIVE_ARCH=NO "+
                        "-sdk iphonesimulator build"]
                toolcontext.exec_and_check(args, "iOS project error")
 
                # Move compiled app to destination
-               if outfile.file_exists then outfile.rmdir
-               args = ["mv", "{ios_project_root}/build/Debug-iphonesimulator/{project_name}.app", outfile]
+               if outfile.file_exists then
+                       var error = outfile.rmdir
+                       if error != null then
+                               print_error error
+                               exit 1
+                       end
+               end
+
+               args = ["mv", "{ios_project_root}/build/{compile_mode}-iphonesimulator/{project_name}.app", outfile]
                toolcontext.exec_and_check(args, "iOS project error")
        end
 end
index 8cea80f..bc99f81 100644 (file)
@@ -340,7 +340,7 @@ class ToolContext
                proc_which.wait
                var res = proc_which.status
                if res != 0 then
-                       print "{error}: executable \"{prog}\" not found"
+                       print_error "{error}: executable \"{prog}\" not found"
                        exit 1
                end
 
@@ -349,7 +349,7 @@ class ToolContext
                proc.wait
                res = proc.status
                if res != 0 then
-                       print "{error}: execution of \"{prog} {args.join(" ")}\" failed"
+                       print_error "{error}: execution of \"{prog} {args.join(" ")}\" failed"
                        exit 1
                end
        end
index 30b8757..bd403ad 100644 (file)
@@ -137,12 +137,10 @@ end
 redef class Person
        super Jsonable
 
-       redef fun to_json do
-               var obj = new JsonObject
-               obj["name"] = name
-               obj["email"] = email
-               obj["page"] = page
-               obj["hash"] = (email or else "").md5.to_lower
-               return obj.to_json
+       redef fun core_serialize_to(v) do
+               v.serialize_attribute("name", name)
+               v.serialize_attribute("email", email)
+               v.serialize_attribute("page", page)
+               v.serialize_attribute("hash", (email or else "").md5.to_lower)
        end
 end
index e2bfa9a..a5cacff 100644 (file)
@@ -100,7 +100,7 @@ class MEntityRatings
                return obj
        end
 
-       redef fun to_json do return json.to_json
+       redef fun serialize_to(v) do json.serialize_to(v)
 end
 
 # Rating value of a MEntity
@@ -130,5 +130,5 @@ class MEntityRating
                return obj
        end
 
-       redef fun to_json do return json.to_json
+       redef fun serialize_to(v) do json.serialize_to(v)
 end
index bb0147c..8c01c0d 100644 (file)
@@ -162,7 +162,7 @@ redef class MetricSet
                return obj
        end
 
-       redef fun to_json do return json.to_json
+       redef fun serialize_to(v) do json.serialize_to(v)
 end
 
 redef class Metric
@@ -179,7 +179,7 @@ redef class Metric
                return obj
        end
 
-       redef fun to_json do return json.to_json
+       redef fun serialize_to(v) do json.serialize_to(v)
 end
 
 redef class IntMetric
index 14bfcca..60f7f2b 100644 (file)
@@ -124,7 +124,7 @@ class APIError
                return obj
        end
 
-       redef fun to_json do return json.to_json
+       redef fun serialize_to(v) do json.serialize_to(v)
 end
 
 # Fullname representation that can be used to build decorated links
@@ -134,9 +134,10 @@ end
 class Namespace
        super Array[nullable NSEntity]
        super NSEntity
+       serialize
 
        redef fun to_s do return self.join("")
-       redef fun to_json do return (new JsonArray.from(self)).to_json
+       redef fun serialize_to(v) do to_a.serialize_to(v)
 end
 
 # Something that goes in a Namespace
@@ -154,16 +155,17 @@ end
 # an infinite loop.
 class NSRef
        super NSEntity
+       serialize
 
        # The mentity to link to/
        var mentity: MEntity
 
-       redef fun to_json do
+       redef fun serialize_to(v) do
                var obj = new JsonObject
                obj["web_url"] = mentity.web_url
                obj["api_url"] = mentity.api_url
                obj["name"] = mentity.name
-               return obj.to_json
+               obj.serialize_to(v)
        end
 end
 
@@ -364,5 +366,5 @@ redef class POSetElement[E]
                return obj
        end
 
-       redef fun to_json do return json.to_json
+       redef fun serialize_to(v) do json.serialize_to(v)
 end
index 6a693ff..10bcfb7 100644 (file)
@@ -7,3 +7,4 @@ mpi
 emscripten
 ui_test
 readline
+postgres
index e76eb6a..d7761d4 100644 (file)
@@ -5,4 +5,6 @@ out/hello_ios.bin/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
 out/hello_ios.bin/LaunchScreen.storyboardc/Info.plist
 out/hello_ios.bin/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
 out/hello_ios.bin/PkgInfo
+out/hello_ios.bin/_CodeSignature
+out/hello_ios.bin/_CodeSignature/CodeResources
 out/hello_ios.bin/hello_ios
index 4162e8d..80f6c94 100644 (file)
@@ -7,4 +7,3 @@ JsonArray
        "blue": [1, 2],
        "ocean": ["fishy", "salty"]
 }
-
diff --git a/tests/sav/neo_doxygen_descriptions.res b/tests/sav/neo_doxygen_descriptions.res
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/tests/sav/neo_doxygen_member_resolve_introducer.res b/tests/sav/neo_doxygen_member_resolve_introducer.res
deleted file mode 100644 (file)
index e69de29..0000000
index cb74989..d757542 100644 (file)
@@ -2,7 +2,7 @@
 <A: true a 0.123 1234 asdf false p4ssw0rd>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"serialization_specific_name": "asdf","n": null}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"serialization_specific_name":"asdf","n":null}
 
 # Back in Nit:
 <A: true a 0.123 1234 asdf false p4ssw0rd>
@@ -11,7 +11,7 @@
 <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"serialization_specific_name": "hjkl","n": 12,"ii": 1111,"ss": "qwer"}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"serialization_specific_name":"hjkl","n":12,"ii":1111,"ss":"qwer"}
 
 # Back in Nit:
 <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>
@@ -20,7 +20,7 @@
 <C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"serialization_specific_name": "asdf","n": null},"b": {"__kind": "obj", "__id": 2, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"serialization_specific_name": "hjkl","n": 12,"ii": 1111,"ss": "qwer"},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"serialization_specific_name":"asdf","n":null},"b":{"__kind": "obj", "__id": 2, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"serialization_specific_name":"hjkl","n":12,"ii":1111,"ss":"qwer"},"aa":{"__kind": "ref", "__id": 1}}
 
 # Back in Nit:
 <C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>>
@@ -30,7 +30,7 @@
 <- false p4ssw0rd> 1111        f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"serialization_specific_name": "new line ->\n<-","n": null,"ii": 1111,"ss": "\tf\"\r\\/","d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"serialization_specific_name":"new line ->\n<-","n":null,"ii":1111,"ss":"\tf\"\r\\/","d":{"__kind": "ref", "__id": 0}}
 
 # Back in Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
@@ -40,7 +40,7 @@
 <E: a: hello, 1234, 123.4; b: hella, 2345, 234.5>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "E","a": {"__kind": "obj", "__id": 1, "__class": "Array","__items": ["hello",1234,123.4]},"b": {"__kind": "obj", "__id": 2, "__class": "Array","__items": ["hella",2345,234.5]}}
+{"__kind": "obj", "__id": 0, "__class": "E","a":{"__kind": "obj", "__id": 1, "__class": "Array","__items": ["hello",1234,123.4]},"b":{"__kind": "obj", "__id": 2, "__class": "Array","__items": ["hella",2345,234.5]}}
 
 # Back in Nit:
 <E: a: hello, 1234, 123.4; b: hella, 2345, 234.5>
@@ -53,7 +53,7 @@ Deserialization Error: Wrong type on `E::b` expected `Array[nullable Serializabl
 <E: 2222>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "F","n": 2222}
+{"__kind": "obj", "__id": 0, "__class": "F","n":2222}
 
 # Back in Nit:
 null
@@ -63,7 +63,7 @@ Deserialization Error: Doesn't know how to deserialize class "F"
 <E: 33.33>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "F","n": 33.33}
+{"__kind": "obj", "__id": 0, "__class": "F","n":33.33}
 
 # Back in Nit:
 null
@@ -73,7 +73,7 @@ Deserialization Error: Doesn't know how to deserialize class "F"
 <G: hs: -1, 0; s: one, two; hm: one. 1, two. 2; am: three. 3, four. 4>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "G","hs": {"__kind": "obj", "__id": 1, "__class": "HashSet","__items": [-1,0]},"s": {"__kind": "obj", "__id": 2, "__class": "ArraySet","__items": ["one","two"]},"hm": {"__kind": "obj", "__id": 3, "__class": "HashMap", "__length": 2,"__keys": ["one","two"],"__values": [1,2]},"am": {"__kind": "obj", "__id": 4, "__class": "ArrayMap", "__length": 2,"__keys": ["three","four"],"__values": ["3","4"]}}
+{"__kind": "obj", "__id": 0, "__class": "G","hs":{"__kind": "obj", "__id": 1, "__class": "HashSet","__items": [-1,0]},"s":{"__kind": "obj", "__id": 2, "__class": "ArraySet","__items": ["one","two"]},"hm":{"__kind": "obj", "__id": 3, "__class": "HashMap", "__length": 2,"__keys": ["one","two"],"__values": [1,2]},"am":{"__kind": "obj", "__id": 4, "__class": "ArrayMap", "__length": 2,"__keys": ["three","four"],"__values": ["3","4"]}}
 
 # Back in Nit:
 <G: hs: ; s: ; hm: ; am: >
index 3a3aec0..a623837 100644 (file)
        "__kind": "obj", "__id": 0, "__class": "E",
        "a": {
                "__kind": "obj", "__id": 1, "__class": "Array",
-               "__items": [
-                       "hello",
-                       1234,
-                       123.4
-               ]
+               "__items": ["hello", 1234, 123.4]
        },
        "b": {
                "__kind": "obj", "__id": 2, "__class": "Array",
-               "__items": [
-                       "hella",
-                       2345,
-                       234.5
-               ]
+               "__items": ["hella", 2345, 234.5]
        }
 }
 
@@ -157,39 +149,21 @@ Deserialization Error: Doesn't know how to deserialize class "F"
        "__kind": "obj", "__id": 0, "__class": "G",
        "hs": {
                "__kind": "obj", "__id": 1, "__class": "HashSet",
-               "__items": [
-                       -1,
-                       0
-               ]
+               "__items": [-1, 0]
        },
        "s": {
                "__kind": "obj", "__id": 2, "__class": "ArraySet",
-               "__items": [
-                       "one",
-                       "two"
-               ]
+               "__items": ["one", "two"]
        },
        "hm": {
                "__kind": "obj", "__id": 3, "__class": "HashMap", "__length": 2,
-               "__keys": [
-                       "one",
-                       "two"
-               ],
-               "__values": [
-                       1,
-                       2
-               ]
+               "__keys": ["one", "two"],
+               "__values": [1, 2]
        },
        "am": {
                "__kind": "obj", "__id": 4, "__class": "ArrayMap", "__length": 2,
-               "__keys": [
-                       "three",
-                       "four"
-               ],
-               "__values": [
-                       "3",
-                       "4"
-               ]
+               "__keys": ["three", "four"],
+               "__values": ["3", "4"]
        }
 }
 
index 67a1674..cc516c5 100644 (file)
@@ -2,24 +2,24 @@
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "\tf\"\r\\/","d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"\tf\"\r\\/","d":{"__kind": "ref", "__id": 0}}
 
index d3fb349..28727b4 100644 (file)
@@ -5,24 +5,24 @@ alt/test_serialization_alt2.nit:64,1--72,3: Warning: superfluous use of `auto_se
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]}},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]}},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"d":{"__kind": "ref", "__id": 0}}
 
index 3b72eda..01b101e 100644 (file)
@@ -3,24 +3,24 @@ alt/test_serialization_alt3.nit:40,1--51,3: Warning: superfluous use of `noseria
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]}},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]}},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"d":{"__kind": "ref", "__id": 0}}
 
index 5f40834..a45b63e 100644 (file)
@@ -3,24 +3,24 @@ alt/test_serialization_alt4.nit:29,2--31,26: Warning: superfluous use of `serial
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "\tf\"\r\\/","d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"\tf\"\r\\/","d":{"__kind": "ref", "__id": 0}}
 
index cc17087..d5d2e2c 100644 (file)
@@ -3,24 +3,24 @@ alt/test_serialization_alt5.nit:22,1--38,3: Warning: duplicated annotation `seri
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "\tf\"\r\\/","d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"\tf\"\r\\/","d":{"__kind": "ref", "__id": 0}}
 
index 67a1674..cc516c5 100644 (file)
@@ -2,24 +2,24 @@
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "\tf\"\r\\/","d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"\tf\"\r\\/","d":{"__kind": "ref", "__id": 0}}
 
index a6a77fd..c0589ed 100644 (file)
@@ -2,24 +2,24 @@
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"iii": 6789,"sss": "redef"}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"iii":6789,"sss":"redef"}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"iii": 6789,"sss": "redef","ii": 1111,"ss": "qwer"}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"iii":6789,"sss":"redef","ii":1111,"ss":"qwer"}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]},"iii": 6789,"sss": "redef"},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"iii": 6789,"sss": "redef","ii": 1111,"ss": "qwer"},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]},"iii":6789,"sss":"redef"},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"iii":6789,"sss":"redef","ii":1111,"ss":"qwer"},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"iii": 6789,"sss": "redef","ii": 1111,"ss": "\tf\"\r\\/","d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"iii":6789,"sss":"redef","ii":1111,"ss":"\tf\"\r\\/","d":{"__kind": "ref", "__id": 0}}
 
index ec4a7d9..7c65b3d 100644 (file)
@@ -2,24 +2,24 @@
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer","ffff": 6.789,"bbbb": false}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"qwer","ffff":6.789,"bbbb":false}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer","ffff": 6.789,"bbbb": false},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"qwer","ffff":6.789,"bbbb":false},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii": 1111,"ss": "\tf\"\r\\/","ffff": 6.789,"bbbb": false,"d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"ii":1111,"ss":"\tf\"\r\\/","ffff":6.789,"bbbb":false,"d":{"__kind": "ref", "__id": 0}}
 
index 48b21cc..e6c3c90 100644 (file)
@@ -2,24 +2,24 @@
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"iii": 6789,"sss": "redef"}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"iii":6789,"sss":"redef"}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"iii": 6789,"sss": "redef","ii": 1111,"ss": "qwer","ffff": 6.789,"bbbb": false}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"iii":6789,"sss":"redef","ii":1111,"ss":"qwer","ffff":6.789,"bbbb":false}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]},"iii": 6789,"sss": "redef"},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"iii": 6789,"sss": "redef","ii": 1111,"ss": "qwer","ffff": 6.789,"bbbb": false},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array","__items": [88,"hello",null]},"iii":6789,"sss":"redef"},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array","__items": [88,"hello",null]},"iii":6789,"sss":"redef","ii":1111,"ss":"qwer","ffff":6.789,"bbbb":false},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"iii": 6789,"sss": "redef","ii": 1111,"ss": "\tf\"\r\\/","ffff": 6.789,"bbbb": false,"d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array","__items": [88,"hello",null]},"iii":6789,"sss":"redef","ii":1111,"ss":"\tf\"\r\\/","ffff":6.789,"bbbb":false,"d":{"__kind": "ref", "__id": 0}}
 
index 2e9d00b..aa4f276 100644 (file)
@@ -17,4 +17,3 @@
        "Zip": "94085",
        "Country": "US"
 }]
-
index 5ab004a..c4040be 100644 (file)
@@ -2,7 +2,7 @@
 <A: true a 0.123 1234 asdf false p4ssw0rd>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"serialization_specific_name": "asdf","n": null}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"serialization_specific_name":"asdf","n":null}
 
 # Back in Nit:
 <A: true a 0.123 1234 asdf false p4ssw0rd>
@@ -11,7 +11,7 @@
 <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"serialization_specific_name": "hjkl","n": 12,"ii": 1111,"ss": "qwer"}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"serialization_specific_name":"hjkl","n":12,"ii":1111,"ss":"qwer"}
 
 # Back in Nit:
 <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>
@@ -20,7 +20,7 @@
 <C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"serialization_specific_name": "asdf","n": null},"b": {"__kind": "obj", "__id": 2, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"serialization_specific_name": "hjkl","n": 12,"ii": 1111,"ss": "qwer"},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"serialization_specific_name":"asdf","n":null},"b":{"__kind": "obj", "__id": 2, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"serialization_specific_name":"hjkl","n":12,"ii":1111,"ss":"qwer"},"aa":{"__kind": "ref", "__id": 1}}
 
 # Back in Nit:
 <C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>>
@@ -30,7 +30,7 @@
 <- false p4ssw0rd> 1111        f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"serialization_specific_name": "new line ->\n<-","n": null,"ii": 1111,"ss": "\tf\"\r\\/","d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"serialization_specific_name":"new line ->\n<-","n":null,"ii":1111,"ss":"\tf\"\r\\/","d":{"__kind": "ref", "__id": 0}}
 
 # Back in Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
index 161fb58..91b7df1 100644 (file)
@@ -2,7 +2,7 @@
 <A: true a 0.123 1234 asdf false p4ssw0rd>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"serialization_specific_name": "asdf","n": null}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"serialization_specific_name":"asdf","n":null}
 
 # Back in Nit:
 <A: true a 0.123 1234 asdf false p4ssw0rd>
@@ -11,7 +11,7 @@
 <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"serialization_specific_name": "hjkl","n": 12,"ii": 1111,"ss": "qwer"}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"serialization_specific_name":"hjkl","n":12,"ii":1111,"ss":"qwer"}
 
 # Back in Nit:
 <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>
@@ -20,7 +20,7 @@
 <C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"serialization_specific_name": "asdf","n": null},"b": {"__kind": "obj", "__id": 2, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"serialization_specific_name": "hjkl","n": 12,"ii": 1111,"ss": "qwer"},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"serialization_specific_name":"asdf","n":null},"b":{"__kind": "obj", "__id": 2, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"serialization_specific_name":"hjkl","n":12,"ii":1111,"ss":"qwer"},"aa":{"__kind": "ref", "__id": 1}}
 
 # Back in Nit:
 <C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>>
@@ -30,7 +30,7 @@
 <- false p4ssw0rd> 1111        f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"serialization_specific_name": "new line ->\n<-","n": null,"ii": 1111,"ss": "\tf\"\r\\/","d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"serialization_specific_name":"new line ->\n<-","n":null,"ii":1111,"ss":"\tf\"\r\\/","d":{"__kind": "ref", "__id": 0}}
 
 # Back in Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
@@ -40,7 +40,7 @@
 <E: a: hello, 1234, 123.4; b: hella, 2345, 234.5>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "E","a": {"__kind": "obj", "__id": 1, "__class": "Array[Object]","__items": ["hello",1234,123.4]},"b": {"__kind": "obj", "__id": 2, "__class": "Array[nullable Serializable]","__items": ["hella",2345,234.5]}}
+{"__kind": "obj", "__id": 0, "__class": "E","a":{"__kind": "obj", "__id": 1, "__class": "Array[Object]","__items": ["hello",1234,123.4]},"b":{"__kind": "obj", "__id": 2, "__class": "Array[nullable Serializable]","__items": ["hella",2345,234.5]}}
 
 # Back in Nit:
 <E: a: hello, 1234, 123.4; b: hella, 2345, 234.5>
@@ -49,7 +49,7 @@
 <E: 2222>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "F[Int]","n": 2222}
+{"__kind": "obj", "__id": 0, "__class": "F[Int]","n":2222}
 
 # Back in Nit:
 <E: 2222>
@@ -58,7 +58,7 @@
 <E: 33.33>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "F[Float]","n": 33.33}
+{"__kind": "obj", "__id": 0, "__class": "F[Float]","n":33.33}
 
 # Back in Nit:
 <E: 33.33>
@@ -67,7 +67,7 @@
 <G: hs: -1, 0; s: one, two; hm: one. 1, two. 2; am: three. 3, four. 4>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "G","hs": {"__kind": "obj", "__id": 1, "__class": "HashSet[Int]","__items": [-1,0]},"s": {"__kind": "obj", "__id": 2, "__class": "ArraySet[String]","__items": ["one","two"]},"hm": {"__kind": "obj", "__id": 3, "__class": "HashMap[String, Int]", "__length": 2,"__keys": ["one","two"],"__values": [1,2]},"am": {"__kind": "obj", "__id": 4, "__class": "ArrayMap[String, String]", "__length": 2,"__keys": ["three","four"],"__values": ["3","4"]}}
+{"__kind": "obj", "__id": 0, "__class": "G","hs":{"__kind": "obj", "__id": 1, "__class": "HashSet[Int]","__items": [-1,0]},"s":{"__kind": "obj", "__id": 2, "__class": "ArraySet[String]","__items": ["one","two"]},"hm":{"__kind": "obj", "__id": 3, "__class": "HashMap[String, Int]", "__length": 2,"__keys": ["one","two"],"__values": [1,2]},"am":{"__kind": "obj", "__id": 4, "__class": "ArrayMap[String, String]", "__length": 2,"__keys": ["three","four"],"__values": ["3","4"]}}
 
 # Back in Nit:
 <G: hs: -1, 0; s: one, two; hm: one. 1, two. 2; am: three. 3, four. 4>
index 48005ec..f7aaf31 100644 (file)
@@ -2,19 +2,19 @@
 <A: true a 0.123 1234 asdf false p4ssw0rd>
 
 # Json:
-{"b": true,"c": "a","f": 0.123,"i": 1234,"serialization_specific_name": "asdf","n": null}
+{"b":true,"c":"a","f":0.123,"i":1234,"serialization_specific_name":"asdf","n":null}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>
 
 # Json:
-{"b": false,"c": "b","f": 123.123,"i": 2345,"serialization_specific_name": "hjkl","n": 12,"ii": 1111,"ss": "qwer"}
+{"b":false,"c":"b","f":123.123,"i":2345,"serialization_specific_name":"hjkl","n":12,"ii":1111,"ss":"qwer"}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl true p4ssw0rd> 1111 qwer>>
 
 # Json:
-{"a": {"b": true,"c": "a","f": 0.123,"i": 1234,"serialization_specific_name": "asdf","n": null},"b": {"b": false,"c": "b","f": 123.123,"i": 2345,"serialization_specific_name": "hjkl","n": 12,"ii": 1111,"ss": "qwer"},"aa": {"b": true,"c": "a","f": 0.123,"i": 1234,"serialization_specific_name": "asdf","n": null}}
+{"a":{"b":true,"c":"a","f":0.123,"i":1234,"serialization_specific_name":"asdf","n":null},"b":{"b":false,"c":"b","f":123.123,"i":2345,"serialization_specific_name":"hjkl","n":12,"ii":1111,"ss":"qwer"},"aa":{"b":true,"c":"a","f":0.123,"i":1234,"serialization_specific_name":"asdf","n":null}}
 
 Serialization warning: Cycle detected in serialized object, replacing reference with 'null'.
 # Nit:
@@ -22,29 +22,29 @@ Serialization warning: Cycle detected in serialized object, replacing reference
 <- false p4ssw0rd> 1111        f"\r\/> true>
 
 # Json:
-{"b": false,"c": "b","f": 123.123,"i": 2345,"serialization_specific_name": "new line ->\n<-","n": null,"ii": 1111,"ss": "\tf\"\r\\/","d": null}
+{"b":false,"c":"b","f":123.123,"i":2345,"serialization_specific_name":"new line ->\n<-","n":null,"ii":1111,"ss":"\tf\"\r\\/","d":null}
 
 # Nit:
 <E: a: hello, 1234, 123.4; b: hella, 2345, 234.5>
 
 # Json:
-{"a": ["hello",1234,123.4],"b": ["hella",2345,234.5]}
+{"a":["hello",1234,123.4],"b":["hella",2345,234.5]}
 
 # Nit:
 <E: 2222>
 
 # Json:
-{"n": 2222}
+{"n":2222}
 
 # Nit:
 <E: 33.33>
 
 # Json:
-{"n": 33.33}
+{"n":33.33}
 
 # Nit:
 <G: hs: -1, 0; s: one, two; hm: one. 1, two. 2; am: three. 3, four. 4>
 
 # Json:
-{"hs": [-1,0],"s": ["one","two"],"hm": {"one": 1,"two": 2},"am": {"three": "3","four": "4"}}
+{"hs":[-1,0],"s":["one","two"],"hm":{"one":1,"two":2},"am":{"three":"3","four":"4"}}
 
index 3904578..d58b2de 100644 (file)
        "__kind": "obj", "__id": 0, "__class": "E",
        "a": {
                "__kind": "obj", "__id": 1, "__class": "Array[Object]",
-               "__items": [
-                       "hello",
-                       1234,
-                       123.4
-               ]
+               "__items": ["hello", 1234, 123.4]
        },
        "b": {
                "__kind": "obj", "__id": 2, "__class": "Array[nullable Serializable]",
-               "__items": [
-                       "hella",
-                       2345,
-                       234.5
-               ]
+               "__items": ["hella", 2345, 234.5]
        }
 }
 
        "__kind": "obj", "__id": 0, "__class": "G",
        "hs": {
                "__kind": "obj", "__id": 1, "__class": "HashSet[Int]",
-               "__items": [
-                       -1,
-                       0
-               ]
+               "__items": [-1, 0]
        },
        "s": {
                "__kind": "obj", "__id": 2, "__class": "ArraySet[String]",
-               "__items": [
-                       "one",
-                       "two"
-               ]
+               "__items": ["one", "two"]
        },
        "hm": {
                "__kind": "obj", "__id": 3, "__class": "HashMap[String, Int]", "__length": 2,
-               "__keys": [
-                       "one",
-                       "two"
-               ],
-               "__values": [
-                       1,
-                       2
-               ]
+               "__keys": ["one", "two"],
+               "__values": [1, 2]
        },
        "am": {
                "__kind": "obj", "__id": 4, "__class": "ArrayMap[String, String]", "__length": 2,
-               "__keys": [
-                       "three",
-                       "four"
-               ],
-               "__values": [
-                       "3",
-                       "4"
-               ]
+               "__keys": ["three", "four"],
+               "__values": ["3", "4"]
        }
 }
 
index 5527174..3c56592 100644 (file)
@@ -82,16 +82,8 @@ Serialization warning: Cycle detected in serialized object, replacing reference
 
 # Json:
 {
-       "a": [
-               "hello",
-               1234,
-               123.4
-       ],
-       "b": [
-               "hella",
-               2345,
-               234.5
-       ]
+       "a": ["hello", 1234, 123.4],
+       "b": ["hella", 2345, 234.5]
 }
 
 # Nit:
@@ -115,14 +107,8 @@ Serialization warning: Cycle detected in serialized object, replacing reference
 
 # Json:
 {
-       "hs": [
-               -1,
-               0
-       ],
-       "s": [
-               "one",
-               "two"
-       ],
+       "hs": [-1, 0],
+       "s": ["one", "two"],
        "hm": {
                "one": 1,
                "two": 2
index 62b3c82..c8b7dd2 100644 (file)
@@ -26,6 +26,6 @@
 # Nit: <MyClass i:123 s:hello f:123.456 a:[one, two] o:<null>>
 
 # JSON: not valid json
-# Errors: 'Parsing error at line 1, position 1: Error: bad JSON entity'
+# Errors: 'Error: bad JSON entity'
 # Nit: null
 
index c0f61cc..9a44a7c 100644 (file)
@@ -2,4 +2,3 @@
        "beer": "test",
        "name": "Gaëa"
 }
-
index ac00f9b..c018d95 100644 (file)
@@ -5,4 +5,6 @@ out/test_platform_ios.bin/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.ni
 out/test_platform_ios.bin/LaunchScreen.storyboardc/Info.plist
 out/test_platform_ios.bin/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
 out/test_platform_ios.bin/PkgInfo
+out/test_platform_ios.bin/_CodeSignature
+out/test_platform_ios.bin/_CodeSignature/CodeResources
 out/test_platform_ios.bin/test_platform_ios
index e3b56a7..8480abe 100644 (file)
@@ -2,24 +2,24 @@
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "\tf\"\r\\/","d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"\tf\"\r\\/","d":{"__kind": "ref", "__id": 0}}
 
index f275932..f640ce7 100644 (file)
@@ -2,19 +2,19 @@
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"b": true,"c": "a","f": 0.123,"i": 1234,"s": "asdf","n": null,"array": [88,"hello",null]}
+{"b":true,"c":"a","f":0.123,"i":1234,"s":"asdf","n":null,"array":[88,"hello",null]}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"b": false,"c": "b","f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": [88,"hello",null],"ii": 1111,"ss": "qwer"}
+{"b":false,"c":"b","f":123.123,"i":2345,"s":"hjkl","n":12,"array":[88,"hello",null],"ii":1111,"ss":"qwer"}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"a": {"b": true,"c": "a","f": 0.123,"i": 1234,"s": "asdf","n": null,"array": [88,"hello",null]},"b": {"b": false,"c": "b","f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": [88,"hello",null],"ii": 1111,"ss": "qwer"},"aa": {"b": true,"c": "a","f": 0.123,"i": 1234,"s": "asdf","n": null,"array": [88,"hello",null]}}
+{"a":{"b":true,"c":"a","f":0.123,"i":1234,"s":"asdf","n":null,"array":[88,"hello",null]},"b":{"b":false,"c":"b","f":123.123,"i":2345,"s":"hjkl","n":12,"array":[88,"hello",null],"ii":1111,"ss":"qwer"},"aa":{"b":true,"c":"a","f":0.123,"i":1234,"s":"asdf","n":null,"array":[88,"hello",null]}}
 
 Serialization warning: Cycle detected in serialized object, replacing reference with 'null'.
 # Nit:
@@ -22,5 +22,5 @@ Serialization warning: Cycle detected in serialized object, replacing reference
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"b": false,"c": "b","f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": [88,"hello",null],"ii": 1111,"ss": "\tf\"\r\\/","d": null}
+{"b":false,"c":"b","f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":[88,"hello",null],"ii":1111,"ss":"\tf\"\r\\/","d":null}
 
index 42ad47b..e733f60 100644 (file)
@@ -5,24 +5,24 @@ alt/test_serialization_alt2.nit:64,1--72,3: Warning: superfluous use of `auto_se
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"d":{"__kind": "ref", "__id": 0}}
 
index 9ad4073..8818e8f 100644 (file)
@@ -3,24 +3,24 @@ alt/test_serialization_alt3.nit:40,1--51,3: Warning: superfluous use of `noseria
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"d":{"__kind": "ref", "__id": 0}}
 
index 039170f..06e2015 100644 (file)
@@ -3,24 +3,24 @@ alt/test_serialization_alt4.nit:29,2--31,26: Warning: superfluous use of `serial
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "\tf\"\r\\/","d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"\tf\"\r\\/","d":{"__kind": "ref", "__id": 0}}
 
index 6f763c2..3c56b96 100644 (file)
@@ -3,24 +3,24 @@ alt/test_serialization_alt5.nit:22,1--38,3: Warning: duplicated annotation `seri
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "\tf\"\r\\/","d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"\tf\"\r\\/","d":{"__kind": "ref", "__id": 0}}
 
index e3b56a7..8480abe 100644 (file)
@@ -2,24 +2,24 @@
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer"},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"qwer"},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "\tf\"\r\\/","d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"\tf\"\r\\/","d":{"__kind": "ref", "__id": 0}}
 
index 337cdaa..9eab831 100644 (file)
@@ -2,24 +2,24 @@
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii": 6789,"sss": "redef"}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii":6789,"sss":"redef"}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii": 6789,"sss": "redef","ii": 1111,"ss": "qwer"}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii":6789,"sss":"redef","ii":1111,"ss":"qwer"}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii": 6789,"sss": "redef"},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii": 6789,"sss": "redef","ii": 1111,"ss": "qwer"},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii":6789,"sss":"redef"},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii":6789,"sss":"redef","ii":1111,"ss":"qwer"},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii": 6789,"sss": "redef","ii": 1111,"ss": "\tf\"\r\\/","d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii":6789,"sss":"redef","ii":1111,"ss":"\tf\"\r\\/","d":{"__kind": "ref", "__id": 0}}
 
index 2deb5ce..8b930a6 100644 (file)
@@ -2,24 +2,24 @@
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]}}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer","ffff": 6.789,"bbbb": false}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"qwer","ffff":6.789,"bbbb":false}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "qwer","ffff": 6.789,"bbbb": false},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]}},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"qwer","ffff":6.789,"bbbb":false},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii": 1111,"ss": "\tf\"\r\\/","ffff": 6.789,"bbbb": false,"d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"ii":1111,"ss":"\tf\"\r\\/","ffff":6.789,"bbbb":false,"d":{"__kind": "ref", "__id": 0}}
 
index 1c1850c..9662b36 100644 (file)
@@ -2,24 +2,24 @@
 <A: true a 0.123 1234 asdf false>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii": 6789,"sss": "redef"}
+{"__kind": "obj", "__id": 0, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii":6789,"sss":"redef"}
 
 # Nit:
 <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii": 6789,"sss": "redef","ii": 1111,"ss": "qwer","ffff": 6.789,"bbbb": false}
+{"__kind": "obj", "__id": 0, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii":6789,"sss":"redef","ii":1111,"ss":"qwer","ffff":6.789,"bbbb":false}
 
 # Nit:
 <C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl true> 1111 qwer>>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "C","a": {"__kind": "obj", "__id": 1, "__class": "A","b": true,"c": {"__kind": "char", "__val": "a"},"f": 0.123,"i": 1234,"s": "asdf","n": null,"array": {"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii": 6789,"sss": "redef"},"b": {"__kind": "obj", "__id": 3, "__class": "B","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "hjkl","n": 12,"array": {"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii": 6789,"sss": "redef","ii": 1111,"ss": "qwer","ffff": 6.789,"bbbb": false},"aa": {"__kind": "ref", "__id": 1}}
+{"__kind": "obj", "__id": 0, "__class": "C","a":{"__kind": "obj", "__id": 1, "__class": "A","b":true,"c":{"__kind": "char", "__val": "a"},"f":0.123,"i":1234,"s":"asdf","n":null,"array":{"__kind": "obj", "__id": 2, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii":6789,"sss":"redef"},"b":{"__kind": "obj", "__id": 3, "__class": "B","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"hjkl","n":12,"array":{"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii":6789,"sss":"redef","ii":1111,"ss":"qwer","ffff":6.789,"bbbb":false},"aa":{"__kind": "ref", "__id": 1}}
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false> 1111         f"\r\/> true>
 
 # Json:
-{"__kind": "obj", "__id": 0, "__class": "D","b": false,"c": {"__kind": "char", "__val": "b"},"f": 123.123,"i": 2345,"s": "new line ->\n<-","n": null,"array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii": 6789,"sss": "redef","ii": 1111,"ss": "\tf\"\r\\/","ffff": 6.789,"bbbb": false,"d": {"__kind": "ref", "__id": 0}}
+{"__kind": "obj", "__id": 0, "__class": "D","b":false,"c":{"__kind": "char", "__val": "b"},"f":123.123,"i":2345,"s":"new line ->\n<-","n":null,"array":{"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]","__items": [88,"hello",null]},"iii":6789,"sss":"redef","ii":1111,"ss":"\tf\"\r\\/","ffff":6.789,"bbbb":false,"d":{"__kind": "ref", "__id": 0}}
 
index 6b936ac..6a4dfdb 100644 (file)
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 import test_deserialization
-import json::serialization
+import json
 #alt1# import test_deserialization_serial
 #alt3# import test_deserialization_serial
 
index c79bba3..d0df911 100644 (file)
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import json::serialization
+import json
 import json::static
 
 class MyData
index 7358c85..da184d5 100644 (file)
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import json::serialization
+import json
 import json::static
 
 class MyClass
index 8800f3e..84850ab 100644 (file)
@@ -12,6 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import json::static
 import json
 
 var str = """{
index b098a82..3530f12 100644 (file)
@@ -17,7 +17,7 @@
 #alt2#module test_serialization_alt2 is serialize
 
 import serialization
-import json::serialization
+import json
 
 # Simple class
 class A