From e29a996ac94e59055feeba2c9fb156a4a9114c31 Mon Sep 17 00:00:00 2001 From: Samuel Giddins Date: Sun, 13 Oct 2024 18:08:59 -0500 Subject: [PATCH] Generate code for Struct/Data hash/== Signed-off-by: Samuel Giddins --- lib/literal/data_structure.rb | 21 +++++--------- lib/literal/properties.rb | 9 +++--- lib/literal/properties/data_schema.rb | 7 ++--- lib/literal/properties/schema.rb | 41 +++++++++++++++++++++++++-- 4 files changed, 53 insertions(+), 25 deletions(-) diff --git a/lib/literal/data_structure.rb b/lib/literal/data_structure.rb index b79dc78..fcc718f 100644 --- a/lib/literal/data_structure.rb +++ b/lib/literal/data_structure.rb @@ -10,20 +10,6 @@ def self.from_pack(payload) object end - def ==(other) - if Literal::DataStructure === other - to_h == other.to_h - else - false - end - end - - alias eql? == - - def hash - [self.class, to_h].hash - end - def [](key) instance_variable_get(:"@#{key}") end @@ -60,4 +46,11 @@ def marshal_load(payload) def marshal_dump [1, to_h, frozen?] end + + def self.__generate_literal_methods__(new_property, buffer = +"") + super + literal_properties.generate_hash(buffer) + literal_properties.generate_eq("Literal::DataStructure", buffer) + buffer + end end diff --git a/lib/literal/properties.rb b/lib/literal/properties.rb index 142cabf..54ec4cc 100644 --- a/lib/literal/properties.rb +++ b/lib/literal/properties.rb @@ -66,16 +66,17 @@ def __literal_property_class__ end def __define_literal_methods__(new_property) - __literal_extension__.module_eval( - __generate_literal_methods__(new_property), - ) + code = __generate_literal_methods__(new_property) + __literal_extension__.module_eval(code) end def __literal_extension__ if defined?(@__literal_extension__) @__literal_extension__ else - @__literal_extension__ = Module.new + @__literal_extension__ = Module.new do + set_temporary_name "Literal::Properties(Extension)" + end end end diff --git a/lib/literal/properties/data_schema.rb b/lib/literal/properties/data_schema.rb index 6cfc8cc..37a239d 100644 --- a/lib/literal/properties/data_schema.rb +++ b/lib/literal/properties/data_schema.rb @@ -1,9 +1,8 @@ # frozen_string_literal: true class Literal::Properties::DataSchema < Literal::Properties::Schema - def generate_initializer_body(buffer = +"") - buffer << "properties = self.class.literal_properties.properties_index\n" - generate_initializer_handle_properties(@sorted_properties, buffer) - buffer << "after_initialize if respond_to?(:after_initialize)\nfreeze\n" + def generate_after_initializer(buffer = +"") + super + buffer << " freeze\n" end end diff --git a/lib/literal/properties/schema.rb b/lib/literal/properties/schema.rb index 2c1c366..6eb248f 100644 --- a/lib/literal/properties/schema.rb +++ b/lib/literal/properties/schema.rb @@ -49,9 +49,13 @@ def generate_initializer(buffer = +"") "rescue Literal::TypeError => error\n" \ " error.set_backtrace(caller(2))\n" \ " raise\n" \ - "else\n" \ - " after_initialize if respond_to?(:after_initialize)\n" \ - "end\n" + "else\n" + generate_after_initializer(buffer) + buffer << "end\n" + end + + def generate_after_initializer(buffer = +"") + buffer << " after_initialize if respond_to?(:after_initialize)\n" end def generate_to_h(buffer = +"") @@ -68,6 +72,37 @@ def generate_to_h(buffer = +"") buffer << " }\n" << "end\n" end + def generate_hash(buffer = +"") + buffer << "def hash\n [self.class,\n" + + sorted_properties = @sorted_properties + i, n = 0, sorted_properties.size + while i < n + property = sorted_properties[i] + buffer << " @" << property.name.name << ",\n" + i += 1 + end + + buffer << " ].hash\n" << "end\n" + end + + def generate_eq(guard, buffer = +"") + buffer << "def ==(other)\n" + buffer << " return false unless #{guard} === other\n" + + sorted_properties = @sorted_properties + i, n = 0, sorted_properties.size + while i < n + property = sorted_properties[i] + buffer << " @" << property.name.name << " == other.#{property.escaped_name}" + buffer << " &&\n " if i < n - 1 + i += 1 + end + buffer << " true" if n.zero? + buffer << "\nend\n" + buffer << "alias eql? ==\n" + end + private def generate_initializer_params(buffer = +"")