implement attr setter correctly
part of #25 still need to do for list and attr_reader
This commit is contained in:
parent
b4b1e6e13b
commit
04720d4950
@ -2,6 +2,8 @@ module Ruby
|
|||||||
class ClassStatement < Statement
|
class ClassStatement < Statement
|
||||||
attr_reader :name, :super_class_name , :body
|
attr_reader :name, :super_class_name , :body
|
||||||
|
|
||||||
|
# init with the class name, super class name and statement body
|
||||||
|
# body must be Method or Send (See to_vool) or empty/nil (possibly not handled right)
|
||||||
def initialize( name , supe , body)
|
def initialize( name , supe , body)
|
||||||
@name , @super_class_name = name , supe
|
@name , @super_class_name = name , supe
|
||||||
case body
|
case body
|
||||||
@ -16,21 +18,50 @@ module Ruby
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Create equivalent vool objects. Mostly for method statements
|
||||||
|
# For calls, call transform_statement, see there
|
||||||
def to_vool
|
def to_vool
|
||||||
meths = body.statements.collect do |meth|
|
meths = []
|
||||||
meth.is_a?(MethodStatement) ? meth.to_vool : tranform_statement(meth)
|
body.statements.each do |meth|
|
||||||
|
if( meth.is_a?(MethodStatement))
|
||||||
|
meths << meth.to_vool
|
||||||
|
else
|
||||||
|
meths += transform_statement(meth)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
Vool::ClassStatement.new(@name , @super_class_name, Vool::Statements.new(meths) )
|
Vool::ClassStatement.new(@name , @super_class_name, Vool::Statements.new(meths) )
|
||||||
end
|
end
|
||||||
|
|
||||||
def tranform_statement( class_send )
|
# We rewrite certain send statements (so raise error for all else)
|
||||||
|
# Currently only attributes (ie attr :name) supported, for which the standard getter
|
||||||
|
# and setter is created and returned as vool
|
||||||
|
def transform_statement( class_send )
|
||||||
unless class_send.is_a?(SendStatement)
|
unless class_send.is_a?(SendStatement)
|
||||||
raise "Other than methods, only class methods allowed, not #{class_send.class}"
|
raise "Other than methods, only class methods allowed, not #{class_send.class}"
|
||||||
end
|
end
|
||||||
unless class_send.name == :attr
|
unless class_send.name == :attr
|
||||||
raise "Only remapping attr and cattr, not #{class_send.name}"
|
raise "Only remapping attr and cattr, not #{class_send.name}"
|
||||||
end
|
end
|
||||||
raise "todo"
|
attr = class_send.arguments.first.value
|
||||||
|
[ getter_for(attr) , setter_for(attr) ]
|
||||||
|
end
|
||||||
|
|
||||||
|
# creates a getter method for the given instance name (sym)
|
||||||
|
# The Method is created in Ruby, and to_vool is called to transform to Vool
|
||||||
|
# The standard getter obviously only returns the ivar
|
||||||
|
def getter_for(instance_name)
|
||||||
|
return_statement = ReturnStatement.new(InstanceVariable.new(instance_name))
|
||||||
|
MethodStatement.new(instance_name , [] , return_statement).to_vool
|
||||||
|
end
|
||||||
|
|
||||||
|
# creates a setter method (name=) for the given instance name (sym)
|
||||||
|
# The Method is created in Ruby, and to_vool is called to transform to Vool
|
||||||
|
# The setter method assigns the incoming value and returns the ivar
|
||||||
|
def setter_for(instance_name)
|
||||||
|
assign = IvarAssignment.new(instance_name , LocalVariable.new(:val))
|
||||||
|
return_statement = ReturnStatement.new(InstanceVariable.new(instance_name))
|
||||||
|
statements = Statements.new([assign, return_statement])
|
||||||
|
MethodStatement.new("#{instance_name}=".to_sym , [:val] , statements).to_vool
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s(depth = 0)
|
def to_s(depth = 0)
|
||||||
|
@ -81,19 +81,44 @@ module Ruby
|
|||||||
input = "class Tryout < Base;attr :page ;end"
|
input = "class Tryout < Base;attr :page ;end"
|
||||||
@vool = compile( input ).to_vool
|
@vool = compile( input ).to_vool
|
||||||
end
|
end
|
||||||
|
def getter
|
||||||
|
@vool.body.statements.first
|
||||||
|
end
|
||||||
|
def setter
|
||||||
|
@vool.body.statements.last
|
||||||
|
end
|
||||||
def test_class
|
def test_class
|
||||||
assert_equal Vool::ClassStatement , @vool.class
|
assert_equal Vool::ClassStatement , @vool.class
|
||||||
end
|
end
|
||||||
def test_body
|
def test_body
|
||||||
assert_equal Vool::Statements , @vool.body.class
|
assert_equal Vool::Statements , @vool.body.class
|
||||||
end
|
end
|
||||||
def test_compile_class_name
|
def test_getter
|
||||||
assert_equal :Tryout , @vool.name
|
assert_equal Vool::MethodStatement , getter.class
|
||||||
end
|
end
|
||||||
def test_compile_class_super
|
def test_getter_return
|
||||||
assert_equal :Base , @vool.super_class_name
|
assert_equal Vool::ReturnStatement , getter.body.class
|
||||||
|
end
|
||||||
|
def test_getter_name
|
||||||
|
assert_equal :page , getter.name
|
||||||
|
end
|
||||||
|
def test_setter
|
||||||
|
assert_equal Vool::MethodStatement , setter.class
|
||||||
|
end
|
||||||
|
def test_setter_assign
|
||||||
|
assert_equal Vool::Statements , setter.body.class
|
||||||
|
assert_equal Vool::IvarAssignment , setter.body.first.class
|
||||||
|
end
|
||||||
|
def test_setter_return
|
||||||
|
assert_equal Vool::Statements , setter.body.class
|
||||||
|
assert_equal Vool::ReturnStatement , setter.body.last.class
|
||||||
|
end
|
||||||
|
def test_setter_name
|
||||||
|
assert_equal :page= , setter.name
|
||||||
|
end
|
||||||
|
def test_setter_args
|
||||||
|
assert_equal [:val] , setter.args
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user