<commit_before># This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2014 <NAME> <<EMAIL>>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Abstract services to serialize Nit objects to different formats
#
# 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.
#
# Interesting entities for end users of serializable classes:
#
# * Serialize an instance subclass of `Serializable` with either
#   `Serializer::serializable` and `Serializable::serialize`.
# * Deserialize an object using `Deserializer::deserialize`.
#   The object type must the be checked with an `assert` or otherwise.
#
# Interesting entities to create custom serializable classes:
#
# * Subclass `Serializable` to declare a class as serializable and to customize
#   the serialization and deserialization behavior.
# * Redefine `Serializable::core_serialize_to` to customize the serialization
#   of the receiver class.
# * Redefine `Deserializer::deserialize_class` to customize the deserialization
#   of a specific class by name.
#
# Interesting entities for serialization format:
#
# * Subclass `Serializer` and `Deserializer` with custom serices.
# * In `Serializer`, `serialize` and `serialize_reference` must be redefined.
# * In `Deserializer`; `deserialize`, `deserialize_attribute and
#   `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.
interface Serializer
	# Entry point method of this service, serialize the `object`
	#
	# This method, and refinements, should handle `null` and probably
	# use double dispatch to customize the bahavior per serializable objects.
	fun serialize(object: nullable Serializable) is abstract

	# Serialize an object, with full serialization or a simple reference
	protected fun serialize_reference(object: Serializable) is abstract

	# Serialize an attribute to compose a serializable object
	#
	# This method should be called from `Serializable::core_serialize_to`.
	fun serialize_attribute(name: String, value: nullable Object)
	do
		if not try_to_serialize(value) then
			warn("argument {name} of type {value.class_name} is not serializable.")
		end
	end

	# Serialize `value` is possie, i.e. it is `Serializable` or `null`
	fun try_to_serialize(value: nullable Object): Bool
	do
		if value isa Serializable then
			value.serialize_to_or_delay(self)
		else if value == null then
			serialize value
		else return false
		return true
	end

	# Warn of problems and potential errors (such as if an attribute
	# is not serializable)
	fun warn(msg: String) do print "Serialization warning: {msg}"
end

# Abstract deserialization service
#
# After initialization of one of its sub-classes, call `deserialize`
abstract class Deserializer
	# Main method of this class, returns a Nit object
	fun deserialize: nullable Object is abstract

	# Internal method to be implemented by sub-classes
	fun deserialize_attribute(name: String): nullable Object is abstract

	# Internal method called by objects in creation,
	# to be implemented by sub-classes
	fun notify_of_creation(new_object: Object) is abstract

	# Deserialize the next available object as an instance of `class_name`
	#
	# Returns the deserialized object on success, aborts on error.
	#
	# This method should be redefined for each custom subclass of `Serializable`.
	# All refinement should look for a precise `class_name` and call super
	# on unsupported classes.
	protected fun deserialize_class(class_name: String): nullable Object do
		return deserialize_class_intern(class_name)
	end

	# Generated service to deserialize the next available object as an instance of `class_name`
	#
	# Refinements to this method will be generated by the serialization phase.
	# To avoid conflicts, there should not be any other refinements to this method.
	# You can instead use `deserialize_class`.
	protected fun deserialize_class_intern(class_name: String): nullable Object do
		errors.add new Error("Deserialization Error: Doesn't know how to deserialize class \"{class_name}\"")
		return null
	end

	# Should `self` keep trying to deserialize an object after an error?
	#
	# This behavior takes effect after each attribute deserialization with<commit_msg>lib/serialization: fix deserialization of Error<commit_after># This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2014 <NAME> <<EMAIL>>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Abstract services to serialize Nit objects to different formats
#
# 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.
#
# Interesting entities for end users of serializable classes:
#
# * Serialize an instance subclass of `Serializable` with either
#   `Serializer::serializable` and `Serializable::serialize`.
# * Deserialize an object using `Deserializer::deserialize`.
#   The object type must the be checked with an `assert` or otherwise.
#
# Interesting entities to create custom serializable classes:
#
# * Subclass `Serializable` to declare a class as serializable and to customize
#   the serialization and deserialization behavior.
# * Redefine `Serializable::core_serialize_to` to customize the serialization
#   of the receiver class.
# * Redefine `Deserializer::deserialize_class` to customize the deserialization
#   of a specific class by name.
#
# Interesting entities for serialization format:
#
# * Subclass `Serializer` and `Deserializer` with custom serices.
# * In `Serializer`, `serialize` and `serialize_reference` must be redefined.
# * In `Deserializer`; `deserialize`, `deserialize_attribute and
#   `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.
interface Serializer
	# Entry point method of this service, serialize the `object`
	#
	# This method, and refinements, should handle `null` and probably
	# use double dispatch to customize the bahavior per serializable objects.
	fun serialize(object: nullable Serializable) is abstract

	# Serialize an object, with full serialization or a simple reference
	protected fun serialize_reference(object: Serializable) is abstract

	# Serialize an attribute to compose a serializable object
	#
	# This method should be called from `Serializable::core_serialize_to`.
	fun serialize_attribute(name: String, value: nullable Object)
	do
		if not try_to_serialize(value) then
			warn("argument {name} of type {value.class_name} is not serializable.")
		end
	end

	# Serialize `value` is possie, i.e. it is `Serializable` or `null`
	fun try_to_serialize(value: nullable Object): Bool
	do
		if value isa Serializable then
			value.serialize_to_or_delay(self)
		else if value == null then
			serialize value
		else return false
		return true
	end

	# Warn of problems and potential errors (such as if an attribute
	# is not serializable)
	fun warn(msg: String) do print "Serialization warning: {msg}"
end

# Abstract deserialization service
#
# After initialization of one of its sub-classes, call `deserialize`
abstract class Deserializer
	# Main method of this class, returns a Nit object
	fun deserialize: nullable Object is abstract

	# Internal method to be implemented by sub-classes
	fun deserialize_attribute(name: String): nullable Object is abstract

	# Internal method called by objects in creation,
	# to be implemented by sub-classes
	fun notify_of_creation(new_object: Object) is abstract

	# Deserialize the next available object as an instance of `class_name`
	#
	# Returns the deserialized object on success, aborts on error.
	#
	# This method should be redefined for each custom subclass of `Serializable`.
	# All refinement should look for a precise `class_name` and call super
	# on unsupported classes.
	protected fun deserialize_class(class_name: String): nullable Object do
		if class_name == "Error" then return new Error.from_deserializer(self)
		return deserialize_class_intern(class_name)
	end

	# Generated service to deserialize the next available object as an instance of `class_name`
	#
	# Refinements to this method will be generated by the serialization phase.
	# To avoid conflicts, there should not be any other refinements to this method.
	# You can instead use `deserialize_class`.
	protected fun deserialize_class_intern(class_name: String): nullable Object do
		errors.add new Error("Deserialization Error: Doesn't know how to deserialize class \"{class_name}\"")
		return null
	end

	# Should `self` keep trying to deserialize an object after an error?
	#
	# This behavior takes effect after each attribute deserialization with
{'fraction_non_alphanumeric': 0.06354974953344465, 'fraction_numerical': 0.0015715548570867301, 'mean_word_length': 4.930110658124636, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2745994', 'n_tokens_mistral': 2755, 'n_tokens_neox': 2669, 'n_words': 1230}