forked from rubocop/rubocop
/
redundant_argument.rb
85 lines (75 loc) · 2.42 KB
/
redundant_argument.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
# frozen_string_literal: true
module RuboCop
module Cop
module Style
# This cop checks for a redundant argument passed to certain methods.
#
# Limitations:
#
# 1. This cop matches for method names only and hence cannot tell apart
# methods with same name in different classes.
# 2. This cop is limited to methods with single parameter.
# 3. This cop is unsafe if certain special global variables (e.g. `$;`, `$/`) are set.
# That depends on the nature of the target methods, of course.
#
# Method names and their redundant arguments can be configured like this:
#
# Methods:
# join: ''
# split: ' '
# chomp: "\n"
# chomp!: "\n"
# foo: 2
#
# @example
# # bad
# array.join('')
# [1, 2, 3].join("")
# string.split(" ")
# "first\nsecond".split(" ")
# string.chomp("\n")
# string.chomp!("\n")
# A.foo(2)
#
# # good
# array.join
# [1, 2, 3].join
# string.split
# "first second".split
# string.chomp
# string.chomp!
# A.foo
class RedundantArgument < Base
include RangeHelp
extend AutoCorrector
MSG = 'Argument %<arg>s is redundant because it is implied by default.'
def on_send(node)
return if node.receiver.nil?
return if node.arguments.count != 1
return unless redundant_argument?(node)
add_offense(node, message: format(MSG, arg: node.arguments.first.source)) do |corrector|
corrector.remove(argument_range(node))
end
end
private
def redundant_argument?(node)
redundant_argument = redundant_arg_for_method(node.method_name.to_s)
return false if redundant_argument.nil?
node.arguments.first == redundant_argument
end
def redundant_arg_for_method(method_name)
arg = cop_config['Methods'].fetch(method_name) { return }
@mem ||= {}
@mem[method_name] ||= parse(arg.inspect).ast
end
def argument_range(node)
if node.parenthesized?
range_between(node.loc.begin.begin_pos, node.loc.end.end_pos)
else
range_with_surrounding_space(range: node.first_argument.source_range, newlines: false)
end
end
end
end
end
end