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
@@ -7,53 +7,145 @@ module RuboCop
|
|
7
7
|
# configured style, snake_case, normalcase, or non_integer,
|
8
8
|
# for their numbering.
|
9
9
|
#
|
10
|
+
# Additionally, `CheckMethodNames` and `CheckSymbols` configuration options
|
11
|
+
# can be used to specify whether method names and symbols should be checked.
|
12
|
+
# Both are enabled by default.
|
13
|
+
#
|
10
14
|
# @example EnforcedStyle: snake_case
|
11
15
|
# # bad
|
12
|
-
#
|
16
|
+
# :some_sym1
|
13
17
|
# variable1 = 1
|
14
18
|
#
|
15
|
-
#
|
19
|
+
# def some_method1; end
|
16
20
|
#
|
21
|
+
# def some_method_1(arg1); end
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# :some_sym_1
|
17
25
|
# variable_1 = 1
|
18
26
|
#
|
27
|
+
# def some_method_1; end
|
28
|
+
#
|
29
|
+
# def some_method_1(arg_1); end
|
30
|
+
#
|
19
31
|
# @example EnforcedStyle: normalcase (default)
|
20
32
|
# # bad
|
21
|
-
#
|
33
|
+
# :some_sym_1
|
22
34
|
# variable_1 = 1
|
23
35
|
#
|
24
|
-
#
|
36
|
+
# def some_method_1; end
|
25
37
|
#
|
38
|
+
# def some_method1(arg_1); end
|
39
|
+
#
|
40
|
+
# # good
|
41
|
+
# :some_sym1
|
26
42
|
# variable1 = 1
|
27
43
|
#
|
44
|
+
# def some_method1; end
|
45
|
+
#
|
46
|
+
# def some_method1(arg1); end
|
47
|
+
#
|
28
48
|
# @example EnforcedStyle: non_integer
|
29
49
|
# # bad
|
50
|
+
# :some_sym1
|
51
|
+
# :some_sym_1
|
30
52
|
#
|
31
53
|
# variable1 = 1
|
32
|
-
#
|
33
54
|
# variable_1 = 1
|
34
55
|
#
|
56
|
+
# def some_method1; end
|
57
|
+
#
|
58
|
+
# def some_method_1; end
|
59
|
+
#
|
60
|
+
# def some_methodone(arg1); end
|
61
|
+
# def some_methodone(arg_1); end
|
62
|
+
#
|
35
63
|
# # good
|
64
|
+
# :some_symone
|
65
|
+
# :some_sym_one
|
36
66
|
#
|
37
67
|
# variableone = 1
|
38
|
-
#
|
39
68
|
# variable_one = 1
|
69
|
+
#
|
70
|
+
# def some_methodone; end
|
71
|
+
#
|
72
|
+
# def some_method_one; end
|
73
|
+
#
|
74
|
+
# def some_methodone(argone); end
|
75
|
+
# def some_methodone(arg_one); end
|
76
|
+
#
|
77
|
+
# # In the following examples, we assume `EnforcedStyle: normalcase` (default).
|
78
|
+
#
|
79
|
+
# @example CheckMethodNames: true (default)
|
80
|
+
# # bad
|
81
|
+
# def some_method_1; end
|
82
|
+
#
|
83
|
+
# @example CheckMethodNames: false
|
84
|
+
# # good
|
85
|
+
# def some_method_1; end
|
86
|
+
#
|
87
|
+
# @example CheckSymbols: true (default)
|
88
|
+
# # bad
|
89
|
+
# :some_sym_1
|
90
|
+
#
|
91
|
+
# @example CheckSymbols: false
|
92
|
+
# # good
|
93
|
+
# :some_sym_1
|
94
|
+
#
|
95
|
+
# @example AllowedIdentifier: [capture3]
|
96
|
+
# # good
|
97
|
+
# expect(Open3).to receive(:capture3)
|
98
|
+
#
|
40
99
|
class VariableNumber < Base
|
41
100
|
include ConfigurableNumbering
|
42
101
|
|
43
|
-
MSG = 'Use %<style>s for
|
102
|
+
MSG = 'Use %<style>s for %<identifier_type>s numbers.'
|
44
103
|
|
45
104
|
def on_arg(node)
|
105
|
+
@node = node
|
46
106
|
name, = *node
|
107
|
+
return if allowed_identifier?(name)
|
108
|
+
|
47
109
|
check_name(node, name, node.loc.name)
|
48
110
|
end
|
49
111
|
alias on_lvasgn on_arg
|
50
112
|
alias on_ivasgn on_arg
|
51
113
|
alias on_cvasgn on_arg
|
52
114
|
|
115
|
+
def on_def(node)
|
116
|
+
@node = node
|
117
|
+
return if allowed_identifier?(node.method_name)
|
118
|
+
|
119
|
+
check_name(node, node.method_name, node.loc.name) if cop_config['CheckMethodNames']
|
120
|
+
end
|
121
|
+
alias on_defs on_def
|
122
|
+
|
123
|
+
def on_sym(node)
|
124
|
+
@node = node
|
125
|
+
return if allowed_identifier?(node.value)
|
126
|
+
|
127
|
+
check_name(node, node.value, node) if cop_config['CheckSymbols']
|
128
|
+
end
|
129
|
+
|
53
130
|
private
|
54
131
|
|
55
132
|
def message(style)
|
56
|
-
|
133
|
+
identifier_type =
|
134
|
+
case @node.type
|
135
|
+
when :def, :defs then 'method name'
|
136
|
+
when :sym then 'symbol'
|
137
|
+
else 'variable'
|
138
|
+
end
|
139
|
+
|
140
|
+
format(MSG, style: style, identifier_type: identifier_type)
|
141
|
+
end
|
142
|
+
|
143
|
+
def allowed_identifier?(name)
|
144
|
+
allowed_identifiers.include?(name.to_s.delete('@'))
|
145
|
+
end
|
146
|
+
|
147
|
+
def allowed_identifiers
|
148
|
+
cop_config.fetch('AllowedIdentifiers', [])
|
57
149
|
end
|
58
150
|
end
|
59
151
|
end
|
data/lib/rubocop/cop/offense.rb
CHANGED
@@ -213,7 +213,7 @@ module RuboCop
|
|
213
213
|
# returns `true` if two offenses contain same attributes
|
214
214
|
def ==(other)
|
215
215
|
COMPARISON_ATTRIBUTES.all? do |attribute|
|
216
|
-
|
216
|
+
public_send(attribute) == other.public_send(attribute)
|
217
217
|
end
|
218
218
|
end
|
219
219
|
|
@@ -221,7 +221,7 @@ module RuboCop
|
|
221
221
|
|
222
222
|
def hash
|
223
223
|
COMPARISON_ATTRIBUTES.reduce(0) do |hash, attribute|
|
224
|
-
hash ^
|
224
|
+
hash ^ public_send(attribute).hash
|
225
225
|
end
|
226
226
|
end
|
227
227
|
|
@@ -234,7 +234,7 @@ module RuboCop
|
|
234
234
|
# comparison result
|
235
235
|
def <=>(other)
|
236
236
|
COMPARISON_ATTRIBUTES.each do |attribute|
|
237
|
-
result =
|
237
|
+
result = public_send(attribute) <=> other.public_send(attribute)
|
238
238
|
return result unless result.zero?
|
239
239
|
end
|
240
240
|
0
|
@@ -3,35 +3,37 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Security
|
6
|
-
# This cop checks for the use of `Kernel#open`.
|
6
|
+
# This cop checks for the use of `Kernel#open` and `URI.open`.
|
7
7
|
#
|
8
|
-
# `Kernel#open`
|
9
|
-
# by prefixing a pipe symbol (e.g., `open("| ls")`).
|
10
|
-
# a serious security risk by using variable input to
|
11
|
-
# `Kernel#open`. It would be better to use
|
12
|
-
# `URI#open` explicitly.
|
8
|
+
# `Kernel#open` and `URI.open` enable not only file access but also process
|
9
|
+
# invocation by prefixing a pipe symbol (e.g., `open("| ls")`).
|
10
|
+
# So, it may lead to a serious security risk by using variable input to
|
11
|
+
# the argument of `Kernel#open` and `URI.open`. It would be better to use
|
12
|
+
# `File.open`, `IO.popen` or `URI.parse#open` explicitly.
|
13
13
|
#
|
14
14
|
# @example
|
15
15
|
# # bad
|
16
16
|
# open(something)
|
17
|
+
# URI.open(something)
|
17
18
|
#
|
18
19
|
# # good
|
19
20
|
# File.open(something)
|
20
21
|
# IO.popen(something)
|
21
22
|
# URI.parse(something).open
|
22
23
|
class Open < Base
|
23
|
-
MSG = 'The use of `
|
24
|
+
MSG = 'The use of `%<receiver>sopen` is a serious security risk.'
|
24
25
|
RESTRICT_ON_SEND = %i[open].freeze
|
25
26
|
|
26
27
|
def_node_matcher :open?, <<~PATTERN
|
27
|
-
(send nil? :open $!str ...)
|
28
|
+
(send ${nil? (const {nil? cbase} :URI)} :open $!str ...)
|
28
29
|
PATTERN
|
29
30
|
|
30
31
|
def on_send(node)
|
31
|
-
open?(node) do |code|
|
32
|
+
open?(node) do |receiver, code|
|
32
33
|
return if safe?(code)
|
33
34
|
|
34
|
-
|
35
|
+
message = format(MSG, receiver: receiver ? "#{receiver.source}." : 'Kernel#')
|
36
|
+
add_offense(node.loc.selector, message: message)
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
@@ -7,7 +7,7 @@ module RuboCop
|
|
7
7
|
# By default it enforces accessors to be placed in grouped declarations,
|
8
8
|
# but it can be configured to enforce separating them in multiple declarations.
|
9
9
|
#
|
10
|
-
#
|
10
|
+
# NOTE: `Sorbet` is not compatible with "grouped" style. Consider "separated" style
|
11
11
|
# or disabling this cop.
|
12
12
|
#
|
13
13
|
# @example EnforcedStyle: grouped (default)
|
@@ -66,14 +66,14 @@ module RuboCop
|
|
66
66
|
node.each_child_node do |expr|
|
67
67
|
if expr.send_type?
|
68
68
|
correct_send(expr, corrector)
|
69
|
-
elsif expr.return_type?
|
70
|
-
correct_other(expr, corrector)
|
71
|
-
elsif expr.assignment?
|
69
|
+
elsif expr.return_type? || expr.assignment?
|
72
70
|
correct_other(expr, corrector)
|
73
71
|
end
|
74
72
|
end
|
75
73
|
|
76
74
|
corrector.replace(node.loc.operator, node.alternate_operator)
|
75
|
+
|
76
|
+
keep_operator_precedence(corrector, node)
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
@@ -125,6 +125,14 @@ module RuboCop
|
|
125
125
|
corrector.wrap(node, '(', ')')
|
126
126
|
end
|
127
127
|
|
128
|
+
def keep_operator_precedence(corrector, node)
|
129
|
+
if node.or_type? && node.parent&.and_type?
|
130
|
+
corrector.wrap(node, '(', ')')
|
131
|
+
elsif node.and_type? && node.rhs.or_type?
|
132
|
+
corrector.wrap(node.rhs, '(', ')')
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
128
136
|
def correctable_send?(node)
|
129
137
|
!node.parenthesized? && node.arguments? && !node.method?(:[])
|
130
138
|
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# In Ruby 2.7, arguments forwarding has been added.
|
7
|
+
#
|
8
|
+
# This cop identifies places where `do_something(*args, &block)`
|
9
|
+
# can be replaced by `do_something(...)`.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# def foo(*args, &block)
|
14
|
+
# bar(*args, &block)
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # bad
|
18
|
+
# def foo(*args, **kwargs, &block)
|
19
|
+
# bar(*args, **kwargs, &block)
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # good
|
23
|
+
# def foo(...)
|
24
|
+
# bar(...)
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# @example AllowOnlyRestArgument: true (default)
|
28
|
+
# # good
|
29
|
+
# def foo(*args)
|
30
|
+
# bar(*args)
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# @example AllowOnlyRestArgument: false
|
34
|
+
# # bad
|
35
|
+
# # The following code can replace the arguments with `...`,
|
36
|
+
# # but it will change the behavior. Because `...` forwards block also.
|
37
|
+
# def foo(*args)
|
38
|
+
# bar(*args)
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
class ArgumentsForwarding < Base
|
42
|
+
include RangeHelp
|
43
|
+
extend AutoCorrector
|
44
|
+
extend TargetRubyVersion
|
45
|
+
|
46
|
+
minimum_target_ruby_version 2.7
|
47
|
+
|
48
|
+
MSG = 'Use arguments forwarding.'
|
49
|
+
|
50
|
+
def_node_matcher :use_rest_arguments?, <<~PATTERN
|
51
|
+
(args (restarg $_) $...)
|
52
|
+
PATTERN
|
53
|
+
|
54
|
+
def_node_matcher :only_rest_arguments?, <<~PATTERN
|
55
|
+
(send _ _ (splat (lvar %1)))
|
56
|
+
PATTERN
|
57
|
+
|
58
|
+
def_node_matcher :forwarding_method_arguments?, <<~PATTERN
|
59
|
+
{
|
60
|
+
(send _ _
|
61
|
+
(splat (lvar %1))
|
62
|
+
(block-pass (lvar %2)))
|
63
|
+
(send _ _
|
64
|
+
(splat (lvar %1))
|
65
|
+
(hash (kwsplat (lvar %3)))
|
66
|
+
(block-pass (lvar %2)))
|
67
|
+
}
|
68
|
+
PATTERN
|
69
|
+
|
70
|
+
def on_def(node)
|
71
|
+
return unless node.body
|
72
|
+
return unless (rest_args_name, args = use_rest_arguments?(node.arguments))
|
73
|
+
|
74
|
+
node.each_descendant(:send) do |send_node|
|
75
|
+
kwargs_name, block_name = extract_argument_names_from(args)
|
76
|
+
|
77
|
+
next unless forwarding_method?(send_node, rest_args_name, kwargs_name, block_name) &&
|
78
|
+
all_lvars_as_forwarding_method_arguments?(node, send_node)
|
79
|
+
|
80
|
+
register_offense_to_forwarding_method_arguments(send_node)
|
81
|
+
register_offense_to_method_definition_arguments(node)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
alias on_defs on_def
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def extract_argument_names_from(args)
|
89
|
+
kwargs_name = args.first.source.delete('**') if args.first&.kwrestarg_type?
|
90
|
+
block_arg_name = args.last.source.delete('&') if args.last&.blockarg_type?
|
91
|
+
|
92
|
+
[kwargs_name, block_arg_name].map { |name| name&.to_sym }
|
93
|
+
end
|
94
|
+
|
95
|
+
def forwarding_method?(node, rest_arg, kwargs, block_arg)
|
96
|
+
return only_rest_arguments?(node, rest_arg) unless allow_only_rest_arguments?
|
97
|
+
|
98
|
+
forwarding_method_arguments?(node, rest_arg, block_arg, kwargs)
|
99
|
+
end
|
100
|
+
|
101
|
+
def all_lvars_as_forwarding_method_arguments?(def_node, forwarding_method)
|
102
|
+
lvars = def_node.body.each_descendant(:lvar, :lvasgn)
|
103
|
+
|
104
|
+
begin_pos = forwarding_method.source_range.begin_pos
|
105
|
+
end_pos = forwarding_method.source_range.end_pos
|
106
|
+
|
107
|
+
lvars.all? do |lvar|
|
108
|
+
lvar.source_range.begin_pos.between?(begin_pos, end_pos)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def register_offense_to_forwarding_method_arguments(forwarding_method)
|
113
|
+
add_offense(arguments_range(forwarding_method)) do |corrector|
|
114
|
+
range = range_between(
|
115
|
+
forwarding_method.loc.selector.end_pos, forwarding_method.source_range.end_pos
|
116
|
+
)
|
117
|
+
corrector.replace(range, '(...)')
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def register_offense_to_method_definition_arguments(method_definition)
|
122
|
+
add_offense(arguments_range(method_definition)) do |corrector|
|
123
|
+
arguments_range = range_with_surrounding_space(
|
124
|
+
range: method_definition.arguments.source_range, side: :left
|
125
|
+
)
|
126
|
+
corrector.replace(arguments_range, '(...)')
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def arguments_range(node)
|
131
|
+
arguments = node.arguments
|
132
|
+
|
133
|
+
range_between(arguments.first.source_range.begin_pos, arguments.last.source_range.end_pos)
|
134
|
+
end
|
135
|
+
|
136
|
+
def allow_only_rest_arguments?
|
137
|
+
cop_config.fetch('AllowOnlyRestArgument', true)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -227,10 +227,6 @@ module RuboCop
|
|
227
227
|
range_between(node.parent.loc.keyword.begin_pos, node.loc.expression.end_pos)
|
228
228
|
end
|
229
229
|
|
230
|
-
def indent(node)
|
231
|
-
' ' * node.loc.column
|
232
|
-
end
|
233
|
-
|
234
230
|
# Named captures work with `=~` (if regexp is on lhs) and with `match` (both sides)
|
235
231
|
def regexp_with_working_captures?(node)
|
236
232
|
case node.type
|
@@ -14,8 +14,9 @@ module RuboCop
|
|
14
14
|
#
|
15
15
|
# # good
|
16
16
|
# ?\C-\M-d
|
17
|
-
class CharacterLiteral <
|
17
|
+
class CharacterLiteral < Base
|
18
18
|
include StringHelp
|
19
|
+
extend AutoCorrector
|
19
20
|
|
20
21
|
MSG = 'Do not use the character literal - ' \
|
21
22
|
'use string literal instead.'
|
@@ -26,17 +27,15 @@ module RuboCop
|
|
26
27
|
node.source.size.between?(2, 3)
|
27
28
|
end
|
28
29
|
|
29
|
-
def autocorrect(node)
|
30
|
-
|
31
|
-
string = node.source[1..-1]
|
30
|
+
def autocorrect(corrector, node)
|
31
|
+
string = node.source[1..-1]
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
33
|
+
# special character like \n
|
34
|
+
# or ' which needs to use "" or be escaped.
|
35
|
+
if string.length == 2 || string == "'"
|
36
|
+
corrector.replace(node, %("#{string}"))
|
37
|
+
elsif string.length == 1 # normal character
|
38
|
+
corrector.replace(node, "'#{string}'")
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|