rubocop 1.5.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +52 -7
- data/config/obsoletion.yml +196 -0
- data/lib/rubocop.rb +14 -0
- data/lib/rubocop/cli/command/suggest_extensions.rb +21 -8
- data/lib/rubocop/config.rb +8 -5
- data/lib/rubocop/config_loader.rb +10 -6
- data/lib/rubocop/config_loader_resolver.rb +21 -4
- data/lib/rubocop/config_obsoletion.rb +64 -262
- data/lib/rubocop/config_obsoletion/changed_enforced_styles.rb +33 -0
- data/lib/rubocop/config_obsoletion/changed_parameter.rb +21 -0
- data/lib/rubocop/config_obsoletion/cop_rule.rb +34 -0
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +44 -0
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +44 -0
- data/lib/rubocop/config_obsoletion/removed_cop.rb +41 -0
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +34 -0
- data/lib/rubocop/config_obsoletion/rule.rb +41 -0
- data/lib/rubocop/config_obsoletion/split_cop.rb +27 -0
- data/lib/rubocop/config_validator.rb +11 -4
- data/lib/rubocop/cop/base.rb +17 -15
- data/lib/rubocop/cop/cop.rb +2 -2
- data/lib/rubocop/cop/correctors/string_literal_corrector.rb +6 -8
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +3 -2
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +145 -0
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +19 -3
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +26 -0
- data/lib/rubocop/cop/layout/line_length.rb +6 -16
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +7 -3
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -10
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +64 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +13 -10
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +59 -0
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +7 -2
- data/lib/rubocop/cop/lint/duplicate_branch.rb +64 -2
- data/lib/rubocop/cop/lint/interpolation_check.rb +7 -2
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +50 -17
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -11
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -0
- data/lib/rubocop/cop/lint/unreachable_loop.rb +17 -0
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/migration/department_name.rb +1 -1
- data/lib/rubocop/cop/mixin/string_help.rb +4 -1
- data/lib/rubocop/cop/naming/accessor_method_name.rb +15 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +59 -5
- data/lib/rubocop/cop/naming/variable_number.rb +3 -1
- data/lib/rubocop/cop/registry.rb +10 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -1
- data/lib/rubocop/cop/style/character_literal.rb +10 -11
- data/lib/rubocop/cop/style/collection_methods.rb +14 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +22 -5
- data/lib/rubocop/cop/style/float_division.rb +44 -1
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/hash_except.rb +95 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +4 -0
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +12 -2
- data/lib/rubocop/cop/style/lambda_call.rb +2 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +3 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +16 -6
- data/lib/rubocop/cop/style/method_def_parentheses.rb +7 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +26 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +3 -1
- data/lib/rubocop/cop/style/mutable_constant.rb +13 -3
- data/lib/rubocop/cop/style/perl_backrefs.rb +86 -9
- data/lib/rubocop/cop/style/raise_args.rb +2 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +21 -2
- data/lib/rubocop/cop/style/redundant_freeze.rb +8 -4
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +24 -8
- data/lib/rubocop/cop/style/single_line_block_params.rb +30 -7
- data/lib/rubocop/cop/style/single_line_methods.rb +4 -0
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +24 -8
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -13
- data/lib/rubocop/cop/style/string_concatenation.rb +26 -1
- data/lib/rubocop/cop/style/string_literals.rb +14 -8
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +4 -3
- data/lib/rubocop/cop/style/symbol_proc.rb +5 -4
- data/lib/rubocop/cop/util.rb +3 -1
- data/lib/rubocop/ext/regexp_node.rb +31 -9
- data/lib/rubocop/ext/regexp_parser.rb +21 -3
- data/lib/rubocop/formatter/emacs_style_formatter.rb +2 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +2 -0
- data/lib/rubocop/formatter/tap_formatter.rb +2 -0
- data/lib/rubocop/lockfile.rb +40 -0
- data/lib/rubocop/options.rb +9 -9
- data/lib/rubocop/rspec/cop_helper.rb +0 -4
- data/lib/rubocop/rspec/expect_offense.rb +34 -22
- data/lib/rubocop/runner.rb +16 -1
- data/lib/rubocop/target_finder.rb +4 -2
- data/lib/rubocop/util.rb +16 -0
- data/lib/rubocop/version.rb +8 -2
- metadata +33 -5
@@ -36,12 +36,13 @@ module RuboCop
|
|
36
36
|
# spec.required_ruby_version = '>= 2.5'
|
37
37
|
# end
|
38
38
|
#
|
39
|
-
# #
|
39
|
+
# # accepted but not recommended
|
40
40
|
# Gem::Specification.new do |spec|
|
41
41
|
# spec.required_ruby_version = ['>= 2.5.0', '< 2.7.0']
|
42
42
|
# end
|
43
43
|
#
|
44
|
-
# #
|
44
|
+
# # accepted but not recommended, since
|
45
|
+
# # Ruby does not really follow semantic versionning
|
45
46
|
# Gem::Specification.new do |spec|
|
46
47
|
# spec.required_ruby_version = '~> 2.5'
|
47
48
|
# end
|
@@ -6,4 +6,5 @@ require_relative 'internal_affairs/node_type_predicate'
|
|
6
6
|
require_relative 'internal_affairs/offense_location_keyword'
|
7
7
|
require_relative 'internal_affairs/redundant_message_argument'
|
8
8
|
require_relative 'internal_affairs/redundant_location_argument'
|
9
|
+
require_relative 'internal_affairs/style_detected_api_use'
|
9
10
|
require_relative 'internal_affairs/useless_message_assertion'
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Checks for correct use of the style_detected API provided by
|
7
|
+
# `ConfigurableEnforcedStyle`. If `correct_style_detected` is used
|
8
|
+
# then `opposite_style_detected`, `unexpected_style_detected`,
|
9
|
+
# `ambiguous_style_detected`, `conflicting_styles_detected`,
|
10
|
+
# `unrecognized_style_detected` or `no_acceptable_style!` should be
|
11
|
+
# used too, and vice versa. The `xxx_style_detected` methods
|
12
|
+
# should not be used as predicates either.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
#
|
16
|
+
# # bad
|
17
|
+
# def on_send(node)
|
18
|
+
# return add_offense(node) if opposite_style_detected
|
19
|
+
#
|
20
|
+
# correct_style_detected
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# def on_send(node)
|
24
|
+
# if offense?
|
25
|
+
# add_offense(node)
|
26
|
+
# else
|
27
|
+
# correct_style_detected
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# def on_send(node)
|
32
|
+
# return unless offense?
|
33
|
+
#
|
34
|
+
# add_offense(node)
|
35
|
+
# opposite_style_detected
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# # good
|
39
|
+
# def on_send(node)
|
40
|
+
# if offense?
|
41
|
+
# add_offense(node)
|
42
|
+
# opposite_style_detected
|
43
|
+
# else
|
44
|
+
# correct_style_detected
|
45
|
+
# end
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# def on_send(node)
|
49
|
+
# add_offense(node) if offense?
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
class StyleDetectedApiUse < Base
|
53
|
+
include RangeHelp
|
54
|
+
|
55
|
+
MSG_FOR_POSITIVE_WITHOUT_NEGATIVE =
|
56
|
+
'`correct_style_detected` method called without ' \
|
57
|
+
'calling a negative `*_style_detected` method.'
|
58
|
+
MSG_FOR_NEGATIVE_WITHOUT_POSITIVE =
|
59
|
+
'negative `*_style_detected` methods called without ' \
|
60
|
+
'calling `correct_style_detected` method.'
|
61
|
+
MSG_FOR_CONDITIONAL_USE =
|
62
|
+
'`*_style_detected` method called in conditional.'
|
63
|
+
RESTRICT_ON_SEND = %i[
|
64
|
+
correct_style_detected opposite_style_detected
|
65
|
+
unexpected_style_detected ambiguous_style_detected
|
66
|
+
conflicting_styles_detected unrecognized_style_detected
|
67
|
+
no_acceptable_style! style_detected
|
68
|
+
].freeze
|
69
|
+
|
70
|
+
def_node_matcher :correct_style_detected_check, <<~PATTERN
|
71
|
+
(send nil? :correct_style_detected)
|
72
|
+
PATTERN
|
73
|
+
|
74
|
+
def_node_matcher :negative_style_detected_method_check, <<~PATTERN
|
75
|
+
(send nil? /(?:opposite|unexpected|ambiguous|unrecognized)_style_detected|conflicting_styles_detected/ ...)
|
76
|
+
PATTERN
|
77
|
+
|
78
|
+
def_node_matcher :no_acceptable_style_check, <<~PATTERN
|
79
|
+
(send nil? :no_acceptable_style!)
|
80
|
+
PATTERN
|
81
|
+
|
82
|
+
def_node_matcher :style_detected_check, <<~PATTERN
|
83
|
+
(send nil? :style_detected ...)
|
84
|
+
PATTERN
|
85
|
+
|
86
|
+
def on_new_investigation
|
87
|
+
@correct_style_detected_called = false
|
88
|
+
@negative_style_detected_methods_called = false
|
89
|
+
@style_detected_called = false
|
90
|
+
end
|
91
|
+
|
92
|
+
def on_investigation_end
|
93
|
+
return if style_detected_called
|
94
|
+
return unless correct_style_detected_called ^ negative_style_detected_methods_called
|
95
|
+
|
96
|
+
add_global_offense(MSG_FOR_POSITIVE_WITHOUT_NEGATIVE) if positive_without_negative?
|
97
|
+
add_global_offense(MSG_FOR_NEGATIVE_WITHOUT_POSITIVE) if negative_without_positive?
|
98
|
+
end
|
99
|
+
|
100
|
+
def on_send(node)
|
101
|
+
if correct_style_detected_check(node)
|
102
|
+
@correct_style_detected_called = true
|
103
|
+
elsif negative_style_detected_method_check(node) || no_acceptable_style_check(node)
|
104
|
+
@negative_style_detected_methods_called = true
|
105
|
+
elsif style_detected_check(node)
|
106
|
+
@style_detected_called = true
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def on_if(node)
|
111
|
+
traverse_condition(node.condition) do |cond|
|
112
|
+
add_offense(cond, message: MSG_FOR_CONDITIONAL_USE) if style_detected_api_used?(cond)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
attr_reader :correct_style_detected_called,
|
119
|
+
:negative_style_detected_methods_called,
|
120
|
+
:style_detected_called
|
121
|
+
|
122
|
+
def positive_without_negative?
|
123
|
+
correct_style_detected_called && !negative_style_detected_methods_called
|
124
|
+
end
|
125
|
+
|
126
|
+
def negative_without_positive?
|
127
|
+
negative_style_detected_methods_called && !correct_style_detected_called
|
128
|
+
end
|
129
|
+
|
130
|
+
def style_detected_api_used?(node)
|
131
|
+
correct_style_detected_check(node) ||
|
132
|
+
negative_style_detected_method_check(node) ||
|
133
|
+
no_acceptable_style_check(node) ||
|
134
|
+
style_detected_check(node)
|
135
|
+
end
|
136
|
+
|
137
|
+
def traverse_condition(condition, &block)
|
138
|
+
yield condition if condition.send_type?
|
139
|
+
|
140
|
+
condition.each_child_node { |child| traverse_condition(child, &block) }
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -76,6 +76,14 @@ module RuboCop
|
|
76
76
|
#
|
77
77
|
# def b
|
78
78
|
# end
|
79
|
+
#
|
80
|
+
# @example AllowAdjacentOneLineDefs: true
|
81
|
+
#
|
82
|
+
# # good
|
83
|
+
# class ErrorA < BaseError; end
|
84
|
+
# class ErrorB < BaseError; end
|
85
|
+
# class ErrorC < BaseError; end
|
86
|
+
#
|
79
87
|
class EmptyLineBetweenDefs < Base
|
80
88
|
include RangeHelp
|
81
89
|
extend AutoCorrector
|
@@ -113,8 +121,8 @@ module RuboCop
|
|
113
121
|
|
114
122
|
def autocorrect(corrector, prev_def, node)
|
115
123
|
# finds position of first newline
|
116
|
-
end_pos = prev_def.
|
117
|
-
source_buffer = prev_def.
|
124
|
+
end_pos = end_loc(prev_def).end_pos
|
125
|
+
source_buffer = end_loc(prev_def).source_buffer
|
118
126
|
newline_pos = source_buffer.source.index("\n", end_pos)
|
119
127
|
|
120
128
|
# Handle the case when multiple one-liners are on the same line.
|
@@ -198,7 +206,15 @@ module RuboCop
|
|
198
206
|
end
|
199
207
|
|
200
208
|
def def_end(node)
|
201
|
-
node.
|
209
|
+
end_loc(node).line
|
210
|
+
end
|
211
|
+
|
212
|
+
def end_loc(node)
|
213
|
+
if node.def_type? && node.endless?
|
214
|
+
node.loc.expression.end
|
215
|
+
else
|
216
|
+
node.loc.end
|
217
|
+
end
|
202
218
|
end
|
203
219
|
|
204
220
|
def autocorrect_remove_lines(corrector, newline_pos, count)
|
@@ -59,7 +59,7 @@ module RuboCop
|
|
59
59
|
private
|
60
60
|
|
61
61
|
def receiver_and_method_call_on_different_lines?(node)
|
62
|
-
node.receiver && node.receiver.loc.last_line != node.loc.selector
|
62
|
+
node.receiver && node.receiver.loc.last_line != node.loc.selector&.line
|
63
63
|
end
|
64
64
|
|
65
65
|
def empty_lines(node)
|
@@ -69,6 +69,8 @@ module RuboCop
|
|
69
69
|
return unless outermost_send
|
70
70
|
return unless outermost_send.loc.end
|
71
71
|
return unless heredoc_arg.first_line != outermost_send.loc.end.line
|
72
|
+
return if subsequent_closing_parentheses_in_same_line?(outermost_send)
|
73
|
+
return if exist_argument_between_heredoc_end_and_closing_parentheses?(node)
|
72
74
|
|
73
75
|
add_offense(outermost_send.loc.end) do |corrector|
|
74
76
|
autocorrect(corrector, outermost_send)
|
@@ -160,6 +162,17 @@ module RuboCop
|
|
160
162
|
|
161
163
|
# Closing parenthesis helpers.
|
162
164
|
|
165
|
+
def subsequent_closing_parentheses_in_same_line?(outermost_send)
|
166
|
+
last_arg_of_outer_send = outermost_send.last_argument
|
167
|
+
return false unless last_arg_of_outer_send&.loc.respond_to?(:end) &&
|
168
|
+
(end_of_last_arg_of_outer_send = last_arg_of_outer_send.loc.end)
|
169
|
+
|
170
|
+
end_of_outer_send = outermost_send.loc.end
|
171
|
+
|
172
|
+
end_of_outer_send.line == end_of_last_arg_of_outer_send.line &&
|
173
|
+
end_of_outer_send.column == end_of_last_arg_of_outer_send.column + 1
|
174
|
+
end
|
175
|
+
|
163
176
|
def fix_closing_parenthesis(node, corrector)
|
164
177
|
remove_incorrect_closing_paren(node, corrector)
|
165
178
|
add_correct_closing_paren(node, corrector)
|
@@ -203,6 +216,19 @@ module RuboCop
|
|
203
216
|
end
|
204
217
|
end
|
205
218
|
|
219
|
+
def exist_argument_between_heredoc_end_and_closing_parentheses?(node)
|
220
|
+
return false unless (heredoc_end = find_most_bottom_of_heredoc_end(node.arguments))
|
221
|
+
|
222
|
+
heredoc_end < node.loc.end.begin_pos &&
|
223
|
+
range_between(heredoc_end, node.loc.end.begin_pos).source.strip != ''
|
224
|
+
end
|
225
|
+
|
226
|
+
def find_most_bottom_of_heredoc_end(arguments)
|
227
|
+
arguments.map do |argument|
|
228
|
+
argument.loc.heredoc_end.end_pos if argument.loc.respond_to?(:heredoc_end)
|
229
|
+
end.compact.max
|
230
|
+
end
|
231
|
+
|
206
232
|
# Internal trailing comma helpers.
|
207
233
|
|
208
234
|
def remove_internal_trailing_comma(node, corrector)
|
@@ -58,12 +58,13 @@ module RuboCop
|
|
58
58
|
# bar: "0000000000",
|
59
59
|
# baz: "0000000000",
|
60
60
|
# }
|
61
|
-
class LineLength <
|
61
|
+
class LineLength < Base
|
62
62
|
include CheckLineBreakable
|
63
63
|
include ConfigurableMax
|
64
64
|
include IgnoredPattern
|
65
65
|
include RangeHelp
|
66
66
|
include LineLengthHelp
|
67
|
+
extend AutoCorrector
|
67
68
|
|
68
69
|
MSG = 'Line is too long. [%<length>d/%<max>d]'
|
69
70
|
|
@@ -78,28 +79,16 @@ module RuboCop
|
|
78
79
|
alias on_hash on_potential_breakable_node
|
79
80
|
alias on_send on_potential_breakable_node
|
80
81
|
|
81
|
-
def
|
82
|
+
def on_new_investigation
|
82
83
|
check_for_breakable_semicolons(processed_source)
|
83
84
|
end
|
84
85
|
|
85
|
-
def
|
86
|
+
def on_investigation_end
|
86
87
|
processed_source.lines.each_with_index do |line, line_index|
|
87
88
|
check_line(line, line_index)
|
88
89
|
end
|
89
90
|
end
|
90
91
|
|
91
|
-
def correctable?
|
92
|
-
super && !breakable_range.nil?
|
93
|
-
end
|
94
|
-
|
95
|
-
def autocorrect(range)
|
96
|
-
return if range.nil?
|
97
|
-
|
98
|
-
lambda do |corrector|
|
99
|
-
corrector.insert_before(range, "\n")
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
92
|
private
|
104
93
|
|
105
94
|
attr_accessor :breakable_range
|
@@ -203,8 +192,9 @@ module RuboCop
|
|
203
192
|
|
204
193
|
self.breakable_range = breakable_range_by_line_index[line_index]
|
205
194
|
|
206
|
-
add_offense(
|
195
|
+
add_offense(loc, message: message) do |corrector|
|
207
196
|
self.max = line_length(line)
|
197
|
+
corrector.insert_before(breakable_range, "\n") unless breakable_range.nil?
|
208
198
|
end
|
209
199
|
end
|
210
200
|
|
@@ -77,7 +77,7 @@ module RuboCop
|
|
77
77
|
|
78
78
|
@base = alignment_base(node, rhs, given_style)
|
79
79
|
correct_column = if @base
|
80
|
-
@base.column + extra_indentation(given_style)
|
80
|
+
@base.column + extra_indentation(given_style, node.parent)
|
81
81
|
else
|
82
82
|
indentation(lhs) + correct_indentation(node)
|
83
83
|
end
|
@@ -85,9 +85,13 @@ module RuboCop
|
|
85
85
|
rhs if @column_delta.nonzero?
|
86
86
|
end
|
87
87
|
|
88
|
-
def extra_indentation(given_style)
|
88
|
+
def extra_indentation(given_style, parent)
|
89
89
|
if given_style == :indented_relative_to_receiver
|
90
|
-
|
90
|
+
if parent && (parent.splat_type? || parent.kwsplat_type?)
|
91
|
+
configured_indentation_width - parent.loc.operator.length
|
92
|
+
else
|
93
|
+
configured_indentation_width
|
94
|
+
end
|
91
95
|
else
|
92
96
|
0
|
93
97
|
end
|
@@ -191,16 +191,9 @@ module RuboCop
|
|
191
191
|
end
|
192
192
|
|
193
193
|
def begin_end_alignment_style
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
# config.for_cop('Layout/BeginEndAlignment')['Enabled'] &&
|
198
|
-
# config.for_cop('Layout/BeginEndAlignment')['EnforcedStyleAlignWith']
|
199
|
-
if config.for_all_cops['NewCops'] == 'enable' ||
|
200
|
-
config.for_cop('Layout/BeginEndAlignment')['Enabled'] &&
|
201
|
-
config.for_cop('Layout/BeginEndAlignment')['Enabled'] != 'pending'
|
202
|
-
config.for_cop('Layout/BeginEndAlignment')['EnforcedStyleAlignWith']
|
203
|
-
end
|
194
|
+
begin_end_alignment_conf = config.for_cop('Layout/BeginEndAlignment')
|
195
|
+
|
196
|
+
begin_end_alignment_conf['Enabled'] && begin_end_alignment_conf['EnforcedStyleAlignWith']
|
204
197
|
end
|
205
198
|
end
|
206
199
|
end
|
@@ -106,6 +106,7 @@ module RuboCop
|
|
106
106
|
def space_missing(left_brace)
|
107
107
|
add_offense(left_brace, message: MISSING_MSG) do |corrector|
|
108
108
|
autocorrect(corrector, left_brace)
|
109
|
+
opposite_style_detected
|
109
110
|
end
|
110
111
|
end
|
111
112
|
|
@@ -114,6 +115,7 @@ module RuboCop
|
|
114
115
|
|
115
116
|
add_offense(space, message: DETECTED_MSG) do |corrector|
|
116
117
|
autocorrect(corrector, space)
|
118
|
+
opposite_style_detected
|
117
119
|
end
|
118
120
|
end
|
119
121
|
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Layout
|
6
|
+
# Checks for space between the name of a receiver and a left
|
7
|
+
# brackets.
|
8
|
+
#
|
9
|
+
# This cop is marked as unsafe because it can occur false positives
|
10
|
+
# for `do_something [this_is_an_array_literal_argument]` that take
|
11
|
+
# an array without parentheses as an argument.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
#
|
15
|
+
# # bad
|
16
|
+
# collection [index_or_key]
|
17
|
+
#
|
18
|
+
# # good
|
19
|
+
# collection[index_or_key]
|
20
|
+
#
|
21
|
+
class SpaceBeforeBrackets < Base
|
22
|
+
include RangeHelp
|
23
|
+
extend AutoCorrector
|
24
|
+
|
25
|
+
MSG = 'Remove the space before the opening brackets.'
|
26
|
+
|
27
|
+
def on_send(node)
|
28
|
+
return if node.parenthesized? || node.parent&.send_type?
|
29
|
+
return unless (first_argument = node.first_argument)
|
30
|
+
|
31
|
+
begin_pos = first_argument.source_range.begin_pos
|
32
|
+
|
33
|
+
return unless (range = offense_range(node, first_argument, begin_pos))
|
34
|
+
|
35
|
+
register_offense(range)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def offense_range(node, first_argument, begin_pos)
|
41
|
+
if space_before_brackets?(node, first_argument)
|
42
|
+
range_between(node.loc.selector.end_pos, begin_pos)
|
43
|
+
elsif node.method?(:[]=)
|
44
|
+
end_pos = node.receiver.source_range.end_pos
|
45
|
+
|
46
|
+
return if begin_pos - end_pos == 1
|
47
|
+
|
48
|
+
range_between(end_pos, begin_pos - 1)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def register_offense(range)
|
53
|
+
add_offense(range) do |corrector|
|
54
|
+
corrector.remove(range)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def space_before_brackets?(node, first_argument)
|
59
|
+
node.receiver.nil? && first_argument.array_type? && node.arguments.size == 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|