From 868ea8e8a7836aa06e17ee2fc7285c0d0cc2cea5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alexis=20Laferri=C3=A8re?= Date: Wed, 16 Mar 2016 18:57:55 -0400 Subject: [PATCH] frontend serialization: serialize_as renames attributes in JSON/bin MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- lib/serialization/serialization.nit | 1 + src/frontend/serialization_phase.nit | 50 ++++++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/lib/serialization/serialization.nit b/lib/serialization/serialization.nit index cdf1db0..8ae8d2f 100644 --- a/lib/serialization/serialization.nit +++ b/lib/serialization/serialization.nit @@ -46,6 +46,7 @@ module serialization is new_annotation auto_serializable new_annotation serialize new_annotation noserialize + new_annotation serialize_as end # Abstract serialization service to be sub-classed by specialized services. diff --git a/src/frontend/serialization_phase.nit b/src/frontend/serialization_phase.nit index b9733a5..8b3de28 100644 --- a/src/frontend/serialization_phase.nit +++ b/src/frontend/serialization_phase.nit @@ -24,8 +24,13 @@ import modelize private import annotation redef class ToolContext + + # Apply the annotation `serialize_as` + var serialization_phase_rename: Phase = new SerializationPhaseRename(self, null) + # Generate serialization and deserialization methods on `auto_serializable` annotated classes. - var serialization_phase_pre_model: Phase = new SerializationPhasePreModel(self, null) + var serialization_phase_pre_model: Phase = new SerializationPhasePreModel(self, + [serialization_phase_rename]) # The second phase of the serialization var serialization_phase_post_model: Phase = new SerializationPhasePostModel(self, @@ -56,6 +61,34 @@ redef class ADefinition end end +private class SerializationPhaseRename + super Phase + + redef fun process_annotated_node(node, nat) + do + var text = nat.n_atid.n_id.text + if text != "serialize_as" then return + + if not node isa AAttrPropdef then + toolcontext.error(node.location, + "Syntax Error: annotation `{text}` applies only to attributes.") + return + end + + # Can't use `arg_as_string` because it needs the literal phase + var args = nat.n_args + if args.length != 1 or not args.first isa AStringFormExpr then + toolcontext.error(node.location, + "Syntax Error: annotation `{text}` expects a single string literal as argument.") + return + end + + var t = args.first.collect_text + var val = t.substring(1, t.length-2) + node.serialize_name = val + end +end + private class SerializationPhasePreModel super Phase @@ -164,8 +197,7 @@ private class SerializationPhasePreModel 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})" + code.add " v.serialize_attribute(\"{attribute.serialize_name}\", {attribute.name})" end code.add "end" @@ -214,11 +246,11 @@ do var name = attribute.name code.add """ - var {{{name}}} = v.deserialize_attribute("{{{name}}}") + var {{{name}}} = v.deserialize_attribute("{{{attribute.serialize_name}}}") if not {{{name}}} isa {{{type_name}}} then # Check if it was a subjectent error v.errors.add new AttributeTypeError("TODO remove this arg on c_src regen", - self, "{{{name}}}", {{{name}}}, "{{{type_name}}}") + self, "{{{attribute.serialize_name}}}", {{{name}}}, "{{{type_name}}}") # Clear subjacent error if v.keep_going == false then return @@ -322,10 +354,10 @@ redef class AIsaExpr end redef class AAttrPropdef - private fun name: String - do - return n_id2.text - end + private fun name: String do return n_id2.text + + # Name of this attribute in the serialized format + private var serialize_name: String = name is lazy end redef class AType -- 1.7.9.5