# File lib/brakeman/processors/alias_processor.rb, line 164
  def process_call exp
    return exp if process_call_defn? exp
    target_var = exp.target
    target_var &&= target_var.deep_clone
    if exp.node_type == :safe_call
      exp.node_type = :call
    end

    if exp.method == :[]
      return process_bracket_call exp
    else
      exp = process_default exp
    end

    #In case it is replaced with something else
    unless call? exp
      return exp
    end

    target = exp.target
    method = exp.method
    first_arg = exp.first_arg

    if method == :send or method == :try
      collapse_send_call exp, first_arg
    end

    if node_type? target, :or and [:+, :-, :*, :/].include? method
      res = process_or_simple_operation(exp)
      return res if res
    elsif target == ARRAY_CONST and method == :new
      return Sexp.new(:array, *exp.args)
    elsif target == HASH_CONST and method == :new and first_arg.nil? and !node_type?(@exp_context.last, :iter)
      return Sexp.new(:hash)
    elsif exp == RAILS_TEST
      return Sexp.new(:false)
    end

    #See if it is possible to simplify some basic cases
    #of addition/concatenation.
    case method
    when :+
      if array? target and array? first_arg
        exp = join_arrays(target, first_arg, exp)
      elsif string? first_arg
        exp = join_strings(target, first_arg, exp)
      elsif number? first_arg
        exp = math_op(:+, target, first_arg, exp)
      end
    when :-, :*, :/
      exp = math_op(method, target, first_arg, exp)
    when :[]
      if array? target
        exp = process_array_access(target, exp.args, exp)
      elsif hash? target
        exp = process_hash_access(target, first_arg, exp)
      end
    when :merge!, :update
      if hash? target and hash? first_arg
         target = process_hash_merge! target, first_arg
         env[target_var] = target
         return target
      end
    when :merge
      if hash? target and hash? first_arg
        return process_hash_merge(target, first_arg)
      end
    when :<<
      if string? target and string? first_arg
        target.value << first_arg.value
        env[target_var] = target
        return target
      elsif string? target and string_interp? first_arg
        exp = Sexp.new(:dstr, target.value + first_arg[1]).concat(first_arg[2..-1])
        env[target_var] = exp
      elsif string? first_arg and string_interp? target
        if string? target.last
          target.last.value << first_arg.value
        elsif target.last.is_a? String
          target.last << first_arg.value
        else
          target << first_arg
        end
        env[target_var] = target
        return first_arg
      elsif array? target
        target << first_arg
        env[target_var] = target
        return target
      else
        target = find_push_target(target_var)
        env[target] = exp unless target.nil? # Happens in TemplateAliasProcessor
      end
    when :first
      if array? target and first_arg.nil? and sexp? target[1]
        exp = target[1]
      end
    when :freeze
      unless target.nil?
        exp = target
      end
    when :join
      if array? target and target.length > 2 and (string? first_arg or first_arg.nil?)
        exp = process_array_join(target, first_arg)
      end
    end

    exp
  end