Merge: Serialization: change annotation to `serialize` and intro `noserialize`
authorJean Privat <jean@pryen.org>
Sat, 30 May 2015 00:36:52 +0000 (20:36 -0400)
committerJean Privat <jean@pryen.org>
Sat, 30 May 2015 00:36:52 +0000 (20:36 -0400)
The annotation `serialize` replaces `auto_serialize` and it is also more versatile. It can annotate a module so all its class definitions are serializable. It can also annotate an attribute so only this attribute is serialized.

The `noserialize` annotation is for exceptions to `serialize`. The most common case is to mark as non-serializable an attribute such as a password or a data blob.

Pull-Request: #1389
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>

24 files changed:
lib/a_star.nit
lib/android/bundle/bundle.nit
lib/android/shared_preferences/shared_preferences_api10.nit
lib/bucketed_game.nit
lib/json/serialization.nit
lib/more_collections.nit
lib/serialization/README.md
lib/serialization/serialization.nit
src/frontend/serialization_phase.nit
src/nitserial.nit
tests/sav/nitg-e/test_json_deserialization_alt1.res
tests/sav/nitg-e/test_serialization_alt2.res [new file with mode: 0644]
tests/sav/nitg-e/test_serialization_alt3.res [new file with mode: 0644]
tests/sav/nitg-e/test_serialization_alt4.res [new file with mode: 0644]
tests/sav/nitg-e/test_serialization_alt5.res [new file with mode: 0644]
tests/sav/test_json_deserialization.res
tests/sav/test_json_deserialization_alt1.res
tests/sav/test_json_deserialization_alt2.res
tests/sav/test_serialization_alt2.res [new file with mode: 0644]
tests/sav/test_serialization_alt3.res [new file with mode: 0644]
tests/sav/test_serialization_alt4.res [new file with mode: 0644]
tests/sav/test_serialization_alt5.res [new file with mode: 0644]
tests/test_deserialization.nit
tests/test_serialization.nit

index a0b1b48..9780e12 100644 (file)
@@ -211,7 +211,7 @@ end
 
 # Link between two nodes and associated to a graph
 class Link
-       auto_serializable
+       serialize
 
        # Type of the nodes in `graph`
        type N: Node
@@ -287,7 +287,7 @@ end
 
 # Result from path finding and a walkable path
 class AStarPath[N]
-       auto_serializable
+       serialize
 
        # Total cost of this path
        var total_cost: Int
@@ -317,7 +317,7 @@ end
 
 # Context related to an evocation of pathfinding
 class PathContext
-       auto_serializable
+       serialize
 
        # Type of the nodes in `graph`
        type N: Node
@@ -352,7 +352,7 @@ end
 # Warning: A* is not optimize for such a case
 class ConstantPathContext
        super PathContext
-       auto_serializable
+       serialize
 
        redef fun worst_cost do return 1
        redef fun cost(l) do return 1
@@ -364,7 +364,7 @@ end
 # A `PathContext` for graphs with `WeightedLink`
 class WeightedPathContext
        super PathContext
-       auto_serializable
+       serialize
 
        redef type L: WeightedLink
 
@@ -393,7 +393,7 @@ end
 # A `Link` with a `weight`
 class WeightedLink
        super Link
-       auto_serializable
+       serialize
 
        # The `weight`, or cost, of this link
        var weight: Int
@@ -401,7 +401,7 @@ end
 
 # Advanced path conditions with customizable accept states
 class TargetCondition[N: Node]
-       auto_serializable
+       serialize
 
        # Should the pathfinding accept `node` as a goal?
        fun accept(node: N): Bool is abstract
index fde88af..edb0c88 100644 (file)
@@ -503,7 +503,7 @@ class Bundle
        # Retrieve an `Object` serialized via `[]=` function
        # Returns `null` if there's no serialized object corresponding to the given key
        # or if it's the wrong value type
-       # Make sure that the serialized object is `auto_serializable` or that it
+       # Make sure that the serialized object is `serialize` or that it
        # redefines the appropriate methods. Refer to `Serializable` documentation
        # for further details
        fun deserialize(key: String): nullable Object
@@ -520,7 +520,7 @@ class Bundle
        # Retrieve an `Array` of `Object` serialized via `[]=` function
        # Returns `null` if there's no serialized `Array` corresponding to the given key
        # or if it's the wrong value type
-       # Make sure that the serialized objects are `auto_serializable` or that they
+       # Make sure that the serialized objects are `serialize` or that they
        # redefine the appropriate methods. Refer to `Serializable` documentation
        # for further details
        fun deserialize_array(key: String): nullable Array[nullable Object]
index d4e71a8..ca3a2b9 100644 (file)
@@ -390,7 +390,7 @@ class SharedPreferences
        # Retrieve an `Object` stored via `[]=` function
        #
        # Returns `null` if there's no serialized object corresponding to the given key
-       # Make sure that the serialized object is `auto_serializable` or that it redefines
+       # Make sure that the serialized object is `serialize` or that it redefines
        # the appropriate methods. Refer to `Serializable` documentation for further details
        fun [](key: String): nullable Object
        do
index a621c54..ad79e6c 100644 (file)
 #
 # Allows for fast support of a large number of entities with rare actions,
 # such as a forest with many individual trees.
-module bucketed_game
+module bucketed_game is serialize
 
 import serialization
 
 # Something acting on the game
 class Turnable[G: Game]
-       auto_serializable
 
        # Execute `turn` for this instance.
        fun do_turn(turn: GameTurn[G]) is abstract
@@ -35,7 +34,6 @@ end
 # Something acting on the game from time to time
 class Bucketable[G: Game]
        super Turnable[G]
-       auto_serializable
 
        private var act_at: nullable Int = null
 
@@ -49,7 +47,6 @@ end
 # Optimized organization of `Bucketable` instances
 class Buckets[G: Game]
        super Turnable[G]
-       auto_serializable
 
        # Bucket type used in this implementation.
        type BUCKET: HashSet[Bucketable[G]]
@@ -118,12 +115,10 @@ end
 # Event raised at the first turn
 class FirstTurnEvent
        super GameEvent
-       auto_serializable
 end
 
 # Game logic on the client
 class ThinGame
-       auto_serializable
 
        # Game tick when `self` should act.
        #
@@ -133,7 +128,6 @@ end
 
 # Game turn on the client
 class ThinGameTurn[G: ThinGame]
-       auto_serializable
 
        # Game tick when `self` should act.
        var tick: Int is protected writable
@@ -145,7 +139,6 @@ end
 # Game turn on the full logic
 class GameTurn[G: Game]
        super ThinGameTurn[G]
-       auto_serializable
 
        # Game that `self` belongs to.
        var game: G
@@ -173,7 +166,6 @@ end
 # Full game logic
 class Game
        super ThinGame
-       auto_serializable
 
        # Game type used in this implementation.
        type G: Game
index 4b7cb15..359acf5 100644 (file)
@@ -39,7 +39,7 @@
 # import json::serialization
 #
 # class Person
-#     auto_serializable
+#     serialize
 #
 #     var name: String
 #     var year_of_birth: Int
index 4f75430..019dc67 100644 (file)
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 # Highly specific, but useful, collections-related classes.
-module more_collections
+module more_collections is serialize
 
 import serialization
 
@@ -32,7 +32,6 @@ import serialization
 #     assert m["four"] == ['i', 'i', 'i', 'i']
 #     assert m["zzz"] == new Array[Char]
 class MultiHashMap[K, V]
-       auto_serializable
        super HashMap[K, Array[V]]
 
        # Add `v` to the array associated with `k`.
@@ -64,7 +63,6 @@ end
 # assert hm2[2, "not-two"] == null
 # ~~~~
 class HashMap2[K1, K2, V]
-       auto_serializable
 
        private var level1 = new HashMap[K1, HashMap[K2, V]]
 
@@ -113,7 +111,6 @@ end
 # assert hm3[2, "not-two", 22] == null
 # ~~~~
 class HashMap3[K1, K2, K3, V]
-       auto_serializable
 
        private var level1 = new HashMap[K1, HashMap2[K2, K3, V]]
 
@@ -193,7 +190,6 @@ end
 # assert dma.default == [65]
 # ~~~~
 class DefaultMap[K, V]
-       auto_serializable
        super HashMap[K, V]
 
        # The default value.
index 4cbcf64..ef8c445 100644 (file)
@@ -1,11 +1,11 @@
 # Abstract serialization services
 
-The serialization services are centered around the `auto_serializable` annotation,
+The serialization services are based on the `serialize` and the `noserialize` annotations,
 the `Serializable` interface and the implementations of `Serializer` and `Deserializer`.
 
-## The `auto_serializable` annotation
+## The `serialize` annotation
 
-A class annotated with `auto_serializable` identifies it as a subclass of Serializable and
+A class annotated with `serialize` identifies it as a subclass of Serializable and
 triggers the generation of customized serialization and deserialization services.
 
 ~~~
@@ -13,7 +13,7 @@ import serialization
 
 # Simple serializable class identifying a human
 class Person
-       auto_serializable
+       serialize
 
        # First and last name
        var name: String
@@ -31,19 +31,19 @@ By definition of a serializable class, an instance can be serialized to a stream
 The deserialized instance will not be the same instance, but they should be equal.
 So, in this case, we can compare both instances with `==` to test their equality.
 
-Some conditions applies to the classes that can be annotated as `auto_serializable`.
+Some conditions applies to the classes that can be annotated as `serialize`.
 All attributes of the class must be serializable, runtime errors will be
 raised when trying to serialize non-serializable attributes.
 
 In the class `Person`, all attributes are typed with classes the standards library.
 These common types are defined defined as serializable by this project.
-The attributes could also be typed with user-defined `auto_serializable`
+The attributes could also be typed with user-defined `serialize`
 classes or any other subclass of `Serializable`.
 
 ~~~
-# This `auto_serializable` class is composed of two `auto_serializable` attributes
+# This `serialize` class is composed of two `serialize` attributes
 class Partnership
-       auto_serializable
+       serialize
 
        var partner_a: Person
        var partner_b: Person
@@ -53,14 +53,59 @@ class Partnership
 end
 ~~~
 
-The `auto_serializable` applies only to the class definition,
-only attributes declared locally will be serialized.
-However, each definition of a class (a refinement or specialization)
-can declare `auto_serializable`.
+### Scope of the `serialize` annotation
+
+`serialize` can annotate class definitions, modules and attributes:
+
+* The annotation on a class applies only to the class definition,
+  only attributes declared locally will be serialized.
+  However, each definition of a class (a refinement or specialization) can be annotated with `serialize`.
+
+* A module declaration annotated with `serialize` states that all its class definitions
+  and locally declared attributes are serializable.
+
+  ~~~
+  module shared_between_clients is serialize
+  ~~~
+
+* Attribute annotated with `serialize` states that it is to be serialized, when the rest of the class does not.
+  The class will become subclass to `Serializable` but its attributes are not to be serialized by default.
+  Only the attributes with the `serialize` annotation will be serialized.
+
+  ~~~
+  # Only serialize the `name`
+  class UserCredentials
+      var name: String is serialize
+      var avatar_path: String = "/somepath/"+name is lazy
+  end
+  ~~~
+
+## The `noserialize` annotation
+
+The `noserialize` annotation mark an exception in a `serialize` module or class definition.
+
+* By default a module is `noserialize`. There is no need to declare it as such.
+
+* A class definition annotated with `noserialize` within a `serialize` module will not be made serializable.
+
+* A `noserialize` attribute within a class or module annotated with `serialize` will not serialize this attribute.
+  The class will still be made subclass of `Serializable` and it won't affect the other attributes.
+  The `noserialize` attribute will not be set at deserialization.
+  Usually, it will also be annotated with `lazy` to get its value by another mean after the object has been deserialized.
+
+  ~~~
+  # Once again, only serialize the `name`
+  class UserCredentials
+      serialize
+
+      var name: String
+      var avatar_path: String = "/somepath/"+name is noserialize, lazy
+  end
+  ~~~
 
 ## Custom serializable classes
 
-The annotation `auto_serializable` should be enough for most cases,
+The annotation `serialize` should be enough for most cases,
 but in some cases you need more control over the serialization process.
 
 For more control, create a subclass to `Serializable` and redefine `core_serialize_to`.
@@ -72,7 +117,7 @@ The method should only act on known class names, and call super otherwise.
 
 ### Example: the User class
 
-The following example cannot use the `auto_serializable` annotations
+The following example cannot use the `serialize` annotations
 because some of the arguments to the `User` class need special treatment:
 
 * The `name` attribute is perfectly normal, it can be serialized and deserialized
@@ -160,7 +205,7 @@ information on the services to redefine.
 
 ## Serialization services
 
-The `auto_serializable` annotation and the `Serializable` class are used on
+The `serialize` annotation and the `Serializable` class are used on
 classes specific to the business domain.
 To write (and read) instances of these classes to a persistent format
 you must use implementations of `Serializer` and `Deserializer`.
@@ -198,7 +243,7 @@ The serialization has some limitations:
 * Not enough classes from the standard library are supported.
   This only requires someone to actually code the support.
   It should not be especially hard for most classes, some can
-  simply declare the `auto_serializable` annotation.
+  simply declare the `serialize` annotation.
 
 * A limitation of the Json parser prevents deserializing from files
   with more than one object.
@@ -206,9 +251,9 @@ The serialization has some limitations:
   serialize a single object to each filesand use different instances of
   serializer and deserializer each time.
 
-* The `auto_serializable` annotation does not handle very well
+* The `serialize` annotation does not handle very well
   complex constructors. This could be improved in the compiler.
-  For now, you may prefer to use `auto_serializable` on simple classes,
+  For now, you may prefer to use `serialize` on simple classes,
   of by using custom `Serializable`.
 
 * The serialization uses only the short name of a class, not its qualified name.
index 8977baa..ca60d7a 100644 (file)
@@ -16,7 +16,7 @@
 
 # Abstract services to serialize Nit objects to different formats
 #
-# This module declares the `auto_serializable` annotation to mark Nit classes as serializable.
+# This module declares the `serialize` annotation to mark Nit classes as serializable.
 # For an introduction to this service, refer to the documentation of the `serialization` group.
 # This documentation provides more technical information on interesting entitie of this module.
 #
@@ -44,6 +44,8 @@
 #   `notify_of_creation` must be redefined.
 module serialization is
        new_annotation auto_serializable
+       new_annotation serialize
+       new_annotation noserialize
 end
 
 # Abstract serialization service to be sub-classed by specialized services.
index 90924f2..8d576ba 100644 (file)
@@ -34,27 +34,118 @@ redef class ToolContext
        private fun place_holder_type_name: String do return "PlaceHolderTypeWhichShouldNotExist"
 end
 
+redef class ANode
+       # Is this node annotated to be made serializable?
+       private fun is_serialize: Bool do return false
+
+       # Is this node annotated to not be made serializable?
+       private fun is_noserialize: Bool do return false
+
+       private fun accept_precise_type_visitor(v: PreciseTypeVisitor) do visit_all(v)
+end
+
+redef class ADefinition
+
+       redef fun is_serialize do
+               return get_annotations("serialize").not_empty or
+                       get_annotations("auto_serializable").not_empty
+       end
+
+       redef fun is_noserialize do
+               return get_annotations("noserialize").not_empty
+       end
+end
+
 # TODO add annotations on attributes (volatile, sensitive or do_not_serialize?)
 private class SerializationPhasePreModel
        super Phase
 
-       redef fun process_annotated_node(nclassdef, nat)
+       redef fun process_annotated_node(node, nat)
        do
                # Skip if we are not interested
-               if nat.n_atid.n_id.text != "auto_serializable" then return
-               if not nclassdef isa AStdClassdef then
-                       toolcontext.error(nclassdef.location, "Syntax Error: only a concrete class can be automatically serialized.")
+               var text = nat.n_atid.n_id.text
+               var serialize = text == "auto_serializable" or text == "serialize"
+               var noserialize = text == "noserialize"
+               if not (serialize or noserialize) then return
+
+               # Check legality of annotation
+               if node isa AModuledecl then
+                       if noserialize then toolcontext.error(node.location, "Syntax Error: superfluous use of `{text}`, by default a module is `{text}`")
+                       return
+               else if not (node isa AStdClassdef or node isa AAttrPropdef) then
+                       toolcontext.error(node.location,
+                               "Syntax Error: only a class, a module or an attribute can be annotated with `{text}`.")
                        return
+               else if serialize and node.is_noserialize then
+                       toolcontext.error(node.location,
+                               "Syntax Error: an entity cannot be both `{text}` and `noserialize`.")
+                       return
+               else if node.as(Prod).get_annotations(text).length > 1 then
+                       toolcontext.warning(node.location, "useless-{text}",
+                               "Warning: duplicated annotation `{text}`.")
                end
 
-               # Add `super Serializable`
-               var sc = toolcontext.parse_superclass("Serializable")
-               sc.location = nat.location
-               nclassdef.n_propdefs.add sc
+               # Check the `serialize` state of the parent
+               if not node isa AModuledecl then
+                       var up_serialize = false
+                       var up: nullable ANode = node
+                       loop
+                               up = up.parent
+                               if up == null then
+                                       break
+                               else if up.is_serialize then
+                                       up_serialize = true
+                                       break
+                               else if up.is_noserialize then
+                                       break
+                               end
+                       end
 
-               generate_serialization_method(nclassdef)
+                       # Check for useless double declarations
+                       if serialize and up_serialize then
+                               toolcontext.warning(node.location, "useless-serialize",
+                                       "Warning: superfluous use of `{text}`.")
+                       else if noserialize and not up_serialize then
+                               toolcontext.warning(node.location, "useless-noserialize",
+                                       "Warning: superfluous use of `{text}`.")
+                       end
+               end
+       end
 
-               generate_deserialization_init(nclassdef)
+       redef fun process_nclassdef(nclassdef)
+       do
+               if not nclassdef isa AStdClassdef then return
+
+               # Is there a declaration on the classdef or the module?
+               var serialize = nclassdef.is_serialize
+
+               if not serialize and not nclassdef.is_noserialize then
+                       # Is the module marked serialize?
+                       serialize = nclassdef.parent.as(AModule).is_serialize
+               end
+
+               var per_attribute = false
+               if not serialize then
+                       # Is there an attribute marked serialize?
+                       for npropdef in nclassdef.n_propdefs do
+                               if npropdef.is_serialize then
+                                       serialize = true
+                                       per_attribute = true
+                                       break
+                               end
+                       end
+               end
+
+               if serialize then
+                       # Add `super Serializable`
+                       var sc = toolcontext.parse_superclass("Serializable")
+                       sc.location = nclassdef.location
+                       nclassdef.n_propdefs.add sc
+
+                       # Add services
+                       generate_serialization_method(nclassdef, per_attribute)
+                       generate_deserialization_init(nclassdef, per_attribute)
+               end
        end
 
        redef fun process_nmodule(nmodule)
@@ -65,8 +156,7 @@ private class SerializationPhasePreModel
                # collect all classes
                var auto_serializable_nclassdefs = new Array[AStdClassdef]
                for nclassdef in nmodule.n_classdefs do
-                       if nclassdef isa AStdClassdef and
-                          not nclassdef.get_annotations("auto_serializable").is_empty then
+                       if nclassdef isa AStdClassdef and nclassdef.is_serialize then
                                auto_serializable_nclassdefs.add nclassdef
                        end
                end
@@ -76,7 +166,7 @@ private class SerializationPhasePreModel
                end
        end
 
-       fun generate_serialization_method(nclassdef: AClassdef)
+       fun generate_serialization_method(nclassdef: AClassdef, per_attribute: Bool)
        do
                var npropdefs = nclassdef.n_propdefs
 
@@ -86,6 +176,11 @@ private class SerializationPhasePreModel
                code.add "      super"
 
                for attribute in npropdefs do if attribute isa AAttrPropdef then
+
+                       # Is `attribute` to be skipped?
+                       if (per_attribute and not attribute.is_serialize) or
+                               attribute.is_noserialize then continue
+
                        var name = attribute.name
                        code.add "      v.serialize_attribute(\"{name}\", {name})"
                end
@@ -97,7 +192,7 @@ private class SerializationPhasePreModel
        end
 
        # Add a constructor to the automated nclassdef
-       fun generate_deserialization_init(nclassdef: AStdClassdef)
+       fun generate_deserialization_init(nclassdef: AClassdef, per_attribute: Bool)
        do
                var npropdefs = nclassdef.n_propdefs
 
@@ -108,6 +203,11 @@ private class SerializationPhasePreModel
                code.add "      v.notify_of_creation self"
 
                for attribute in npropdefs do if attribute isa AAttrPropdef then
+
+                       # Is `attribute` to be skipped?
+                       if (per_attribute and not attribute.is_serialize) or
+                               attribute.is_noserialize then continue
+
                        var n_type = attribute.n_type
                        var type_name
                        if n_type == null then
@@ -201,10 +301,6 @@ private class PreciseTypeVisitor
        redef fun visit(n) do n.accept_precise_type_visitor(self)
 end
 
-redef class ANode
-       private fun accept_precise_type_visitor(v: PreciseTypeVisitor) do visit_all(v)
-end
-
 redef class AIsaExpr
        redef fun accept_precise_type_visitor(v)
        do
@@ -257,6 +353,8 @@ redef class AModule
        end
 
        private var inits_to_retype = new Array[AMethPropdef]
+
+       redef fun is_serialize do return n_moduledecl != null and n_moduledecl.is_serialize
 end
 
 redef class AStdClassdef
index 0b60a1b..8ead776 100644 (file)
@@ -94,7 +94,7 @@ end
 
 redef class MClassType
        redef fun is_visible_from(mmodule) do
-               return mmodule.is_visible(mclass.intro_mmodule, public_visibility)
+               return mmodule.is_visible(mclass.intro_mmodule, mclass.visibility)
        end
 end
 
index 90e0d60..f4b4a49 100644 (file)
@@ -1,40 +1,40 @@
-Runtime error: Aborted (../lib/serialization/serialization.nit:109)
+Runtime error: Aborted (../lib/serialization/serialization.nit:111)
 # Nit:
-<A: true a 0.123 1234 asdf false>
+<A: true a 0.123 1234 asdf false p4ssw0rd>
 
 # Json:
 {"__kind": "obj", "__id": 0, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "s": "asdf", "n": null}
 
 # Back in Nit:
-<A: true a 0.123 1234 asdf false>
+<A: true a 0.123 1234 asdf false p4ssw0rd>
 
 # Nit:
-<B: <A: false b 123.123 2345 hjkl false> 1111 qwer>
+<B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 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:
-<B: <A: false b 123.123 2345 hjkl false> 1111 qwer>
+<B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>
 
 # Nit:
-<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 1111 qwer>>
+<C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>>
 
 # Json:
 {"__kind": "obj", "__id": 0, "__class": "C", "a": {"__kind": "obj", "__id": 1, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "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:
-<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 1111 qwer>>
+<C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>>
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
-<- false> 1111         f"\r\/> true>
+<- false p4ssw0rd> 1111        f"\r\/> true>
 
 # Json:
 {"__kind": "obj", "__id": 0, "__class": "D", "b": false, "c": {"__kind": "char", "__val": "b"}, "f": 123.123, "i": 2345, "s": "new line ->\n<-", "n": null, "ii": 1111, "ss": "\tf\"\r\\\/", "d": {"__kind": "ref", "__id": 0}}
 
 # Back in Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
-<- false> 1111         f"\r\/> true>
+<- false p4ssw0rd> 1111        f"\r\/> true>
 
 Error: doesn't know how to deserialize class "Array"
diff --git a/tests/sav/nitg-e/test_serialization_alt2.res b/tests/sav/nitg-e/test_serialization_alt2.res
new file mode 100644 (file)
index 0000000..34da2d6
--- /dev/null
@@ -0,0 +1,28 @@
+alt/test_serialization_alt2.nit:22,1--47,3: Warning: superfluous use of `serialize`.
+alt/test_serialization_alt2.nit:70,1--86,3: Warning: superfluous use of `auto_serializable`.
+alt/test_serialization_alt2.nit:88,1--96,3: Warning: superfluous use of `auto_serializable`.
+# Nit:
+<A: true a 0.123 1234 asdf false>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "A", "b": true, "f": 0.123, "i": 1234, "s": "asdf", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}}
+
+# Nit:
+<B: <A: false b 123.123 2345 hjkl false> 1111 qwer>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "B", "b": false, "f": 123.123, "i": 2345, "s": "hjkl", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}}
+
+# Nit:
+<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 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", "__length": 3, "__items": [88, "hello", null]}}, "b": {"__kind": "obj", "__id": 3, "__class": "B", "b": false, "f": 123.123, "i": 2345, "s": "hjkl", "n": null, "array": {"__kind": "obj", "__id": 4, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}}, "aa": {"__kind": "ref", "__id": 1}}
+
+# Nit:
+<D: <B: <A: false b 123.123 2345 new line ->
+<- false> 1111         f"\r\/> true>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "D", "b": false, "f": 123.123, "i": 2345, "s": "new line ->\n<-", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}, "d": {"__kind": "ref", "__id": 0}}
+
diff --git a/tests/sav/nitg-e/test_serialization_alt3.res b/tests/sav/nitg-e/test_serialization_alt3.res
new file mode 100644 (file)
index 0000000..afd0ee8
--- /dev/null
@@ -0,0 +1,26 @@
+alt/test_serialization_alt3.nit:49,1--68,3: Warning: superfluous use of `noserialize`.
+# Nit:
+<A: true a 0.123 1234 asdf false>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "s": "asdf", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}}
+
+# Nit:
+<B: <A: false b 123.123 2345 hjkl false> 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, "array": {"__kind": "obj", "__id": 1, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}}
+
+# Nit:
+<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 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", "__length": 3, "__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": null, "array": {"__kind": "obj", "__id": 4, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}}, "aa": {"__kind": "ref", "__id": 1}}
+
+# Nit:
+<D: <B: <A: false b 123.123 2345 new line ->
+<- false> 1111         f"\r\/> true>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "D", "b": false, "c": {"__kind": "char", "__val": "b"}, "f": 123.123, "i": 2345, "s": "new line ->\n<-", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}, "d": {"__kind": "ref", "__id": 0}}
+
diff --git a/tests/sav/nitg-e/test_serialization_alt4.res b/tests/sav/nitg-e/test_serialization_alt4.res
new file mode 100644 (file)
index 0000000..e843c62
--- /dev/null
@@ -0,0 +1,26 @@
+alt/test_serialization_alt4.nit:29,2--31,26: Warning: superfluous use of `serialize`.
+# Nit:
+<A: true a 0.123 1234 asdf false>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "s": "asdf", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}}
+
+# Nit:
+<B: <A: false b 123.123 2345 hjkl false> 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, "array": {"__kind": "obj", "__id": 1, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}, "ii": 1111, "ss": "qwer"}
+
+# Nit:
+<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 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", "__length": 3, "__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": null, "array": {"__kind": "obj", "__id": 4, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}, "ii": 1111, "ss": "qwer"}, "aa": {"__kind": "ref", "__id": 1}}
+
+# Nit:
+<D: <B: <A: false b 123.123 2345 new line ->
+<- false> 1111         f"\r\/> true>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "D", "b": false, "c": {"__kind": "char", "__val": "b"}, "f": 123.123, "i": 2345, "s": "new line ->\n<-", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}, "ii": 1111, "ss": "\tf\"\r\\\/", "d": {"__kind": "ref", "__id": 0}}
+
diff --git a/tests/sav/nitg-e/test_serialization_alt5.res b/tests/sav/nitg-e/test_serialization_alt5.res
new file mode 100644 (file)
index 0000000..d4ba4e1
--- /dev/null
@@ -0,0 +1,26 @@
+alt/test_serialization_alt5.nit:22,1--47,3: Warning: duplicated annotation `serialize`.
+# Nit:
+<A: true a 0.123 1234 asdf false>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "s": "asdf", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}}
+
+# Nit:
+<B: <A: false b 123.123 2345 hjkl false> 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, "array": {"__kind": "obj", "__id": 1, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}, "ii": 1111, "ss": "qwer"}
+
+# Nit:
+<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 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", "__length": 3, "__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": null, "array": {"__kind": "obj", "__id": 4, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}, "ii": 1111, "ss": "qwer"}, "aa": {"__kind": "ref", "__id": 1}}
+
+# Nit:
+<D: <B: <A: false b 123.123 2345 new line ->
+<- false> 1111         f"\r\/> true>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "D", "b": false, "c": {"__kind": "char", "__val": "b"}, "f": 123.123, "i": 2345, "s": "new line ->\n<-", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array", "__length": 3, "__items": [88, "hello", null]}, "ii": 1111, "ss": "\tf\"\r\\\/", "d": {"__kind": "ref", "__id": 0}}
+
index 047314c..f4172ad 100644 (file)
@@ -1,38 +1,38 @@
 # Nit:
-<A: true a 0.123 1234 asdf false>
+<A: true a 0.123 1234 asdf false p4ssw0rd>
 
 # Json:
 {"__kind": "obj", "__id": 0, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "s": "asdf", "n": null}
 
 # Back in Nit:
-<A: true a 0.123 1234 asdf false>
+<A: true a 0.123 1234 asdf false p4ssw0rd>
 
 # Nit:
-<B: <A: false b 123.123 2345 hjkl false> 1111 qwer>
+<B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 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:
-<B: <A: false b 123.123 2345 hjkl false> 1111 qwer>
+<B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>
 
 # Nit:
-<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 1111 qwer>>
+<C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>>
 
 # Json:
 {"__kind": "obj", "__id": 0, "__class": "C", "a": {"__kind": "obj", "__id": 1, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "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:
-<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 1111 qwer>>
+<C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>>
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
-<- false> 1111         f"\r\/> true>
+<- false p4ssw0rd> 1111        f"\r\/> true>
 
 # Json:
 {"__kind": "obj", "__id": 0, "__class": "D", "b": false, "c": {"__kind": "char", "__val": "b"}, "f": 123.123, "i": 2345, "s": "new line ->\n<-", "n": null, "ii": 1111, "ss": "\tf\"\r\\\/", "d": {"__kind": "ref", "__id": 0}}
 
 # Back in Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
-<- false> 1111         f"\r\/> true>
+<- false p4ssw0rd> 1111        f"\r\/> true>
 
index 58293c5..8c7e49a 100644 (file)
@@ -1,40 +1,40 @@
 # Nit:
-<A: true a 0.123 1234 asdf false>
+<A: true a 0.123 1234 asdf false p4ssw0rd>
 
 # Json:
 {"__kind": "obj", "__id": 0, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "s": "asdf", "n": null}
 
 # Back in Nit:
-<A: true a 0.123 1234 asdf false>
+<A: true a 0.123 1234 asdf false p4ssw0rd>
 
 # Nit:
-<B: <A: false b 123.123 2345 hjkl false> 1111 qwer>
+<B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 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:
-<B: <A: false b 123.123 2345 hjkl false> 1111 qwer>
+<B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>
 
 # Nit:
-<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 1111 qwer>>
+<C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>>
 
 # Json:
 {"__kind": "obj", "__id": 0, "__class": "C", "a": {"__kind": "obj", "__id": 1, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "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:
-<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 1111 qwer>>
+<C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>>
 
 # Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
-<- false> 1111         f"\r\/> true>
+<- false p4ssw0rd> 1111        f"\r\/> true>
 
 # Json:
 {"__kind": "obj", "__id": 0, "__class": "D", "b": false, "c": {"__kind": "char", "__val": "b"}, "f": 123.123, "i": 2345, "s": "new line ->\n<-", "n": null, "ii": 1111, "ss": "\tf\"\r\\\/", "d": {"__kind": "ref", "__id": 0}}
 
 # Back in Nit:
 <D: <B: <A: false b 123.123 2345 new line ->
-<- false> 1111         f"\r\/> true>
+<- false p4ssw0rd> 1111        f"\r\/> true>
 
 # Nit:
 <E: a: hello, 1234, 123.4; b: hella, 2345, 234.5>
index 99e49d6..2dde071 100644 (file)
@@ -1,24 +1,24 @@
 # Nit:
-<A: true a 0.123 1234 asdf false>
+<A: true a 0.123 1234 asdf false p4ssw0rd>
 
 # Json:
 {"b": true, "c": "a", "f": 0.123, "i": 1234, "s": "asdf", "n": null}
 
 # Nit:
-<B: <A: false b 123.123 2345 hjkl false> 1111 qwer>
+<B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>
 
 # Json:
 {"b": false, "c": "b", "f": 123.123, "i": 2345, "s": "hjkl", "n": null, "ii": 1111, "ss": "qwer"}
 
 # Nit:
-<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 1111 qwer>>
+<C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 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:
 <D: <B: <A: false b 123.123 2345 new line ->
-<- false> 1111         f"\r\/> true>
+<- false p4ssw0rd> 1111        f"\r\/> true>
 
 # Json:
 {"b": false, "c": "b", "f": 123.123, "i": 2345, "s": "new line ->\n<-", "n": null, "ii": 1111, "ss": "\tf\"\r\\\/", "d": null}
diff --git a/tests/sav/test_serialization_alt2.res b/tests/sav/test_serialization_alt2.res
new file mode 100644 (file)
index 0000000..e5910cf
--- /dev/null
@@ -0,0 +1,28 @@
+alt/test_serialization_alt2.nit:22,1--47,3: Warning: superfluous use of `serialize`.
+alt/test_serialization_alt2.nit:70,1--86,3: Warning: superfluous use of `auto_serializable`.
+alt/test_serialization_alt2.nit:88,1--96,3: Warning: superfluous use of `auto_serializable`.
+# Nit:
+<A: true a 0.123 1234 asdf false>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "A", "b": true, "f": 0.123, "i": 1234, "s": "asdf", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]", "__length": 3, "__items": [88, "hello", null]}}
+
+# Nit:
+<B: <A: false b 123.123 2345 hjkl false> 1111 qwer>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "B", "b": false, "f": 123.123, "i": 2345, "s": "hjkl", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]", "__length": 3, "__items": [88, "hello", null]}}
+
+# Nit:
+<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 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]", "__length": 3, "__items": [88, "hello", null]}}, "b": {"__kind": "obj", "__id": 3, "__class": "B", "b": false, "f": 123.123, "i": 2345, "s": "hjkl", "n": null, "array": {"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]", "__length": 3, "__items": [88, "hello", null]}}, "aa": {"__kind": "ref", "__id": 1}}
+
+# Nit:
+<D: <B: <A: false b 123.123 2345 new line ->
+<- false> 1111         f"\r\/> true>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "D", "b": false, "f": 123.123, "i": 2345, "s": "new line ->\n<-", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]", "__length": 3, "__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
new file mode 100644 (file)
index 0000000..c8f072c
--- /dev/null
@@ -0,0 +1,26 @@
+alt/test_serialization_alt3.nit:49,1--68,3: Warning: superfluous use of `noserialize`.
+# Nit:
+<A: true a 0.123 1234 asdf false>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "s": "asdf", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]", "__length": 3, "__items": [88, "hello", null]}}
+
+# Nit:
+<B: <A: false b 123.123 2345 hjkl false> 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, "array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]", "__length": 3, "__items": [88, "hello", null]}}
+
+# Nit:
+<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 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]", "__length": 3, "__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": null, "array": {"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]", "__length": 3, "__items": [88, "hello", null]}}, "aa": {"__kind": "ref", "__id": 1}}
+
+# Nit:
+<D: <B: <A: false b 123.123 2345 new line ->
+<- false> 1111         f"\r\/> true>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "D", "b": false, "c": {"__kind": "char", "__val": "b"}, "f": 123.123, "i": 2345, "s": "new line ->\n<-", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]", "__length": 3, "__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
new file mode 100644 (file)
index 0000000..966388f
--- /dev/null
@@ -0,0 +1,26 @@
+alt/test_serialization_alt4.nit:29,2--31,26: Warning: superfluous use of `serialize`.
+# Nit:
+<A: true a 0.123 1234 asdf false>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "s": "asdf", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]", "__length": 3, "__items": [88, "hello", null]}}
+
+# Nit:
+<B: <A: false b 123.123 2345 hjkl false> 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, "array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]", "__length": 3, "__items": [88, "hello", null]}, "ii": 1111, "ss": "qwer"}
+
+# Nit:
+<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 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]", "__length": 3, "__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": null, "array": {"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]", "__length": 3, "__items": [88, "hello", null]}, "ii": 1111, "ss": "qwer"}, "aa": {"__kind": "ref", "__id": 1}}
+
+# Nit:
+<D: <B: <A: false b 123.123 2345 new line ->
+<- false> 1111         f"\r\/> true>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "D", "b": false, "c": {"__kind": "char", "__val": "b"}, "f": 123.123, "i": 2345, "s": "new line ->\n<-", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]", "__length": 3, "__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
new file mode 100644 (file)
index 0000000..d1b73a6
--- /dev/null
@@ -0,0 +1,26 @@
+alt/test_serialization_alt5.nit:22,1--47,3: Warning: duplicated annotation `serialize`.
+# Nit:
+<A: true a 0.123 1234 asdf false>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "A", "b": true, "c": {"__kind": "char", "__val": "a"}, "f": 0.123, "i": 1234, "s": "asdf", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]", "__length": 3, "__items": [88, "hello", null]}}
+
+# Nit:
+<B: <A: false b 123.123 2345 hjkl false> 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, "array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]", "__length": 3, "__items": [88, "hello", null]}, "ii": 1111, "ss": "qwer"}
+
+# Nit:
+<C: <A: true a 0.123 1234 asdf false> <B: <A: false b 123.123 2345 hjkl false> 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]", "__length": 3, "__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": null, "array": {"__kind": "obj", "__id": 4, "__class": "Array[nullable Object]", "__length": 3, "__items": [88, "hello", null]}, "ii": 1111, "ss": "qwer"}, "aa": {"__kind": "ref", "__id": 1}}
+
+# Nit:
+<D: <B: <A: false b 123.123 2345 new line ->
+<- false> 1111         f"\r\/> true>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "D", "b": false, "c": {"__kind": "char", "__val": "b"}, "f": 123.123, "i": 2345, "s": "new line ->\n<-", "n": null, "array": {"__kind": "obj", "__id": 1, "__class": "Array[nullable Object]", "__length": 3, "__items": [88, "hello", null]}, "ii": 1111, "ss": "\tf\"\r\\\/", "d": {"__kind": "ref", "__id": 0}}
+
index 1360bf2..deb8997 100644 (file)
@@ -26,6 +26,7 @@ class A
        var i = 123
        var s = "asdf"
        var n: nullable Int
+       var password = "p4ssw0rd" is lazy, noserialize
 
        init(b: Bool, c: Char, f: Float, i: Int, s: String, n: nullable Int)
        do
@@ -36,7 +37,7 @@ class A
                self.s = s
        end
 
-       redef fun to_s do return "<A: {b} {c} {f} {i} {s} {n != null}>"
+       redef fun to_s do return "<A: {b} {c} {f} {i} {s} {n != null} {password}>"
 end
 
 # Sub-class of A
index 5517cff..75c7a9d 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+#alt2#module test_serialization_alt2 is serialize
+
 import serialization
 import json::serialization
 
 # Simple class
 class A
-       auto_serializable
+       serialize
+#alt5# serialize
 
        var b = false
-       var c: Char
-       var f: Float
+       var c: Char#alt2#
+       #alt2#var c: Char is noserialize
+       var f: Float#alt4#
+       #alt4#var f: Float is serialize
        var i = 123
        var s = "asdf"
        var n: nullable Int
@@ -43,7 +48,9 @@ end
 
 # Sub-class of A
 class B
-       auto_serializable
+       auto_serializable#alt2##alt3#
+#alt2# noserialize
+#alt3# noserialize
        super A
 
        var ii: Int