rubocop 1.18.3 → 1.20.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 +46 -7
- 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/config_validator.rb +18 -5
- data/lib/rubocop/cop/bundler/gem_filename.rb +103 -0
- data/lib/rubocop/cop/bundler/ordered_gems.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/class_structure.rb +5 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +9 -0
- data/lib/rubocop/cop/layout/end_alignment.rb +10 -2
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/hash_alignment.rb +22 -18
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +0 -7
- data/lib/rubocop/cop/layout/indentation_style.rb +2 -2
- data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +33 -14
- 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/space_around_operators.rb +8 -1
- 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/trailing_whitespace.rb +24 -1
- 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 -2
- data/lib/rubocop/cop/lint/duplicate_branch.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +8 -5
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -1
- data/lib/rubocop/cop/mixin/annotation_comment.rb +57 -34
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
- data/lib/rubocop/cop/mixin/documentation_comment.rb +5 -2
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +14 -1
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +6 -1
- data/lib/rubocop/cop/mixin/heredoc.rb +7 -0
- data/lib/rubocop/cop/mixin/percent_array.rb +13 -7
- 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/inclusive_language.rb +18 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +39 -6
- 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/double_cop_disable_directive.rb +1 -7
- data/lib/rubocop/cop/style/double_negation.rb +12 -1
- data/lib/rubocop/cop/style/encoding.rb +26 -15
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
- data/lib/rubocop/cop/style/explicit_block_argument.rb +32 -7
- 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/method_def_parentheses.rb +10 -1
- data/lib/rubocop/cop/style/missing_else.rb +7 -0
- data/lib/rubocop/cop/style/mutable_constant.rb +73 -13
- data/lib/rubocop/cop/style/redundant_begin.rb +25 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +4 -3
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +83 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
- 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/single_line_methods.rb +14 -9
- 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/struct_inheritance.rb +3 -0
- data/lib/rubocop/cop/style/symbol_array.rb +3 -3
- data/lib/rubocop/cop/style/word_array.rb +23 -5
- data/lib/rubocop/cop/util.rb +7 -2
- data/lib/rubocop/formatter/git_hub_actions_formatter.rb +1 -1
- data/lib/rubocop/magic_comment.rb +44 -15
- data/lib/rubocop/options.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +6 -1
- metadata +12 -5
@@ -97,9 +97,9 @@ module RuboCop
|
|
97
97
|
# If a send node contains a heredoc argument, splitting cannot happen
|
98
98
|
# after the heredoc or else it will cause a syntax error.
|
99
99
|
def shift_elements_for_heredoc_arg(node, elements, index)
|
100
|
-
return index unless node.send_type?
|
100
|
+
return index unless node.send_type? || node.array_type?
|
101
101
|
|
102
|
-
heredoc_index = elements.index { |arg|
|
102
|
+
heredoc_index = elements.index { |arg| arg.respond_to?(:heredoc?) && arg.heredoc? }
|
103
103
|
return index unless heredoc_index
|
104
104
|
return nil if heredoc_index.zero?
|
105
105
|
|
@@ -5,7 +5,6 @@ module RuboCop
|
|
5
5
|
# Common functionality for checking documentation.
|
6
6
|
module DocumentationComment
|
7
7
|
extend NodePattern::Macros
|
8
|
-
include Style::AnnotationComment
|
9
8
|
|
10
9
|
private
|
11
10
|
|
@@ -15,7 +14,7 @@ module RuboCop
|
|
15
14
|
return false unless preceding_comment?(node, preceding_lines.last)
|
16
15
|
|
17
16
|
preceding_lines.any? do |comment|
|
18
|
-
!
|
17
|
+
!AnnotationComment.new(comment, annotation_keywords).annotation? &&
|
19
18
|
!interpreter_directive_comment?(comment) &&
|
20
19
|
!rubocop_directive_comment?(comment)
|
21
20
|
end
|
@@ -44,6 +43,10 @@ module RuboCop
|
|
44
43
|
def rubocop_directive_comment?(comment)
|
45
44
|
!!DirectiveComment.new(comment).match_captures
|
46
45
|
end
|
46
|
+
|
47
|
+
def annotation_keywords
|
48
|
+
config.for_cop('Style/CommentAnnotation')['Keywords']
|
49
|
+
end
|
47
50
|
end
|
48
51
|
end
|
49
52
|
end
|
@@ -8,7 +8,10 @@ module RuboCop
|
|
8
8
|
|
9
9
|
FROZEN_STRING_LITERAL = '# frozen_string_literal:'
|
10
10
|
FROZEN_STRING_LITERAL_ENABLED = '# frozen_string_literal: true'
|
11
|
-
|
11
|
+
FROZEN_STRING_LITERAL_TYPES_RUBY27 = %i[str dstr].freeze
|
12
|
+
FROZEN_STRING_LITERAL_TYPES_RUBY30 = %i[str].freeze
|
13
|
+
|
14
|
+
private_constant :FROZEN_STRING_LITERAL_TYPES_RUBY27, :FROZEN_STRING_LITERAL_TYPES_RUBY30
|
12
15
|
|
13
16
|
def frozen_string_literal_comment_exists?
|
14
17
|
leading_comment_lines.any? { |line| MagicComment.parse(line).valid_literal_value? }
|
@@ -16,6 +19,16 @@ module RuboCop
|
|
16
19
|
|
17
20
|
private
|
18
21
|
|
22
|
+
def frozen_string_literal?(node)
|
23
|
+
literal_types = if target_ruby_version >= 3.0
|
24
|
+
FROZEN_STRING_LITERAL_TYPES_RUBY30
|
25
|
+
else
|
26
|
+
FROZEN_STRING_LITERAL_TYPES_RUBY27
|
27
|
+
end
|
28
|
+
|
29
|
+
literal_types.include?(node.type) && frozen_string_literals_enabled?
|
30
|
+
end
|
31
|
+
|
19
32
|
def frozen_string_literals_enabled?
|
20
33
|
ruby_version = processed_source.ruby_version
|
21
34
|
return false unless ruby_version
|
@@ -175,7 +175,12 @@ module RuboCop
|
|
175
175
|
end
|
176
176
|
|
177
177
|
def set_new_body_expression(transforming_body_expr, corrector)
|
178
|
-
|
178
|
+
body_source = transforming_body_expr.loc.expression.source
|
179
|
+
if transforming_body_expr.hash_type? && !transforming_body_expr.braces?
|
180
|
+
body_source = "{ #{body_source} }"
|
181
|
+
end
|
182
|
+
|
183
|
+
corrector.replace(block_node.body, body_source)
|
179
184
|
end
|
180
185
|
end
|
181
186
|
end
|
@@ -20,6 +20,13 @@ module RuboCop
|
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
|
+
def indent_level(str)
|
24
|
+
indentations = str.lines
|
25
|
+
.map { |line| line[/^\s*/] }
|
26
|
+
.reject { |line| line.end_with?("\n") }
|
27
|
+
indentations.empty? ? 0 : indentations.min_by(&:size).size
|
28
|
+
end
|
29
|
+
|
23
30
|
def delimiter_string(node)
|
24
31
|
node.source.match(OPENING_DELIMITER).captures[1]
|
25
32
|
end
|
@@ -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
|
@@ -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
|
@@ -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,6 +58,14 @@ 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
|
|
@@ -123,7 +133,7 @@ module RuboCop
|
|
123
133
|
next if term_definition.nil?
|
124
134
|
|
125
135
|
allowed_strings.concat(process_allowed_regex(term_definition['AllowedRegex']))
|
126
|
-
regex_string = ensure_regex_string(term_definition
|
136
|
+
regex_string = ensure_regex_string(extract_regexp(term, term_definition))
|
127
137
|
flagged_term_strings << regex_string
|
128
138
|
|
129
139
|
add_to_flagged_term_hash(regex_string, term, term_definition)
|
@@ -132,6 +142,13 @@ module RuboCop
|
|
132
142
|
set_regexes(flagged_term_strings, allowed_strings)
|
133
143
|
end
|
134
144
|
|
145
|
+
def extract_regexp(term, term_definition)
|
146
|
+
return term_definition['Regex'] if term_definition['Regex']
|
147
|
+
return /(?:\b|(?<=[\W_]))#{term}(?:\b|(?=[\W_]))/ if term_definition['WholeWord']
|
148
|
+
|
149
|
+
term
|
150
|
+
end
|
151
|
+
|
135
152
|
def add_to_flagged_term_hash(regex_string, term, term_definition)
|
136
153
|
@flagged_term_hash[Regexp.new(regex_string, Regexp::IGNORECASE)] =
|
137
154
|
term_definition.merge('Term' => term,
|
@@ -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
|
@@ -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
|