rubocop 0.34.2 → 0.35.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubocop might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +86 -0
- data/README.md +103 -31
- data/config/default.yml +32 -2
- data/config/disabled.yml +24 -0
- data/config/enabled.yml +20 -2
- data/lib/rubocop.rb +13 -0
- data/lib/rubocop/ast_node.rb +48 -0
- data/lib/rubocop/cli.rb +9 -0
- data/lib/rubocop/config.rb +8 -6
- data/lib/rubocop/config_loader.rb +30 -8
- data/lib/rubocop/cop/commissioner.rb +1 -1
- data/lib/rubocop/cop/cop.rb +19 -6
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +33 -2
- data/lib/rubocop/cop/lint/debugger.rb +9 -56
- data/lib/rubocop/cop/lint/end_alignment.rb +29 -9
- data/lib/rubocop/cop/lint/eval.rb +6 -2
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +24 -6
- data/lib/rubocop/cop/lint/literal_in_condition.rb +0 -5
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +10 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
- data/lib/rubocop/cop/lint/space_before_first_arg.rb +1 -1
- data/lib/rubocop/cop/lint/unused_block_argument.rb +6 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +8 -0
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/mixin/access_modifier_node.rb +1 -1
- data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +26 -3
- data/lib/rubocop/cop/mixin/check_assignment.rb +2 -3
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +59 -12
- data/lib/rubocop/cop/mixin/configurable_max.rb +1 -1
- data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
- data/lib/rubocop/cop/mixin/first_element_line_break.rb +41 -0
- data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -1
- data/lib/rubocop/cop/mixin/safe_assignment.rb +3 -14
- data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
- data/lib/rubocop/cop/performance/detect.rb +5 -1
- data/lib/rubocop/cop/performance/fixed_size.rb +50 -0
- data/lib/rubocop/cop/performance/size.rb +1 -1
- data/lib/rubocop/cop/performance/string_replacement.rb +14 -8
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +97 -0
- data/lib/rubocop/cop/style/align_hash.rb +1 -12
- data/lib/rubocop/cop/style/align_parameters.rb +19 -7
- data/lib/rubocop/cop/style/and_or.rb +42 -13
- data/lib/rubocop/cop/style/block_comments.rb +4 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +57 -18
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +1 -1
- data/lib/rubocop/cop/style/command_literal.rb +2 -10
- data/lib/rubocop/cop/style/copyright.rb +5 -3
- data/lib/rubocop/cop/style/documentation.rb +9 -6
- data/lib/rubocop/cop/style/dot_position.rb +6 -0
- data/lib/rubocop/cop/style/double_negation.rb +4 -15
- data/lib/rubocop/cop/style/each_with_object.rb +17 -4
- data/lib/rubocop/cop/style/empty_line_between_defs.rb +1 -5
- data/lib/rubocop/cop/style/encoding.rb +10 -4
- data/lib/rubocop/cop/style/extra_spacing.rb +23 -13
- data/lib/rubocop/cop/style/first_array_element_line_break.rb +41 -0
- data/lib/rubocop/cop/style/first_hash_element_line_break.rb +35 -0
- data/lib/rubocop/cop/style/first_method_argument_line_break.rb +37 -0
- data/lib/rubocop/cop/style/first_method_parameter_line_break.rb +42 -0
- data/lib/rubocop/cop/style/for.rb +2 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +31 -0
- data/lib/rubocop/cop/style/indent_hash.rb +67 -37
- data/lib/rubocop/cop/style/indentation_width.rb +1 -1
- data/lib/rubocop/cop/style/leading_comment_space.rb +3 -2
- data/lib/rubocop/cop/style/method_call_parentheses.rb +8 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +10 -7
- data/lib/rubocop/cop/style/multiline_operation_indentation.rb +8 -13
- data/lib/rubocop/cop/style/nested_modifier.rb +97 -0
- data/lib/rubocop/cop/style/next.rb +18 -0
- data/lib/rubocop/cop/style/parallel_assignment.rb +57 -15
- data/lib/rubocop/cop/style/predicate_name.rb +7 -2
- data/lib/rubocop/cop/style/regexp_literal.rb +2 -10
- data/lib/rubocop/cop/style/single_line_methods.rb +7 -5
- data/lib/rubocop/cop/style/single_space_before_first_arg.rb +1 -1
- data/lib/rubocop/cop/style/space_around_operators.rb +2 -0
- data/lib/rubocop/cop/style/special_global_vars.rb +4 -2
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +108 -0
- data/lib/rubocop/cop/style/trailing_comma.rb +9 -6
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +23 -2
- data/lib/rubocop/cop/style/unneeded_percent_q.rb +31 -20
- data/lib/rubocop/cop/style/variable_name.rb +5 -0
- data/lib/rubocop/cop/style/word_array.rb +2 -1
- data/lib/rubocop/cop/team.rb +17 -4
- data/lib/rubocop/cop/util.rb +5 -0
- data/lib/rubocop/cop/variable_force/locatable.rb +1 -1
- data/lib/rubocop/formatter/base_formatter.rb +1 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +22 -10
- data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
- data/lib/rubocop/node_pattern.rb +390 -0
- data/lib/rubocop/options.rb +48 -36
- data/lib/rubocop/processed_source.rb +3 -1
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/remote_config.rb +60 -0
- data/lib/rubocop/result_cache.rb +4 -2
- data/lib/rubocop/runner.rb +33 -10
- data/lib/rubocop/token.rb +2 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop/warning.rb +11 -0
- data/relnotes/v0.35.0.md +210 -0
- data/rubocop.gemspec +2 -2
- metadata +20 -6
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for a line break before the first element in a
|
7
|
+
# multi-line hash.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# { a: 1,
|
13
|
+
# b: 2}
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# {
|
17
|
+
# a: 1,
|
18
|
+
# b: 2 }
|
19
|
+
class FirstHashElementLineBreak < Cop
|
20
|
+
include FirstElementLineBreak
|
21
|
+
|
22
|
+
MSG = 'Add a line break before the first element of a ' \
|
23
|
+
'multi-line hash.'
|
24
|
+
|
25
|
+
def on_hash(node)
|
26
|
+
if node.loc.begin
|
27
|
+
check_children_line_break(node, node.children)
|
28
|
+
elsif method_uses_parens?(node.parent, node)
|
29
|
+
check_children_line_break(node, node.children, node.parent)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for a line break before the first argument in a
|
7
|
+
# multi-line method call.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# method(foo, bar,
|
13
|
+
# baz)
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# method(
|
17
|
+
# foo, bar,
|
18
|
+
# baz)
|
19
|
+
#
|
20
|
+
# # ignored
|
21
|
+
# method foo, bar,
|
22
|
+
# baz
|
23
|
+
class FirstMethodArgumentLineBreak < Cop
|
24
|
+
include FirstElementLineBreak
|
25
|
+
|
26
|
+
MSG = 'Add a line break before the first argument of a ' \
|
27
|
+
'multi-line method argument list.'
|
28
|
+
|
29
|
+
def on_send(node)
|
30
|
+
_receiver, _name, *args = *node
|
31
|
+
|
32
|
+
check_method_line_break(node, args)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for a line break before the first parameter in a
|
7
|
+
# multi-line method parameter definition.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# def method(foo, bar,
|
13
|
+
# baz)
|
14
|
+
# do_something
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# def method(
|
19
|
+
# foo, bar,
|
20
|
+
# baz)
|
21
|
+
# do_something
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# # ignored
|
25
|
+
# def method foo,
|
26
|
+
# bar
|
27
|
+
# do_something
|
28
|
+
# end
|
29
|
+
class FirstMethodParameterLineBreak < Cop
|
30
|
+
include OnMethodDef
|
31
|
+
include FirstElementLineBreak
|
32
|
+
|
33
|
+
MSG = 'Add a line break before the first parameter of a ' \
|
34
|
+
'multi-line method parameter list.'
|
35
|
+
|
36
|
+
def on_method_def(node, _method_name, args, _body)
|
37
|
+
check_method_line_break(node, args.to_a)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -9,6 +9,7 @@ module RuboCop
|
|
9
9
|
# allowed, however.
|
10
10
|
class For < Cop
|
11
11
|
include ConfigurableEnforcedStyle
|
12
|
+
EACH_LENGTH = 'each'.length
|
12
13
|
|
13
14
|
def on_for(node)
|
14
15
|
if style == :each
|
@@ -32,7 +33,7 @@ module RuboCop
|
|
32
33
|
if style == :for
|
33
34
|
end_pos = method.loc.expression.end_pos
|
34
35
|
range = Parser::Source::Range.new(processed_source.buffer,
|
35
|
-
end_pos -
|
36
|
+
end_pos - EACH_LENGTH,
|
36
37
|
end_pos)
|
37
38
|
add_offense(range, range, 'Prefer `for` over `each`.') do
|
38
39
|
opposite_style_detected
|
@@ -9,6 +9,8 @@ module RuboCop
|
|
9
9
|
class IfUnlessModifier < Cop
|
10
10
|
include StatementModifier
|
11
11
|
|
12
|
+
ASSIGNMENT_TYPES = [:lvasgn, :casgn, :cvasgn, :gvasgn, :ivasgn, :masgn]
|
13
|
+
|
12
14
|
def message(keyword)
|
13
15
|
"Favor modifier `#{keyword}` usage when having a single-line body." \
|
14
16
|
' Another good alternative is the usage of control flow `&&`/`||`.'
|
@@ -20,10 +22,38 @@ module RuboCop
|
|
20
22
|
return if modifier_if?(node)
|
21
23
|
return if elsif?(node)
|
22
24
|
return if if_else?(node)
|
25
|
+
return if chained?(node)
|
23
26
|
return unless fit_within_line_as_modifier_form?(node)
|
24
27
|
add_offense(node, :keyword, message(node.loc.keyword.source))
|
25
28
|
end
|
26
29
|
|
30
|
+
def chained?(node)
|
31
|
+
# Don't register offense for `if ... end.method`
|
32
|
+
return false if node.parent.nil? || !node.parent.send_type?
|
33
|
+
receiver = node.parent.children[0]
|
34
|
+
node.equal?(receiver)
|
35
|
+
end
|
36
|
+
|
37
|
+
def parenthesize?(node)
|
38
|
+
# Parenthesize corrected expression if changing to modifier-if form
|
39
|
+
# would change the meaning of the parent expression
|
40
|
+
# (due to the low operator precedence of modifier-if)
|
41
|
+
return false if node.parent.nil?
|
42
|
+
return true if ASSIGNMENT_TYPES.include?(node.parent.type)
|
43
|
+
|
44
|
+
if node.parent.send_type?
|
45
|
+
_receiver, _name, *args = *node.parent
|
46
|
+
return !method_uses_parens?(node.parent, args.first)
|
47
|
+
end
|
48
|
+
|
49
|
+
false
|
50
|
+
end
|
51
|
+
|
52
|
+
def method_uses_parens?(node, limit)
|
53
|
+
source = node.loc.expression.source_line[0...limit.loc.column]
|
54
|
+
source =~ /\s*\(\s*$/
|
55
|
+
end
|
56
|
+
|
27
57
|
def autocorrect(node)
|
28
58
|
cond, body, _else = if_node_parts(node)
|
29
59
|
|
@@ -36,6 +66,7 @@ module RuboCop
|
|
36
66
|
if first_line_comment
|
37
67
|
oneline << ' ' << first_line_comment.loc.expression.source
|
38
68
|
end
|
69
|
+
oneline = "(#{oneline})" if parenthesize?(node)
|
39
70
|
|
40
71
|
->(corrector) { corrector.replace(node.loc.expression, oneline) }
|
41
72
|
end
|
@@ -7,14 +7,37 @@ module RuboCop
|
|
7
7
|
# where the opening brace and the first key are on separate lines. The
|
8
8
|
# other keys' indentations are handled by the AlignHash cop.
|
9
9
|
#
|
10
|
-
# Hash literals that are arguments in a method call with
|
11
|
-
# where the opening curly brace of the hash is on the
|
12
|
-
# opening parenthesis of the method call, shall have
|
13
|
-
# indented one step (two spaces) more than the position
|
14
|
-
# opening parenthesis.
|
10
|
+
# By default, Hash literals that are arguments in a method call with
|
11
|
+
# parentheses, and where the opening curly brace of the hash is on the
|
12
|
+
# same line as the opening parenthesis of the method call, shall have
|
13
|
+
# their first key indented one step (two spaces) more than the position
|
14
|
+
# inside the opening parenthesis.
|
15
15
|
#
|
16
16
|
# Other hash literals shall have their first key indented one step more
|
17
17
|
# than the start of the line where the opening curly brace is.
|
18
|
+
#
|
19
|
+
# This default style is called 'special_inside_parentheses'. Alternative
|
20
|
+
# styles are 'consistent' and 'align_braces'. Here are examples:
|
21
|
+
#
|
22
|
+
# # special_inside_parentheses
|
23
|
+
# hash = {
|
24
|
+
# key: :value
|
25
|
+
# }
|
26
|
+
# but_in_a_method_call({
|
27
|
+
# its_like: :this
|
28
|
+
# })
|
29
|
+
# # consistent
|
30
|
+
# hash = {
|
31
|
+
# key: :value
|
32
|
+
# }
|
33
|
+
# and_in_a_method_call({
|
34
|
+
# no: :difference
|
35
|
+
# })
|
36
|
+
# # align_braces
|
37
|
+
# and_now_for_something = {
|
38
|
+
# completely: :different
|
39
|
+
# }
|
40
|
+
#
|
18
41
|
class IndentHash < Cop
|
19
42
|
include AutocorrectAlignment
|
20
43
|
include ConfigurableEnforcedStyle
|
@@ -62,13 +85,16 @@ module RuboCop
|
|
62
85
|
end
|
63
86
|
|
64
87
|
def check_right_brace(right_brace, left_brace, left_parenthesis)
|
88
|
+
# if the right brace is on the same line as the last value, accept
|
65
89
|
return if right_brace.source_line[0...right_brace.column] =~ /\S/
|
66
90
|
|
67
91
|
expected_column = base_column(left_brace, left_parenthesis)
|
68
92
|
@column_delta = expected_column - right_brace.column
|
69
93
|
return if @column_delta == 0
|
70
94
|
|
71
|
-
msg = if style == :
|
95
|
+
msg = if style == :align_braces
|
96
|
+
'Indent the right brace the same as the left brace.'
|
97
|
+
elsif style == :special_inside_parentheses && left_parenthesis
|
72
98
|
'Indent the right brace the same as the first position ' \
|
73
99
|
'after the preceding left parenthesis.'
|
74
100
|
else
|
@@ -93,15 +119,24 @@ module RuboCop
|
|
93
119
|
end
|
94
120
|
|
95
121
|
def check_first_pair(first_pair, left_brace, left_parenthesis, offset)
|
96
|
-
|
122
|
+
actual_column = first_pair.loc.expression.column
|
97
123
|
expected_column = base_column(left_brace, left_parenthesis) +
|
98
124
|
configured_indentation_width + offset
|
99
|
-
@column_delta = expected_column -
|
125
|
+
@column_delta = expected_column - actual_column
|
100
126
|
|
101
127
|
if @column_delta == 0
|
102
|
-
|
128
|
+
# which column was actually used as 'base column' for indentation?
|
129
|
+
# (not the column which we think should be the 'base column',
|
130
|
+
# but the one which has actually been used for that purpose)
|
131
|
+
base_column = actual_column - configured_indentation_width - offset
|
132
|
+
styles = detected_styles(base_column, left_parenthesis, left_brace)
|
133
|
+
if styles.size > 1
|
134
|
+
ambiguous_style_detected(*styles)
|
135
|
+
else
|
136
|
+
correct_style_detected
|
137
|
+
end
|
103
138
|
else
|
104
|
-
incorrect_style_detected(
|
139
|
+
incorrect_style_detected(actual_column, offset, first_pair,
|
105
140
|
left_parenthesis, left_brace)
|
106
141
|
end
|
107
142
|
end
|
@@ -110,17 +145,29 @@ module RuboCop
|
|
110
145
|
left_parenthesis, left_brace)
|
111
146
|
add_offense(first_pair, :expression,
|
112
147
|
message(base_description(left_parenthesis))) do
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
else
|
117
|
-
unrecognized_style_detected
|
118
|
-
end
|
148
|
+
base_column = column - configured_indentation_width - offset
|
149
|
+
styles = detected_styles(base_column, left_parenthesis, left_brace)
|
150
|
+
ambiguous_style_detected(*styles)
|
119
151
|
end
|
120
152
|
end
|
121
153
|
|
154
|
+
def detected_styles(column, left_parenthesis, left_brace)
|
155
|
+
styles = []
|
156
|
+
if column == (left_brace.source_line =~ /\S/)
|
157
|
+
styles << :consistent
|
158
|
+
styles << :special_inside_parentheses unless left_parenthesis
|
159
|
+
end
|
160
|
+
if left_parenthesis && column == left_parenthesis.column + 1
|
161
|
+
styles << :special_inside_parentheses
|
162
|
+
end
|
163
|
+
styles << :align_braces if column == left_brace.column
|
164
|
+
styles
|
165
|
+
end
|
166
|
+
|
122
167
|
def base_column(left_brace, left_parenthesis)
|
123
|
-
if
|
168
|
+
if style == :align_braces
|
169
|
+
left_brace.column
|
170
|
+
elsif left_parenthesis && style == :special_inside_parentheses
|
124
171
|
left_parenthesis.column + 1
|
125
172
|
else
|
126
173
|
left_brace.source_line =~ /\S/
|
@@ -129,32 +176,15 @@ module RuboCop
|
|
129
176
|
|
130
177
|
# Returns the description of what the correct indentation is based on.
|
131
178
|
def base_description(left_parenthesis)
|
132
|
-
if
|
179
|
+
if style == :align_braces
|
180
|
+
'the position of the opening brace'
|
181
|
+
elsif left_parenthesis && style == :special_inside_parentheses
|
133
182
|
'the first position after the preceding left parenthesis'
|
134
183
|
else
|
135
184
|
'the start of the line where the left curly brace is'
|
136
185
|
end
|
137
186
|
end
|
138
187
|
|
139
|
-
# Returns the "unexpected column", which is the column that would be
|
140
|
-
# correct if the configuration was changed.
|
141
|
-
def unexpected_column(left_brace, left_parenthesis, offset)
|
142
|
-
# Set a crazy value by default, indicating that there's no other
|
143
|
-
# configuration that can be chosen to make the used indentation
|
144
|
-
# accepted.
|
145
|
-
unexpected_base_column = -1000
|
146
|
-
|
147
|
-
if left_parenthesis
|
148
|
-
unexpected_base_column = if style == :special_inside_parentheses
|
149
|
-
left_brace.source_line =~ /\S/
|
150
|
-
else
|
151
|
-
left_parenthesis.column + 1
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
unexpected_base_column + configured_indentation_width + offset
|
156
|
-
end
|
157
|
-
|
158
188
|
def message(base_description)
|
159
189
|
format('Use %d spaces for indentation in a hash, relative to %s.',
|
160
190
|
configured_indentation_width, base_description)
|
@@ -6,13 +6,14 @@ module RuboCop
|
|
6
6
|
# This cop checks whether comments have a leading space
|
7
7
|
# after the # denoting the start of the comment. The
|
8
8
|
# leading space is not required for some RDoc special syntax,
|
9
|
-
# like #++, #--, #:nodoc, etc.
|
9
|
+
# like #++, #--, #:nodoc, etc. Neither is it required for
|
10
|
+
# =begin/=end comments.
|
10
11
|
class LeadingCommentSpace < Cop
|
11
12
|
MSG = 'Missing space after #.'
|
12
13
|
|
13
14
|
def investigate(processed_source)
|
14
15
|
processed_source.comments.each do |comment|
|
15
|
-
next unless comment.text =~
|
16
|
+
next unless comment.text =~ /\A#+[^#\s=:+-]/
|
16
17
|
next if comment.text.start_with?('#!') && comment.loc.line == 1
|
17
18
|
|
18
19
|
add_offense(comment, :expression)
|
@@ -37,6 +37,14 @@ module RuboCop
|
|
37
37
|
mlhs_node, _mrhs_node = *asgn_node
|
38
38
|
asgn_node = mlhs_node.children[node.sibling_index]
|
39
39
|
end
|
40
|
+
# `obj.method = value` parses as (send ... :method= ...), and will
|
41
|
+
# not be returned as an `asgn_node` here
|
42
|
+
# however, `obj.method ||= value` parses as (or-asgn (send ...) ...)
|
43
|
+
# which IS an `asgn_node`
|
44
|
+
if asgn_node.or_asgn_type? || asgn_node.and_asgn_type?
|
45
|
+
asgn_node, _value = *asgn_node
|
46
|
+
return false if asgn_node.send_type?
|
47
|
+
end
|
40
48
|
|
41
49
|
asgn_node.loc.name.source == method_name.to_s
|
42
50
|
end
|
@@ -10,7 +10,9 @@ module RuboCop
|
|
10
10
|
include ConfigurableEnforcedStyle
|
11
11
|
|
12
12
|
def on_method_def(node, _method_name, args, _body)
|
13
|
-
if style == :require_parentheses
|
13
|
+
if style == :require_parentheses ||
|
14
|
+
(style == :require_no_parentheses_except_multiline &&
|
15
|
+
args.multiline?)
|
14
16
|
if arguments?(args) && !parentheses?(args)
|
15
17
|
missing_parentheses(node, args)
|
16
18
|
else
|
@@ -25,7 +27,11 @@ module RuboCop
|
|
25
27
|
|
26
28
|
def autocorrect(node)
|
27
29
|
lambda do |corrector|
|
28
|
-
if
|
30
|
+
if node.args_type?
|
31
|
+
# offense is registered on args node when parentheses are unwanted
|
32
|
+
corrector.replace(node.loc.begin, ' ')
|
33
|
+
corrector.remove(node.loc.end)
|
34
|
+
else
|
29
35
|
args_expr = args_node(node).loc.expression
|
30
36
|
args_with_space = range_with_surrounding_space(args_expr, :left)
|
31
37
|
just_space = Parser::Source::Range.new(args_expr.source_buffer,
|
@@ -33,9 +39,6 @@ module RuboCop
|
|
33
39
|
args_expr.begin_pos)
|
34
40
|
corrector.replace(just_space, '(')
|
35
41
|
corrector.insert_after(args_expr, ')')
|
36
|
-
elsif style == :require_no_parentheses
|
37
|
-
corrector.replace(node.loc.begin, ' ')
|
38
|
-
corrector.remove(node.loc.end)
|
39
42
|
end
|
40
43
|
end
|
41
44
|
end
|
@@ -45,13 +48,13 @@ module RuboCop
|
|
45
48
|
def missing_parentheses(node, args)
|
46
49
|
add_offense(node, args.loc.expression,
|
47
50
|
'Use def with parentheses when there are parameters.') do
|
48
|
-
|
51
|
+
unexpected_style_detected(:require_no_parentheses)
|
49
52
|
end
|
50
53
|
end
|
51
54
|
|
52
55
|
def unwanted_parentheses(args)
|
53
56
|
add_offense(args, :expression, 'Use def without parentheses.') do
|
54
|
-
|
57
|
+
unexpected_style_detected(:require_parentheses)
|
55
58
|
end
|
56
59
|
end
|
57
60
|
|
@@ -98,7 +98,7 @@ module RuboCop
|
|
98
98
|
article = kw =~ /^[iu]/ ? 'an' : 'a'
|
99
99
|
"a #{kind} in #{article} `#{kw}` statement"
|
100
100
|
else
|
101
|
-
'an expression' + (
|
101
|
+
'an expression' + (assignment_rhs?(node) ? ' in an assignment' : '')
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
@@ -142,7 +142,7 @@ module RuboCop
|
|
142
142
|
|
143
143
|
def should_align?(node, given_style)
|
144
144
|
given_style == :aligned && (kw_node_with_special_indentation(node) ||
|
145
|
-
|
145
|
+
assignment_rhs?(node))
|
146
146
|
end
|
147
147
|
|
148
148
|
def kw_node_with_special_indentation(node)
|
@@ -160,17 +160,12 @@ module RuboCop
|
|
160
160
|
end
|
161
161
|
end
|
162
162
|
|
163
|
-
def
|
164
|
-
node.
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
# as a :send node.
|
170
|
-
method_name == :[]=
|
171
|
-
when *ASGN_NODES
|
172
|
-
true
|
173
|
-
end
|
163
|
+
def assignment_rhs?(node)
|
164
|
+
node.ancestors.unshift(node).each_cons(2).any? do |child, parent|
|
165
|
+
return true if parent.asgn_rhs.equal?(child)
|
166
|
+
grandparent = parent.parent
|
167
|
+
return true if grandparent && grandparent.masgn_type? &&
|
168
|
+
grandparent.asgn_rhs.equal?(parent)
|
174
169
|
end
|
175
170
|
end
|
176
171
|
|