rubocop 0.93.1 → 1.6.1
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 +36 -16
- data/config/default.yml +276 -82
- data/config/obsoletion.yml +196 -0
- data/exe/rubocop +1 -1
- data/lib/rubocop.rb +31 -2
- data/lib/rubocop/cli.rb +5 -1
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +1 -1
- data/lib/rubocop/cli/command/execute_runner.rb +26 -11
- data/lib/rubocop/cli/command/suggest_extensions.rb +80 -0
- data/lib/rubocop/cli/command/version.rb +1 -1
- data/lib/rubocop/comment_config.rb +1 -1
- data/lib/rubocop/config.rb +4 -0
- data/lib/rubocop/config_loader.rb +34 -8
- data/lib/rubocop/config_loader_resolver.rb +12 -6
- data/lib/rubocop/config_obsoletion.rb +65 -247
- 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_regeneration.rb +1 -1
- data/lib/rubocop/config_validator.rb +25 -10
- data/lib/rubocop/cop/autocorrect_logic.rb +21 -6
- data/lib/rubocop/cop/badge.rb +9 -24
- data/lib/rubocop/cop/base.rb +33 -16
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +26 -6
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/commissioner.rb +37 -23
- data/lib/rubocop/cop/cop.rb +2 -2
- data/lib/rubocop/cop/corrector.rb +3 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/string_literal_corrector.rb +6 -8
- data/lib/rubocop/cop/force.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +3 -3
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +4 -5
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
- data/lib/rubocop/cop/generator.rb +3 -10
- data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +1 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/class_structure.rb +22 -3
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +15 -2
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +80 -10
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +6 -1
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +3 -3
- data/lib/rubocop/cop/layout/end_of_line.rb +5 -5
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -2
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +7 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +4 -4
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +12 -0
- data/lib/rubocop/cop/layout/line_length.rb +10 -13
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +7 -3
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +24 -18
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +4 -1
- data/lib/rubocop/cop/layout/space_inside_parens.rb +35 -13
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +37 -13
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +2 -1
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +26 -2
- data/lib/rubocop/cop/lint/debugger.rb +17 -28
- data/lib/rubocop/cop/lint/duplicate_branch.rb +93 -0
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +2 -12
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +77 -0
- data/lib/rubocop/cop/lint/else_layout.rb +29 -3
- data/lib/rubocop/cop/lint/empty_block.rb +82 -0
- data/lib/rubocop/cop/lint/empty_class.rb +93 -0
- data/lib/rubocop/cop/lint/flip_flop.rb +8 -2
- data/lib/rubocop/cop/lint/interpolation_check.rb +7 -2
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +39 -7
- data/lib/rubocop/cop/lint/loop.rb +4 -4
- data/lib/rubocop/cop/lint/missing_super.rb +7 -4
- data/lib/rubocop/cop/lint/nested_percent_literal.rb +14 -0
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +58 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +46 -13
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +27 -8
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +19 -16
- data/lib/rubocop/cop/lint/shadowed_exception.rb +4 -5
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -0
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +86 -0
- data/lib/rubocop/cop/lint/to_json.rb +1 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +85 -0
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +199 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
- data/lib/rubocop/cop/lint/useless_method_definition.rb +2 -4
- data/lib/rubocop/cop/lint/useless_setter_call.rb +6 -1
- data/lib/rubocop/cop/metrics/abc_size.rb +25 -1
- data/lib/rubocop/cop/metrics/block_length.rb +13 -7
- data/lib/rubocop/cop/metrics/method_length.rb +7 -2
- data/lib/rubocop/cop/metrics/parameter_lists.rb +68 -2
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +20 -10
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +146 -0
- data/lib/rubocop/cop/metrics/utils/repeated_csend_discount.rb +6 -1
- data/lib/rubocop/cop/migration/department_name.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/configurable_numbering.rb +4 -3
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +9 -1
- data/lib/rubocop/cop/mixin/ignored_methods.rb +36 -3
- data/lib/rubocop/cop/mixin/line_length_help.rb +1 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +6 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -4
- data/lib/rubocop/cop/mixin/string_help.rb +4 -1
- data/lib/rubocop/cop/mixin/visibility_help.rb +1 -3
- data/lib/rubocop/cop/naming/accessor_method_name.rb +15 -1
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +12 -2
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +11 -5
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +67 -18
- data/lib/rubocop/cop/naming/predicate_name.rb +2 -1
- data/lib/rubocop/cop/naming/variable_number.rb +100 -8
- data/lib/rubocop/cop/offense.rb +3 -3
- data/lib/rubocop/cop/security/open.rb +12 -10
- data/lib/rubocop/cop/style/accessor_grouping.rb +1 -1
- data/lib/rubocop/cop/style/and_or.rb +11 -3
- data/lib/rubocop/cop/style/arguments_forwarding.rb +142 -0
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +0 -4
- data/lib/rubocop/cop/style/case_like_if.rb +0 -4
- data/lib/rubocop/cop/style/character_literal.rb +10 -11
- data/lib/rubocop/cop/style/class_and_module_children.rb +8 -3
- data/lib/rubocop/cop/style/collection_compact.rb +91 -0
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +169 -0
- data/lib/rubocop/cop/style/documentation.rb +12 -1
- data/lib/rubocop/cop/style/double_negation.rb +6 -1
- data/lib/rubocop/cop/style/float_division.rb +44 -1
- data/lib/rubocop/cop/style/format_string.rb +8 -3
- data/lib/rubocop/cop/style/format_string_token.rb +47 -2
- data/lib/rubocop/cop/style/hash_syntax.rb +3 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +7 -2
- data/lib/rubocop/cop/style/if_inside_else.rb +37 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +11 -3
- data/lib/rubocop/cop/style/if_with_semicolon.rb +39 -4
- data/lib/rubocop/cop/style/infinite_loop.rb +4 -0
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +12 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +10 -13
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +8 -13
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +7 -11
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -2
- data/lib/rubocop/cop/style/mixin_grouping.rb +0 -4
- data/lib/rubocop/cop/style/multiple_comparison.rb +55 -7
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +106 -0
- data/lib/rubocop/cop/style/nil_lambda.rb +52 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +14 -11
- data/lib/rubocop/cop/style/perl_backrefs.rb +86 -9
- data/lib/rubocop/cop/style/raise_args.rb +21 -6
- data/lib/rubocop/cop/style/redundant_argument.rb +88 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +4 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +7 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +24 -8
- data/lib/rubocop/cop/style/redundant_self.rb +3 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +16 -4
- data/lib/rubocop/cop/style/semicolon.rb +3 -0
- data/lib/rubocop/cop/style/single_line_block_params.rb +30 -7
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +65 -3
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -13
- data/lib/rubocop/cop/style/static_class.rb +97 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +39 -2
- 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/swap_values.rb +108 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +5 -3
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +3 -1
- data/lib/rubocop/cop/style/while_until_modifier.rb +9 -0
- data/lib/rubocop/cop/team.rb +6 -1
- data/lib/rubocop/cop/util.rb +6 -2
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/core_ext/hash.rb +20 -0
- data/lib/rubocop/ext/regexp_node.rb +36 -11
- data/lib/rubocop/ext/regexp_parser.rb +95 -0
- data/lib/rubocop/formatter/disabled_config_formatter.rb +21 -6
- data/lib/rubocop/formatter/emacs_style_formatter.rb +2 -0
- data/lib/rubocop/formatter/formatter_set.rb +2 -1
- data/lib/rubocop/formatter/git_hub_actions_formatter.rb +47 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +2 -0
- data/lib/rubocop/formatter/tap_formatter.rb +2 -0
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
- data/lib/rubocop/lockfile.rb +40 -0
- data/lib/rubocop/magic_comment.rb +2 -2
- data/lib/rubocop/options.rb +11 -1
- data/lib/rubocop/rake_task.rb +2 -2
- data/lib/rubocop/rspec/shared_contexts.rb +4 -0
- data/lib/rubocop/runner.rb +1 -1
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/target_ruby.rb +65 -1
- data/lib/rubocop/version.rb +56 -6
- metadata +50 -9
- data/bin/console +0 -10
- data/bin/rubocop-profile +0 -32
- data/bin/setup +0 -7
@@ -3,8 +3,14 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# This cop looks for uses of flip-flop operator
|
7
|
-
#
|
6
|
+
# This cop looks for uses of flip-flop operator
|
7
|
+
# based on the Ruby Style Guide.
|
8
|
+
#
|
9
|
+
# Here is the history of flip-flops in Ruby.
|
10
|
+
# flip-flop operator is deprecated in Ruby 2.6.0 and
|
11
|
+
# the deprecation has been reverted by Ruby 2.7.0 and
|
12
|
+
# backported to Ruby 2.6.
|
13
|
+
# See: https://bugs.ruby-lang.org/issues/5400
|
8
14
|
#
|
9
15
|
# @example
|
10
16
|
# # bad
|
@@ -23,10 +23,11 @@ module RuboCop
|
|
23
23
|
'Use double quoted strings if you need interpolation.'
|
24
24
|
|
25
25
|
def on_str(node)
|
26
|
-
|
27
|
-
return if
|
26
|
+
return unless node
|
27
|
+
return if string_or_regex?(node.parent)
|
28
28
|
return unless /(?<!\\)#\{.*\}/.match?(node.source)
|
29
29
|
return if heredoc?(node)
|
30
|
+
return unless node.loc.begin && node.loc.end
|
30
31
|
|
31
32
|
add_offense(node) do |corrector|
|
32
33
|
autocorrect(corrector, node)
|
@@ -35,6 +36,10 @@ module RuboCop
|
|
35
36
|
|
36
37
|
private
|
37
38
|
|
39
|
+
def string_or_regex?(node)
|
40
|
+
node&.dstr_type? || node&.regexp_type?
|
41
|
+
end
|
42
|
+
|
38
43
|
def autocorrect(corrector, node)
|
39
44
|
starting_token, ending_token = if node.source.include?('"')
|
40
45
|
['%{', '}']
|
@@ -27,21 +27,33 @@ module RuboCop
|
|
27
27
|
|
28
28
|
def on_interpolation(begin_node)
|
29
29
|
final_node = begin_node.children.last
|
30
|
-
return unless final_node
|
31
|
-
|
32
|
-
|
30
|
+
return unless offending?(final_node)
|
31
|
+
|
32
|
+
# %W and %I split the content into words before expansion
|
33
|
+
# treating each interpolation as a word component, so
|
34
|
+
# interpolation should not be removed if the expanded value
|
35
|
+
# contains a space character.
|
36
|
+
expanded_value = autocorrected_value(final_node)
|
37
|
+
return if in_array_percent_literal?(begin_node) &&
|
38
|
+
/\s/.match?(expanded_value)
|
33
39
|
|
34
40
|
add_offense(final_node) do |corrector|
|
35
41
|
return if final_node.dstr_type? # nested, fixed in next iteration
|
36
42
|
|
37
|
-
|
38
|
-
|
39
|
-
corrector.replace(final_node.parent, value)
|
43
|
+
corrector.replace(final_node.parent, expanded_value)
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
43
47
|
private
|
44
48
|
|
49
|
+
def offending?(node)
|
50
|
+
node &&
|
51
|
+
!special_keyword?(node) &&
|
52
|
+
prints_as_self?(node) &&
|
53
|
+
# Special case for Layout/TrailingWhitespace
|
54
|
+
!(space_literal?(node) && ends_heredoc_line?(node))
|
55
|
+
end
|
56
|
+
|
45
57
|
def special_keyword?(node)
|
46
58
|
# handle strings like __FILE__
|
47
59
|
(node.str_type? && !node.loc.respond_to?(:begin)) ||
|
@@ -83,7 +95,7 @@ module RuboCop
|
|
83
95
|
def autocorrected_value_for_array(node)
|
84
96
|
return node.source.gsub('"', '\"') unless node.percent_literal?
|
85
97
|
|
86
|
-
contents_range(node).source.split
|
98
|
+
contents_range(node).source.split.to_s.gsub('"', '\"')
|
87
99
|
end
|
88
100
|
|
89
101
|
# Does node print its own source when converted to a string?
|
@@ -92,6 +104,26 @@ module RuboCop
|
|
92
104
|
(COMPOSITE.include?(node.type) &&
|
93
105
|
node.children.all? { |child| prints_as_self?(child) })
|
94
106
|
end
|
107
|
+
|
108
|
+
def space_literal?(node)
|
109
|
+
node.str_type? && node.value.blank?
|
110
|
+
end
|
111
|
+
|
112
|
+
def ends_heredoc_line?(node)
|
113
|
+
grandparent = node.parent.parent
|
114
|
+
return false unless grandparent&.dstr_type? && grandparent&.heredoc?
|
115
|
+
|
116
|
+
line = processed_source.lines[node.last_line - 1]
|
117
|
+
line.size == node.loc.last_column + 1
|
118
|
+
end
|
119
|
+
|
120
|
+
def in_array_percent_literal?(node)
|
121
|
+
parent = node.parent
|
122
|
+
return false unless parent.dstr_type? || parent.dsym_type?
|
123
|
+
|
124
|
+
grandparent = parent.parent
|
125
|
+
grandparent&.array_type? && grandparent&.percent_literal?
|
126
|
+
end
|
95
127
|
end
|
96
128
|
end
|
97
129
|
end
|
@@ -5,6 +5,10 @@ module RuboCop
|
|
5
5
|
module Lint
|
6
6
|
# This cop checks for uses of `begin...end while/until something`.
|
7
7
|
#
|
8
|
+
# The cop is marked as unsafe because behaviour can change in some cases, including
|
9
|
+
# if a local variable inside the loop body is accessed outside of it, or if the
|
10
|
+
# loop body raises a `StopIteration` exception (which `Kernel#loop` rescues).
|
11
|
+
#
|
8
12
|
# @example
|
9
13
|
#
|
10
14
|
# # bad
|
@@ -76,10 +80,6 @@ module RuboCop
|
|
76
80
|
conditional_keyword = node.while_post_type? ? 'unless' : 'if'
|
77
81
|
"break #{conditional_keyword} #{node.condition.source}\n#{indent(node)}"
|
78
82
|
end
|
79
|
-
|
80
|
-
def indent(node)
|
81
|
-
' ' * node.loc.column
|
82
|
-
end
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
@@ -6,6 +6,11 @@ module RuboCop
|
|
6
6
|
# This cop checks for the presence of constructors and lifecycle callbacks
|
7
7
|
# without calls to `super`.
|
8
8
|
#
|
9
|
+
# This cop does not consider `method_missing` (and `respond_to_missing?`)
|
10
|
+
# because in some cases it makes sense to overtake what is considered a
|
11
|
+
# missing method. In other cases, the theoretical ideal handling could be
|
12
|
+
# challenging or verbose for no actual gain.
|
13
|
+
#
|
9
14
|
# @example
|
10
15
|
# # bad
|
11
16
|
# class Employee < Person
|
@@ -43,15 +48,13 @@ module RuboCop
|
|
43
48
|
|
44
49
|
STATELESS_CLASSES = %w[BasicObject Object].freeze
|
45
50
|
|
46
|
-
OBJECT_LIFECYCLE_CALLBACKS = %i[method_missing respond_to_missing?].freeze
|
47
51
|
CLASS_LIFECYCLE_CALLBACKS = %i[inherited].freeze
|
48
52
|
METHOD_LIFECYCLE_CALLBACKS = %i[method_added method_removed method_undefined
|
49
53
|
singleton_method_added singleton_method_removed
|
50
54
|
singleton_method_undefined].freeze
|
51
55
|
|
52
|
-
CALLBACKS = (
|
53
|
-
|
54
|
-
METHOD_LIFECYCLE_CALLBACKS).to_set.freeze
|
56
|
+
CALLBACKS = (CLASS_LIFECYCLE_CALLBACKS +
|
57
|
+
METHOD_LIFECYCLE_CALLBACKS).to_set.freeze
|
55
58
|
|
56
59
|
def on_def(node)
|
57
60
|
return unless offender?(node)
|
@@ -15,6 +15,20 @@ module RuboCop
|
|
15
15
|
# valid_attributes: %i[name content],
|
16
16
|
# nested_attributes: %i[name content %i[incorrectly nested]]
|
17
17
|
# }
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
#
|
21
|
+
# # Neither is incompatible with the bad case, but probably the intended code.
|
22
|
+
# attributes = {
|
23
|
+
# valid_attributes: %i[name content],
|
24
|
+
# nested_attributes: [:name, :content, %i[incorrectly nested]]
|
25
|
+
# }
|
26
|
+
#
|
27
|
+
# attributes = {
|
28
|
+
# valid_attributes: %i[name content],
|
29
|
+
# nested_attributes: [:name, :content, [:incorrectly, :nested]]
|
30
|
+
# }
|
31
|
+
#
|
18
32
|
class NestedPercentLiteral < Base
|
19
33
|
include PercentLiteral
|
20
34
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for the presence of a `return` inside a `begin..end` block
|
7
|
+
# in assignment contexts.
|
8
|
+
# In this situation, the `return` will result in an exit from the current
|
9
|
+
# method, possibly leading to unexpected behavior.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
#
|
13
|
+
# # bad
|
14
|
+
#
|
15
|
+
# @some_variable ||= begin
|
16
|
+
# return some_value if some_condition_is_met
|
17
|
+
#
|
18
|
+
# do_something
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
#
|
25
|
+
# @some_variable ||= begin
|
26
|
+
# if some_condition_is_met
|
27
|
+
# some_value
|
28
|
+
# else
|
29
|
+
# do_something
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# # good
|
34
|
+
#
|
35
|
+
# some_variable = if some_condition_is_met
|
36
|
+
# return if another_condition_is_met
|
37
|
+
#
|
38
|
+
# some_value
|
39
|
+
# else
|
40
|
+
# do_something
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
class NoReturnInBeginEndBlocks < Base
|
44
|
+
MSG = 'Do not `return` in `begin..end` blocks in assignment contexts.'
|
45
|
+
|
46
|
+
def on_lvasgn(node)
|
47
|
+
node.each_node(:kwbegin) do |kwbegin_node|
|
48
|
+
kwbegin_node.each_node(:return) do |return_node|
|
49
|
+
add_offense(return_node)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
alias on_or_asgn on_lvasgn
|
54
|
+
alias on_op_asgn on_lvasgn
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -7,6 +7,17 @@ module RuboCop
|
|
7
7
|
# number conversion can cause unexpected error if auto type conversion
|
8
8
|
# fails. Cop prefer parsing with number class instead.
|
9
9
|
#
|
10
|
+
# Conversion with `Integer`, `Float`, etc. will raise an `ArgumentError`
|
11
|
+
# if given input that is not numeric (eg. an empty string), whereas
|
12
|
+
# `to_i`, etc. will try to convert regardless of input (`''.to_i => 0`).
|
13
|
+
# As such, this cop is disabled by default because it's not necessarily
|
14
|
+
# always correct to raise if a value is not numeric.
|
15
|
+
#
|
16
|
+
# NOTE: Some values cannot be converted properly using one of the `Kernel`
|
17
|
+
# method (for instance, `Time` and `DateTime` values are allowed by this
|
18
|
+
# cop by default). Similarly, Rails' duration methods do not work well
|
19
|
+
# with `Integer()` and can be ignored with `IgnoredMethods`.
|
20
|
+
#
|
10
21
|
# @example
|
11
22
|
#
|
12
23
|
# # bad
|
@@ -20,8 +31,19 @@ module RuboCop
|
|
20
31
|
# Integer('10', 10)
|
21
32
|
# Float('10.2')
|
22
33
|
# Complex('10')
|
34
|
+
#
|
35
|
+
# @example IgnoredMethods: [minutes]
|
36
|
+
#
|
37
|
+
# # good
|
38
|
+
# 10.minutes.to_i
|
39
|
+
#
|
40
|
+
# @example IgnoredClasses: [Time, DateTime] (default)
|
41
|
+
#
|
42
|
+
# # good
|
43
|
+
# Time.now.to_datetime.to_i
|
23
44
|
class NumberConversion < Base
|
24
45
|
extend AutoCorrector
|
46
|
+
include IgnoredMethods
|
25
47
|
|
26
48
|
CONVERSION_METHOD_CLASS_MAPPING = {
|
27
49
|
to_i: "#{Integer.name}(%<number_object>s, 10)",
|
@@ -38,13 +60,9 @@ module RuboCop
|
|
38
60
|
(send $_ ${:to_i :to_f :to_c})
|
39
61
|
PATTERN
|
40
62
|
|
41
|
-
def_node_matcher :datetime?, <<~PATTERN
|
42
|
-
(send (const {nil? (cbase)} {:Time :DateTime}) ...)
|
43
|
-
PATTERN
|
44
|
-
|
45
63
|
def on_send(node)
|
46
64
|
to_method(node) do |receiver, to_method|
|
47
|
-
next if receiver.nil? ||
|
65
|
+
next if receiver.nil? || ignore_receiver?(receiver)
|
48
66
|
|
49
67
|
message = format(
|
50
68
|
MSG,
|
@@ -60,18 +78,33 @@ module RuboCop
|
|
60
78
|
|
61
79
|
private
|
62
80
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
|
81
|
+
def correct_method(node, receiver)
|
82
|
+
format(CONVERSION_METHOD_CLASS_MAPPING[node.method_name],
|
83
|
+
number_object: receiver.source)
|
84
|
+
end
|
67
85
|
|
68
|
-
|
86
|
+
def ignore_receiver?(receiver)
|
87
|
+
if receiver.send_type? && ignored_method?(receiver.method_name)
|
88
|
+
true
|
89
|
+
elsif (receiver = top_receiver(receiver))
|
90
|
+
receiver.const_type? && ignored_class?(receiver.const_name)
|
91
|
+
else
|
92
|
+
false
|
69
93
|
end
|
70
94
|
end
|
71
95
|
|
72
|
-
def
|
73
|
-
|
74
|
-
|
96
|
+
def top_receiver(node)
|
97
|
+
receiver = node
|
98
|
+
receiver = receiver.receiver until receiver.receiver.nil?
|
99
|
+
receiver
|
100
|
+
end
|
101
|
+
|
102
|
+
def ignored_classes
|
103
|
+
cop_config.fetch('IgnoredClasses', [])
|
104
|
+
end
|
105
|
+
|
106
|
+
def ignored_class?(name)
|
107
|
+
ignored_classes.include?(name.to_s)
|
75
108
|
end
|
76
109
|
end
|
77
110
|
end
|
@@ -19,7 +19,7 @@ module RuboCop
|
|
19
19
|
# puts $1 # => foo
|
20
20
|
#
|
21
21
|
class OutOfRangeRegexpRef < Base
|
22
|
-
MSG = '
|
22
|
+
MSG = '$%<backref>s is out of range (%<count>s regexp capture %<group>s detected).'
|
23
23
|
|
24
24
|
REGEXP_RECEIVER_METHODS = %i[=~ === match].to_set.freeze
|
25
25
|
REGEXP_ARGUMENT_METHODS = %i[=~ match grep gsub gsub! sub sub! [] slice slice! index rindex
|
@@ -35,14 +35,13 @@ module RuboCop
|
|
35
35
|
check_regexp(node.children.first)
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
38
|
+
def after_send(node)
|
39
39
|
@valid_ref = nil
|
40
40
|
|
41
|
-
if node
|
42
|
-
check_regexp(node.receiver)
|
43
|
-
elsif node.first_argument&.regexp_type? \
|
44
|
-
&& REGEXP_ARGUMENT_METHODS.include?(node.method_name)
|
41
|
+
if regexp_first_argument?(node)
|
45
42
|
check_regexp(node.first_argument)
|
43
|
+
elsif regexp_receiver?(node)
|
44
|
+
check_regexp(node.receiver)
|
46
45
|
end
|
47
46
|
end
|
48
47
|
|
@@ -56,9 +55,16 @@ module RuboCop
|
|
56
55
|
|
57
56
|
def on_nth_ref(node)
|
58
57
|
backref, = *node
|
59
|
-
return if @valid_ref.nil?
|
58
|
+
return if @valid_ref.nil? || backref <= @valid_ref
|
59
|
+
|
60
|
+
message = format(
|
61
|
+
MSG,
|
62
|
+
backref: backref,
|
63
|
+
count: @valid_ref.zero? ? 'no' : @valid_ref,
|
64
|
+
group: @valid_ref == 1 ? 'group' : 'groups'
|
65
|
+
)
|
60
66
|
|
61
|
-
add_offense(node
|
67
|
+
add_offense(node, message: message)
|
62
68
|
end
|
63
69
|
|
64
70
|
private
|
@@ -73,6 +79,19 @@ module RuboCop
|
|
73
79
|
node.each_capture(named: false).count
|
74
80
|
end
|
75
81
|
end
|
82
|
+
|
83
|
+
def regexp_first_argument?(send_node)
|
84
|
+
send_node.first_argument&.regexp_type? \
|
85
|
+
&& REGEXP_ARGUMENT_METHODS.include?(send_node.method_name)
|
86
|
+
end
|
87
|
+
|
88
|
+
def regexp_receiver?(send_node)
|
89
|
+
send_node.receiver&.regexp_type?
|
90
|
+
end
|
91
|
+
|
92
|
+
def nth_ref_receiver?(send_node)
|
93
|
+
send_node.receiver&.nth_ref_type?
|
94
|
+
end
|
76
95
|
end
|
77
96
|
end
|
78
97
|
end
|
@@ -88,31 +88,34 @@ module RuboCop
|
|
88
88
|
begin_pos = reposition(source, begin_pos, -1)
|
89
89
|
end_pos = reposition(source, end_pos, 1)
|
90
90
|
|
91
|
-
|
92
|
-
if source[begin_pos - 1] == ','
|
93
|
-
:before
|
94
|
-
elsif source[end_pos] == ','
|
95
|
-
:after
|
96
|
-
else
|
97
|
-
:none
|
98
|
-
end
|
99
|
-
|
100
|
-
range_to_remove(begin_pos, end_pos, comma_pos, comment)
|
91
|
+
range_to_remove(begin_pos, end_pos, comment)
|
101
92
|
end
|
102
93
|
|
103
|
-
def range_to_remove(begin_pos, end_pos,
|
94
|
+
def range_to_remove(begin_pos, end_pos, comment)
|
104
95
|
start = comment_start(comment)
|
96
|
+
source = comment.loc.expression.source
|
105
97
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
range_between(start + begin_pos, start + end_pos + 1)
|
98
|
+
if source[begin_pos - 1] == ','
|
99
|
+
range_with_comma_before(start, begin_pos, end_pos)
|
100
|
+
elsif source[end_pos] == ','
|
101
|
+
range_with_comma_after(comment, start, begin_pos, end_pos)
|
111
102
|
else
|
112
103
|
range_between(start, comment.loc.expression.end_pos)
|
113
104
|
end
|
114
105
|
end
|
115
106
|
|
107
|
+
def range_with_comma_before(start, begin_pos, end_pos)
|
108
|
+
range_between(start + begin_pos - 1, start + end_pos)
|
109
|
+
end
|
110
|
+
|
111
|
+
# If the list of cops is comma-separated, but without a empty space after the comma,
|
112
|
+
# we should **not** remove the prepending empty space, thus begin_pos += 1
|
113
|
+
def range_with_comma_after(comment, start, begin_pos, end_pos)
|
114
|
+
begin_pos += 1 if comment.loc.expression.source[end_pos + 1] != ' '
|
115
|
+
|
116
|
+
range_between(start + begin_pos, start + end_pos + 1)
|
117
|
+
end
|
118
|
+
|
116
119
|
def all_or_name(name)
|
117
120
|
name == 'all' ? 'all cops' : name
|
118
121
|
end
|