Move and improve some operations between two of the serialization phases, placing them after `modelize_property_phase` so they have access to the static type of serializable attributes.
The static type is then used by the JSON deserializer as a fallback if there is no metadata and no heuristic to find which Nit type to deserialize. This affects both the attributes of standard serializable classes and the items of `SimpleCollection`, when using the `JsonDeserializer` only. This means the we need much less `class_name_heuristic` for reading plain JSON.
The static types of generic attributes is also used as heuristic to support deserializing the given parameterized type. So as long as the static type is not an abstract class, does not need an anchor, is not a subclass hiding the parameter E (for JSON arrays)... it should work. This is actually most of the time, so avoid abstract generic static types like `Set` or `Sequence`. This also means less `class_name_heuristic` for any JSON and binary data.
All of it makes it easier to deal with the following input `json_string` without metadata:
~~~
var plain_json = """{
"corners": [{"x": 0, "y": 0},
{"x": 3, "y": 0},
{"x": 2, "y": 2}],
"name": "the same triangle"
}"""
~~~
which can be deserialized with the following Nit code:
~~~
module my_module is serialize
class Triangle
var corners = new Array[Point] # Could as well be HashSet[Point]
redef var to_s is serialize_as("name") # The static type comes from the model
end
class Point
var x: Int
var y: Int
end
var deser_engine = new JsonDeserializer(json_string)
var obj = new Triangle.deserialize_from(deser_engine) # The root object still needs a type
assert deser_engine.errors.is_empty # If false, don't trust `obj`
print obj
print obj.other_corners
~~~
Pull-Request: #2257
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>