rubocop 1.52.0 → 1.53.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 +38 -1
- data/lib/rubocop/cli/command/lsp.rb +19 -0
- data/lib/rubocop/cli.rb +3 -0
- data/lib/rubocop/config_loader_resolver.rb +4 -3
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_version.rb +2 -2
- data/lib/rubocop/cop/gemspec/dependency_version.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +32 -8
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +3 -3
- data/lib/rubocop/cop/layout/class_structure.rb +7 -0
- data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -1
- data/lib/rubocop/cop/lint/debugger.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +46 -19
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -2
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +1 -1
- data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +1 -2
- data/lib/rubocop/cop/lint/inherit_exception.rb +3 -1
- data/lib/rubocop/cop/lint/missing_super.rb +31 -5
- data/lib/rubocop/cop/lint/mixed_case_range.rb +109 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +5 -0
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +120 -0
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +8 -3
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +2 -2
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
- data/lib/rubocop/cop/lint/shadowed_exception.rb +5 -11
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/useless_assignment.rb +2 -1
- data/lib/rubocop/cop/lint/void.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
- data/lib/rubocop/cop/migration/department_name.rb +2 -2
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +3 -3
- data/lib/rubocop/cop/style/begin_block.rb +1 -2
- data/lib/rubocop/cop/style/block_comments.rb +1 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +3 -3
- data/lib/rubocop/cop/style/class_equality_comparison.rb +17 -39
- data/lib/rubocop/cop/style/conditional_assignment.rb +3 -1
- data/lib/rubocop/cop/style/dir.rb +1 -1
- data/lib/rubocop/cop/style/dir_empty.rb +8 -14
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
- data/lib/rubocop/cop/style/file_read.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +6 -2
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/redundant_conditional.rb +1 -1
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +38 -0
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +2 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +86 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +2 -1
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +3 -1
- data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -0
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +81 -0
- data/lib/rubocop/cop/style/signal_exception.rb +1 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +3 -1
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
- data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/utils/regexp_ranges.rb +100 -0
- data/lib/rubocop/cop/variable_force/assignment.rb +14 -1
- data/lib/rubocop/cops_documentation_generator.rb +1 -1
- data/lib/rubocop/ext/regexp_parser.rb +4 -1
- data/lib/rubocop/lsp/logger.rb +22 -0
- data/lib/rubocop/lsp/routes.rb +223 -0
- data/lib/rubocop/lsp/runtime.rb +79 -0
- data/lib/rubocop/lsp/server.rb +62 -0
- data/lib/rubocop/lsp/severity.rb +27 -0
- data/lib/rubocop/options.rb +11 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +8 -0
- metadata +36 -9
@@ -14,6 +14,13 @@ module RuboCop
|
|
14
14
|
# Autocorrection is not supported because the position of `super` cannot be
|
15
15
|
# determined automatically.
|
16
16
|
#
|
17
|
+
# `Object` and `BasicObject` are allowed by this cop because of their
|
18
|
+
# stateless nature. However, sometimes you might want to allow other parent
|
19
|
+
# classes from this cop, for example in the case of an abstract class that is
|
20
|
+
# not meant to be called with `super`. In those cases, you can use the
|
21
|
+
# `AllowedParentClasses` option to specify which classes should be allowed
|
22
|
+
# *in addition to* `Object` and `BasicObject`.
|
23
|
+
#
|
17
24
|
# @example
|
18
25
|
# # bad
|
19
26
|
# class Employee < Person
|
@@ -60,6 +67,21 @@ module RuboCop
|
|
60
67
|
# end
|
61
68
|
# end
|
62
69
|
#
|
70
|
+
# # good
|
71
|
+
# class ClassWithNoParent
|
72
|
+
# def initialize
|
73
|
+
# do_something
|
74
|
+
# end
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# @example AllowedParentClasses: [MyAbstractClass]
|
78
|
+
# # good
|
79
|
+
# class MyConcreteClass < MyAbstractClass
|
80
|
+
# def initialize
|
81
|
+
# do_something
|
82
|
+
# end
|
83
|
+
# end
|
84
|
+
#
|
63
85
|
class MissingSuper < Base
|
64
86
|
CONSTRUCTOR_MSG = 'Call `super` to initialize state of the parent class.'
|
65
87
|
CALLBACK_MSG = 'Call `super` to invoke callback defined in the parent class.'
|
@@ -103,7 +125,7 @@ module RuboCop
|
|
103
125
|
end
|
104
126
|
|
105
127
|
def callback_method_def?(node)
|
106
|
-
return unless CALLBACKS.include?(node.method_name)
|
128
|
+
return false unless CALLBACKS.include?(node.method_name)
|
107
129
|
|
108
130
|
node.each_ancestor(:class, :sclass, :module).first
|
109
131
|
end
|
@@ -116,16 +138,20 @@ module RuboCop
|
|
116
138
|
if (block_node = node.each_ancestor(:block, :numblock).first)
|
117
139
|
return false unless (super_class = class_new_block(block_node))
|
118
140
|
|
119
|
-
!
|
141
|
+
!allowed_class?(super_class)
|
120
142
|
elsif (class_node = node.each_ancestor(:class).first)
|
121
|
-
class_node.parent_class && !
|
143
|
+
class_node.parent_class && !allowed_class?(class_node.parent_class)
|
122
144
|
else
|
123
145
|
false
|
124
146
|
end
|
125
147
|
end
|
126
148
|
|
127
|
-
def
|
128
|
-
|
149
|
+
def allowed_class?(node)
|
150
|
+
allowed_classes.include?(node.const_name)
|
151
|
+
end
|
152
|
+
|
153
|
+
def allowed_classes
|
154
|
+
@allowed_classes ||= STATELESS_CLASSES + cop_config.fetch('AllowedParentClasses', [])
|
129
155
|
end
|
130
156
|
end
|
131
157
|
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for mixed-case character ranges since they include likely unintended characters.
|
7
|
+
#
|
8
|
+
# Offenses are registered for regexp character classes like `/[A-z]/`
|
9
|
+
# as well as range objects like `('A'..'z')`.
|
10
|
+
#
|
11
|
+
# NOTE: Range objects cannot be autocorrected.
|
12
|
+
#
|
13
|
+
# @safety
|
14
|
+
# The cop autocorrects regexp character classes
|
15
|
+
# by replacing one character range with two: `A-z` becomes `A-Za-z`.
|
16
|
+
# In most cases this is probably what was originally intended
|
17
|
+
# but it changes the regexp to no longer match symbols it used to include.
|
18
|
+
# For this reason, this cop's autocorrect is unsafe (it will
|
19
|
+
# change the behavior of the code).
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
#
|
23
|
+
# # bad
|
24
|
+
# r = /[A-z]/
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# r = /[A-Za-z]/
|
28
|
+
class MixedCaseRange < Base
|
29
|
+
extend AutoCorrector
|
30
|
+
include RangeHelp
|
31
|
+
|
32
|
+
MSG = 'Ranges from upper to lower case ASCII letters may include unintended ' \
|
33
|
+
'characters. Instead of `A-z` (which also includes several symbols) ' \
|
34
|
+
'specify each range individually: `A-Za-z` and individually specify any symbols.'
|
35
|
+
RANGES = [('a'..'z').freeze, ('A'..'Z').freeze].freeze
|
36
|
+
|
37
|
+
def on_irange(node)
|
38
|
+
return unless node.children.compact.all?(&:str_type?)
|
39
|
+
|
40
|
+
range_start, range_end = node.children
|
41
|
+
|
42
|
+
return if range_start.nil? || range_end.nil?
|
43
|
+
|
44
|
+
add_offense(node) if unsafe_range?(range_start.value, range_end.value)
|
45
|
+
end
|
46
|
+
alias on_erange on_irange
|
47
|
+
|
48
|
+
def on_regexp(node)
|
49
|
+
each_unsafe_regexp_range(node) do |loc|
|
50
|
+
add_offense(loc) do |corrector|
|
51
|
+
corrector.replace(loc, rewrite_regexp_range(loc.source))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def each_unsafe_regexp_range(node)
|
57
|
+
node.parsed_tree&.each_expression do |expr|
|
58
|
+
next if skip_expression?(expr)
|
59
|
+
|
60
|
+
range_pairs(expr).reject do |range_start, range_end|
|
61
|
+
next if skip_range?(range_start, range_end)
|
62
|
+
|
63
|
+
next unless unsafe_range?(range_start.text, range_end.text)
|
64
|
+
|
65
|
+
yield(build_source_range(range_start, range_end))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def build_source_range(range_start, range_end)
|
73
|
+
range_between(range_start.expression.begin_pos, range_end.expression.end_pos)
|
74
|
+
end
|
75
|
+
|
76
|
+
def range_for(char)
|
77
|
+
RANGES.detect do |range|
|
78
|
+
range.include?(char)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def range_pairs(expr)
|
83
|
+
RuboCop::Cop::Utils::RegexpRanges.new(expr).pairs
|
84
|
+
end
|
85
|
+
|
86
|
+
def unsafe_range?(range_start, range_end)
|
87
|
+
range_for(range_start) != range_for(range_end)
|
88
|
+
end
|
89
|
+
|
90
|
+
def skip_expression?(expr)
|
91
|
+
!(expr.type == :set && expr.token == :character)
|
92
|
+
end
|
93
|
+
|
94
|
+
def skip_range?(range_start, range_end)
|
95
|
+
[range_start, range_end].any? do |bound|
|
96
|
+
bound.type == :escape
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def rewrite_regexp_range(source)
|
101
|
+
open, close = source.split('-')
|
102
|
+
first = [open, range_for(open).end]
|
103
|
+
second = [range_for(close).begin, close]
|
104
|
+
"#{first.uniq.join('-')}#{second.uniq.join('-')}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -74,6 +74,7 @@ module RuboCop
|
|
74
74
|
extend AutoCorrector
|
75
75
|
include AllowedMethods
|
76
76
|
include AllowedPattern
|
77
|
+
include IgnoredNode
|
77
78
|
|
78
79
|
CONVERSION_METHOD_CLASS_MAPPING = {
|
79
80
|
to_i: "#{Integer.name}(%<number_object>s, 10)",
|
@@ -116,7 +117,11 @@ module RuboCop
|
|
116
117
|
corrected_method: correct_method(node, receiver)
|
117
118
|
)
|
118
119
|
add_offense(node, message: message) do |corrector|
|
120
|
+
next if part_of_ignored_node?(node)
|
121
|
+
|
119
122
|
corrector.replace(node, correct_method(node, node.receiver))
|
123
|
+
|
124
|
+
ignore_node(node)
|
120
125
|
end
|
121
126
|
end
|
122
127
|
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for redundant quantifiers inside Regexp literals.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# /(?:x+)+/
|
11
|
+
#
|
12
|
+
# # good
|
13
|
+
# /(?:x)+/
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# /(?:x+)/
|
17
|
+
#
|
18
|
+
# # bad
|
19
|
+
# /(?:x+)?/
|
20
|
+
#
|
21
|
+
# # good
|
22
|
+
# /(?:x)*/
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
# /(?:x*)/
|
26
|
+
class RedundantRegexpQuantifiers < Base
|
27
|
+
include RangeHelp
|
28
|
+
extend AutoCorrector
|
29
|
+
|
30
|
+
MSG_REDUNDANT_QUANTIFIER = 'Replace redundant quantifiers ' \
|
31
|
+
'`%<inner_quantifier>s` and `%<outer_quantifier>s` ' \
|
32
|
+
'with a single `%<replacement>s`.'
|
33
|
+
|
34
|
+
def on_regexp(node)
|
35
|
+
each_redundantly_quantified_pair(node) do |group, child|
|
36
|
+
replacement = merged_quantifier(group, child)
|
37
|
+
add_offense(
|
38
|
+
quantifier_range(group, child),
|
39
|
+
message: message(group, child, replacement)
|
40
|
+
) do |corrector|
|
41
|
+
# drop outer quantifier
|
42
|
+
corrector.replace(group.loc.quantifier, '')
|
43
|
+
# replace inner quantifier
|
44
|
+
corrector.replace(child.loc.quantifier, replacement)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def each_redundantly_quantified_pair(node)
|
52
|
+
seen = Set.new
|
53
|
+
node.parsed_tree&.each_expression do |(expr)|
|
54
|
+
next if seen.include?(expr) || !redundant_group?(expr) || !mergeable_quantifier(expr)
|
55
|
+
|
56
|
+
expr.each_expression do |(subexp)|
|
57
|
+
seen << subexp
|
58
|
+
break unless redundantly_quantifiable?(subexp)
|
59
|
+
|
60
|
+
yield(expr, subexp) if mergeable_quantifier(subexp)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def redundant_group?(expr)
|
66
|
+
expr.is?(:passive, :group) && expr.count { |child| child.type != :free_space } == 1
|
67
|
+
end
|
68
|
+
|
69
|
+
def redundantly_quantifiable?(node)
|
70
|
+
redundant_group?(node) || character_set?(node) || node.terminal?
|
71
|
+
end
|
72
|
+
|
73
|
+
def character_set?(expr)
|
74
|
+
expr.is?(:character, :set)
|
75
|
+
end
|
76
|
+
|
77
|
+
def mergeable_quantifier(expr)
|
78
|
+
# Merging reluctant or possessive quantifiers would be more complex,
|
79
|
+
# and Ruby does not emit warnings for these cases.
|
80
|
+
return unless expr.quantifier&.greedy?
|
81
|
+
|
82
|
+
# normalize quantifiers, e.g. "{1,}" => "+"
|
83
|
+
case expr.quantity
|
84
|
+
when [0, -1]
|
85
|
+
'*'
|
86
|
+
when [0, 1]
|
87
|
+
'?'
|
88
|
+
when [1, -1]
|
89
|
+
'+'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def merged_quantifier(exp1, exp2)
|
94
|
+
quantifier1 = mergeable_quantifier(exp1)
|
95
|
+
quantifier2 = mergeable_quantifier(exp2)
|
96
|
+
if quantifier1 == quantifier2
|
97
|
+
# (?:a+)+ equals (?:a+) ; (?:a*)* equals (?:a*) ; # (?:a?)? equals (?:a?)
|
98
|
+
quantifier1
|
99
|
+
else
|
100
|
+
# (?:a+)*, (?:a+)?, (?:a*)+, (?:a*)?, (?:a?)+, (?:a?)* - all equal (?:a*)
|
101
|
+
'*'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def quantifier_range(group, child)
|
106
|
+
range_between(child.loc.quantifier.begin_pos, group.loc.quantifier.end_pos)
|
107
|
+
end
|
108
|
+
|
109
|
+
def message(group, child, replacement)
|
110
|
+
format(
|
111
|
+
MSG_REDUNDANT_QUANTIFIER,
|
112
|
+
inner_quantifier: child.quantifier.to_s,
|
113
|
+
outer_quantifier: group.quantifier.to_s,
|
114
|
+
replacement: replacement
|
115
|
+
)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -49,6 +49,11 @@ module RuboCop
|
|
49
49
|
(str #redundant_feature?))
|
50
50
|
PATTERN
|
51
51
|
|
52
|
+
# @!method pp_const?(node)
|
53
|
+
def_node_matcher :pp_const?, <<~PATTERN
|
54
|
+
(const {nil? cbase} :PP)
|
55
|
+
PATTERN
|
56
|
+
|
52
57
|
def on_send(node)
|
53
58
|
return unless redundant_require_statement?(node)
|
54
59
|
|
@@ -72,16 +77,16 @@ module RuboCop
|
|
72
77
|
feature_name == 'enumerator' ||
|
73
78
|
(target_ruby_version >= 2.1 && feature_name == 'thread') ||
|
74
79
|
(target_ruby_version >= 2.2 && RUBY_22_LOADED_FEATURES.include?(feature_name)) ||
|
75
|
-
(target_ruby_version >= 2.5 && feature_name == 'pp' && !
|
80
|
+
(target_ruby_version >= 2.5 && feature_name == 'pp' && !need_to_require_pp?) ||
|
76
81
|
(target_ruby_version >= 2.7 && feature_name == 'ruby2_keywords') ||
|
77
82
|
(target_ruby_version >= 3.1 && feature_name == 'fiber') ||
|
78
83
|
(target_ruby_version >= 3.2 && feature_name == 'set')
|
79
84
|
end
|
80
85
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
81
86
|
|
82
|
-
def
|
87
|
+
def need_to_require_pp?
|
83
88
|
processed_source.ast.each_descendant(:send).any? do |node|
|
84
|
-
PRETTY_PRINT_METHODS.include?(node.method_name)
|
89
|
+
pp_const?(node.receiver) || PRETTY_PRINT_METHODS.include?(node.method_name)
|
85
90
|
end
|
86
91
|
end
|
87
92
|
end
|
@@ -49,7 +49,7 @@ module RuboCop
|
|
49
49
|
# do_something if attrs&.not_nil_safe_method(:[])
|
50
50
|
#
|
51
51
|
class RedundantSafeNavigation < Base
|
52
|
-
include
|
52
|
+
include AllowedMethods
|
53
53
|
include RangeHelp
|
54
54
|
extend AutoCorrector
|
55
55
|
|
@@ -63,7 +63,7 @@ module RuboCop
|
|
63
63
|
PATTERN
|
64
64
|
|
65
65
|
def on_csend(node)
|
66
|
-
return unless check?(node) &&
|
66
|
+
return unless check?(node) && allowed_method?(node.method_name)
|
67
67
|
return if respond_to_nil_specific_method?(node)
|
68
68
|
|
69
69
|
range = range_between(node.loc.dot.begin_pos, node.source_range.end_pos)
|
@@ -3,8 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
#
|
7
|
-
# This cop checks for `send`, `public_send`, and `__send__` methods
|
6
|
+
# Checks for `send`, `public_send`, and `__send__` methods
|
8
7
|
# when using mix-in.
|
9
8
|
#
|
10
9
|
# `include` and `prepend` methods were private methods until Ruby 2.0,
|
@@ -121,18 +121,12 @@ module RuboCop
|
|
121
121
|
|
122
122
|
if rescued_exceptions.any?
|
123
123
|
rescued_exceptions.each_with_object([]) do |exception, converted|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
begin
|
128
|
-
RuboCop::Util.silence_warnings do
|
129
|
-
# Avoid printing deprecation warnings about constants
|
130
|
-
converted << Kernel.const_get(exception.source)
|
131
|
-
end
|
132
|
-
rescue NameError
|
133
|
-
converted << nil
|
124
|
+
RuboCop::Util.silence_warnings do
|
125
|
+
# Avoid printing deprecation warnings about constants
|
126
|
+
converted << Kernel.const_get(exception.source)
|
134
127
|
end
|
135
|
-
|
128
|
+
rescue NameError
|
129
|
+
converted << nil
|
136
130
|
end
|
137
131
|
else
|
138
132
|
# treat an empty `rescue` as `rescue StandardError`
|
@@ -117,7 +117,7 @@ module RuboCop
|
|
117
117
|
|
118
118
|
def comment_between_rescue_and_end?(node)
|
119
119
|
ancestor = node.each_ancestor(:kwbegin, :def, :defs, :block, :numblock).first
|
120
|
-
return unless ancestor
|
120
|
+
return false unless ancestor
|
121
121
|
|
122
122
|
end_line = ancestor.loc.end.line
|
123
123
|
processed_source[node.first_line...end_line].any? { |line| comment_line?(line) }
|
@@ -136,7 +136,8 @@ module RuboCop
|
|
136
136
|
def autocorrect(corrector, assignment)
|
137
137
|
if assignment.exception_assignment?
|
138
138
|
remove_exception_assignment_part(corrector, assignment.node)
|
139
|
-
elsif assignment.multiple_assignment? || assignment.rest_assignment?
|
139
|
+
elsif assignment.multiple_assignment? || assignment.rest_assignment? ||
|
140
|
+
assignment.for_assignment?
|
140
141
|
rename_variable_with_underscore(corrector, assignment.node)
|
141
142
|
elsif assignment.operator_assignment?
|
142
143
|
remove_trailing_character_from_operator(corrector, assignment.node)
|
@@ -144,7 +144,7 @@ module RuboCop
|
|
144
144
|
end
|
145
145
|
|
146
146
|
def check_nonmutating(node)
|
147
|
-
return
|
147
|
+
return if !node.send_type? && !node.block_type? && !node.numblock_type?
|
148
148
|
|
149
149
|
method_name = node.method_name
|
150
150
|
return unless NONMUTATING_METHODS.include?(method_name)
|
@@ -16,7 +16,7 @@ module RuboCop
|
|
16
16
|
# The token that makes up a disable comment.
|
17
17
|
# The allowed specification for comments after `# rubocop: disable` is
|
18
18
|
# `DepartmentName/CopName` or` all`.
|
19
|
-
DISABLING_COPS_CONTENT_TOKEN = %r{[A-z]+/[A-z]+|all}.freeze
|
19
|
+
DISABLING_COPS_CONTENT_TOKEN = %r{[A-Za-z]+/[A-Za-z]+|all}.freeze
|
20
20
|
|
21
21
|
def on_new_investigation
|
22
22
|
processed_source.comments.each do |comment|
|
@@ -67,7 +67,7 @@ module RuboCop
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def contain_unexpected_character_for_department_name?(name)
|
70
|
-
name.match?(%r{[^A-z/, ]})
|
70
|
+
name.match?(%r{[^A-Za-z/, ]})
|
71
71
|
end
|
72
72
|
|
73
73
|
def qualified_legacy_cop_name(cop_name)
|
@@ -25,7 +25,7 @@ module RuboCop
|
|
25
25
|
def comments_contain_disables?(node, cop_name)
|
26
26
|
disabled_ranges = processed_source.disabled_line_ranges[cop_name]
|
27
27
|
|
28
|
-
return unless disabled_ranges
|
28
|
+
return false unless disabled_ranges
|
29
29
|
|
30
30
|
node_range = node.source_range.line...find_end_line(node)
|
31
31
|
|
@@ -109,7 +109,7 @@ module RuboCop
|
|
109
109
|
end
|
110
110
|
|
111
111
|
def use_block_argument_as_local_variable?(node, last_argument)
|
112
|
-
return if node.body.nil?
|
112
|
+
return false if node.body.nil?
|
113
113
|
|
114
114
|
node.body.each_descendant(:lvar, :lvasgn).any? do |lvar|
|
115
115
|
!lvar.parent.block_pass_type? && lvar.node_parts[0].to_s == last_argument
|
@@ -204,14 +204,14 @@ module RuboCop
|
|
204
204
|
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
205
205
|
def on_defined?(node)
|
206
206
|
arg = node.arguments.first
|
207
|
-
return unless arg.ivar_type?
|
207
|
+
return false unless arg.ivar_type?
|
208
208
|
|
209
209
|
method_node, method_name = find_definition(node)
|
210
|
-
return unless method_node
|
210
|
+
return false unless method_node
|
211
211
|
|
212
212
|
var_name = arg.children.first
|
213
213
|
defined_memoized?(method_node.body, var_name) do |defined_ivar, return_ivar, ivar_assign|
|
214
|
-
return if matches?(method_name, ivar_assign)
|
214
|
+
return false if matches?(method_name, ivar_assign)
|
215
215
|
|
216
216
|
suggested_var = suggested_var(method_name)
|
217
217
|
msg = format(
|
@@ -35,7 +35,7 @@ module RuboCop
|
|
35
35
|
unless contents.empty?
|
36
36
|
corrector.replace(
|
37
37
|
contents,
|
38
|
-
contents.source.gsub(/\A/, '# ').gsub(
|
38
|
+
contents.source.gsub(/\A/, '# ').gsub("\n\n", "\n#\n").gsub(/\n(?=[^#])/, "\n# ")
|
39
39
|
)
|
40
40
|
end
|
41
41
|
corrector.remove(eq_end)
|
@@ -411,7 +411,7 @@ module RuboCop
|
|
411
411
|
end
|
412
412
|
|
413
413
|
def correction_would_break_code?(node)
|
414
|
-
return unless node.keywords?
|
414
|
+
return false unless node.keywords?
|
415
415
|
|
416
416
|
node.send_node.arguments? && !node.send_node.parenthesized?
|
417
417
|
end
|
@@ -433,7 +433,7 @@ module RuboCop
|
|
433
433
|
end
|
434
434
|
|
435
435
|
def return_value_used?(node)
|
436
|
-
return unless node.parent
|
436
|
+
return false unless node.parent
|
437
437
|
|
438
438
|
# If there are parentheses around the block, check if that
|
439
439
|
# is being used.
|
@@ -445,7 +445,7 @@ module RuboCop
|
|
445
445
|
end
|
446
446
|
|
447
447
|
def return_value_of_scope?(node)
|
448
|
-
return unless node.parent
|
448
|
+
return false unless node.parent
|
449
449
|
|
450
450
|
conditional?(node.parent) || array_or_range?(node.parent) ||
|
451
451
|
node.parent.children.last == node
|
@@ -5,7 +5,7 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Enforces the use of `Object#instance_of?` instead of class comparison
|
7
7
|
# for equality.
|
8
|
-
# `==`, `equal?`, and `eql?`
|
8
|
+
# `==`, `equal?`, and `eql?` custom method definitions are allowed by default.
|
9
9
|
# These are customizable with `AllowedMethods` option.
|
10
10
|
#
|
11
11
|
# @example
|
@@ -18,53 +18,31 @@ module RuboCop
|
|
18
18
|
# # good
|
19
19
|
# var.instance_of?(Date)
|
20
20
|
#
|
21
|
-
# @example AllowedMethods: [] (default)
|
21
|
+
# @example AllowedMethods: ['==', 'equal?', 'eql?'] (default)
|
22
22
|
# # good
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
# var.class == Date
|
27
|
-
# var.class.equal?(Date)
|
28
|
-
# var.class.eql?(Date)
|
29
|
-
# var.class.name == 'Date'
|
30
|
-
# var.class.to_s == 'Date'
|
31
|
-
# var.class.inspect == 'Date'
|
23
|
+
# def ==(other)
|
24
|
+
# self.class == other.class && name == other.name
|
25
|
+
# end
|
32
26
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
# var.class == Date
|
37
|
-
# var.class.name == 'Date'
|
38
|
-
# var.class.to_s == 'Date'
|
39
|
-
# var.class.inspect == 'Date'
|
27
|
+
# def equal?(other)
|
28
|
+
# self.class.equal?(other.class) && name.equal?(other.name)
|
29
|
+
# end
|
40
30
|
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
31
|
+
# def eql?(other)
|
32
|
+
# self.class.eql?(other.class) && name.eql?(other.name)
|
33
|
+
# end
|
44
34
|
#
|
45
35
|
# @example AllowedPatterns: [] (default)
|
46
|
-
# # good
|
47
|
-
# var.instance_of?(Date)
|
48
|
-
#
|
49
36
|
# # bad
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
# var.class.name == 'Date'
|
54
|
-
# var.class.to_s == 'Date'
|
55
|
-
# var.class.inspect == 'Date'
|
37
|
+
# def eq(other)
|
38
|
+
# self.class.eq(other.class) && name.eq(other.name)
|
39
|
+
# end
|
56
40
|
#
|
57
41
|
# @example AllowedPatterns: ['eq']
|
58
42
|
# # good
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
# # bad
|
64
|
-
# var.class == Date
|
65
|
-
# var.class.name == 'Date'
|
66
|
-
# var.class.to_s == 'Date'
|
67
|
-
# var.class.inspect == 'Date'
|
43
|
+
# def eq(other)
|
44
|
+
# self.class.eq(other.class) && name.eq(other.name)
|
45
|
+
# end
|
68
46
|
#
|
69
47
|
class ClassEqualityComparison < Base
|
70
48
|
include RangeHelp
|