rubocop 1.59.0 → 1.65.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/LICENSE.txt +1 -1
- data/README.md +3 -4
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +93 -17
- data/lib/rubocop/cached_data.rb +11 -3
- data/lib/rubocop/cli/command/auto_generate_config.rb +12 -3
- data/lib/rubocop/cli/command/lsp.rb +2 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
- data/lib/rubocop/cli.rb +10 -1
- data/lib/rubocop/config.rb +36 -12
- data/lib/rubocop/config_finder.rb +12 -2
- data/lib/rubocop/config_loader.rb +1 -2
- data/lib/rubocop/config_loader_resolver.rb +9 -3
- data/lib/rubocop/config_obsoletion.rb +1 -1
- data/lib/rubocop/config_validator.rb +14 -7
- data/lib/rubocop/cop/autocorrect_logic.rb +6 -1
- data/lib/rubocop/cop/base.rb +63 -16
- data/lib/rubocop/cop/bundler/gem_version.rb +3 -5
- data/lib/rubocop/cop/cop.rb +22 -4
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
- data/lib/rubocop/cop/documentation.rb +16 -6
- data/lib/rubocop/cop/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/force.rb +12 -0
- data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
- data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
- data/lib/rubocop/cop/internal_affairs/example_description.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +122 -28
- data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/assignment_indentation.rb +3 -2
- data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/condition_position.rb +0 -4
- data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +8 -2
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -1
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +20 -20
- data/lib/rubocop/cop/layout/redundant_line_break.rb +14 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +3 -0
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -4
- data/lib/rubocop/cop/legacy/corrector.rb +12 -2
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +0 -2
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +0 -2
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +0 -2
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
- data/lib/rubocop/cop/lint/boolean_symbol.rb +0 -2
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +0 -13
- data/lib/rubocop/cop/lint/debugger.rb +27 -6
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +0 -10
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -5
- data/lib/rubocop/cop/lint/duplicate_hash_key.rb +0 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -10
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +0 -4
- data/lib/rubocop/cop/lint/else_layout.rb +0 -2
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +2 -2
- data/lib/rubocop/cop/lint/empty_ensure.rb +1 -11
- data/lib/rubocop/cop/lint/empty_interpolation.rb +0 -4
- data/lib/rubocop/cop/lint/empty_when.rb +1 -3
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -6
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +21 -14
- data/lib/rubocop/cop/lint/float_comparison.rb +3 -1
- data/lib/rubocop/cop/lint/float_out_of_range.rb +0 -4
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +0 -10
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +15 -12
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +0 -7
- data/lib/rubocop/cop/lint/interpolation_check.rb +0 -4
- data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +13 -6
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +0 -4
- data/lib/rubocop/cop/lint/loop.rb +6 -12
- data/lib/rubocop/cop/lint/mixed_case_range.rb +9 -4
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -7
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +0 -4
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +0 -5
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +1 -1
- data/lib/rubocop/cop/lint/percent_string_array.rb +0 -4
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +0 -4
- data/lib/rubocop/cop/lint/rand_one.rb +0 -4
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +3 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +14 -9
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +0 -4
- data/lib/rubocop/cop/lint/redundant_with_index.rb +4 -0
- data/lib/rubocop/cop/lint/require_parentheses.rb +0 -4
- data/lib/rubocop/cop/lint/rescue_exception.rb +0 -4
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
- data/lib/rubocop/cop/lint/return_in_void_context.rb +0 -2
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +0 -4
- data/lib/rubocop/cop/lint/script_permission.rb +3 -3
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +6 -10
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -3
- data/lib/rubocop/cop/lint/unified_integer.rb +0 -4
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +4 -7
- data/lib/rubocop/cop/lint/unreachable_loop.rb +8 -2
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -5
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +0 -4
- data/lib/rubocop/cop/lint/useless_setter_call.rb +0 -4
- data/lib/rubocop/cop/lint/useless_times.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +11 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +19 -7
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +5 -5
- data/lib/rubocop/cop/mixin/alignment.rb +5 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +7 -1
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +15 -3
- data/lib/rubocop/cop/mixin/code_length.rb +12 -1
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/mixin/configurable_max.rb +5 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +9 -2
- data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
- data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +32 -5
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/inclusive_language.rb +1 -2
- data/lib/rubocop/cop/naming/predicate_name.rb +54 -28
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -1
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/security/compound_hash.rb +2 -2
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +50 -0
- data/lib/rubocop/cop/style/alias.rb +1 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +89 -17
- data/lib/rubocop/cop/style/case_like_if.rb +1 -1
- data/lib/rubocop/cop/style/class_vars.rb +3 -3
- data/lib/rubocop/cop/style/collection_compact.rb +14 -5
- data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +6 -7
- data/lib/rubocop/cop/style/copyright.rb +31 -21
- data/lib/rubocop/cop/style/def_with_parentheses.rb +0 -2
- data/lib/rubocop/cop/style/documentation.rb +24 -24
- data/lib/rubocop/cop/style/documentation_method.rb +20 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -8
- data/lib/rubocop/cop/style/eval_with_location.rb +15 -23
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -1
- data/lib/rubocop/cop/style/file_read.rb +2 -5
- data/lib/rubocop/cop/style/file_write.rb +2 -5
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/format_string.rb +9 -9
- data/lib/rubocop/cop/style/global_std_stream.rb +7 -1
- data/lib/rubocop/cop/style/hash_each_methods.rb +29 -8
- data/lib/rubocop/cop/style/hash_except.rb +8 -5
- data/lib/rubocop/cop/style/hash_syntax.rb +24 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +4 -1
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -4
- data/lib/rubocop/cop/style/inverse_methods.rb +8 -8
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +46 -4
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +81 -50
- data/lib/rubocop/cop/style/map_into_array.rb +175 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +10 -6
- data/lib/rubocop/cop/style/map_to_set.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +18 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/missing_else.rb +0 -4
- data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -3
- data/lib/rubocop/cop/style/multiline_when_then.rb +0 -4
- data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +10 -2
- data/lib/rubocop/cop/style/object_then.rb +5 -3
- data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
- data/lib/rubocop/cop/style/parallel_assignment.rb +3 -5
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +4 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +25 -2
- data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +0 -1
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +5 -4
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +17 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +18 -2
- data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -24
- data/lib/rubocop/cop/style/redundant_return.rb +6 -0
- data/lib/rubocop/cop/style/require_order.rb +1 -1
- data/lib/rubocop/cop/style/sample.rb +1 -3
- data/lib/rubocop/cop/style/send.rb +4 -4
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +104 -0
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +21 -2
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
- data/lib/rubocop/cop/style/super_arguments.rb +174 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +75 -5
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/while_until_do.rb +0 -2
- data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
- data/lib/rubocop/cop/style/zero_length_predicate.rb +32 -24
- data/lib/rubocop/cop/team.rb +13 -0
- data/lib/rubocop/cop/util.rb +7 -1
- data/lib/rubocop/cop/utils/regexp_ranges.rb +1 -1
- data/lib/rubocop/cop/variable_force.rb +13 -1
- data/lib/rubocop/cops_documentation_generator.rb +16 -4
- data/lib/rubocop/core_ext/string.rb +2 -6
- data/lib/rubocop/directive_comment.rb +10 -8
- data/lib/rubocop/ext/regexp_node.rb +18 -35
- data/lib/rubocop/ext/regexp_parser.rb +4 -21
- data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
- data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -8
- data/lib/rubocop/formatter/formatter_set.rb +7 -1
- data/lib/rubocop/formatter/html_formatter.rb +32 -10
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
- data/lib/rubocop/formatter/tap_formatter.rb +3 -7
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lockfile.rb +56 -7
- data/lib/rubocop/lsp/logger.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +12 -15
- data/lib/rubocop/lsp/runtime.rb +1 -1
- data/lib/rubocop/lsp/server.rb +7 -2
- data/lib/rubocop/lsp/severity.rb +1 -1
- data/lib/rubocop/lsp.rb +36 -0
- data/lib/rubocop/magic_comment.rb +1 -1
- data/lib/rubocop/options.rb +17 -12
- data/lib/rubocop/path_util.rb +6 -2
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/rspec/cop_helper.rb +8 -2
- data/lib/rubocop/rspec/expect_offense.rb +16 -8
- data/lib/rubocop/rspec/shared_contexts.rb +73 -16
- data/lib/rubocop/rspec/support.rb +3 -0
- data/lib/rubocop/runner.rb +14 -3
- data/lib/rubocop/server/cache.rb +11 -2
- data/lib/rubocop/server/client_command/exec.rb +2 -3
- data/lib/rubocop/server/client_command/start.rb +1 -1
- data/lib/rubocop/server/core.rb +4 -0
- data/lib/rubocop/server/server_command/exec.rb +0 -1
- data/lib/rubocop/target_finder.rb +84 -78
- data/lib/rubocop/target_ruby.rb +82 -80
- data/lib/rubocop/version.rb +19 -4
- data/lib/rubocop.rb +9 -0
- metadata +18 -11
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -29,36 +29,36 @@ module RuboCop
|
|
29
29
|
# end
|
30
30
|
#
|
31
31
|
# # allowed
|
32
|
-
#
|
32
|
+
# # Class without body
|
33
|
+
# class Person
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# # Namespace - A namespace can be a class or a module
|
37
|
+
# # Containing a class
|
38
|
+
# module Namespace
|
39
|
+
# # Description/Explanation of Person class
|
33
40
|
# class Person
|
41
|
+
# # ...
|
34
42
|
# end
|
43
|
+
# end
|
35
44
|
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
# # Description/Explanation of Person class
|
40
|
-
# class Person
|
41
|
-
# # ...
|
42
|
-
# end
|
45
|
+
# # Containing constant visibility declaration
|
46
|
+
# module Namespace
|
47
|
+
# class Private
|
43
48
|
# end
|
44
49
|
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
# class Private
|
48
|
-
# end
|
49
|
-
#
|
50
|
-
# private_constant :Private
|
51
|
-
# end
|
50
|
+
# private_constant :Private
|
51
|
+
# end
|
52
52
|
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
53
|
+
# # Containing constant definition
|
54
|
+
# module Namespace
|
55
|
+
# Public = Class.new
|
56
|
+
# end
|
57
57
|
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
58
|
+
# # Macro calls
|
59
|
+
# module Namespace
|
60
|
+
# extend Foo
|
61
|
+
# end
|
62
62
|
#
|
63
63
|
# @example AllowedConstants: ['ClassMethods']
|
64
64
|
#
|
@@ -67,7 +67,7 @@ module RuboCop
|
|
67
67
|
# module ClassMethods
|
68
68
|
# # ...
|
69
69
|
# end
|
70
|
-
#
|
70
|
+
# end
|
71
71
|
#
|
72
72
|
class Documentation < Base
|
73
73
|
include DocumentationComment
|
@@ -95,6 +95,17 @@ module RuboCop
|
|
95
95
|
# end
|
96
96
|
# end
|
97
97
|
#
|
98
|
+
# @example AllowedMethods: ['method_missing', 'respond_to_missing?']
|
99
|
+
#
|
100
|
+
# # good
|
101
|
+
# class Foo
|
102
|
+
# def method_missing(name, *args)
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
# def respond_to_missing?(symbol, include_private)
|
106
|
+
# end
|
107
|
+
# end
|
108
|
+
#
|
98
109
|
class DocumentationMethod < Base
|
99
110
|
include DocumentationComment
|
100
111
|
include DefNode
|
@@ -119,6 +130,7 @@ module RuboCop
|
|
119
130
|
def check(node)
|
120
131
|
return if non_public?(node) && !require_for_non_public_methods?
|
121
132
|
return if documentation_comment?(node)
|
133
|
+
return if method_allowed?(node)
|
122
134
|
|
123
135
|
add_offense(node)
|
124
136
|
end
|
@@ -126,6 +138,14 @@ module RuboCop
|
|
126
138
|
def require_for_non_public_methods?
|
127
139
|
cop_config['RequireForNonPublicMethods']
|
128
140
|
end
|
141
|
+
|
142
|
+
def method_allowed?(node)
|
143
|
+
allowed_methods.include?(node.method_name)
|
144
|
+
end
|
145
|
+
|
146
|
+
def allowed_methods
|
147
|
+
@allowed_methods ||= cop_config.fetch('AllowedMethods', []).map(&:to_sym)
|
148
|
+
end
|
129
149
|
end
|
130
150
|
end
|
131
151
|
end
|
@@ -16,7 +16,6 @@ module RuboCop
|
|
16
16
|
# # good
|
17
17
|
# 5.times { }
|
18
18
|
#
|
19
|
-
# @example
|
20
19
|
# # bad
|
21
20
|
# (0...10).each {}
|
22
21
|
#
|
@@ -32,27 +31,27 @@ module RuboCop
|
|
32
31
|
|
33
32
|
send_node = node.send_node
|
34
33
|
|
35
|
-
|
36
|
-
|
37
|
-
add_offense(range) do |corrector|
|
34
|
+
add_offense(send_node) do |corrector|
|
38
35
|
range_type, min, max = each_range(node)
|
39
36
|
|
40
37
|
max += 1 if range_type == :irange
|
41
38
|
|
42
|
-
corrector.replace(
|
39
|
+
corrector.replace(send_node, "#{max - min}.times")
|
43
40
|
end
|
44
41
|
end
|
45
42
|
|
46
43
|
private
|
47
44
|
|
48
45
|
def offending?(node)
|
46
|
+
return false unless node.arguments.empty?
|
47
|
+
|
49
48
|
each_range_with_zero_origin?(node) || each_range_without_block_argument?(node)
|
50
49
|
end
|
51
50
|
|
52
51
|
# @!method each_range(node)
|
53
52
|
def_node_matcher :each_range, <<~PATTERN
|
54
53
|
(block
|
55
|
-
(
|
54
|
+
(call
|
56
55
|
(begin
|
57
56
|
(${irange erange}
|
58
57
|
(int $_) (int $_)))
|
@@ -64,7 +63,7 @@ module RuboCop
|
|
64
63
|
# @!method each_range_with_zero_origin?(node)
|
65
64
|
def_node_matcher :each_range_with_zero_origin?, <<~PATTERN
|
66
65
|
(block
|
67
|
-
(
|
66
|
+
(call
|
68
67
|
(begin
|
69
68
|
({irange erange}
|
70
69
|
(int 0) (int _)))
|
@@ -76,7 +75,7 @@ module RuboCop
|
|
76
75
|
# @!method each_range_without_block_argument?(node)
|
77
76
|
def_node_matcher :each_range_without_block_argument?, <<~PATTERN
|
78
77
|
(block
|
79
|
-
(
|
78
|
+
(call
|
80
79
|
(begin
|
81
80
|
({irange erange}
|
82
81
|
(int _) (int _)))
|
@@ -17,6 +17,18 @@ module RuboCop
|
|
17
17
|
# will not attempt to automatically add a binding, or add filename and
|
18
18
|
# line values.
|
19
19
|
#
|
20
|
+
# NOTE: This cop works only when a string literal is given as a code string.
|
21
|
+
# No offense is reported if a string variable is given as below:
|
22
|
+
#
|
23
|
+
# [source,ruby]
|
24
|
+
# ----
|
25
|
+
# code = <<-RUBY
|
26
|
+
# def do_something
|
27
|
+
# end
|
28
|
+
# RUBY
|
29
|
+
# eval code # not checked.
|
30
|
+
# ----
|
31
|
+
#
|
20
32
|
# @example
|
21
33
|
# # bad
|
22
34
|
# eval <<-RUBY
|
@@ -42,17 +54,6 @@ module RuboCop
|
|
42
54
|
# end
|
43
55
|
# RUBY
|
44
56
|
#
|
45
|
-
# This cop works only when a string literal is given as a code string.
|
46
|
-
# No offense is reported if a string variable is given as below:
|
47
|
-
#
|
48
|
-
# @example
|
49
|
-
# # not checked
|
50
|
-
# code = <<-RUBY
|
51
|
-
# def do_something
|
52
|
-
# end
|
53
|
-
# RUBY
|
54
|
-
# eval code
|
55
|
-
#
|
56
57
|
class EvalWithLocation < Base
|
57
58
|
extend AutoCorrector
|
58
59
|
|
@@ -128,17 +129,6 @@ module RuboCop
|
|
128
129
|
node.method?(:eval) ? node.arguments.size >= 2 : true
|
129
130
|
end
|
130
131
|
|
131
|
-
# FIXME: It's a Style/ConditionalAssignment's false positive.
|
132
|
-
# rubocop:disable Style/ConditionalAssignment
|
133
|
-
def with_lineno?(node)
|
134
|
-
if node.method?(:eval)
|
135
|
-
node.arguments.size == 4
|
136
|
-
else
|
137
|
-
node.arguments.size == 3
|
138
|
-
end
|
139
|
-
end
|
140
|
-
# rubocop:enable Style/ConditionalAssignment
|
141
|
-
|
142
132
|
def add_offense_for_incorrect_line(method_name, line_node, sign, line_diff)
|
143
133
|
expected = expected_line(sign, line_diff)
|
144
134
|
message = format(MSG_INCORRECT_LINE,
|
@@ -152,7 +142,7 @@ module RuboCop
|
|
152
142
|
end
|
153
143
|
|
154
144
|
def check_file(node, file_node)
|
155
|
-
return
|
145
|
+
return if special_file_keyword?(file_node)
|
156
146
|
|
157
147
|
message = format(MSG_INCORRECT_FILE,
|
158
148
|
method_name: node.method_name,
|
@@ -166,6 +156,8 @@ module RuboCop
|
|
166
156
|
|
167
157
|
def check_line(node, code)
|
168
158
|
line_node = node.last_argument
|
159
|
+
return if line_node.variable? || (line_node.send_type? && !line_node.method?(:+))
|
160
|
+
|
169
161
|
line_diff = line_difference(line_node, code)
|
170
162
|
if line_diff.zero?
|
171
163
|
add_offense_for_same_line(node, line_node)
|
@@ -38,12 +38,13 @@ module RuboCop
|
|
38
38
|
PATTERN
|
39
39
|
|
40
40
|
def on_send(node)
|
41
|
+
return unless (receiver = node.receiver)
|
41
42
|
return unless (regexp = exact_regexp_match(node))
|
42
43
|
|
43
44
|
parsed_regexp = Regexp::Parser.parse(regexp)
|
44
45
|
return unless exact_match_pattern?(parsed_regexp)
|
45
46
|
|
46
|
-
prefer = "#{
|
47
|
+
prefer = "#{receiver.source} #{new_method(node)} '#{parsed_regexp[1].text}'"
|
47
48
|
|
48
49
|
add_offense(node, message: format(MSG, prefer: prefer)) do |corrector|
|
49
50
|
corrector.replace(node, prefer)
|
@@ -6,8 +6,7 @@ module RuboCop
|
|
6
6
|
# Favor `File.(bin)read` convenience methods.
|
7
7
|
#
|
8
8
|
# @example
|
9
|
-
#
|
10
|
-
# # bad
|
9
|
+
# # bad - text mode
|
11
10
|
# File.open(filename).read
|
12
11
|
# File.open(filename, &:read)
|
13
12
|
# File.open(filename) { |f| f.read }
|
@@ -23,9 +22,7 @@ module RuboCop
|
|
23
22
|
# # good
|
24
23
|
# File.read(filename)
|
25
24
|
#
|
26
|
-
#
|
27
|
-
# ## binary mode
|
28
|
-
# # bad
|
25
|
+
# # bad - binary mode
|
29
26
|
# File.open(filename, 'rb').read
|
30
27
|
# File.open(filename, 'rb', &:read)
|
31
28
|
# File.open(filename, 'rb') do |f|
|
@@ -17,8 +17,7 @@ module RuboCop
|
|
17
17
|
# ----
|
18
18
|
#
|
19
19
|
# @example
|
20
|
-
#
|
21
|
-
# # bad
|
20
|
+
# # bad - text mode
|
22
21
|
# File.open(filename, 'w').write(content)
|
23
22
|
# File.open(filename, 'w') do |f|
|
24
23
|
# f.write(content)
|
@@ -27,9 +26,7 @@ module RuboCop
|
|
27
26
|
# # good
|
28
27
|
# File.write(filename, content)
|
29
28
|
#
|
30
|
-
#
|
31
|
-
# ## binary mode
|
32
|
-
# # bad
|
29
|
+
# # bad - binary mode
|
33
30
|
# File.open(filename, 'wb').write(content)
|
34
31
|
# File.open(filename, 'wb') do |f|
|
35
32
|
# f.write(content)
|
@@ -25,27 +25,27 @@ module RuboCop
|
|
25
25
|
#
|
26
26
|
# @example EnforcedStyle: format (default)
|
27
27
|
# # bad
|
28
|
-
# puts sprintf('%10s', '
|
29
|
-
# puts '%10s' % '
|
28
|
+
# puts sprintf('%10s', 'foo')
|
29
|
+
# puts '%10s' % 'foo'
|
30
30
|
#
|
31
31
|
# # good
|
32
|
-
# puts format('%10s', '
|
32
|
+
# puts format('%10s', 'foo')
|
33
33
|
#
|
34
34
|
# @example EnforcedStyle: sprintf
|
35
35
|
# # bad
|
36
|
-
# puts format('%10s', '
|
37
|
-
# puts '%10s' % '
|
36
|
+
# puts format('%10s', 'foo')
|
37
|
+
# puts '%10s' % 'foo'
|
38
38
|
#
|
39
39
|
# # good
|
40
|
-
# puts sprintf('%10s', '
|
40
|
+
# puts sprintf('%10s', 'foo')
|
41
41
|
#
|
42
42
|
# @example EnforcedStyle: percent
|
43
43
|
# # bad
|
44
|
-
# puts format('%10s', '
|
45
|
-
# puts sprintf('%10s', '
|
44
|
+
# puts format('%10s', 'foo')
|
45
|
+
# puts sprintf('%10s', 'foo')
|
46
46
|
#
|
47
47
|
# # good
|
48
|
-
# puts '%10s' % '
|
48
|
+
# puts '%10s' % 'foo'
|
49
49
|
#
|
50
50
|
class FormatString < Base
|
51
51
|
include ConfigurableEnforcedStyle
|
@@ -44,7 +44,9 @@ module RuboCop
|
|
44
44
|
PATTERN
|
45
45
|
|
46
46
|
def on_const(node)
|
47
|
-
|
47
|
+
return if namespaced?(node)
|
48
|
+
|
49
|
+
const_name = node.short_name
|
48
50
|
return unless STD_STREAMS.include?(const_name)
|
49
51
|
|
50
52
|
gvar_name = gvar_name(const_name).to_sym
|
@@ -61,6 +63,10 @@ module RuboCop
|
|
61
63
|
format(MSG, gvar_name: gvar_name(const_name), const_name: const_name)
|
62
64
|
end
|
63
65
|
|
66
|
+
def namespaced?(node)
|
67
|
+
!node.namespace.nil? && (node.relative? || !node.namespace.cbase_type?)
|
68
|
+
end
|
69
|
+
|
64
70
|
def gvar_name(const_name)
|
65
71
|
"$#{const_name.to_s.downcase}"
|
66
72
|
end
|
@@ -40,6 +40,7 @@ module RuboCop
|
|
40
40
|
|
41
41
|
MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
|
42
42
|
UNUSED_BLOCK_ARG_MSG = "#{MSG.chop} and remove the unused `%<unused_code>s` block argument."
|
43
|
+
ARRAY_CONVERTER_METHODS = %i[assoc chunk flatten rassoc sort sort_by to_a].freeze
|
43
44
|
|
44
45
|
# @!method kv_each(node)
|
45
46
|
def_node_matcher :kv_each, <<~PATTERN
|
@@ -56,7 +57,6 @@ module RuboCop
|
|
56
57
|
(call $(call _ ${:keys :values}) :each (block_pass (sym _)))
|
57
58
|
PATTERN
|
58
59
|
|
59
|
-
# rubocop:disable Metrics/AbcSize
|
60
60
|
def on_block(node)
|
61
61
|
return unless handleable?(node)
|
62
62
|
|
@@ -66,12 +66,24 @@ module RuboCop
|
|
66
66
|
|
67
67
|
return unless (key, value = each_arguments(node))
|
68
68
|
|
69
|
-
|
69
|
+
check_unused_block_args(node, key, value)
|
70
|
+
end
|
71
|
+
alias on_numblock on_block
|
72
|
+
|
73
|
+
# rubocop:disable Metrics/AbcSize
|
74
|
+
def check_unused_block_args(node, key, value)
|
75
|
+
return if node.body.nil?
|
76
|
+
|
77
|
+
value_unused = unused_block_arg_exist?(node, value)
|
78
|
+
key_unused = unused_block_arg_exist?(node, key)
|
79
|
+
return if value_unused && key_unused
|
80
|
+
|
81
|
+
if value_unused
|
70
82
|
message = message('each_key', node.method_name, value.source)
|
71
83
|
unused_range = key.source_range.end.join(value.source_range.end)
|
72
84
|
|
73
85
|
register_each_args_offense(node, message, 'each_key', unused_range)
|
74
|
-
elsif
|
86
|
+
elsif key_unused
|
75
87
|
message = message('each_value', node.method_name, key.source)
|
76
88
|
unused_range = key.source_range.begin.join(value.source_range.begin)
|
77
89
|
|
@@ -80,8 +92,6 @@ module RuboCop
|
|
80
92
|
end
|
81
93
|
# rubocop:enable Metrics/AbcSize
|
82
94
|
|
83
|
-
alias on_numblock on_block
|
84
|
-
|
85
95
|
def on_block_pass(node)
|
86
96
|
kv_each_with_block_pass(node.parent) do |target, method|
|
87
97
|
register_kv_with_block_pass_offense(node, target, method)
|
@@ -91,6 +101,7 @@ module RuboCop
|
|
91
101
|
private
|
92
102
|
|
93
103
|
def handleable?(node)
|
104
|
+
return false if use_array_converter_method_as_preceding?(node)
|
94
105
|
return false unless (root_receiver = root_receiver(node))
|
95
106
|
|
96
107
|
!root_receiver.literal? || root_receiver.hash_type?
|
@@ -111,11 +122,11 @@ module RuboCop
|
|
111
122
|
lvar_sources = node.body.each_descendant(:lvar).map(&:source)
|
112
123
|
|
113
124
|
if block_arg.mlhs_type?
|
114
|
-
block_arg.each_descendant(:arg).all? do |block_arg|
|
115
|
-
lvar_sources.none?(block_arg.source)
|
125
|
+
block_arg.each_descendant(:arg, :restarg).all? do |block_arg|
|
126
|
+
lvar_sources.none?(block_arg.source.delete_prefix('*'))
|
116
127
|
end
|
117
128
|
else
|
118
|
-
lvar_sources.none?(block_arg.source)
|
129
|
+
lvar_sources.none?(block_arg.source.delete_prefix('*'))
|
119
130
|
end
|
120
131
|
end
|
121
132
|
|
@@ -143,6 +154,16 @@ module RuboCop
|
|
143
154
|
end
|
144
155
|
end
|
145
156
|
|
157
|
+
def use_array_converter_method_as_preceding?(node)
|
158
|
+
return false unless (preceding_method = node.children.first.children.first)
|
159
|
+
unless preceding_method.call_type? ||
|
160
|
+
preceding_method.block_type? || preceding_method.numblock_type?
|
161
|
+
return false
|
162
|
+
end
|
163
|
+
|
164
|
+
ARRAY_CONVERTER_METHODS.include?(preceding_method.method_name)
|
165
|
+
end
|
166
|
+
|
146
167
|
def root_receiver(node)
|
147
168
|
receiver = node.receiver
|
148
169
|
if receiver&.receiver
|
@@ -23,9 +23,9 @@ module RuboCop
|
|
23
23
|
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| k == :bar }
|
24
24
|
# {foo: 1, bar: 2, baz: 3}.select {|k, v| k != :bar }
|
25
25
|
# {foo: 1, bar: 2, baz: 3}.filter {|k, v| k != :bar }
|
26
|
-
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| %i[
|
27
|
-
# {foo: 1, bar: 2, baz: 3}.select {|k, v| !%i[
|
28
|
-
# {foo: 1, bar: 2, baz: 3}.filter {|k, v| !%i[
|
26
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| %i[bar].include?(k) }
|
27
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| !%i[bar].include?(k) }
|
28
|
+
# {foo: 1, bar: 2, baz: 3}.filter {|k, v| !%i[bar].include?(k) }
|
29
29
|
#
|
30
30
|
# # good
|
31
31
|
# {foo: 1, bar: 2, baz: 3}.except(:bar)
|
@@ -73,8 +73,9 @@ module RuboCop
|
|
73
73
|
PATTERN
|
74
74
|
|
75
75
|
def on_send(node)
|
76
|
+
method_name = node.method_name
|
76
77
|
block = node.parent
|
77
|
-
return unless bad_method?(block) && semantically_except_method?(node, block)
|
78
|
+
return unless bad_method?(method_name, block) && semantically_except_method?(node, block)
|
78
79
|
|
79
80
|
except_key = except_key(block)
|
80
81
|
return if except_key.nil? || !safe_to_register_offense?(block, except_key)
|
@@ -91,7 +92,7 @@ module RuboCop
|
|
91
92
|
private
|
92
93
|
|
93
94
|
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
94
|
-
def bad_method?(block)
|
95
|
+
def bad_method?(method_name, block)
|
95
96
|
if active_support_extensions_enabled?
|
96
97
|
bad_method_with_active_support?(block) do |key_arg, send_node|
|
97
98
|
if send_node.method?(:in?) && send_node.receiver&.source != key_arg.source
|
@@ -103,6 +104,8 @@ module RuboCop
|
|
103
104
|
end
|
104
105
|
else
|
105
106
|
bad_method_with_poro?(block) do |key_arg, send_node|
|
107
|
+
return false if method_name == :reject && block.body.method?(:!)
|
108
|
+
|
106
109
|
!send_node.method?(:include?) || send_node.first_argument&.source == key_arg.source
|
107
110
|
end
|
108
111
|
end
|
@@ -29,6 +29,8 @@ module RuboCop
|
|
29
29
|
# * never - forces use of explicit hash literal value
|
30
30
|
# * either - accepts both shorthand and explicit use of hash literal value
|
31
31
|
# * consistent - forces use of the 3.1 syntax only if all values can be omitted in the hash
|
32
|
+
# * either_consistent - accepts both shorthand and explicit use of hash literal value,
|
33
|
+
# but they must be consistent
|
32
34
|
#
|
33
35
|
# @example EnforcedStyle: ruby19 (default)
|
34
36
|
# # bad
|
@@ -110,6 +112,22 @@ module RuboCop
|
|
110
112
|
# # good - can't omit `baz`
|
111
113
|
# {foo: foo, bar: baz}
|
112
114
|
#
|
115
|
+
# @example EnforcedShorthandSyntax: either_consistent
|
116
|
+
#
|
117
|
+
# # good - `foo` and `bar` values can be omitted, but they are consistent, so it's accepted
|
118
|
+
# {foo: foo, bar: bar}
|
119
|
+
#
|
120
|
+
# # bad - `bar` value can be omitted
|
121
|
+
# {foo:, bar: bar}
|
122
|
+
#
|
123
|
+
# # bad - mixed syntaxes
|
124
|
+
# {foo:, bar: baz}
|
125
|
+
#
|
126
|
+
# # good
|
127
|
+
# {foo:, bar:}
|
128
|
+
#
|
129
|
+
# # good - can't omit `baz`
|
130
|
+
# {foo: foo, bar: baz}
|
113
131
|
class HashSyntax < Base
|
114
132
|
include ConfigurableEnforcedStyle
|
115
133
|
include HashShorthandSyntax
|
@@ -195,6 +213,7 @@ module RuboCop
|
|
195
213
|
acceptable_19_syntax_symbol?(pair.key.source)
|
196
214
|
end
|
197
215
|
|
216
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
198
217
|
def acceptable_19_syntax_symbol?(sym_name)
|
199
218
|
sym_name.delete_prefix!(':')
|
200
219
|
|
@@ -209,9 +228,12 @@ module RuboCop
|
|
209
228
|
# Most hash keys can be matched against a simple regex.
|
210
229
|
return true if /\A[_a-z]\w*[?!]?\z/i.match?(sym_name)
|
211
230
|
|
212
|
-
|
213
|
-
|
231
|
+
return false if target_ruby_version <= 2.1
|
232
|
+
|
233
|
+
(sym_name.start_with?("'") && sym_name.end_with?("'")) ||
|
234
|
+
(sym_name.start_with?('"') && sym_name.end_with?('"'))
|
214
235
|
end
|
236
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
215
237
|
|
216
238
|
def check(pairs, delim, msg)
|
217
239
|
pairs.each do |pair|
|
@@ -158,7 +158,10 @@ module RuboCop
|
|
158
158
|
if head.assignment?
|
159
159
|
# The `send` node is used instead of the `indexasgn` node, so `name` cannot be used.
|
160
160
|
# https://github.com/rubocop/rubocop-ast/blob/v1.29.0/lib/rubocop/ast/node/indexasgn_node.rb
|
161
|
-
|
161
|
+
#
|
162
|
+
# FIXME: It would be better to update `RuboCop::AST::OpAsgnNode` or its subclasses to
|
163
|
+
# handle `self.foo ||= value` as a solution, instead of using `head.node_parts[0].to_s`.
|
164
|
+
assigned_value = head.send_type? ? head.receiver.source : head.node_parts[0].to_s
|
162
165
|
|
163
166
|
return if condition_variable == assigned_value
|
164
167
|
end
|
@@ -44,7 +44,6 @@ module RuboCop
|
|
44
44
|
# # good
|
45
45
|
# foo == bar
|
46
46
|
#
|
47
|
-
# @example
|
48
47
|
# # bad
|
49
48
|
# if foo.do_something?
|
50
49
|
# true
|
@@ -112,9 +111,11 @@ module RuboCop
|
|
112
111
|
end
|
113
112
|
|
114
113
|
def message(node, keyword)
|
115
|
-
|
116
|
-
|
117
|
-
|
114
|
+
if node.elsif?
|
115
|
+
MSG_FOR_ELSIF
|
116
|
+
else
|
117
|
+
format(MSG, keyword: keyword)
|
118
|
+
end
|
118
119
|
end
|
119
120
|
|
120
121
|
def return_boolean_value?(condition)
|
@@ -76,9 +76,9 @@ module RuboCop
|
|
76
76
|
PATTERN
|
77
77
|
|
78
78
|
def on_send(node)
|
79
|
-
inverse_candidate?(node) do |
|
79
|
+
inverse_candidate?(node) do |method_call, lhs, method, rhs|
|
80
80
|
return unless inverse_methods.key?(method)
|
81
|
-
return if negated?(node)
|
81
|
+
return if negated?(node) || relational_comparison_with_safe_navigation?(method_call)
|
82
82
|
return if part_of_ignored_node?(node)
|
83
83
|
return if possible_class_hierarchy_check?(lhs, rhs, method)
|
84
84
|
|
@@ -155,16 +155,16 @@ module RuboCop
|
|
155
155
|
node.parent.respond_to?(:method?) && node.parent.method?(:!)
|
156
156
|
end
|
157
157
|
|
158
|
+
def relational_comparison_with_safe_navigation?(node)
|
159
|
+
node.csend_type? && CLASS_COMPARISON_METHODS.include?(node.method_name)
|
160
|
+
end
|
161
|
+
|
158
162
|
def not_to_receiver(node, method_call)
|
159
|
-
|
160
|
-
node.loc.selector.begin_pos,
|
161
|
-
method_call.source_range.begin_pos)
|
163
|
+
node.loc.selector.begin.join(method_call.source_range.begin)
|
162
164
|
end
|
163
165
|
|
164
166
|
def end_parentheses(node, method_call)
|
165
|
-
|
166
|
-
method_call.source_range.end_pos,
|
167
|
-
node.source_range.end_pos)
|
167
|
+
method_call.source_range.end.join(node.source_range.end)
|
168
168
|
end
|
169
169
|
|
170
170
|
# When comparing classes, `!(Integer < Numeric)` is not the same as
|