diff --git a/benchmarks/json/scripts/nitcc_parser.nit b/benchmarks/json/scripts/nitcc_parser.nit index f09b746c71..627ae39550 100644 --- a/benchmarks/json/scripts/nitcc_parser.nit +++ b/benchmarks/json/scripts/nitcc_parser.nit @@ -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 diff --git a/contrib/benitlux/src/client/base.nit b/contrib/benitlux/src/client/base.nit index 7cfde7292a..28b4c889de 100644 --- a/contrib/benitlux/src/client/base.nit +++ b/contrib/benitlux/src/client/base.nit @@ -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 diff --git a/contrib/benitlux/src/server/benitlux_controller.nit b/contrib/benitlux/src/server/benitlux_controller.nit index 56493455b4..a2ab392d58 100644 --- a/contrib/benitlux/src/server/benitlux_controller.nit +++ b/contrib/benitlux/src/server/benitlux_controller.nit @@ -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 diff --git a/contrib/neo_doxygen/src/model/descriptions.nit b/contrib/neo_doxygen/src/model/descriptions.nit index 1f504ef837..58ef0e6c99 100644 --- a/contrib/neo_doxygen/src/model/descriptions.nit +++ b/contrib/neo_doxygen/src/model/descriptions.nit @@ -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. diff --git a/contrib/neo_doxygen/src/model/graph.nit b/contrib/neo_doxygen/src/model/graph.nit index 74a81b5e6b..26c8e669a7 100644 --- a/contrib/neo_doxygen/src/model/graph.nit +++ b/contrib/neo_doxygen/src/model/graph.nit @@ -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 diff --git a/contrib/neo_doxygen/src/model/location.nit b/contrib/neo_doxygen/src/model/location.nit index b78a2ef875..d5f37278e0 100644 --- a/contrib/neo_doxygen/src/model/location.nit +++ b/contrib/neo_doxygen/src/model/location.nit @@ -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 index d277be7dfa..0000000000 --- a/contrib/neo_doxygen/src/tests/neo_doxygen_descriptions.nit +++ /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 index 4909e9de5a..0000000000 --- a/contrib/neo_doxygen/src/tests/neo_doxygen_member_resolve_introducer.nit +++ /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 diff --git a/contrib/nitrpg/src/achievements.nit b/contrib/nitrpg/src/achievements.nit index 9055b22876..2097ec363b 100644 --- a/contrib/nitrpg/src/achievements.nit +++ b/contrib/nitrpg/src/achievements.nit @@ -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 diff --git a/contrib/nitrpg/src/events.nit b/contrib/nitrpg/src/events.nit index c540dc5e91..08d387d540 100644 --- a/contrib/nitrpg/src/events.nit +++ b/contrib/nitrpg/src/events.nit @@ -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 diff --git a/contrib/nitrpg/src/game.nit b/contrib/nitrpg/src/game.nit index 504c445881..b1d8916f26 100644 --- a/contrib/nitrpg/src/game.nit +++ b/contrib/nitrpg/src/game.nit @@ -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 diff --git a/contrib/nitrpg/src/statistics.nit b/contrib/nitrpg/src/statistics.nit index cde68161b5..764616f462 100644 --- a/contrib/nitrpg/src/statistics.nit +++ b/contrib/nitrpg/src/statistics.nit @@ -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 diff --git a/contrib/nitrpg/src/test_achievements.nit b/contrib/nitrpg/src/test_achievements.nit index 033832f4a4..c210c6030d 100644 --- a/contrib/nitrpg/src/test_achievements.nit +++ b/contrib/nitrpg/src/test_achievements.nit @@ -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 diff --git a/contrib/nitrpg/src/test_events.nit b/contrib/nitrpg/src/test_events.nit index b9605016db..640e8dc839 100644 --- a/contrib/nitrpg/src/test_events.nit +++ b/contrib/nitrpg/src/test_events.nit @@ -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 diff --git a/contrib/nitrpg/src/test_game.nit b/contrib/nitrpg/src/test_game.nit index fceafb9ddd..25ddcadaa6 100644 --- a/contrib/nitrpg/src/test_game.nit +++ b/contrib/nitrpg/src/test_game.nit @@ -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"] diff --git a/contrib/refund/src/refund_json.nit b/contrib/refund/src/refund_json.nit index 4da71f584d..f670f9d90c 100644 --- a/contrib/refund/src/refund_json.nit +++ b/contrib/refund/src/refund_json.nit @@ -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 diff --git a/contrib/refund/tests/res/json_error1.res b/contrib/refund/tests/res/json_error1.res index 958aa8db6c..e7eb308d82 100644 --- a/contrib/refund/tests/res/json_error1.res +++ b/contrib/refund/tests/res/json_error1.res @@ -1,3 +1,3 @@ { - "message": "Wrong input file (Unexpected Eof; is acceptable instead: value)" + "message": "Wrong input file (Empty JSON)" } diff --git a/contrib/refund/tests/res/json_error3.res b/contrib/refund/tests/res/json_error3.res index d35b98219a..83de0af287 100644 --- a/contrib/refund/tests/res/json_error3.res +++ b/contrib/refund/tests/res/json_error3.res @@ -1,3 +1,3 @@ { - "message": "Wrong input file (Unexpected Eof; is acceptable instead: members, pair)" + "message": "Wrong input file (Malformed JSON object)" } diff --git a/contrib/shibuqam/examples/shibuqamoauth.nit b/contrib/shibuqam/examples/shibuqamoauth.nit index 2a52be90d1..bda76a3560 100644 --- a/contrib/shibuqam/examples/shibuqamoauth.nit +++ b/contrib/shibuqam/examples/shibuqamoauth.nit @@ -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. diff --git a/contrib/tinks/src/client/linux_client.nit b/contrib/tinks/src/client/linux_client.nit index bd60702d27..5e7cca4253 100644 --- a/contrib/tinks/src/client/linux_client.nit +++ b/contrib/tinks/src/client/linux_client.nit @@ -17,7 +17,7 @@ module linux_client import mnit::linux import linux::audio -import json::serialization +import json import client diff --git a/contrib/tnitter/src/action.nit b/contrib/tnitter/src/action.nit index 60ee384db9..f567294224 100644 --- a/contrib/tnitter/src/action.nit +++ b/contrib/tnitter/src/action.nit @@ -18,7 +18,7 @@ module action import nitcorn -import json::serialization +import json import model import database diff --git a/contrib/tnitter/src/push.nit b/contrib/tnitter/src/push.nit index bc47789270..9900cfa227 100644 --- a/contrib/tnitter/src/push.nit +++ b/contrib/tnitter/src/push.nit @@ -16,7 +16,7 @@ module push import nitcorn -import json::serialization +import json import model import database diff --git a/contrib/tnitter/src/tnitter_app.nit b/contrib/tnitter/src/tnitter_app.nit index cf1d162cd3..82180043bc 100644 --- a/contrib/tnitter/src/tnitter_app.nit +++ b/contrib/tnitter/src/tnitter_app.nit @@ -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 diff --git a/examples/rosettacode/json_output.nit b/examples/rosettacode/json_output.nit index 59fb72b1e6..800a310566 100644 --- a/examples/rosettacode/json_output.nit +++ b/examples/rosettacode/json_output.nit @@ -7,6 +7,7 @@ # SEE: module json_output +import json::static import json var str = """{ diff --git a/lib/android/bundle/bundle.nit b/lib/android/bundle/bundle.nit index 82acbec2b4..e02702a9a0 100644 --- a/lib/android/bundle/bundle.nit +++ b/lib/android/bundle/bundle.nit @@ -19,7 +19,7 @@ module bundle import serialization -import json::serialization +import json import platform import activities diff --git a/lib/android/intent/intent_api10.nit b/lib/android/intent/intent_api10.nit index 746c0c4556..f9e6c3bf8e 100644 --- a/lib/android/intent/intent_api10.nit +++ b/lib/android/intent/intent_api10.nit @@ -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; diff --git a/lib/android/shared_preferences/shared_preferences_api10.nit b/lib/android/shared_preferences/shared_preferences_api10.nit index b2680875ed..f17661f90c 100644 --- a/lib/android/shared_preferences/shared_preferences_api10.nit +++ b/lib/android/shared_preferences/shared_preferences_api10.nit @@ -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; diff --git a/lib/app/http_request.nit b/lib/app/http_request.nit index 3fc48c67b9..0260cab243 100644 --- a/lib/app/http_request.nit +++ b/lib/app/http_request.nit @@ -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) diff --git a/lib/github/api.nit b/lib/github/api.nit index 7c85422a40..8bd1ee3131 100644 --- a/lib/github/api.nit +++ b/lib/github/api.nit @@ -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. diff --git a/lib/github/events.nit b/lib/github/events.nit index 2dc0af7537..3417de2ccc 100644 --- a/lib/github/events.nit +++ b/lib/github/events.nit @@ -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. diff --git a/lib/github/github_curl.nit b/lib/github/github_curl.nit index b5874f3832..f2d5737371 100644 --- a/lib/github/github_curl.nit +++ b/lib/github/github_curl.nit @@ -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 diff --git a/lib/ios/data_store.nit b/lib/ios/data_store.nit index 6d1579d11f..a06586c6e6 100644 --- a/lib/ios/data_store.nit +++ b/lib/ios/data_store.nit @@ -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 index 0000000000..b964d1cd66 --- /dev/null +++ b/lib/json/README.md @@ -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" +~~~ diff --git a/lib/json/error.nit b/lib/json/error.nit index 85e6154401..26a9952033 100644 --- a/lib/json/error.nit +++ b/lib/json/error.nit @@ -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 diff --git a/lib/json/json.nit b/lib/json/json.nit index 7df7e82448..391f746ae9 100644 --- a/lib/json/json.nit +++ b/lib/json/json.nit @@ -1,8 +1,5 @@ # This file is part of NIT ( http://www.nitlanguage.org ). # -# Copyright 2014 Alexis Laferrière -# Copyright 2014 Jean-Christophe Beaupré -# # 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 @@ -15,20 +12,8 @@ # 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 index 983f50b7c3..0000000000 --- a/lib/json/serialization.nit +++ /dev/null @@ -1,968 +0,0 @@ -# This file is part of NIT ( http://www.nitlanguage.org ). -# -# Copyright 2014 Alexis Laferrière -# -# 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 index 0000000000..e29f5bde8a --- /dev/null +++ b/lib/json/serialization_read.nit @@ -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 index 0000000000..e26236cb2a --- /dev/null +++ b/lib/json/serialization_write.nit @@ -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 diff --git a/lib/json/static.nit b/lib/json/static.nit index dd1cc85093..f3107cce92 100644 --- a/lib/json/static.nit +++ b/lib/json/static.nit @@ -16,11 +16,10 @@ # 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 ################################################################################ diff --git a/lib/json/store.nit b/lib/json/store.nit index 42a04df255..b8ce0f9a10 100644 --- a/lib/json/store.nit +++ b/lib/json/store.nit @@ -90,6 +90,7 @@ module store import static +import json # A JsonStore can save and load json data from file system. class JsonStore diff --git a/lib/json/string_parser.nit b/lib/json/string_parser.nit index 51d302e93e..19c8fd1fa3 100644 --- a/lib/json/string_parser.nit +++ b/lib/json/string_parser.nit @@ -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 diff --git a/lib/linux/data_store.nit b/lib/linux/data_store.nit index 4d7ff2bdeb..5924822b8c 100644 --- a/lib/linux/data_store.nit +++ b/lib/linux/data_store.nit @@ -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 diff --git a/lib/mongodb/mongodb.nit b/lib/mongodb/mongodb.nit index 80c4d4c844..17b137fbf2 100644 --- a/lib/mongodb/mongodb.nit +++ b/lib/mongodb/mongodb.nit @@ -42,6 +42,7 @@ # ~~~ module mongodb +import json::static import json private import native_mongodb diff --git a/lib/mpi/mpi.nit b/lib/mpi/mpi.nit index bc47997830..5ea6596db8 100644 --- a/lib/mpi/mpi.nit +++ b/lib/mpi/mpi.nit @@ -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 diff --git a/lib/neo4j/curl_json.nit b/lib/neo4j/curl_json.nit index 03a7ca49bf..f2a541f565 100644 --- a/lib/neo4j/curl_json.nit +++ b/lib/neo4j/curl_json.nit @@ -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 diff --git a/lib/neo4j/error.nit b/lib/neo4j/error.nit index f9df000adf..58068ad7c7 100644 --- a/lib/neo4j/error.nit +++ b/lib/neo4j/error.nit @@ -12,23 +12,21 @@ 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 diff --git a/lib/neo4j/graph/json_graph_store.nit b/lib/neo4j/graph/json_graph_store.nit index 618a1d3485..d924bd9b41 100644 --- a/lib/neo4j/graph/json_graph_store.nit +++ b/lib/neo4j/graph/json_graph_store.nit @@ -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 diff --git a/lib/nitcc_runtime.nit b/lib/nitcc_runtime.nit index a09bc3cbde..cfddec3f65 100644 --- a/lib/nitcc_runtime.nit +++ b/lib/nitcc_runtime.nit @@ -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 diff --git a/lib/nitcorn/restful.nit b/lib/nitcorn/restful.nit index 158643a281..4342a111b7 100644 --- a/lib/nitcorn/restful.nit +++ b/lib/nitcorn/restful.nit @@ -16,7 +16,7 @@ module restful is new_annotation(restful) import nitcorn -import json::serialization +import json # Action with `restful` methods class RestfulAction diff --git a/lib/parser_base.nit b/lib/parser_base.nit index f97fbf0a7f..b62313763b 100644 --- a/lib/parser_base.nit +++ b/lib/parser_base.nit @@ -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 diff --git a/lib/popcorn/pop_handlers.nit b/lib/popcorn/pop_handlers.nit index e4da4a5428..8d66cc9580 100644 --- a/lib/popcorn/pop_handlers.nit +++ b/lib/popcorn/pop_handlers.nit @@ -18,6 +18,7 @@ module pop_handlers import pop_routes +import json::static import json # Class handler for a route. diff --git a/lib/popcorn/pop_repos.nit b/lib/popcorn/pop_repos.nit index 4c3ea14c7a..7b02c3511c 100644 --- a/lib/popcorn/pop_repos.nit +++ b/lib/popcorn/pop_repos.nit @@ -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`. diff --git a/lib/popcorn/pop_validation.nit b/lib/popcorn/pop_validation.nit index 386bb24ff8..b1464b857a 100644 --- a/lib/popcorn/pop_validation.nit +++ b/lib/popcorn/pop_validation.nit @@ -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 diff --git a/lib/serialization/README.md b/lib/serialization/README.md index 47eef73b7a..3f6ac6c063 100644 --- a/lib/serialization/README.md +++ b/lib/serialization/README.md @@ -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 diff --git a/src/doc/doc_phases/doc_indexing.nit b/src/doc/doc_phases/doc_indexing.nit index d532d9c9e8..066f8ab73a 100644 --- a/src/doc/doc_phases/doc_indexing.nit +++ b/src/doc/doc_phases/doc_indexing.nit @@ -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 diff --git a/src/doc/html_templates/html_components.nit b/src/doc/html_templates/html_components.nit index 630d28eb11..a0f13993a6 100644 --- a/src/doc/html_templates/html_components.nit +++ b/src/doc/html_templates/html_components.nit @@ -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 diff --git a/src/examples/nitwebcrawl.nit b/src/examples/nitwebcrawl.nit index 1187476d75..e981ac6f1e 100644 --- a/src/examples/nitwebcrawl.nit +++ b/src/examples/nitwebcrawl.nit @@ -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 diff --git a/src/model/model_json.nit b/src/model/model_json.nit index 2c5cd04395..1d8483cd7a 100644 --- a/src/model/model_json.nit +++ b/src/model/model_json.nit @@ -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 diff --git a/src/web/api_catalog.nit b/src/web/api_catalog.nit index 30b8757182..bd403adb61 100644 --- a/src/web/api_catalog.nit +++ b/src/web/api_catalog.nit @@ -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 diff --git a/src/web/api_feedback.nit b/src/web/api_feedback.nit index e2bfa9a014..a5cacff6fa 100644 --- a/src/web/api_feedback.nit +++ b/src/web/api_feedback.nit @@ -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 diff --git a/src/web/api_metrics.nit b/src/web/api_metrics.nit index bb0147c180..8c01c0dfb9 100644 --- a/src/web/api_metrics.nit +++ b/src/web/api_metrics.nit @@ -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 diff --git a/src/web/web_base.nit b/src/web/web_base.nit index 14bfcca693..60f7f2b5a1 100644 --- a/src/web/web_base.nit +++ b/src/web/web_base.nit @@ -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 diff --git a/tests/sav/json_output.res b/tests/sav/json_output.res index 4162e8d981..80f6c94a9f 100644 --- a/tests/sav/json_output.res +++ b/tests/sav/json_output.res @@ -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 index e69de29bb2..0000000000 diff --git a/tests/sav/neo_doxygen_member_resolve_introducer.res b/tests/sav/neo_doxygen_member_resolve_introducer.res deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/sav/nitce/test_json_deserialization_alt1.res b/tests/sav/nitce/test_json_deserialization_alt1.res index cb74989ec4..d757542186 100644 --- a/tests/sav/nitce/test_json_deserialization_alt1.res +++ b/tests/sav/nitce/test_json_deserialization_alt1.res @@ -2,7 +2,7 @@ # 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: @@ -11,7 +11,7 @@ 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: 1111 qwer> @@ -20,7 +20,7 @@ 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: 1111 qwer>> @@ -30,7 +30,7 @@ <- false p4ssw0rd> 1111 f" \/> 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: @@ -40,7 +40,7 @@ # 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: @@ -53,7 +53,7 @@ Deserialization Error: Wrong type on `E::b` expected `Array[nullable Serializabl # 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" # 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" # 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: diff --git a/tests/sav/nitce/test_json_deserialization_alt3.res b/tests/sav/nitce/test_json_deserialization_alt3.res index 3a3aec0959..a6238372d1 100644 --- a/tests/sav/nitce/test_json_deserialization_alt3.res +++ b/tests/sav/nitce/test_json_deserialization_alt3.res @@ -100,19 +100,11 @@ "__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"] } } diff --git a/tests/sav/nitce/test_serialization.res b/tests/sav/nitce/test_serialization.res index 67a1674925..cc516c58ea 100644 --- a/tests/sav/nitce/test_serialization.res +++ b/tests/sav/nitce/test_serialization.res @@ -2,24 +2,24 @@ # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/nitce/test_serialization_alt2.res b/tests/sav/nitce/test_serialization_alt2.res index d3fb349ebf..28727b4c1f 100644 --- a/tests/sav/nitce/test_serialization_alt2.res +++ b/tests/sav/nitce/test_serialization_alt2.res @@ -5,24 +5,24 @@ alt/test_serialization_alt2.nit:64,1--72,3: Warning: superfluous use of `auto_se # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/nitce/test_serialization_alt3.res b/tests/sav/nitce/test_serialization_alt3.res index 3b72eda387..01b101ed13 100644 --- a/tests/sav/nitce/test_serialization_alt3.res +++ b/tests/sav/nitce/test_serialization_alt3.res @@ -3,24 +3,24 @@ alt/test_serialization_alt3.nit:40,1--51,3: Warning: superfluous use of `noseria # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/nitce/test_serialization_alt4.res b/tests/sav/nitce/test_serialization_alt4.res index 5f408342fa..a45b63ed2d 100644 --- a/tests/sav/nitce/test_serialization_alt4.res +++ b/tests/sav/nitce/test_serialization_alt4.res @@ -3,24 +3,24 @@ alt/test_serialization_alt4.nit:29,2--31,26: Warning: superfluous use of `serial # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/nitce/test_serialization_alt5.res b/tests/sav/nitce/test_serialization_alt5.res index cc170878d9..d5d2e2c790 100644 --- a/tests/sav/nitce/test_serialization_alt5.res +++ b/tests/sav/nitce/test_serialization_alt5.res @@ -3,24 +3,24 @@ alt/test_serialization_alt5.nit:22,1--38,3: Warning: duplicated annotation `seri # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/nitce/test_serialization_redef.res b/tests/sav/nitce/test_serialization_redef.res index 67a1674925..cc516c58ea 100644 --- a/tests/sav/nitce/test_serialization_redef.res +++ b/tests/sav/nitce/test_serialization_redef.res @@ -2,24 +2,24 @@ # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/nitce/test_serialization_redef_alt0.res b/tests/sav/nitce/test_serialization_redef_alt0.res index a6a77fddd1..c0589ed0ce 100644 --- a/tests/sav/nitce/test_serialization_redef_alt0.res +++ b/tests/sav/nitce/test_serialization_redef_alt0.res @@ -2,24 +2,24 @@ # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/nitce/test_serialization_redef_alt1.res b/tests/sav/nitce/test_serialization_redef_alt1.res index ec4a7d9fd5..7c65b3dced 100644 --- a/tests/sav/nitce/test_serialization_redef_alt1.res +++ b/tests/sav/nitce/test_serialization_redef_alt1.res @@ -2,24 +2,24 @@ # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/nitce/test_serialization_redef_alt2.res b/tests/sav/nitce/test_serialization_redef_alt2.res index 48b21cc2b1..e6c3c90d99 100644 --- a/tests/sav/nitce/test_serialization_redef_alt2.res +++ b/tests/sav/nitce/test_serialization_redef_alt2.res @@ -2,24 +2,24 @@ # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/test_adhoc_json_parse_args1.res b/tests/sav/test_adhoc_json_parse_args1.res index 2e9d00b8ca..aa4f276f6a 100644 --- a/tests/sav/test_adhoc_json_parse_args1.res +++ b/tests/sav/test_adhoc_json_parse_args1.res @@ -17,4 +17,3 @@ "Zip": "94085", "Country": "US" }] - diff --git a/tests/sav/test_json_deserialization.res b/tests/sav/test_json_deserialization.res index 5ab004a8e9..c4040be9dc 100644 --- a/tests/sav/test_json_deserialization.res +++ b/tests/sav/test_json_deserialization.res @@ -2,7 +2,7 @@ # 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: @@ -11,7 +11,7 @@ 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: 1111 qwer> @@ -20,7 +20,7 @@ 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: 1111 qwer>> @@ -30,7 +30,7 @@ <- false p4ssw0rd> 1111 f" \/> 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: diff --git a/tests/sav/test_json_deserialization_alt1.res b/tests/sav/test_json_deserialization_alt1.res index 161fb58c57..91b7df1cfd 100644 --- a/tests/sav/test_json_deserialization_alt1.res +++ b/tests/sav/test_json_deserialization_alt1.res @@ -2,7 +2,7 @@ # 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: @@ -11,7 +11,7 @@ 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: 1111 qwer> @@ -20,7 +20,7 @@ 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: 1111 qwer>> @@ -30,7 +30,7 @@ <- false p4ssw0rd> 1111 f" \/> 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: @@ -40,7 +40,7 @@ # 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: @@ -49,7 +49,7 @@ # Json: -{"__kind": "obj", "__id": 0, "__class": "F[Int]","n": 2222} +{"__kind": "obj", "__id": 0, "__class": "F[Int]","n":2222} # Back in Nit: @@ -58,7 +58,7 @@ # Json: -{"__kind": "obj", "__id": 0, "__class": "F[Float]","n": 33.33} +{"__kind": "obj", "__id": 0, "__class": "F[Float]","n":33.33} # Back in Nit: @@ -67,7 +67,7 @@ # 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: diff --git a/tests/sav/test_json_deserialization_alt2.res b/tests/sav/test_json_deserialization_alt2.res index 48005ec114..f7aaf3181d 100644 --- a/tests/sav/test_json_deserialization_alt2.res +++ b/tests/sav/test_json_deserialization_alt2.res @@ -2,19 +2,19 @@ # 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: 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: 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" \/> 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: # Json: -{"a": ["hello",1234,123.4],"b": ["hella",2345,234.5]} +{"a":["hello",1234,123.4],"b":["hella",2345,234.5]} # Nit: # Json: -{"n": 2222} +{"n":2222} # Nit: # Json: -{"n": 33.33} +{"n":33.33} # Nit: # 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"}} diff --git a/tests/sav/test_json_deserialization_alt3.res b/tests/sav/test_json_deserialization_alt3.res index 3904578841..d58b2de909 100644 --- a/tests/sav/test_json_deserialization_alt3.res +++ b/tests/sav/test_json_deserialization_alt3.res @@ -100,19 +100,11 @@ "__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] } } @@ -151,39 +143,21 @@ "__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"] } } diff --git a/tests/sav/test_json_deserialization_alt4.res b/tests/sav/test_json_deserialization_alt4.res index 5527174df0..3c56592329 100644 --- a/tests/sav/test_json_deserialization_alt4.res +++ b/tests/sav/test_json_deserialization_alt4.res @@ -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 diff --git a/tests/sav/test_json_deserialization_plain.res b/tests/sav/test_json_deserialization_plain.res index 62b3c82090..c8b7dd2eef 100644 --- a/tests/sav/test_json_deserialization_plain.res +++ b/tests/sav/test_json_deserialization_plain.res @@ -26,6 +26,6 @@ # Nit: > # JSON: not valid json -# Errors: 'Parsing error at line 1, position 1: Error: bad JSON entity' +# Errors: 'Error: bad JSON entity' # Nit: null diff --git a/tests/sav/test_json_unicode.res b/tests/sav/test_json_unicode.res index c0f61ccdcb..9a44a7c843 100644 --- a/tests/sav/test_json_unicode.res +++ b/tests/sav/test_json_unicode.res @@ -2,4 +2,3 @@ "beer": "test", "name": "Gaëa" } - diff --git a/tests/sav/test_serialization.res b/tests/sav/test_serialization.res index e3b56a7868..8480abe0cd 100644 --- a/tests/sav/test_serialization.res +++ b/tests/sav/test_serialization.res @@ -2,24 +2,24 @@ # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/test_serialization_alt1.res b/tests/sav/test_serialization_alt1.res index f275932a14..f640ce7afc 100644 --- a/tests/sav/test_serialization_alt1.res +++ b/tests/sav/test_serialization_alt1.res @@ -2,19 +2,19 @@ # 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: 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: 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" \/> 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} diff --git a/tests/sav/test_serialization_alt2.res b/tests/sav/test_serialization_alt2.res index 42ad47b0ac..e733f605cd 100644 --- a/tests/sav/test_serialization_alt2.res +++ b/tests/sav/test_serialization_alt2.res @@ -5,24 +5,24 @@ alt/test_serialization_alt2.nit:64,1--72,3: Warning: superfluous use of `auto_se # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/test_serialization_alt3.res b/tests/sav/test_serialization_alt3.res index 9ad407314d..8818e8fe99 100644 --- a/tests/sav/test_serialization_alt3.res +++ b/tests/sav/test_serialization_alt3.res @@ -3,24 +3,24 @@ alt/test_serialization_alt3.nit:40,1--51,3: Warning: superfluous use of `noseria # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/test_serialization_alt4.res b/tests/sav/test_serialization_alt4.res index 039170f672..06e2015671 100644 --- a/tests/sav/test_serialization_alt4.res +++ b/tests/sav/test_serialization_alt4.res @@ -3,24 +3,24 @@ alt/test_serialization_alt4.nit:29,2--31,26: Warning: superfluous use of `serial # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/test_serialization_alt5.res b/tests/sav/test_serialization_alt5.res index 6f763c2682..3c56b96851 100644 --- a/tests/sav/test_serialization_alt5.res +++ b/tests/sav/test_serialization_alt5.res @@ -3,24 +3,24 @@ alt/test_serialization_alt5.nit:22,1--38,3: Warning: duplicated annotation `seri # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/test_serialization_redef.res b/tests/sav/test_serialization_redef.res index e3b56a7868..8480abe0cd 100644 --- a/tests/sav/test_serialization_redef.res +++ b/tests/sav/test_serialization_redef.res @@ -2,24 +2,24 @@ # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/test_serialization_redef_alt0.res b/tests/sav/test_serialization_redef_alt0.res index 337cdaa9a2..9eab831a65 100644 --- a/tests/sav/test_serialization_redef_alt0.res +++ b/tests/sav/test_serialization_redef_alt0.res @@ -2,24 +2,24 @@ # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/test_serialization_redef_alt1.res b/tests/sav/test_serialization_redef_alt1.res index 2deb5ceb4f..8b930a6d6f 100644 --- a/tests/sav/test_serialization_redef_alt1.res +++ b/tests/sav/test_serialization_redef_alt1.res @@ -2,24 +2,24 @@ # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/sav/test_serialization_redef_alt2.res b/tests/sav/test_serialization_redef_alt2.res index 1c1850c06a..9662b36a5f 100644 --- a/tests/sav/test_serialization_redef_alt2.res +++ b/tests/sav/test_serialization_redef_alt2.res @@ -2,24 +2,24 @@ # 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: 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: 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: <- false> 1111 f" \/> 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}} diff --git a/tests/test_json_deserialization.nit b/tests/test_json_deserialization.nit index 6b936acb44..6a4dfdb0df 100644 --- a/tests/test_json_deserialization.nit +++ b/tests/test_json_deserialization.nit @@ -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 diff --git a/tests/test_json_deserialization_heuristic.nit b/tests/test_json_deserialization_heuristic.nit index c79bba31a1..d0df911253 100644 --- a/tests/test_json_deserialization_heuristic.nit +++ b/tests/test_json_deserialization_heuristic.nit @@ -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 diff --git a/tests/test_json_deserialization_plain.nit b/tests/test_json_deserialization_plain.nit index 7358c85db9..da184d592c 100644 --- a/tests/test_json_deserialization_plain.nit +++ b/tests/test_json_deserialization_plain.nit @@ -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 diff --git a/tests/test_json_unicode.nit b/tests/test_json_unicode.nit index 8800f3eb06..84850abb08 100644 --- a/tests/test_json_unicode.nit +++ b/tests/test_json_unicode.nit @@ -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 = """{ diff --git a/tests/test_serialization.nit b/tests/test_serialization.nit index b098a8277f..3530f1266b 100644 --- a/tests/test_serialization.nit +++ b/tests/test_serialization.nit @@ -17,7 +17,7 @@ #alt2#module test_serialization_alt2 is serialize import serialization -import json::serialization +import json # Simple class class A