Merge: lib/json: unify the writing API using serialization only
authorJean Privat <jean@pryen.org>
Fri, 23 Sep 2016 19:26:44 +0000 (15:26 -0400)
committerJean Privat <jean@pryen.org>
Fri, 23 Sep 2016 19:26:44 +0000 (15:26 -0400)
Some context first, before this PR, there were 2 API to write JSON:
* The module `static` provided `to_json` and `to_pretty_json` which supported writing only basic Nit types associated with JSON types and objects with a manually implemented `to_json`.
* The module `serialization` provides `serialize_to_json` which supports all `Serializable` types, a superset of the JSON types, and where standard Nit objects are serialized to JSON objects by generated code.

The advantages of the `serialization` API are:
* Objects written to JSON with some metadata (mainly the name of the Nit type) can be deserialized back to Nit objects.
* The boilerplate code to write the attributes is generated, usually a single `is serialize` after the module declarations does the trick. (`core_serialize_to`, the equivalent of `to_json`, doesn't have to be implemented in each classes, the generated version is usually enough.)
* Implementing `core_serialize_to` (or leaving it to the generated code) instead of `to_json` makes the object compatible with both the JSON and binary serialization services.
* In general, the `serialization` API allows to easily write Nit objects to JSON and build JSON objects using `Map` instances:
~~~
import json::serialization

class Person
    serialize

    var name: String
    var year_of_birth: Int
end

var bob = new Person("Bob", 1986)
assert bob.serialize_to_json(pretty=true, plain=true) == """
{
    "name": "Bob",
    "year_of_birth": 1986
}"""

var charlie = new Map[String, nullable Serializable]
charlie["name"] = "Charlie"
charlie["year_of_birth"] = 1968
assert charlie.serialize_to_json(pretty=true, plain=true) == """
{
    "name": "Charlie",
    "year_of_birth": 1968
}"""
~~~

So this PR drops the `static` writing API, and replaces its services (`to_json` and `to_pretty_json`) by aliases in `serialization`. Some subclasses have been updated to implement the recursive `serialize_to` instead of the `to_json`, the changes are minimal to avoid breaking any software, but they are not optimal. The result is a single JSON writing API!

The generated JSON should not have changed much (maybe a bit less or more white spaces), except for some error messages which were translated to invalid JSON and are now serialized to a valid JSON object.

I expect some tests to fail as this is a big change, and clients of the `json::static` writing services (@morriar) should probably double check my changes to their code.

In the future, I'm thinking of dropping the name `serialize_to_json` and `to_pretty_json` and move the optionnal parameters to `to_json`. The JSON module also really needs refactoring at this point.

Pull-Request: #2312
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
Reviewed-by: Romain Chanoir <romain.chanoir@viacesi.fr>
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>


Trivial merge