lib/rubocop/cop/lint/literal_in_condition.rb
# encoding: utf-8 module Rubocop module Cop module Lint # This cop checks for literals used as the conditions or as # operands in and/or expressions serving as the conditions of # if/while/until. # # @example # # if 20 # do_something # end # # if some_var && true # do_something # end # class LiteralInCondition < Cop MSG = 'Literal %s appeared in a condition.' LITERALS = [:str, :dstr, :int, :float, :array, :hash, :regexp, :nil, :true, :false] def on_if(node) check_for_literal(node) super end def on_while(node) check_for_literal(node) super end def on_while_post(node) check_for_literal(node) super end def on_until(node) check_for_literal(node) super end def on_until_post(node) check_for_literal(node) super end private def check_for_literal(node) cond, = *node # if the cond node is literal we obviously have a problem if literal?(cond) add_offence(:warning, cond.loc.expression, format(MSG, cond.loc.expression.source)) else # alternatively we have to consider a logical node with a # literal argument check_node(cond) end end def not?(node) return false unless node && node.type == :send _receiver, method_name, *_args = *node method_name == :! end def literal?(node) LITERALS.include?(node.type) end def check_node(node) return unless node if not?(node) receiver, = *node handle_node(receiver) elsif [:and, :or].include?(node.type) *operands = *node operands.each do |op| handle_node(op) end elsif node.type == :begin && node.children.size == 1 child_node = node.children.first handle_node(child_node) end end def handle_node(node) if literal?(node) add_offence(:warning, node.loc.expression, format(MSG, node.loc.expression.source)) elsif [:send, :and, :or, :begin].include?(node.type) check_node(node) end end end end end end