X-Git-Url: http://nitlanguage.org diff --git a/src/frontend/serialization_phase.nit b/src/frontend/serialization_phase.nit index 3a70e66..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,7 +61,34 @@ redef class ADefinition end end -# TODO add annotations on attributes (volatile, sensitive or do_not_serialize?) +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 @@ -165,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" @@ -180,6 +211,16 @@ private class SerializationPhasePreModel do var npropdefs = nclassdef.n_propdefs + # Do not insert a `from_deserializer` if it already exists + for npropdef in npropdefs do + if npropdef isa AMethPropdef then + var methid = npropdef.n_methid + if methid != null and methid.collect_text == "from_deserializer" then + return + end + end + end + var code = new Array[String] code.add """ redef init from_deserializer(v: Deserializer) @@ -205,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 @@ -251,7 +292,7 @@ do end for nclassdef in nclassdefs do - var name = nclassdef.n_id.text + var name = nclassdef.n_qid.n_id.text if nclassdef.n_formaldefs.is_empty and nclassdef.n_classkind isa AConcreteClasskind then @@ -313,16 +354,16 @@ 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 private fun type_name: String do - var name = n_id.text + var name = n_qid.n_id.text if n_kwnullable != null then name = "nullable {name}" @@ -339,7 +380,7 @@ redef class AModule private fun deserializer_nclassdef: nullable AStdClassdef do for nclassdef in n_classdefs do - if nclassdef isa AStdClassdef and nclassdef.n_id.text == "Deserializer" then + if nclassdef isa AStdClassdef and nclassdef.n_qid.n_id.text == "Deserializer" then return nclassdef end end