redid the type hashing
account for the class the type is for by adding it to the hash code, so even the ivars are identical the types are not
This commit is contained in:
parent
0fa7f54bcc
commit
b9073d0c88
@ -25,7 +25,7 @@ module Parfait
|
||||
|
||||
def self.type_for( arguments )
|
||||
my_class = Parfait.object_space.classes[:NamedList]
|
||||
Parfait::Type.for_hash( my_class , arguments.merge(type: my_class.instance_type))
|
||||
Type.for_hash( my_class , {type: my_class.instance_type}.merge(arguments))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -42,9 +42,7 @@ module Parfait
|
||||
message = @first_message
|
||||
end
|
||||
@classes.each do |name , cl|
|
||||
raise "upps #{cl.instance_type.hash}" unless cl.instance_type.hash.is_a?(Fixnum)
|
||||
|
||||
@types[cl.instance_type.hash] = cl.instance_type
|
||||
add_type(cl.instance_type)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -45,30 +45,6 @@ module Parfait
|
||||
Parfait.object_space.add_type(new_type)
|
||||
end
|
||||
|
||||
def self.hash_code_for_hash( dict )
|
||||
index = 1
|
||||
hash_code = str_hash(dict[:type])
|
||||
dict.each do |name , type|
|
||||
next if name == :type
|
||||
item_hash = str_hash(name) + str_hash(type)
|
||||
hash_code += item_hash + (item_hash / 256 ) * index
|
||||
index += 1
|
||||
end
|
||||
hash_code
|
||||
end
|
||||
|
||||
def self.str_hash(str)
|
||||
if RUBY_ENGINE == 'opal'
|
||||
hash = 5381
|
||||
str.to_s.each_char do |c|
|
||||
hash = ((hash << 5) + hash) + c.to_i; # hash * 33 + c without getting bignums
|
||||
end
|
||||
hash % (2 ** 51)
|
||||
else
|
||||
str.hash
|
||||
end
|
||||
end
|
||||
|
||||
def initialize( object_class , hash )
|
||||
super()
|
||||
set_object_class( object_class)
|
||||
@ -192,16 +168,43 @@ module Parfait
|
||||
end
|
||||
alias :name :sof_reference_name
|
||||
|
||||
def each
|
||||
index = 1
|
||||
while( index <= get_length() )
|
||||
yield( name_at(index) , type_at(index) )
|
||||
index += 1
|
||||
end
|
||||
end
|
||||
|
||||
def to_hash
|
||||
hash = Dictionary.new
|
||||
@names.each_with_index do |name, index |
|
||||
hash[name] = @types[index]
|
||||
hash = {}
|
||||
each do |name , type|
|
||||
hash[name] = type
|
||||
end
|
||||
hash
|
||||
end
|
||||
|
||||
def hash
|
||||
Type.hash_code_for_hash( to_hash )
|
||||
index = 1
|
||||
hash_code = Type.str_hash( @object_class.name )
|
||||
each do |name , type|
|
||||
item_hash = Type.str_hash(name) + Type.str_hash(type)
|
||||
hash_code += item_hash + (item_hash / 256 ) * index
|
||||
index += 1
|
||||
end
|
||||
hash_code
|
||||
end
|
||||
|
||||
def self.str_hash(str)
|
||||
if RUBY_ENGINE == 'opal'
|
||||
hash = 5381
|
||||
str.to_s.each_char do |c|
|
||||
hash = ((hash << 5) + hash) + c.to_i; # hash * 33 + c without getting bignums
|
||||
end
|
||||
hash % (2 ** 51)
|
||||
else
|
||||
str.hash
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -47,6 +47,20 @@ class TestSpace < MiniTest::Test
|
||||
end
|
||||
end
|
||||
|
||||
def test_classes_types_in_space_types
|
||||
@space.classes do |name , clazz|
|
||||
assert_equal clazz.instance_type , @space.get_type_for(clazz.instance_type.hash) , clazz.name
|
||||
end
|
||||
end
|
||||
|
||||
def test_word_class
|
||||
word = @space.classes[:Word]
|
||||
assert word.instance_type
|
||||
t_word = @space.get_type_for(word.instance_type.hash)
|
||||
assert_equal word.instance_type.hash , t_word.hash
|
||||
assert_equal word.instance_type.object_id , t_word.object_id
|
||||
end
|
||||
|
||||
def test_classes_type
|
||||
classes.each do |name|
|
||||
assert_equal Parfait::Type , @space.classes[name].get_type.class
|
||||
@ -97,4 +111,38 @@ class TestSpace < MiniTest::Test
|
||||
assert @space.get_class_by_name(:NewerClass)
|
||||
end
|
||||
|
||||
def test_class_types_are_stored
|
||||
@space.classes.each do |name,clazz|
|
||||
assert @space.get_type_for(clazz.instance_type.hash)
|
||||
end
|
||||
end
|
||||
|
||||
def test_class_types_are_identical
|
||||
@space.classes.each do |name , clazz|
|
||||
cl_type = @space.get_type_for(clazz.instance_type.hash)
|
||||
assert_equal cl_type.object_id , clazz.instance_type.object_id
|
||||
end
|
||||
end
|
||||
|
||||
def test_remove_methods
|
||||
@space.each_type do | type |
|
||||
type.method_names.each do |method|
|
||||
type.remove_method(method)
|
||||
end
|
||||
end
|
||||
assert_equal 0 , @space.collect_methods.length
|
||||
end
|
||||
def test_no_methods_in_types
|
||||
test_remove_methods
|
||||
@space.each_type do |type|
|
||||
assert_equal 0 , type.methods.get_length , "name #{type.name}"
|
||||
end
|
||||
end
|
||||
def ttest_no_methods_in_classes
|
||||
test_remove_methods
|
||||
@space.classes.each do |name , cl|
|
||||
assert_equal 0 , cl.instance_type.methods.get_length , "name #{cl.name}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -26,25 +26,10 @@ class TypeHash < MiniTest::Test
|
||||
end
|
||||
|
||||
def test_to_hash
|
||||
assert_equal "Word_Type" , @first.name
|
||||
assert_equal :Word , @first.object_class.name
|
||||
hash = @first.to_hash
|
||||
assert_equal :Type , @first.types.first
|
||||
assert_equal hash[:type] , :Type
|
||||
assert_equal hash[:char_length] , :Integer
|
||||
assert_equal 2 , @first.instance_length
|
||||
assert_equal 2 , hash.length
|
||||
end
|
||||
|
||||
def test_hashcode_with_hash
|
||||
assert_equal @first.hash , Parfait::Type.hash_code_for_hash( @first.to_hash)
|
||||
end
|
||||
|
||||
def test_second_hash_different
|
||||
hash2 = @first.to_hash
|
||||
hash2[:random] = :Type
|
||||
assert @first.hash != Parfait::Type.hash_code_for_hash( hash2 )
|
||||
end
|
||||
|
||||
def test_add_is_different
|
||||
type = @first.add_instance_variable :random , :Integer
|
||||
assert type != @first , "new: #{type.inspect} , old: #{@first.inspect}"
|
||||
@ -52,8 +37,9 @@ class TypeHash < MiniTest::Test
|
||||
end
|
||||
|
||||
def test_hash_for_no_ivars
|
||||
h1 = Parfait::Type.hash_code_for_hash( type: :NewInt)
|
||||
h2 = Parfait::Type.hash_code_for_hash( type: :NewObj)
|
||||
assert h1 != h2 , "Hashes should differ"
|
||||
list = @space.get_class_by_name(:NamedList )
|
||||
t1 = Parfait::Type.for_hash( list , type: :NewInt)
|
||||
t2 = Parfait::Type.for_hash( list , type: :NewObj)
|
||||
assert t1.hash != t2.hash , "Hashes should differ"
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user