/
method_call_with_args_parentheses.rb
190 lines (180 loc) · 4.88 KB
/
method_call_with_args_parentheses.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# frozen_string_literal: true
module RuboCop
module Cop
module Style
# This cop enforces the presence (default) or absence of parentheses in
# method calls containing parameters.
#
# In the default style (require_parentheses), macro methods are ignored.
# Additional methods can be added to the `IgnoredMethods`
# or `IgnoredPatterns` list. These options are
# valid only in the default style. Macros can be included by
# either setting `IgnoreMacros` to false or adding specific macros to
# the `IncludedMacros` list.
#
# Precedence of options is all follows:
#
# 1. `IgnoredMethods`
# 2. `IgnoredPatterns`
# 3. `IncludedMacros`
#
# eg. If a method is listed in both
# `IncludedMacros` and `IgnoredMethods`, then the latter takes
# precedence (that is, the method is ignored).
#
# In the alternative style (omit_parentheses), there are three additional
# options.
#
# 1. `AllowParenthesesInChaining` is `false` by default. Setting it to
# `true` allows the presence of parentheses in the last call during
# method chaining.
#
# 2. `AllowParenthesesInMultilineCall` is `false` by default. Setting it
# to `true` allows the presence of parentheses in multi-line method
# calls.
#
# 3. `AllowParenthesesInCamelCaseMethod` is `false` by default. This
# allows the presence of parentheses when calling a method whose name
# begins with a capital letter and which has no arguments. Setting it
# to `true` allows the presence of parentheses in such a method call
# even with arguments.
#
# @example EnforcedStyle: require_parentheses (default)
#
# # bad
# array.delete e
#
# # good
# array.delete(e)
#
# # good
# # Operators don't need parens
# foo == bar
#
# # good
# # Setter methods don't need parens
# foo.bar = baz
#
# # okay with `puts` listed in `IgnoredMethods`
# puts 'test'
#
# # okay with `^assert` listed in `IgnoredPatterns`
# assert_equal 'test', x
#
# @example EnforcedStyle: omit_parentheses
#
# # bad
# array.delete(e)
#
# # good
# array.delete e
#
# # bad
# foo.enforce(strict: true)
#
# # good
# foo.enforce strict: true
#
# @example IgnoreMacros: true (default)
#
# # good
# class Foo
# bar :baz
# end
#
# @example IgnoreMacros: false
#
# # bad
# class Foo
# bar :baz
# end
#
# @example AllowParenthesesInMultilineCall: false (default)
#
# # bad
# foo.enforce(
# strict: true
# )
#
# # good
# foo.enforce \
# strict: true
#
# @example AllowParenthesesInMultilineCall: true
#
# # good
# foo.enforce(
# strict: true
# )
#
# # good
# foo.enforce \
# strict: true
#
# @example AllowParenthesesInChaining: false (default)
#
# # bad
# foo().bar(1)
#
# # good
# foo().bar 1
#
# @example AllowParenthesesInChaining: true
#
# # good
# foo().bar(1)
#
# # good
# foo().bar 1
#
# @example AllowParenthesesInCamelCaseMethod: false (default)
#
# # bad
# Array(1)
#
# # good
# Array 1
#
# @example AllowParenthesesInCamelCaseMethod: true
#
# # good
# Array(1)
#
# # good
# Array 1
class MethodCallWithArgsParentheses < Cop
include ConfigurableEnforcedStyle
include IgnoredMethods
include IgnoredPattern
def initialize(*)
super
return unless style_configured?
case style
when :require_parentheses
extend RequireParentheses
when :omit_parentheses
extend OmitParentheses
end
end
# @abstract Overridden in style modules
def autocorrect(_node); end
private
def args_begin(node)
loc = node.loc
selector =
node.super_type? || node.yield_type? ? loc.keyword : loc.selector
resize_by = args_parenthesized?(node) ? 2 : 1
selector.end.resize(resize_by)
end
def args_end(node)
node.loc.expression.end
end
def args_parenthesized?(node)
return false unless node.arguments.one?
first_node = node.arguments.first
first_node.begin_type? && first_node.parenthesized_call?
end
end
end
end
end