forked from rubocop/rubocop
-
Notifications
You must be signed in to change notification settings - Fork 0
/
deprecated_class_methods.rb
115 lines (99 loc) · 3.39 KB
/
deprecated_class_methods.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# 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 = '`%<current>s` is deprecated in favor of `%<prefer>s`.'
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
DEPRECATED_METHODS = DEPRECATED_METHODS_OBJECT.map(&:deprecated_method).freeze
def on_send(node)
return unless DEPRECATED_METHODS.include?(node.method_name)
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('%<constant>s.%<method>s', constant: class_constant,
method: method)
else
format('%<method>s', method: method)
end
end
end
end
end
end