From: Jean Privat Date: Sat, 23 May 2015 01:01:25 +0000 (-0400) Subject: Merge: Markdown: some improvement and fixes X-Git-Tag: v0.7.5~35 X-Git-Url: http://nitlanguage.org?hp=64305852535cd22eff796134a5f80866a73426de Merge: Markdown: some improvement and fixes Misc modification to markdown lib to facilitate custon Markdown parsing from external tools. Pull-Request: #1371 Reviewed-by: Jean Privat Reviewed-by: Lucas Bajolet --- diff --git a/contrib/benitlux/src/benitlux_controller.nit b/contrib/benitlux/src/benitlux_controller.nit index 2297bbd..f124315 100644 --- a/contrib/benitlux/src/benitlux_controller.nit +++ b/contrib/benitlux/src/benitlux_controller.nit @@ -18,7 +18,7 @@ module benitlux_controller import nitcorn -import json_serialization +private import json::serialization import benitlux_model import benitlux_db diff --git a/lib/android/bundle/bundle.nit b/lib/android/bundle/bundle.nit index 3678cbc..19b2f8e 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::serialization import platform import activities diff --git a/lib/android/intent/intent_api10.nit b/lib/android/intent/intent_api10.nit index 5f37179..5312c15 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::serialization 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 72a634c..84d213d 100644 --- a/lib/android/shared_preferences/shared_preferences_api10.nit +++ b/lib/android/shared_preferences/shared_preferences_api10.nit @@ -19,11 +19,11 @@ module shared_preferences_api10 import dalvik import serialization -private import json_serialization +private import json::serialization in "Java" `{ import android.content.SharedPreferences; - import android.content.Context; + import android.content.Context; import android.app.Activity; import java.util.Map; import java.util.Iterator; diff --git a/lib/json_serialization.nit b/lib/json/serialization.nit similarity index 53% rename from lib/json_serialization.nit rename to lib/json/serialization.nit index b9667db..61c6f61 100644 --- a/lib/json_serialization.nit +++ b/lib/json/serialization.nit @@ -14,11 +14,52 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Handles serialization and deserialization of objects to/from Json. -module json_serialization +# Handles serialization and deserialization of objects to/from JSON +# +# ## Nity JSON +# +# `JsonSerializer` write Nit objects that subclass `Serializable` to JSON, +# and `JsonDeserializer` can read them. They both use meta-data 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 +# +# ## 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 this service is provided by `Serializable::to_plain_json`. +# +# ### Usage Example +# +# ~~~nitish +# import json::serialization +# +# class Person +# auto_serializable +# +# 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.to_plain_json == """ +# {"name": "Bob", "year_of_birth": 1986, "next_of_kin": null}""" +# +# assert alice.to_plain_json == """ +# {"name": "Alice", "year_of_birth": 1978, "next_of_kin": {"name": "Bob", "year_of_birth": 1986, "next_of_kin": null}}""" +# ~~~ +module serialization -import serialization -import json::static +import ::serialization +private import ::serialization::engine_tools +private import static # Serializer of Nit objects to Json string. class JsonSerializer @@ -27,25 +68,87 @@ class JsonSerializer # Target writing stream var stream: Writer + # Write plain JSON? easier to read but does not support Nit deserialization + # + # If `false`, the default, serialize to support deserialization: + # + # * Write meta-data, 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 meta-data, 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 meta-data needed to deserialize the objects + # back to regular Nit objects. + # * Keys of Nit `HashMap` are converted to their string reprensentation using `to_s`. + var plain_json = false is writable + + # 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 object.serialize_to_json(self) + else + if plain_json then + for o in open_objects do + if object.is_same_serialized(o) then + # Cycle detected + stream.write "null" + return + end + end + + open_objects.add object + end + + first_attribute = true + object.serialize_to_json self + first_attribute = false + + if plain_json then open_objects.pop + end end redef fun serialize_attribute(name, value) do - stream.write ", \"{name}\": " + if not plain_json or not first_attribute then + stream.write ", " + first_attribute = false + end + + stream.write "\"" + stream.write name + stream.write "\": " super end redef fun serialize_reference(object) do - if refs_map.has_key(object) then + if not plain_json and refs_map.has_key(object) then # if already serialized, add local reference var id = ref_id_for(object) - stream.write "\{\"__kind\": \"ref\", \"__id\": {id}\}" + stream.write "\{\"__kind\": \"ref\", \"__id\": " + stream.write id.to_s + stream.write "\}" else # serialize here serialize object @@ -76,10 +179,10 @@ class JsonDeserializer private var text: Text # Root json object parsed from input text. - var root: nullable Jsonable is noinit + private var root: nullable Jsonable is noinit # Depth-first path in the serialized object tree. - var path = new Array[JsonObject] + private var path = new Array[JsonObject] # Map of references to already deserialized objects. private var id_to_object = new StrictHashMap[Int, Object] @@ -189,10 +292,31 @@ redef class Serializable private fun serialize_to_json(v: JsonSerializer) do var id = v.ref_id_for(self) - v.stream.write "\{\"__kind\": \"obj\", \"__id\": {id}, \"__class\": \"{class_name}\"" + v.stream.write "\{" + if not v.plain_json then + 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.stream.write "\}" end + + # Serialize this object to plain JSON + # + # This is a shortcut using `JsonSerializer::plain_json`, + # see its documentation for more information. + fun to_plain_json: String + do + var stream = new StringWriter + var serializer = new JsonSerializer(stream) + serializer.plain_json = true + serializer.serialize self + stream.close + return stream.to_s + end end redef class Int @@ -208,7 +332,16 @@ redef class Bool end redef class Char - redef fun serialize_to_json(v) do v.stream.write "\{\"__kind\": \"char\", \"__val\": {to_s.to_json}\}" + redef fun serialize_to_json(v) + do + if v.plain_json then + v.stream.write to_s.to_json + else + v.stream.write "\{\"__kind\": \"char\", \"__val\": " + v.stream.write to_s.to_json + v.stream.write "\}" + end + end end redef class String @@ -242,16 +375,22 @@ redef class SimpleCollection[E] redef fun serialize_to_json(v) do # Register as pseudo object - var id = v.ref_id_for(self) - 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 """, "__items": """ + if not v.plain_json then + var id = v.ref_id_for(self) + 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 """, "__items": """ + end + serialize_to_pure_json v - v.stream.write "\}" + + if not v.plain_json then + v.stream.write "\}" + end end redef init from_deserializer(v: Deserializer) @@ -273,7 +412,7 @@ end redef class Array[E] redef fun serialize_to_json(v) do - if class_name == "Array[nullable Serializable]" then + if v.plain_json or class_name == "Array[nullable Serializable]" then # Using class_name to get the exact type, # we do not want Array[Int] or anything else here. @@ -288,19 +427,40 @@ redef class Map[K, V] # Register as pseudo object var id = v.ref_id_for(self) - 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 """, "__keys": """ + if v.plain_json then + v.stream.write "\{" + var first = true + for key, val in self do + if not first then + v.stream.write ", " + else first = false + + if key == null then key = "null" + + v.stream.write key.to_s.to_json + v.stream.write ": " + if not v.try_to_serialize(val) then + v.warn("element of type {val.class_name} is not serializable.") + v.stream.write "null" + end + end + v.stream.write "\}" + else + 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 - keys.serialize_to_pure_json v + v.stream.write """, "__keys": """ + keys.serialize_to_pure_json v - v.stream.write """, "__values": """ - values.serialize_to_pure_json v - v.stream.write "\}" + v.stream.write """, "__values": """ + values.serialize_to_pure_json v + + v.stream.write "\}" + end end # Instantiate a new `Array` from its serialized representation. @@ -322,59 +482,3 @@ redef class Map[K, V] end end end - -# Maps instances to a value, uses `is_same_instance` -# -# Warning: This class does not implement all the services from `Map`. -private class StrictHashMap[K, V] - super Map[K, V] - - # private - var map = new HashMap[K, Array[Couple[K, V]]] - - redef var length = 0 - - redef fun is_empty do return length == 0 - - # private - fun node_at(key: K): nullable Couple[K, V] - do - if not map.keys.has(key) then return null - - var arr = map[key] - for couple in arr do - if couple.first.is_same_serialized(key) then - return couple - end - end - - return null - end - - redef fun [](key) - do - var node = node_at(key) - assert node != null - return node.second - end - - redef fun []=(key, value) - do - var node = node_at(key) - if node != null then - node.second = value - return - end - - var arr - if not map.keys.has(key) then - arr = new Array[Couple[K, V]] - map[key] = arr - else arr = map[key] - - arr.add new Couple[K, V](key, value) - self.length += 1 - end - - redef fun has_key(key) do return node_at(key) != null -end diff --git a/lib/linux/data_store.nit b/lib/linux/data_store.nit index 5743d82..8291616 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::serialization redef class App redef var data_store = new LinuxStore diff --git a/lib/mpi.nit b/lib/mpi.nit index 5696d32..69d0d9f 100644 --- a/lib/mpi.nit +++ b/lib/mpi.nit @@ -33,7 +33,7 @@ end import c intrude import standard::string import serialization -private import json_serialization +private import json::serialization in "C Header" `{ #include diff --git a/lib/serialization/engine_tools.nit b/lib/serialization/engine_tools.nit new file mode 100644 index 0000000..1e0ee0b --- /dev/null +++ b/lib/serialization/engine_tools.nit @@ -0,0 +1,74 @@ +# 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. + +# Advanced services for serialization engines +module engine_tools + +import serialization + +# Maps instances to a value, uses `is_same_instance` +# +# Warning: This class does not implement all the services from `Map`. +class StrictHashMap[K, V] + super Map[K, V] + + # private + var map = new HashMap[K, Array[Couple[K, V]]] + + redef var length = 0 + + redef fun is_empty do return length == 0 + + # private + fun node_at(key: K): nullable Couple[K, V] + do + if not map.keys.has(key) then return null + + var arr = map[key] + for couple in arr do + if couple.first.is_same_serialized(key) then + return couple + end + end + + return null + end + + redef fun [](key) + do + var node = node_at(key) + assert node != null + return node.second + end + + redef fun []=(key, value) + do + var node = node_at(key) + if node != null then + node.second = value + return + end + + var arr + if not map.keys.has(key) then + arr = new Array[Couple[K, V]] + map[key] = arr + else arr = map[key] + + arr.add new Couple[K, V](key, value) + self.length += 1 + end + + redef fun has_key(key) do return node_at(key) != null +end diff --git a/lib/standard/file.nit b/lib/standard/file.nit index 5324f01..1490ee7 100644 --- a/lib/standard/file.nit +++ b/lib/standard/file.nit @@ -1024,39 +1024,23 @@ redef class String # assert files.is_empty # # TODO find a better way to handle errors and to give them back to the user. - fun files: Array[String] is extern import Array[String], Array[String].add, NativeString.to_s, String.to_cstring `{ - char *dir_path; - DIR *dir; - - dir_path = String_to_cstring( recv ); - if ((dir = opendir(dir_path)) == NULL) - { - //perror( dir_path ); - //exit( 1 ); - Array_of_String results; - results = new_Array_of_String(); - return results; - } - else - { - Array_of_String results; - String file_name; - struct dirent *de; - - results = new_Array_of_String(); - - while ( ( de = readdir( dir ) ) != NULL ) - if ( strcmp( de->d_name, ".." ) != 0 && - strcmp( de->d_name, "." ) != 0 ) - { - file_name = NativeString_to_s( strdup( de->d_name ) ); - Array_of_String_add( results, file_name ); - } + fun files: Array[String] + do + var res = new Array[String] + var d = new NativeDir.opendir(to_cstring) + if d.address_is_null then return res + + loop + var de = d.readdir + if de.address_is_null then break + var name = de.to_s_with_copy + if name == "." or name == ".." then continue + res.add name + end + d.closedir - closedir( dir ); - return results; - } - `} + return res + end end redef class NativeString @@ -1129,6 +1113,24 @@ private extern class NativeFile `{ FILE* `} new native_stderr is extern "file_NativeFileCapable_NativeFileCapable_native_stderr_0" end +# Standard `DIR*` pointer +private extern class NativeDir `{ DIR* `} + + # Open a directory + new opendir(path: NativeString) `{ return opendir(path); `} + + # Close a directory + fun closedir `{ closedir(recv); `} + + # Read the next directory entry + fun readdir: NativeString `{ + struct dirent *de; + de = readdir(recv); + if (!de) return NULL; + return de->d_name; + `} +end + redef class Sys # Standard input diff --git a/src/compiler/global_compiler.nit b/src/compiler/global_compiler.nit index ede1beb..b2cf479 100644 --- a/src/compiler/global_compiler.nit +++ b/src/compiler/global_compiler.nit @@ -404,6 +404,7 @@ class GlobalCompilerVisitor do var ret_type = mmodule.native_array_type(elttype) ret_type = anchor(ret_type).as(MClassType) + length = autobox(length, compiler.mainmodule.int_type) return self.new_expr("NEW_{ret_type.c_name}({length})", ret_type) end diff --git a/src/compiler/separate_compiler.nit b/src/compiler/separate_compiler.nit index 3e7fbcb..085a36d 100644 --- a/src/compiler/separate_compiler.nit +++ b/src/compiler/separate_compiler.nit @@ -2032,6 +2032,7 @@ class SeparateCompilerVisitor self.require_declaration("NEW_{mtype.mclass.c_name}") assert mtype isa MGenericType var compiler = self.compiler + length = autobox(length, compiler.mainmodule.int_type) if mtype.need_anchor then hardening_live_open_type(mtype) link_unresolved_type(self.frame.mpropdef.mclassdef, mtype) diff --git a/tests/sav/nitg-e/test_deserialization_serial.res b/tests/sav/nitg-e/test_deserialization_serial.res deleted file mode 100644 index 90e0d60..0000000 --- a/tests/sav/nitg-e/test_deserialization_serial.res +++ /dev/null @@ -1,40 +0,0 @@ -Runtime error: Aborted (../lib/serialization/serialization.nit:109) -# Nit: - - -# Json: -{"__kind": "obj", "__id": 0, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "s": "asdf", "n": null} - -# Back in Nit: - - -# 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": null, "ii": 1111, "ss": "qwer"} - -# Back in Nit: - 1111 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}, "b": {"__kind": "obj", "__id": 2, "__class": "B", "b": false, "c": {"__kind": "char", "__val": "b"}, "f": 123.123, "i": 2345, "s": "hjkl", "n": null, "ii": 1111, "ss": "qwer"}, "aa": {"__kind": "ref", "__id": 1}} - -# Back in Nit: - 1111 qwer>> - -# 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, "ii": 1111, "ss": "\tf\"\r\\\/", "d": {"__kind": "ref", "__id": 0}} - -# Back in Nit: - -<- false> 1111 f" \/> true> - -Error: doesn't know how to deserialize class "Array" diff --git a/tests/sav/nitg-e/test_deserialization.res b/tests/sav/nitg-e/test_json_deserialization_alt1.res similarity index 100% rename from tests/sav/nitg-e/test_deserialization.res rename to tests/sav/nitg-e/test_json_deserialization_alt1.res diff --git a/tests/sav/nitg-e/test_new_native.res b/tests/sav/nitg-e/test_new_native.res index e69ef40..44b504c 100644 --- a/tests/sav/nitg-e/test_new_native.res +++ b/tests/sav/nitg-e/test_new_native.res @@ -5,3 +5,5 @@ NativeArray 3 1 1,10,100 +1 +1 diff --git a/tests/sav/nitg-e/test_new_native_alt1.res b/tests/sav/nitg-e/test_new_native_alt1.res index 58f1483..cf6635c 100644 --- a/tests/sav/nitg-e/test_new_native_alt1.res +++ b/tests/sav/nitg-e/test_new_native_alt1.res @@ -5,3 +5,5 @@ NativeArray 3 1 1,true,100 +1 +1 diff --git a/tests/sav/nitserial_args1.res b/tests/sav/nitserial_args1.res index 22ebc32..fc2e797 100644 --- a/tests/sav/nitserial_args1.res +++ b/tests/sav/nitserial_args1.res @@ -13,7 +13,6 @@ redef class Deserializer if name == "Array[nullable Object]" then return new Array[nullable Object].from_deserializer(self) if name == "Array[Serializable]" then return new Array[Serializable].from_deserializer(self) if name == "Array[String]" then return new Array[String].from_deserializer(self) - if name == "StrictHashMap[Serializable, Int]" then return new StrictHashMap[Serializable, Int].from_deserializer(self) if name == "HashMap[Serializable, Array[Couple[Serializable, Int]]]" then return new HashMap[Serializable, Array[Couple[Serializable, Int]]].from_deserializer(self) if name == "Array[Couple[Serializable, Int]]" then return new Array[Couple[Serializable, Int]].from_deserializer(self) return super diff --git a/tests/sav/test_deserialization.res b/tests/sav/test_deserialization.res deleted file mode 100644 index 13f9a72..0000000 --- a/tests/sav/test_deserialization.res +++ /dev/null @@ -1,40 +0,0 @@ -Runtime error: Aborted (../lib/serialization/serialization.nit:109) -# Nit: - - -# Json: -{"__kind": "obj", "__id": 0, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "s": "asdf", "n": null} - -# Back in Nit: - - -# 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": null, "ii": 1111, "ss": "qwer"} - -# Back in Nit: - 1111 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}, "b": {"__kind": "obj", "__id": 2, "__class": "B", "b": false, "c": {"__kind": "char", "__val": "b"}, "f": 123.123, "i": 2345, "s": "hjkl", "n": null, "ii": 1111, "ss": "qwer"}, "aa": {"__kind": "ref", "__id": 1}} - -# Back in Nit: - 1111 qwer>> - -# 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, "ii": 1111, "ss": "\tf\"\r\\\/", "d": {"__kind": "ref", "__id": 0}} - -# Back in Nit: - -<- false> 1111 f" \/> true> - -Error: doesn't know how to deserialize class "Array[Object]" diff --git a/tests/sav/test_deserialization_alt1.res b/tests/sav/test_json_deserialization.res similarity index 100% rename from tests/sav/test_deserialization_alt1.res rename to tests/sav/test_json_deserialization.res diff --git a/tests/sav/test_deserialization_serial.res b/tests/sav/test_json_deserialization_alt1.res similarity index 100% rename from tests/sav/test_deserialization_serial.res rename to tests/sav/test_json_deserialization_alt1.res diff --git a/tests/sav/test_json_deserialization_alt2.res b/tests/sav/test_json_deserialization_alt2.res new file mode 100644 index 0000000..99e49d6 --- /dev/null +++ b/tests/sav/test_json_deserialization_alt2.res @@ -0,0 +1,49 @@ +# Nit: + + +# Json: +{"b": true, "c": "a", "f": 0.123, "i": 1234, "s": "asdf", "n": null} + +# Nit: + 1111 qwer> + +# Json: +{"b": false, "c": "b", "f": 123.123, "i": 2345, "s": "hjkl", "n": null, "ii": 1111, "ss": "qwer"} + +# Nit: + 1111 qwer>> + +# Json: +{"a": {"b": true, "c": "a", "f": 0.123, "i": 1234, "s": "asdf", "n": null}, "b": {"b": false, "c": "b", "f": 123.123, "i": 2345, "s": "hjkl", "n": null, "ii": 1111, "ss": "qwer"}, "aa": {"b": true, "c": "a", "f": 0.123, "i": 1234, "s": "asdf", "n": null}} + +# Nit: + +<- false> 1111 f" \/> true> + +# Json: +{"b": false, "c": "b", "f": 123.123, "i": 2345, "s": "new line ->\n<-", "n": null, "ii": 1111, "ss": "\tf\"\r\\\/", "d": null} + +# Nit: + + +# Json: +{"a": ["hello", 1234, 123.4], "b": ["hella", 2345, 234.5]} + +# Nit: + + +# Json: +{"n": 2222} + +# Nit: + + +# Json: +{"n": 33.33} + +# Nit: + + +# Json: +{"hs": [-1, 0], "s": ["one", "two"], "hm": {"one": 1, "two": 2}, "am": {"three": "3", "four": "4"}} + diff --git a/tests/sav/test_new_native.res b/tests/sav/test_new_native.res index 4fd1ad6..060a759 100644 --- a/tests/sav/test_new_native.res +++ b/tests/sav/test_new_native.res @@ -5,3 +5,5 @@ NativeArray[Int] 3 1 1,10,100 +1 +1 diff --git a/tests/sav/test_serialization_alt1.res b/tests/sav/test_serialization_alt1.res new file mode 100644 index 0000000..9b381b9 --- /dev/null +++ b/tests/sav/test_serialization_alt1.res @@ -0,0 +1,25 @@ +# Nit: + + +# Json: +{"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": null, "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": null, "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]}} + +# Nit: + +<- 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} + diff --git a/tests/test_deserialization.nit b/tests/test_deserialization.nit index f26bcbf..1360bf2 100644 --- a/tests/test_deserialization.nit +++ b/tests/test_deserialization.nit @@ -15,7 +15,6 @@ # limitations under the License. import serialization -import json_serialization # Simple class class A @@ -93,7 +92,6 @@ class E var a = new Array[Object].with_items("hello", 1234, 123.4) var b = new Array[nullable Serializable].with_items("hella", 2345, 234.5) - init do end redef fun to_s do return "" end @@ -103,7 +101,6 @@ class F[N: Numeric] auto_serializable var n: N - init(n: N) do self.n = n redef fun to_s do return "" end @@ -133,31 +130,23 @@ class G "hm: {hm.join(", ", ". ")}; am: {am.join(", ", ". ")}>" end -var a = new A(true, 'a', 0.1234, 1234, "asdf", null) -var b = new B(false, 'b', 123.123, 2345, "hjkl", 12, 1111, "qwer") -var c = new C(a, b) -var d = new D(false, 'b', 123.123, 2345, "new line ->\n<-", null, 1111, "\t\f\"\r\\/") -d.d = d -var e = new E -var fi = new F[Int](2222) -var ff = new F[Float](33.33) -var g = new G - -# Default works only with Nit serial -var tests = [a, b, c, d, e, fi, ff, g: Serializable] - -# Alt1 should work without nitserial -#alt1# tests = new Array[Serializable].with_items(a, b, c, d) - -for o in tests do - var stream = new StringWriter - var serializer = new JsonSerializer(stream) - serializer.serialize(o) - - var deserializer = new JsonDeserializer(stream.to_s) - var deserialized = deserializer.deserialize - - print "# Nit:\n{o}\n" - print "# Json:\n{stream}\n" - print "# Back in Nit:\n{deserialized or else "null"}\n" +class TestEntities + var a = new A(true, 'a', 0.1234, 1234, "asdf", null) + var b = new B(false, 'b', 123.123, 2345, "hjkl", 12, 1111, "qwer") + var c = new C(a, b) + var d = new D(false, 'b', 123.123, 2345, "new line ->\n<-", null, 1111, "\t\f\"\r\\/") + init do d.d = d + var e = new E + var fi = new F[Int](2222) + var ff = new F[Float](33.33) + var g = new G + + # should work without nitserial + var without_generics: Array[Serializable] = [a, b, c, d: Serializable] + + # Default works only with Nit serial + var with_generics: Array[Serializable] = [a, b, c, d, e, fi, ff, g: Serializable] end + +# We instanciate it here so that `nitserial` detects generic types as being alive +var entities = new TestEntities diff --git a/tests/test_deserialization_serial.nit b/tests/test_deserialization_serial.nit index 7d1d443..b0be7fa 100644 --- a/tests/test_deserialization_serial.nit +++ b/tests/test_deserialization_serial.nit @@ -33,13 +33,7 @@ redef class Deserializer if name == "ArrayMap[String, String]" then return new ArrayMap[String, String].from_deserializer(self) if name == "Array[Serializable]" then return new Array[Serializable].from_deserializer(self) if name == "Array[String]" then return new Array[String].from_deserializer(self) - if name == "HashMap[Serializable, Int]" then return new HashMap[Serializable, Int].from_deserializer(self) - if name == "Array[JsonObject]" then return new Array[JsonObject].from_deserializer(self) - if name == "HashMap[Int, Object]" then return new HashMap[Int, Object].from_deserializer(self) - if name == "Array[Node]" then return new Array[Node].from_deserializer(self) - if name == "Array[LRState]" then return new Array[LRState].from_deserializer(self) if name == "Array[Couple[String, String]]" then return new Array[Couple[String, String]].from_deserializer(self) - if name == "Array[nullable Jsonable]" then return new Array[nullable Jsonable].from_deserializer(self) return super end end diff --git a/tests/test_json_deserialization.nit b/tests/test_json_deserialization.nit new file mode 100644 index 0000000..8baadb1 --- /dev/null +++ b/tests/test_json_deserialization.nit @@ -0,0 +1,37 @@ +# 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 test_deserialization +import json::serialization +#alt1# import test_deserialization_serial + +var entities = new TestEntities + +var tests = entities.without_generics#alt1##alt2# +#alt1#var tests = entities.with_generics +#alt2#var tests = entities.with_generics + +for o in tests do + var stream = new StringWriter + var serializer = new JsonSerializer(stream) + #alt2#serializer.plain_json = true + serializer.serialize(o) + + var deserializer = new JsonDeserializer(stream.to_s)#alt2# + var deserialized = deserializer.deserialize#alt2# + + print "# Nit:\n{o}\n" + print "# Json:\n{stream}\n" + print "# Back in Nit:\n{deserialized or else "null"}\n"#alt2# +end diff --git a/tests/test_new_native.nit b/tests/test_new_native.nit index 49ab177..c1ecc49 100644 --- a/tests/test_new_native.nit +++ b/tests/test_new_native.nit @@ -31,3 +31,10 @@ print a.length print a[0] print a.to_a.join(",") +var i +i = 3 +a = new NativeArray[Int](i) +i = 1 +a[i] = i +print a[i] +print a[1] diff --git a/tests/test_serialization.nit b/tests/test_serialization.nit index 1d3de0a..5517cff 100644 --- a/tests/test_serialization.nit +++ b/tests/test_serialization.nit @@ -15,7 +15,7 @@ # limitations under the License. import serialization -import json_serialization +import json::serialization # Simple class class A @@ -97,6 +97,7 @@ d.d = d for o in new Array[Serializable].with_items(a, b, c, d) do var stream = new StringWriter var serializer = new JsonSerializer(stream) + #alt1#serializer.plain_json = true serializer.serialize(o) print "# Nit:\n{o}\n"