提交 36cdce51 编写于 作者: J Justin

Merge pull request #577 from presidentbeef/handle_multiple_assignment

Handle multiple assignment
......@@ -351,6 +351,33 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
exp
end
# Multiple/parallel assignment:
#
# x, y = z, w
def process_masgn exp
unless array? exp[1] and array? exp[2] and exp[1].length == exp[2].length
return process_default(exp)
end
vars = exp[1].dup
vals = exp[2].dup
vars.shift
vals.shift
# Call each assignment as if it is normal
vars.each_with_index do |var, i|
val = vals[i]
if val
assign = var.dup
assign.rhs = val
process assign
end
end
exp
end
#Merge values into hash when processing
#
# h.merge! :something => "value"
......
......@@ -4,7 +4,7 @@
class Sexp
attr_reader :paren
attr_accessor :original_line, :or_depth
ASSIGNMENT_BOOL = [:gasgn, :iasgn, :lasgn, :cvdecl, :cdecl, :or, :and, :colon2]
ASSIGNMENT_BOOL = [:gasgn, :iasgn, :lasgn, :cvdecl, :cvasgn, :cdecl, :or, :and, :colon2]
def method_missing name, *args
#Brakeman does not use this functionality,
......@@ -419,6 +419,7 @@ class Sexp
#Sets the left hand side of assignment or boolean.
def lhs= exp
expect *ASSIGNMENT_BOOL
@my_hash_value = nil
self[1] = exp
end
......@@ -427,14 +428,25 @@ class Sexp
# s(:lasgn, :x, s(:lit, 1))
# ^--rhs---^
def rhs
expect *ASSIGNMENT_BOOL
self[2]
expect :attrasgn, *ASSIGNMENT_BOOL
if self.node_type == :attrasgn
self[3]
else
self[2]
end
end
#Sets the right hand side of assignment or boolean.
def rhs= exp
expect *ASSIGNMENT_BOOL
self[2] = exp
expect :attrasgn, *ASSIGNMENT_BOOL
@my_hash_value = nil
if self.node_type == :attrasgn
self[3] = exp
else
self[2] = exp
end
end
#Returns name of method being defined in a method definition.
......
......@@ -600,6 +600,18 @@ class AliasProcessorTests < Test::Unit::TestCase
OUTPUT
end
def test_multiple_assignment
assert_output <<-INPUT, <<-OUTPUT
x, $y = 1, 2
x
$y
INPUT
x, $y = 1, 2
1
2
OUTPUT
end
def test_branch_with_self_assign_target
assert_alias 'a.w.y', <<-INPUT
x = a
......
......@@ -162,13 +162,23 @@ class SexpTests < Test::Unit::TestCase
assert_equal s(:lit, 1), exp.rhs
end
def test_class_variable_assignment
def test_class_variable_declaration
exp = parse '@@x = 1'
assert_equal :cvdecl, exp.node_type
assert_equal :@@x, exp.lhs
assert_equal s(:lit, 1), exp.rhs
end
def test_class_variable_assignment
exp = parse 'def x; @@a = 1; end'
asgn = exp.last
assert_equal :cvasgn, asgn.node_type
assert_equal :@@a, asgn.lhs
assert_equal s(:lit, 1), asgn.rhs
end
def test_method_def_name
exp = parse <<-RUBY
def x(y)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册