# frozen_string_literal: true module RuboCop module Cop module Lint # This cop checks for uses of the deprecated class method usages. # # @example # # # bad # # File.exists?(some_path) # Dir.exists?(some_path) # iterator? # # @example # # # good # # File.exist?(some_path) # Dir.exist?(some_path) # block_given? class DeprecatedClassMethods < Cop # Inner class to DeprecatedClassMethods. # This class exists to add abstraction and clean naming to the # objects that are going to be operated on. class DeprecatedClassMethod include RuboCop::AST::Sexp attr_reader :class_constant, :deprecated_method, :replacement_method def initialize(deprecated:, replacement:, class_constant: nil) @deprecated_method = deprecated @replacement_method = replacement @class_constant = class_constant end def class_nodes @class_nodes ||= if class_constant [ s(:const, nil, class_constant), s(:const, s(:cbase), class_constant) ] else [nil] end end end MSG = '`%s` is deprecated in favor of `%s`.'.freeze DEPRECATED_METHODS_OBJECT = [ DeprecatedClassMethod.new(deprecated: :exists?, replacement: :exist?, class_constant: :File), DeprecatedClassMethod.new(deprecated: :exists?, replacement: :exist?, class_constant: :Dir), DeprecatedClassMethod.new(deprecated: :iterator?, replacement: :block_given?) ].freeze def on_send(node) check(node) do |data| message = format(MSG, current: deprecated_method(data), prefer: replacement_method(data)) add_offense(node, location: :selector, message: message) end end def autocorrect(node) lambda do |corrector| check(node) do |data| corrector.replace(node.loc.selector, data.replacement_method.to_s) end end end private def check(node) DEPRECATED_METHODS_OBJECT.each do |data| next unless data.class_nodes.include?(node.receiver) next unless node.method?(data.deprecated_method) yield data end end def deprecated_method(data) method_call(data.class_constant, data.deprecated_method) end def replacement_method(data) method_call(data.class_constant, data.replacement_method) end def method_call(class_constant, method) if class_constant format('%s.%s', constant: class_constant, method: method) else format('%s', method: method) end end end end end end