rubocop 1.18.4 → 1.21.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 +65 -13
- data/lib/rubocop/cli.rb +18 -0
- data/lib/rubocop/config_loader.rb +2 -2
- data/lib/rubocop/config_loader_resolver.rb +21 -6
- data/lib/rubocop/cop/base.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_filename.rb +103 -0
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +12 -11
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/require_library_corrector.rb +23 -0
- data/lib/rubocop/cop/documentation.rb +1 -1
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +34 -0
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +71 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/class_structure.rb +2 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +9 -0
- data/lib/rubocop/cop/layout/end_alignment.rb +3 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +7 -3
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +0 -7
- data/lib/rubocop/cop/layout/leading_comment_space.rb +2 -2
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +33 -14
- data/lib/rubocop/cop/layout/line_length.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +3 -0
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +22 -9
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +15 -4
- data/lib/rubocop/cop/layout/space_after_not.rb +1 -0
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +2 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +8 -1
- data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_comment.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_parens.rb +5 -5
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +24 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +107 -0
- data/lib/rubocop/cop/lint/ambiguous_range.rb +105 -0
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +5 -2
- data/lib/rubocop/cop/lint/debugger.rb +2 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +8 -5
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +67 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +7 -1
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -1
- data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -3
- data/lib/rubocop/cop/lint/useless_times.rb +1 -1
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/mixin/annotation_comment.rb +57 -34
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/documentation_comment.rb +5 -2
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +19 -1
- data/lib/rubocop/cop/mixin/heredoc.rb +7 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -2
- data/lib/rubocop/cop/mixin/percent_array.rb +13 -7
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +9 -1
- data/lib/rubocop/cop/mixin/require_library.rb +59 -0
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/naming/ascii_identifiers.rb +0 -3
- data/lib/rubocop/cop/naming/constant_name.rb +1 -1
- data/lib/rubocop/cop/naming/inclusive_language.rb +27 -10
- data/lib/rubocop/cop/style/accessor_grouping.rb +2 -2
- data/lib/rubocop/cop/style/and_or.rb +4 -0
- data/lib/rubocop/cop/style/ascii_comments.rb +0 -3
- data/lib/rubocop/cop/style/block_delimiters.rb +39 -6
- data/lib/rubocop/cop/style/case_equality.rb +6 -9
- data/lib/rubocop/cop/style/collection_methods.rb +2 -1
- data/lib/rubocop/cop/style/comment_annotation.rb +25 -39
- data/lib/rubocop/cop/style/commented_keyword.rb +2 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +19 -5
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
- data/lib/rubocop/cop/style/documentation.rb +23 -8
- data/lib/rubocop/cop/style/double_negation.rb +12 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/encoding.rb +26 -15
- data/lib/rubocop/cop/style/explicit_block_argument.rb +46 -11
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +11 -0
- data/lib/rubocop/cop/style/hash_except.rb +4 -3
- data/lib/rubocop/cop/style/hash_transform_keys.rb +0 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +30 -5
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -2
- data/lib/rubocop/cop/style/lambda_call.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +6 -6
- data/lib/rubocop/cop/style/method_def_parentheses.rb +10 -1
- data/lib/rubocop/cop/style/missing_else.rb +7 -0
- data/lib/rubocop/cop/style/mutable_constant.rb +68 -6
- data/lib/rubocop/cop/style/negated_if.rb +1 -1
- data/lib/rubocop/cop/style/negated_unless.rb +1 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +2 -2
- data/lib/rubocop/cop/style/not.rb +2 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -1
- data/lib/rubocop/cop/style/percent_q_literals.rb +2 -2
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +25 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -3
- data/lib/rubocop/cop/style/redundant_freeze.rb +4 -3
- data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
- data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -3
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +83 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +19 -4
- data/lib/rubocop/cop/style/regexp_literal.rb +3 -3
- data/lib/rubocop/cop/style/return_nil.rb +2 -1
- data/lib/rubocop/cop/style/semicolon.rb +32 -24
- data/lib/rubocop/cop/style/single_line_block_params.rb +3 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -0
- data/lib/rubocop/cop/style/special_global_vars.rb +21 -0
- data/lib/rubocop/cop/style/static_class.rb +1 -2
- data/lib/rubocop/cop/style/string_concatenation.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +3 -0
- data/lib/rubocop/cop/style/symbol_array.rb +3 -3
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +23 -5
- data/lib/rubocop/cop/style/yoda_condition.rb +4 -7
- data/lib/rubocop/cop/util.rb +7 -2
- data/lib/rubocop/magic_comment.rb +44 -15
- data/lib/rubocop/options.rb +1 -1
- data/lib/rubocop/result_cache.rb +1 -1
- data/lib/rubocop/runner.rb +1 -2
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +9 -2
- metadata +14 -5
@@ -18,15 +18,16 @@ module RuboCop
|
|
18
18
|
!parent.parenthesized? && parent&.block_literal?
|
19
19
|
end
|
20
20
|
|
21
|
+
# Override to determine values that are invalid in a percent array
|
22
|
+
def invalid_percent_array_contents?(_node)
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
21
26
|
def allowed_bracket_array?(node)
|
22
27
|
comments_in_array?(node) || below_array_length?(node) ||
|
23
28
|
invalid_percent_array_context?(node)
|
24
29
|
end
|
25
30
|
|
26
|
-
def message(_node)
|
27
|
-
style == :percent ? self.class::PERCENT_MSG : self.class::ARRAY_MSG
|
28
|
-
end
|
29
|
-
|
30
31
|
def comments_in_array?(node)
|
31
32
|
line_span = node.source_range.first_line...node.source_range.last_line
|
32
33
|
processed_source.each_comment_in_lines(line_span).any?
|
@@ -35,9 +36,14 @@ module RuboCop
|
|
35
36
|
def check_percent_array(node)
|
36
37
|
array_style_detected(:percent, node.values.size)
|
37
38
|
|
38
|
-
return unless style == :brackets
|
39
|
+
return unless style == :brackets || invalid_percent_array_contents?(node)
|
40
|
+
|
41
|
+
bracketed_array = build_bracketed_array(node)
|
42
|
+
message = format(self.class::ARRAY_MSG, prefer: bracketed_array)
|
39
43
|
|
40
|
-
add_offense(node)
|
44
|
+
add_offense(node, message: message) do |corrector|
|
45
|
+
corrector.replace(node, bracketed_array)
|
46
|
+
end
|
41
47
|
end
|
42
48
|
|
43
49
|
def check_bracketed_array(node, literal_prefix)
|
@@ -47,7 +53,7 @@ module RuboCop
|
|
47
53
|
|
48
54
|
return unless style == :percent
|
49
55
|
|
50
|
-
add_offense(node) do |corrector|
|
56
|
+
add_offense(node, message: self.class::PERCENT_MSG) do |corrector|
|
51
57
|
percent_literal_corrector = PercentLiteralCorrector.new(@config, @preferred_delimiters)
|
52
58
|
percent_literal_corrector.correct(corrector, node, literal_prefix)
|
53
59
|
end
|
@@ -93,7 +93,15 @@ module RuboCop
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def aligned_assignment?(range, line)
|
96
|
-
range.source[-1] == '=' && line[range.last_column - 1] == '='
|
96
|
+
(range.source[-1] == '=' && line[range.last_column - 1] == '=') ||
|
97
|
+
aligned_with_append_operator?(range, line)
|
98
|
+
end
|
99
|
+
|
100
|
+
def aligned_with_append_operator?(range, line)
|
101
|
+
last_column = range.last_column
|
102
|
+
|
103
|
+
(range.source == '<<' && line[last_column - 1] == '=') ||
|
104
|
+
(range.source[-1] == '=' && line[(last_column - 2)..(last_column - 1)] == '<<')
|
97
105
|
end
|
98
106
|
|
99
107
|
def aligned_identical?(range, line)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Ensure a require statement is present for a standard library determined
|
6
|
+
# by variable library_name
|
7
|
+
module RequireLibrary
|
8
|
+
extend NodePattern::Macros
|
9
|
+
|
10
|
+
def ensure_required(corrector, node, library_name)
|
11
|
+
node = node.parent while node.parent&.parent?
|
12
|
+
|
13
|
+
if node.parent&.begin_type?
|
14
|
+
return if @required_libs.include?(library_name)
|
15
|
+
|
16
|
+
remove_subsequent_requires(corrector, node, library_name)
|
17
|
+
end
|
18
|
+
|
19
|
+
RequireLibraryCorrector.correct(corrector, node, library_name)
|
20
|
+
end
|
21
|
+
|
22
|
+
def remove_subsequent_requires(corrector, node, library_name)
|
23
|
+
node.right_siblings.each do |sibling|
|
24
|
+
next unless require_library_name?(sibling, library_name)
|
25
|
+
|
26
|
+
range = range_by_whole_lines(sibling.source_range, include_final_newline: true)
|
27
|
+
corrector.remove(range)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def on_send(node)
|
32
|
+
return if node.parent&.parent?
|
33
|
+
|
34
|
+
name = require_any_library?(node)
|
35
|
+
return if name.nil?
|
36
|
+
|
37
|
+
@required_libs.add(name)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def on_new_investigation
|
43
|
+
# Holds the required files at top-level
|
44
|
+
@required_libs = Set.new
|
45
|
+
super
|
46
|
+
end
|
47
|
+
|
48
|
+
# @!method require_any_library?(node)
|
49
|
+
def_node_matcher :require_any_library?, <<~PATTERN
|
50
|
+
(send {(const {nil? cbase} :Kernel) nil?} :require (str $_))
|
51
|
+
PATTERN
|
52
|
+
|
53
|
+
# @!method require_library_name?(node, library_name)
|
54
|
+
def_node_matcher :require_library_name?, <<~PATTERN
|
55
|
+
(send {(const {nil? cbase} :Kernel) nil?} :require (str %1))
|
56
|
+
PATTERN
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
MSG = 'Space found before %<token>s.'
|
11
11
|
|
12
12
|
def on_new_investigation
|
13
|
-
each_missing_space(processed_source.
|
13
|
+
each_missing_space(processed_source.sorted_tokens) do |token, pos_before|
|
14
14
|
add_offense(pos_before, message: format(MSG, token: kind(token))) do |corrector|
|
15
15
|
PunctuationCorrector.remove_space(corrector, pos_before)
|
16
16
|
end
|
@@ -54,7 +54,7 @@ module RuboCop
|
|
54
54
|
private
|
55
55
|
|
56
56
|
def allowed_assignment?(value)
|
57
|
-
value && %i[block const casgn].include?(value.type) ||
|
57
|
+
(value && %i[block const casgn].include?(value.type)) ||
|
58
58
|
allowed_method_call_on_rhs?(value) ||
|
59
59
|
class_or_struct_return_method?(value) ||
|
60
60
|
allowed_conditional_expression_on_rhs?(value)
|
@@ -19,6 +19,8 @@ module RuboCop
|
|
19
19
|
# Regex can be specified to identify offenses. Suggestions for replacing a flagged term can
|
20
20
|
# be configured and will be displayed as part of the offense message.
|
21
21
|
# An AllowedRegex can be specified for a flagged term to exempt allowed uses of the term.
|
22
|
+
# `WholeWord: true` can be set on a flagged term to indicate the cop should only match when
|
23
|
+
# a term matches the whole word (partial matches will not be offenses).
|
22
24
|
#
|
23
25
|
# @example FlaggedTerms: { whitelist: { Suggestions: ['allowlist'] } }
|
24
26
|
# # Suggest replacing identifier whitelist with allowlist
|
@@ -56,10 +58,20 @@ module RuboCop
|
|
56
58
|
# # good
|
57
59
|
# # They had a master's degree
|
58
60
|
#
|
61
|
+
# @example FlaggedTerms: { slave: { WholeWord: true } }
|
62
|
+
# # Specify that only terms that are full matches will be flagged.
|
63
|
+
#
|
64
|
+
# # bad
|
65
|
+
# Slave
|
66
|
+
#
|
67
|
+
# # good (won't be flagged despite containing `slave`)
|
68
|
+
# TeslaVehicle
|
59
69
|
class InclusiveLanguage < Base
|
60
70
|
include RangeHelp
|
61
71
|
|
62
72
|
EMPTY_ARRAY = [].freeze
|
73
|
+
MSG = "Consider replacing '%<term>s'%<suffix>s."
|
74
|
+
MSG_FOR_FILE_PATH = "Consider replacing '%<term>s' in file path%<suffix>s."
|
63
75
|
|
64
76
|
WordLocation = Struct.new(:word, :position)
|
65
77
|
|
@@ -123,7 +135,7 @@ module RuboCop
|
|
123
135
|
next if term_definition.nil?
|
124
136
|
|
125
137
|
allowed_strings.concat(process_allowed_regex(term_definition['AllowedRegex']))
|
126
|
-
regex_string = ensure_regex_string(term_definition
|
138
|
+
regex_string = ensure_regex_string(extract_regexp(term, term_definition))
|
127
139
|
flagged_term_strings << regex_string
|
128
140
|
|
129
141
|
add_to_flagged_term_hash(regex_string, term, term_definition)
|
@@ -132,6 +144,13 @@ module RuboCop
|
|
132
144
|
set_regexes(flagged_term_strings, allowed_strings)
|
133
145
|
end
|
134
146
|
|
147
|
+
def extract_regexp(term, term_definition)
|
148
|
+
return term_definition['Regex'] if term_definition['Regex']
|
149
|
+
return /(?:\b|(?<=[\W_]))#{term}(?:\b|(?=[\W_]))/ if term_definition['WholeWord']
|
150
|
+
|
151
|
+
term
|
152
|
+
end
|
153
|
+
|
135
154
|
def add_to_flagged_term_hash(regex_string, term, term_definition)
|
136
155
|
@flagged_term_hash[Regexp.new(regex_string, Regexp::IGNORECASE)] =
|
137
156
|
term_definition.merge('Term' => term,
|
@@ -180,12 +199,11 @@ module RuboCop
|
|
180
199
|
end
|
181
200
|
|
182
201
|
def create_single_word_message_for_file(word)
|
183
|
-
create_message(word
|
202
|
+
create_message(word, MSG_FOR_FILE_PATH)
|
184
203
|
end
|
185
204
|
|
186
205
|
def create_multiple_word_message_for_file(words)
|
187
|
-
|
188
|
-
"Consider replacing problematic terms #{quoted_words.join(', ')} in file path."
|
206
|
+
format(MSG_FOR_FILE_PATH, term: words.join("', '"), suffix: ' with other terms')
|
189
207
|
end
|
190
208
|
|
191
209
|
def scan_for_words(input)
|
@@ -206,9 +224,12 @@ module RuboCop
|
|
206
224
|
safe_str.gsub(@allowed_regex) { |match| '*' * match.size }
|
207
225
|
end
|
208
226
|
|
209
|
-
def create_message(word)
|
227
|
+
def create_message(word, message = MSG)
|
210
228
|
flagged_term = find_flagged_term(word)
|
211
|
-
|
229
|
+
suggestions = flagged_term['SuggestionString']
|
230
|
+
suggestions = ' with another term' if suggestions.blank?
|
231
|
+
|
232
|
+
format(message, term: word, suffix: suggestions)
|
212
233
|
end
|
213
234
|
|
214
235
|
def find_flagged_term(word)
|
@@ -218,10 +239,6 @@ module RuboCop
|
|
218
239
|
flagged_term
|
219
240
|
end
|
220
241
|
|
221
|
-
def create_message_for_file(word)
|
222
|
-
create_message(word).sub(/\.$/, ' in file path.')
|
223
|
-
end
|
224
|
-
|
225
242
|
def preprocess_suggestions(suggestions)
|
226
243
|
return '' if suggestions.nil? ||
|
227
244
|
(suggestions.is_a?(String) && suggestions.strip.empty?) || suggestions.empty?
|
@@ -59,8 +59,8 @@ module RuboCop
|
|
59
59
|
|
60
60
|
def check(send_node)
|
61
61
|
return if previous_line_comment?(send_node)
|
62
|
-
return unless grouped_style? && sibling_accessors(send_node).size > 1 ||
|
63
|
-
separated_style? && send_node.arguments.size > 1
|
62
|
+
return unless (grouped_style? && sibling_accessors(send_node).size > 1) ||
|
63
|
+
(separated_style? && send_node.arguments.size > 1)
|
64
64
|
|
65
65
|
message = message(send_node)
|
66
66
|
add_offense(send_node, message: message) do |corrector|
|
@@ -7,6 +7,10 @@ module RuboCop
|
|
7
7
|
# `||` instead. It can be configured to check only in conditions or in
|
8
8
|
# all contexts.
|
9
9
|
#
|
10
|
+
# It is marked as unsafe auto-correction because it may change the
|
11
|
+
# operator precedence between logical operators (`&&` and `||`) and
|
12
|
+
# semantic operators (`and` and `or`).
|
13
|
+
#
|
10
14
|
# @example EnforcedStyle: always
|
11
15
|
# # bad
|
12
16
|
# foo.save and return
|
@@ -1,11 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Metrics/ClassLength
|
3
4
|
module RuboCop
|
4
5
|
module Cop
|
5
6
|
module Style
|
6
7
|
# Check for uses of braces or do/end around single line or
|
7
8
|
# multi-line blocks.
|
8
9
|
#
|
10
|
+
# Methods that can be either procedural or functional and cannot be
|
11
|
+
# categorised from their usage alone is ignored.
|
12
|
+
# `lambda`, `proc`, and `it` are their defaults.
|
13
|
+
# Additional methods can be added to the `IgnoredMethods`.
|
14
|
+
#
|
9
15
|
# @example EnforcedStyle: line_count_based (default)
|
10
16
|
# # bad - single line block
|
11
17
|
# items.each do |item| item / 5 end
|
@@ -132,6 +138,17 @@ module RuboCop
|
|
132
138
|
# puts foo
|
133
139
|
# end
|
134
140
|
#
|
141
|
+
# @example IgnoredMethods: ['lambda', 'proc', 'it' ] (default)
|
142
|
+
#
|
143
|
+
# # good
|
144
|
+
# foo = lambda do |x|
|
145
|
+
# puts "Hello, #{x}"
|
146
|
+
# end
|
147
|
+
#
|
148
|
+
# foo = lambda do |x|
|
149
|
+
# x * 100
|
150
|
+
# end
|
151
|
+
#
|
135
152
|
class BlockDelimiters < Base
|
136
153
|
include ConfigurableEnforcedStyle
|
137
154
|
include IgnoredMethods
|
@@ -175,7 +192,7 @@ module RuboCop
|
|
175
192
|
if node.braces?
|
176
193
|
replace_braces_with_do_end(corrector, node.loc)
|
177
194
|
else
|
178
|
-
replace_do_end_with_braces(corrector, node
|
195
|
+
replace_do_end_with_braces(corrector, node)
|
179
196
|
end
|
180
197
|
end
|
181
198
|
|
@@ -240,7 +257,8 @@ module RuboCop
|
|
240
257
|
corrector.replace(e, 'end')
|
241
258
|
end
|
242
259
|
|
243
|
-
def replace_do_end_with_braces(corrector,
|
260
|
+
def replace_do_end_with_braces(corrector, node)
|
261
|
+
loc = node.loc
|
244
262
|
b = loc.begin
|
245
263
|
e = loc.end
|
246
264
|
|
@@ -248,6 +266,8 @@ module RuboCop
|
|
248
266
|
|
249
267
|
corrector.replace(b, '{')
|
250
268
|
corrector.replace(e, '}')
|
269
|
+
|
270
|
+
corrector.wrap(node.body, "begin\n", "\nend") if begin_required?(node)
|
251
271
|
end
|
252
272
|
|
253
273
|
def whitespace_before?(range)
|
@@ -259,14 +279,20 @@ module RuboCop
|
|
259
279
|
end
|
260
280
|
|
261
281
|
def move_comment_before_block(corrector, comment, block_node, closing_brace)
|
262
|
-
range =
|
263
|
-
|
264
|
-
corrector.remove(range_with_surrounding_space(range:
|
265
|
-
corrector.insert_after(
|
282
|
+
range = block_node.chained? ? end_of_chain(block_node.parent).source_range : closing_brace
|
283
|
+
comment_range = range_between(range.end_pos, comment.loc.expression.end_pos)
|
284
|
+
corrector.remove(range_with_surrounding_space(range: comment_range, side: :right))
|
285
|
+
corrector.insert_after(range, "\n")
|
266
286
|
|
267
287
|
corrector.insert_before(block_node, "#{comment.text}\n")
|
268
288
|
end
|
269
289
|
|
290
|
+
def end_of_chain(node)
|
291
|
+
return node unless node.chained?
|
292
|
+
|
293
|
+
end_of_chain(node.parent)
|
294
|
+
end
|
295
|
+
|
270
296
|
def get_blocks(node, &block)
|
271
297
|
case node.type
|
272
298
|
when :block
|
@@ -391,7 +417,14 @@ module RuboCop
|
|
391
417
|
def array_or_range?(node)
|
392
418
|
node.array_type? || node.range_type?
|
393
419
|
end
|
420
|
+
|
421
|
+
def begin_required?(block_node)
|
422
|
+
# If the block contains `rescue` or `ensure`, it needs to be wrapped in
|
423
|
+
# `begin`...`end` when changing `do-end` to `{}`.
|
424
|
+
block_node.each_child_node(:rescue, :ensure).any? && !block_node.single_line?
|
425
|
+
end
|
394
426
|
end
|
395
427
|
end
|
396
428
|
end
|
397
429
|
end
|
430
|
+
# rubocop:enable Metrics/ClassLength
|
@@ -5,9 +5,11 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# This cop checks for uses of the case equality operator(===).
|
7
7
|
#
|
8
|
+
# If `AllowOnConstant` option is enabled, the cop will ignore violations when the receiver of
|
9
|
+
# the case equality operator is a constant.
|
10
|
+
#
|
8
11
|
# @example
|
9
12
|
# # bad
|
10
|
-
# Array === something
|
11
13
|
# (1..100) === 7
|
12
14
|
# /something/ === some_string
|
13
15
|
#
|
@@ -16,18 +18,13 @@ module RuboCop
|
|
16
18
|
# (1..100).include?(7)
|
17
19
|
# /something/.match?(some_string)
|
18
20
|
#
|
19
|
-
# @example AllowOnConstant
|
20
|
-
# # Style/CaseEquality:
|
21
|
-
# # AllowOnConstant: true
|
22
|
-
#
|
21
|
+
# @example AllowOnConstant: false (default)
|
23
22
|
# # bad
|
24
|
-
#
|
25
|
-
# /something/ === some_string
|
23
|
+
# Array === something
|
26
24
|
#
|
25
|
+
# @example AllowOnConstant: true
|
27
26
|
# # good
|
28
27
|
# Array === something
|
29
|
-
# (1..100).include?(7)
|
30
|
-
# /something/.match?(some_string)
|
31
28
|
#
|
32
29
|
class CaseEquality < Base
|
33
30
|
extend AutoCorrector
|
@@ -68,7 +68,8 @@ module RuboCop
|
|
68
68
|
return false unless node.arguments.any?
|
69
69
|
|
70
70
|
node.last_argument.block_pass_type? ||
|
71
|
-
node.last_argument.sym_type? &&
|
71
|
+
(node.last_argument.sym_type? &&
|
72
|
+
methods_accepting_symbol.include?(node.method_name.to_s))
|
72
73
|
end
|
73
74
|
|
74
75
|
def message(node)
|
@@ -6,6 +6,9 @@ module RuboCop
|
|
6
6
|
# This cop checks that comment annotation keywords are written according
|
7
7
|
# to guidelines.
|
8
8
|
#
|
9
|
+
# Annotation keywords can be specified by overriding the cop's `Keywords`
|
10
|
+
# configuration. Keywords are allowed to be single words or phrases.
|
11
|
+
#
|
9
12
|
# NOTE: With a multiline comment block (where each line is only a
|
10
13
|
# comment), only the first line will be able to register an offense, even
|
11
14
|
# if an annotation keyword starts another line. This is done to prevent
|
@@ -56,7 +59,6 @@ module RuboCop
|
|
56
59
|
# # good
|
57
60
|
# # OPTIMIZE does not work
|
58
61
|
class CommentAnnotation < Base
|
59
|
-
include AnnotationComment
|
60
62
|
include RangeHelp
|
61
63
|
extend AutoCorrector
|
62
64
|
|
@@ -73,27 +75,27 @@ module RuboCop
|
|
73
75
|
next unless first_comment_line?(processed_source.comments, index) ||
|
74
76
|
inline_comment?(comment)
|
75
77
|
|
76
|
-
|
77
|
-
next unless annotation?
|
78
|
-
|
79
|
-
range = annotation_range(comment, margin, first_word, colon, space)
|
78
|
+
annotation = AnnotationComment.new(comment, keywords)
|
79
|
+
next unless annotation.annotation? && !annotation.correct?(colon: requires_colon?)
|
80
80
|
|
81
|
-
register_offense(
|
81
|
+
register_offense(annotation)
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
85
|
private
|
86
86
|
|
87
|
-
def register_offense(
|
88
|
-
|
87
|
+
def register_offense(annotation)
|
88
|
+
range = annotation_range(annotation)
|
89
|
+
message = if annotation.note
|
90
|
+
requires_colon? ? MSG_COLON_STYLE : MSG_SPACE_STYLE
|
91
|
+
else
|
92
|
+
MISSING_NOTE
|
93
|
+
end
|
89
94
|
|
90
|
-
add_offense(
|
91
|
-
|
92
|
-
message: format(note ? message : MISSING_NOTE, keyword: first_word)
|
93
|
-
) do |corrector|
|
94
|
-
next if note.nil?
|
95
|
+
add_offense(range, message: format(message, keyword: annotation.keyword)) do |corrector|
|
96
|
+
next if annotation.note.nil?
|
95
97
|
|
96
|
-
correct_offense(corrector, range,
|
98
|
+
correct_offense(corrector, range, annotation.keyword)
|
97
99
|
end
|
98
100
|
end
|
99
101
|
|
@@ -105,39 +107,23 @@ module RuboCop
|
|
105
107
|
!comment_line?(comment.loc.expression.source_line)
|
106
108
|
end
|
107
109
|
|
108
|
-
def annotation_range(
|
109
|
-
|
110
|
-
length = concat_length(first_word, colon, space)
|
111
|
-
range_between(start, start + length)
|
112
|
-
end
|
113
|
-
|
114
|
-
def concat_length(*args)
|
115
|
-
args.reduce(0) { |acc, elem| acc + elem.to_s.length }
|
110
|
+
def annotation_range(annotation)
|
111
|
+
range_between(*annotation.bounds)
|
116
112
|
end
|
117
113
|
|
118
|
-
def
|
119
|
-
return
|
114
|
+
def correct_offense(corrector, range, keyword)
|
115
|
+
return corrector.replace(range, "#{keyword.upcase}: ") if requires_colon?
|
120
116
|
|
121
|
-
|
122
|
-
end
|
123
|
-
|
124
|
-
def correct_colon_annotation?(first_word, colon, space, note)
|
125
|
-
keyword?(first_word) && (colon && space && note || !colon && !note)
|
126
|
-
end
|
127
|
-
|
128
|
-
def correct_space_annotation?(first_word, colon, space, note)
|
129
|
-
keyword?(first_word) && (!colon && space && note || !colon && !note)
|
130
|
-
end
|
131
|
-
|
132
|
-
def correct_offense(corrector, range, first_word)
|
133
|
-
return corrector.replace(range, "#{first_word.upcase}: ") if requires_colon?
|
134
|
-
|
135
|
-
corrector.replace(range, "#{first_word.upcase} ")
|
117
|
+
corrector.replace(range, "#{keyword.upcase} ")
|
136
118
|
end
|
137
119
|
|
138
120
|
def requires_colon?
|
139
121
|
cop_config['RequireColon']
|
140
122
|
end
|
123
|
+
|
124
|
+
def keywords
|
125
|
+
cop_config['Keywords']
|
126
|
+
end
|
141
127
|
end
|
142
128
|
end
|
143
129
|
end
|