Wrap all compiler assignments in begin/end
This is much safer than having to explicitly call "wrap" in a potential large amount of places.
This commit is contained in:
parent
aaba0049ab
commit
4b50a161ed
|
@ -56,11 +56,14 @@ module Oga
|
|||
##
|
||||
# Returns an assignment node.
|
||||
#
|
||||
# This method wraps assigned values in a begin/end block to ensure that
|
||||
# multiple lines of code result in the proper value being assigned.
|
||||
#
|
||||
# @param [Oga::Ruby::Node] other
|
||||
# @return [Oga::Ruby::Node]
|
||||
#
|
||||
def assign(other)
|
||||
Node.new(:assign, [self, other])
|
||||
Node.new(:assign, [self, other.wrap])
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
@ -1358,49 +1358,6 @@ module Oga
|
|||
#
|
||||
# Everything else is processed the usual (and possibly slower) way.
|
||||
#
|
||||
# The variables used by this operator are assigned a "begin" block
|
||||
# containing the actual result. This ensures that each variable is
|
||||
# assigned the result of the entire block instead of the first expression
|
||||
# that occurs.
|
||||
#
|
||||
# For example, take the following expression:
|
||||
#
|
||||
# 10 = 10 = 20
|
||||
#
|
||||
# Without a "begin" we'd end up with the following code (trimmed for
|
||||
# readability):
|
||||
#
|
||||
# eq_left3 = eq_left1 = ...
|
||||
#
|
||||
# eq_left2 = ...
|
||||
#
|
||||
# eq_left1, eq_left2 = to_compatible_types(eq_left1, eq_left2)
|
||||
#
|
||||
# eq_left1 == eq_left2
|
||||
#
|
||||
# eq_left4 = ...
|
||||
#
|
||||
# eq_left3 == eq_left4
|
||||
#
|
||||
# This would be incorrect as the first boolean expression (`10 = 10`)
|
||||
# would be ignored. By using a "begin" we instead get the following:
|
||||
#
|
||||
# eq_left3 = begin
|
||||
# eq_left1 = ...
|
||||
#
|
||||
# eq_left2 = ...
|
||||
#
|
||||
# eq_left1, eq_left2 = to_compatible_types(eq_left1, eq_left2)
|
||||
#
|
||||
# eq_left1 == eq_left2
|
||||
# end
|
||||
#
|
||||
# eq_left4 = begin
|
||||
# ...
|
||||
# end
|
||||
#
|
||||
# eq_left3 == eq_left4
|
||||
#
|
||||
# @param [AST::Node] ast
|
||||
# @param [Oga::Ruby::Node] input
|
||||
# @param [TrueClass|FalseClass] optimize_first
|
||||
|
@ -1415,8 +1372,8 @@ module Oga
|
|||
left_ast = try_match_first_node(left, input, optimize_first)
|
||||
right_ast = try_match_first_node(right, input, optimize_first)
|
||||
|
||||
initial_assign = left_var.assign(left_ast.wrap)
|
||||
.followed_by(right_var.assign(right_ast.wrap))
|
||||
initial_assign = left_var.assign(left_ast)
|
||||
.followed_by(right_var.assign(right_ast))
|
||||
.followed_by { yield left_var, right_var }
|
||||
end
|
||||
|
||||
|
|
|
@ -21,7 +21,11 @@ describe Oga::Ruby::Generator do
|
|||
val = Oga::Ruby::Node.new(:lit, %w{10})
|
||||
assign = var.assign(val)
|
||||
|
||||
@generator.on_assign(assign).should == 'number = 10'
|
||||
@generator.on_assign(assign).should == <<-EOF
|
||||
number = begin
|
||||
10
|
||||
end
|
||||
EOF
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -34,7 +34,11 @@ describe Oga::Ruby::Node do
|
|||
node = left.assign(right)
|
||||
|
||||
node.type.should == :assign
|
||||
node.to_a.should == [left, right]
|
||||
|
||||
node.to_a[0].should == left
|
||||
|
||||
node.to_a[1].type.should == :begin
|
||||
node.to_a[1].to_a[0].should == right
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue