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.
|
# 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
|
# @param [Oga::Ruby::Node] other
|
||||||
# @return [Oga::Ruby::Node]
|
# @return [Oga::Ruby::Node]
|
||||||
#
|
#
|
||||||
def assign(other)
|
def assign(other)
|
||||||
Node.new(:assign, [self, other])
|
Node.new(:assign, [self, other.wrap])
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
|
@ -1358,49 +1358,6 @@ module Oga
|
||||||
#
|
#
|
||||||
# Everything else is processed the usual (and possibly slower) way.
|
# 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 [AST::Node] ast
|
||||||
# @param [Oga::Ruby::Node] input
|
# @param [Oga::Ruby::Node] input
|
||||||
# @param [TrueClass|FalseClass] optimize_first
|
# @param [TrueClass|FalseClass] optimize_first
|
||||||
|
@ -1415,8 +1372,8 @@ module Oga
|
||||||
left_ast = try_match_first_node(left, input, optimize_first)
|
left_ast = try_match_first_node(left, input, optimize_first)
|
||||||
right_ast = try_match_first_node(right, input, optimize_first)
|
right_ast = try_match_first_node(right, input, optimize_first)
|
||||||
|
|
||||||
initial_assign = left_var.assign(left_ast.wrap)
|
initial_assign = left_var.assign(left_ast)
|
||||||
.followed_by(right_var.assign(right_ast.wrap))
|
.followed_by(right_var.assign(right_ast))
|
||||||
.followed_by { yield left_var, right_var }
|
.followed_by { yield left_var, right_var }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,11 @@ describe Oga::Ruby::Generator do
|
||||||
val = Oga::Ruby::Node.new(:lit, %w{10})
|
val = Oga::Ruby::Node.new(:lit, %w{10})
|
||||||
assign = var.assign(val)
|
assign = var.assign(val)
|
||||||
|
|
||||||
@generator.on_assign(assign).should == 'number = 10'
|
@generator.on_assign(assign).should == <<-EOF
|
||||||
|
number = begin
|
||||||
|
10
|
||||||
|
end
|
||||||
|
EOF
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,11 @@ describe Oga::Ruby::Node do
|
||||||
node = left.assign(right)
|
node = left.assign(right)
|
||||||
|
|
||||||
node.type.should == :assign
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue