implements resolve_method on parfait type
with associated changes to class adds note about the not being the final version
This commit is contained in:
parent
e387bdb5f2
commit
47683817ee
@ -55,13 +55,23 @@ module Parfait
|
|||||||
@instance_type = type
|
@instance_type = type
|
||||||
end
|
end
|
||||||
|
|
||||||
def super_class
|
# return the super class, but raise exception if either the super class name
|
||||||
|
# or the super classs is nil.
|
||||||
|
# Use only for non Object base class
|
||||||
|
def super_class!
|
||||||
raise "No super_class for class #{@name}" unless @super_class_name
|
raise "No super_class for class #{@name}" unless @super_class_name
|
||||||
s = Parfait.object_space.get_class_by_name(@super_class_name)
|
s = super_class
|
||||||
raise "superclass not found for class #{@name} (#{@super_class_name})" unless s
|
raise "superclass not found for class #{@name} (#{@super_class_name})" unless s
|
||||||
s
|
s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# return the super class
|
||||||
|
# we only store the name, and so have to resolve.
|
||||||
|
# Nil name means no superclass, and so nil is a valid return value
|
||||||
|
def super_class
|
||||||
|
return nil unless @super_class_name
|
||||||
|
Parfait.object_space.get_class_by_name(@super_class_name)
|
||||||
|
end
|
||||||
|
|
||||||
# ruby 2.1 list (just for reference, keep at bottom)
|
# ruby 2.1 list (just for reference, keep at bottom)
|
||||||
#:allocate, :new, :superclass
|
#:allocate, :new, :superclass
|
||||||
|
@ -114,6 +114,20 @@ module Parfait
|
|||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# resolve according to normal oo logic, ie look up in superclass if not present
|
||||||
|
# NOTE: this will probably not work in future as the code for the superclass
|
||||||
|
# method, being bound to t adifferent type, will assume that types (not the run-time
|
||||||
|
# actual types) layout. Either need to enforce some c++ style upwards compatibility (buuh)
|
||||||
|
# or copy the methods and recompile them for the actual type. (maybe still later dynamically)
|
||||||
|
# But for now we walk up, as it should really just be to object
|
||||||
|
def resolve_method( fname )
|
||||||
|
method = get_method(fname)
|
||||||
|
return method if method
|
||||||
|
sup = object_class.super_class
|
||||||
|
return nil unless sup
|
||||||
|
sup.instance_type.resolve_method(fname)
|
||||||
|
end
|
||||||
|
|
||||||
def == other
|
def == other
|
||||||
self.object_id == other.object_id
|
self.object_id == other.object_id
|
||||||
end
|
end
|
||||||
|
@ -16,6 +16,7 @@ class TestClass < MiniTest::Test
|
|||||||
assert_equal :Object , @try.super_class_name
|
assert_equal :Object , @try.super_class_name
|
||||||
end
|
end
|
||||||
def test_new_superclass
|
def test_new_superclass
|
||||||
|
assert_equal "Class(Object)" , @try.super_class!.inspect
|
||||||
assert_equal "Class(Object)" , @try.super_class.inspect
|
assert_equal "Class(Object)" , @try.super_class.inspect
|
||||||
end
|
end
|
||||||
def test_new_methods
|
def test_new_methods
|
||||||
@ -31,7 +32,7 @@ class TestClass < MiniTest::Test
|
|||||||
def test_remove_method
|
def test_remove_method
|
||||||
assert_equal false , @try.remove_instance_method( :foo)
|
assert_equal false , @try.remove_instance_method( :foo)
|
||||||
end
|
end
|
||||||
def test_add_method
|
def test_add_nil_method_raises
|
||||||
assert_raises{ @try.add_instance_method(nil)}
|
assert_raises{ @try.add_instance_method(nil)}
|
||||||
end
|
end
|
||||||
def test_add_instance_variable_changes_type
|
def test_add_instance_variable_changes_type
|
||||||
|
@ -9,28 +9,33 @@ class TestMethodApi < MiniTest::Test
|
|||||||
@try_type = @try_class.instance_type
|
@try_type = @try_class.instance_type
|
||||||
end
|
end
|
||||||
|
|
||||||
def foo_method for_class = :Try
|
def foo_method( for_class = :Try)
|
||||||
args = Parfait::Type.for_hash( @try_class , { bar: :Integer})
|
args = Parfait::Type.for_hash( @try_class , { bar: :Integer})
|
||||||
::Parfait::TypedMethod.new @space.get_class_by_name(for_class).instance_type , :foo , args
|
::Parfait::TypedMethod.new @space.get_class_by_name(for_class).instance_type , :foo , args
|
||||||
end
|
end
|
||||||
|
def add_foo_to( clazz = :Try )
|
||||||
|
foo = foo_method( clazz )
|
||||||
|
assert_equal foo , @space.get_class_by_name(clazz).instance_type.add_method(foo)
|
||||||
|
foo
|
||||||
|
end
|
||||||
|
def object_type
|
||||||
|
@space.get_class_by_name(:Object).instance_type
|
||||||
|
end
|
||||||
def test_new_methods
|
def test_new_methods
|
||||||
assert_equal @try_type.method_names.class, @try_type.methods.class
|
assert_equal @try_type.method_names.class, @try_type.methods.class
|
||||||
assert_equal @try_type.method_names.get_length , @try_type.methods.get_length
|
assert_equal @try_type.method_names.get_length , @try_type.methods.get_length
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_add_method
|
def test_add_method
|
||||||
before = @try_type.methods.get_length
|
before = @try_type.methods.get_length
|
||||||
foo = foo_method
|
add_foo_to
|
||||||
assert_equal foo , @try_type.add_method(foo)
|
|
||||||
assert_equal 1 , @try_type.methods.get_length - before
|
assert_equal 1 , @try_type.methods.get_length - before
|
||||||
assert @try_type.method_names.inspect.include?(":foo")
|
assert @try_type.method_names.inspect.include?(":foo")
|
||||||
end
|
end
|
||||||
def test_remove_method
|
def test_remove_method
|
||||||
test_add_method
|
add_foo_to
|
||||||
assert_equal true , @try_type.remove_method(:foo)
|
assert_equal true , @try_type.remove_method(:foo)
|
||||||
end
|
end
|
||||||
def test_remove_nothere
|
def test_remove_not_there
|
||||||
assert_raises RuntimeError do
|
assert_raises RuntimeError do
|
||||||
@try_type.remove_method(:foo)
|
@try_type.remove_method(:foo)
|
||||||
end
|
end
|
||||||
@ -41,7 +46,7 @@ class TestMethodApi < MiniTest::Test
|
|||||||
assert @try_type.method_names.inspect.include?("bar")
|
assert @try_type.method_names.inspect.include?("bar")
|
||||||
end
|
end
|
||||||
def test_method_get
|
def test_method_get
|
||||||
test_add_method
|
add_foo_to
|
||||||
assert_equal Parfait::TypedMethod , @try_type.get_method(:foo).class
|
assert_equal Parfait::TypedMethod , @try_type.get_method(:foo).class
|
||||||
end
|
end
|
||||||
def test_method_get_nothere
|
def test_method_get_nothere
|
||||||
@ -55,4 +60,20 @@ class TestMethodApi < MiniTest::Test
|
|||||||
type.add_method(foo)
|
type.add_method(foo)
|
||||||
assert_equal :foo , type.get_method(:foo).name
|
assert_equal :foo , type.get_method(:foo).name
|
||||||
end
|
end
|
||||||
|
def test_resolve_on_object
|
||||||
|
add_foo_to :Object
|
||||||
|
assert_equal :foo , object_type.resolve_method( :foo ).name
|
||||||
|
end
|
||||||
|
def test_resolve_super
|
||||||
|
add_foo_to :Object
|
||||||
|
assert_equal :foo , @try_class.instance_type.resolve_method( :foo ).name
|
||||||
|
end
|
||||||
|
def test_resolve_is_get
|
||||||
|
add_foo_to
|
||||||
|
assert_equal :foo , @try_class.instance_type.resolve_method( :foo ).name
|
||||||
|
assert_equal :foo , @try_class.instance_type.get_method( :foo ).name
|
||||||
|
end
|
||||||
|
def test_resolve_fail
|
||||||
|
assert_nil object_type.resolve_method( :foo )
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user