Skip to content

Commit

Permalink
- builders/default: fix treatment of masgn in &&/|| (refs #69).
Browse files Browse the repository at this point in the history
  • Loading branch information
whitequark committed Jun 15, 2013
1 parent 6675fc7 commit 75c512b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 11 deletions.
22 changes: 18 additions & 4 deletions lib/parser/builders/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ def not_op(not_t, receiver=nil)
# Logical operations: and, or

def logical_op(type, lhs, op_t, rhs)
n(type, [ check_condition(lhs), check_condition(rhs) ],
n(type, [ lhs, rhs ],
binary_op_map(lhs, op_t, rhs))
end

Expand Down Expand Up @@ -801,11 +801,25 @@ def begin(begin_t, body, end_t)
#

def check_condition(cond)
if cond.type == :masgn
case cond.type
when :masgn
diagnostic :error, ERRORS[:masgn_as_condition],
cond.loc.expression
elsif cond.type == :begin
check_condition(cond.children.last)

when :begin
if cond.children.count == 1
check_condition(cond.children.last)
else
cond
end

when :and, :or
lhs, rhs = *cond

cond.updated(nil, [
check_condition(lhs),
check_condition(rhs)
])
end

cond
Expand Down
42 changes: 35 additions & 7 deletions test/test_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3410,13 +3410,23 @@ def test_or
|~~~~~~~~~~ expression})
end

def test_and_or_masgn_invalid
assert_diagnoses(
[:error, :masgn_as_condition],
def test_and_or_masgn
assert_parses(
s(:and,
s(:lvar, :foo),
s(:begin,
s(:masgn,
s(:mlhs, s(:lvasgn, :a), s(:lvasgn, :b)),
s(:lvar, :bar)))),
%q{foo && (a, b = bar)})

assert_diagnoses(
[:error, :masgn_as_condition],
assert_parses(
s(:or,
s(:lvar, :foo),
s(:begin,
s(:masgn,
s(:mlhs, s(:lvasgn, :a), s(:lvasgn, :b)),
s(:lvar, :bar)))),
%q{foo || (a, b = bar)})
end

Expand Down Expand Up @@ -3561,10 +3571,28 @@ def test_tern_masgn
end

def test_cond_begin_masgn
assert_parses(
s(:if,
s(:begin,
s(:lvar, :bar),
s(:masgn,
s(:mlhs, s(:lvasgn, :a), s(:lvasgn, :b)),
s(:lvar, :foo))),
s(:nil),
nil),
%q{if (bar; a, b = foo); end})
end

def test_cond_begin_and_or_masgn
assert_diagnoses(
[:error, :masgn_as_condition],
%q{if (bar; a, b = foo); end},
%q{ ~~~~~~~~~~ location})
%q{if foo && (a, b = bar); end},
%q{ ~~~~~~~~~~ location})

assert_diagnoses(
[:error, :masgn_as_condition],
%q{if foo || (a, b = bar); end},
%q{ ~~~~~~~~~~ location})
end

# Case matching
Expand Down

0 comments on commit 75c512b

Please sign in to comment.