rubocop 1.86.1 → 1.87.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.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +15 -1
  3. data/lib/rubocop/cli/command/auto_generate_config.rb +27 -1
  4. data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
  5. data/lib/rubocop/cli/command/show_docs_url.rb +3 -7
  6. data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
  7. data/lib/rubocop/cli.rb +6 -7
  8. data/lib/rubocop/comment_config.rb +12 -15
  9. data/lib/rubocop/config_loader.rb +17 -2
  10. data/lib/rubocop/config_loader_resolver.rb +11 -3
  11. data/lib/rubocop/config_store.rb +1 -1
  12. data/lib/rubocop/cop/autocorrect_logic.rb +2 -1
  13. data/lib/rubocop/cop/base.rb +8 -2
  14. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
  15. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +33 -2
  16. data/lib/rubocop/cop/correctors.rb +28 -0
  17. data/lib/rubocop/cop/exclude_limit.rb +31 -5
  18. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  19. data/lib/rubocop/cop/gemspec/require_mfa.rb +4 -4
  20. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
  21. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  22. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
  23. data/lib/rubocop/cop/layout/class_structure.rb +1 -1
  24. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +14 -5
  25. data/lib/rubocop/cop/layout/end_alignment.rb +2 -2
  26. data/lib/rubocop/cop/layout/indentation_width.rb +13 -1
  27. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
  28. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +26 -1
  29. data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -1
  30. data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -1
  31. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  32. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
  33. data/lib/rubocop/cop/lint/constant_reassignment.rb +36 -4
  34. data/lib/rubocop/cop/lint/constant_resolution.rb +5 -5
  35. data/lib/rubocop/cop/lint/deprecated_constants.rb +1 -1
  36. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  37. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  38. data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
  39. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +1 -1
  40. data/lib/rubocop/cop/lint/number_conversion.rb +5 -5
  41. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  42. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -13
  43. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +2 -2
  44. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +3 -3
  45. data/lib/rubocop/cop/lint/require_relative_self_path.rb +3 -1
  46. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  47. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -1
  48. data/lib/rubocop/cop/lint/unreachable_code.rb +2 -2
  49. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -8
  50. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +1 -1
  51. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +18 -7
  52. data/lib/rubocop/cop/metrics/block_length.rb +1 -1
  53. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  54. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
  55. data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
  56. data/lib/rubocop/cop/mixin/project_index_help.rb +48 -0
  57. data/lib/rubocop/cop/mixin.rb +86 -0
  58. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  59. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  60. data/lib/rubocop/cop/naming/predicate_method.rb +2 -2
  61. data/lib/rubocop/cop/naming/predicate_prefix.rb +1 -1
  62. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
  63. data/lib/rubocop/cop/offense.rb +8 -0
  64. data/lib/rubocop/cop/registry.rb +42 -25
  65. data/lib/rubocop/cop/security/io_methods.rb +1 -1
  66. data/lib/rubocop/cop/style/alias.rb +10 -1
  67. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  68. data/lib/rubocop/cop/style/class_and_module_children.rb +8 -0
  69. data/lib/rubocop/cop/style/copyright.rb +21 -10
  70. data/lib/rubocop/cop/style/date_time.rb +2 -2
  71. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
  72. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  73. data/lib/rubocop/cop/style/file_write.rb +18 -16
  74. data/lib/rubocop/cop/style/format_string.rb +4 -3
  75. data/lib/rubocop/cop/style/hash_conversion.rb +1 -1
  76. data/lib/rubocop/cop/style/hash_lookup_method.rb +12 -7
  77. data/lib/rubocop/cop/style/if_inside_else.rb +15 -2
  78. data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
  79. data/lib/rubocop/cop/style/min_max_comparison.rb +1 -1
  80. data/lib/rubocop/cop/style/module_member_existence_check.rb +6 -3
  81. data/lib/rubocop/cop/style/reduce_to_hash.rb +16 -0
  82. data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
  83. data/lib/rubocop/cop/style/redundant_constant_base.rb +5 -5
  84. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +2 -2
  85. data/lib/rubocop/cop/style/redundant_self.rb +2 -2
  86. data/lib/rubocop/cop/style/regexp_literal.rb +31 -2
  87. data/lib/rubocop/cop/style/rescue_modifier.rb +3 -3
  88. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  89. data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -2
  90. data/lib/rubocop/cop/style/struct_inheritance.rb +13 -0
  91. data/lib/rubocop/cop/style/symbol_proc.rb +3 -3
  92. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -2
  93. data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
  94. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -0
  95. data/lib/rubocop/cop/style/yoda_condition.rb +1 -1
  96. data/lib/rubocop/cop/team.rb +86 -35
  97. data/lib/rubocop/file_patterns.rb +9 -1
  98. data/lib/rubocop/formatter/disabled_config_formatter.rb +4 -1
  99. data/lib/rubocop/lsp/runtime.rb +1 -2
  100. data/lib/rubocop/options.rb +26 -4
  101. data/lib/rubocop/project_index_loader.rb +66 -0
  102. data/lib/rubocop/rspec/shared_contexts.rb +21 -0
  103. data/lib/rubocop/runner.rb +123 -57
  104. data/lib/rubocop/target_finder.rb +13 -6
  105. data/lib/rubocop/version.rb +20 -2
  106. data/lib/rubocop.rb +8 -96
  107. metadata +8 -3
@@ -5,8 +5,10 @@ module RuboCop
5
5
  module Layout
6
6
  # Enforces empty line after guard clause.
7
7
  #
8
- # This cop allows `# :nocov:` directive after guard clause because
9
- # SimpleCov excludes code from the coverage report by wrapping it in `# :nocov:`:
8
+ # This cop allows a SimpleCov directive comment after guard clause because
9
+ # SimpleCov excludes code from the coverage report by wrapping it in such directives.
10
+ # Both the legacy `# :nocov:` comment and the newer `# simplecov:disable` /
11
+ # `# simplecov:enable` comments are recognized:
10
12
  #
11
13
  # [source,ruby]
12
14
  # ----
@@ -16,6 +18,13 @@ module RuboCop
16
18
  # # :nocov:
17
19
  # bar
18
20
  # end
21
+ #
22
+ # def foo
23
+ # # simplecov:disable
24
+ # return if condition
25
+ # # simplecov:enable
26
+ # bar
27
+ # end
19
28
  # ----
20
29
  #
21
30
  # Refer to SimpleCov's documentation for more details:
@@ -58,7 +67,7 @@ module RuboCop
58
67
 
59
68
  MSG = 'Add empty line after guard clause.'
60
69
  END_OF_HEREDOC_LINE = 1
61
- SIMPLE_DIRECTIVE_COMMENT_PATTERN = /\A# *:nocov:\z/.freeze
70
+ SIMPLECOV_COMMENT_PATTERN = /\A#\s*(?::nocov:|simplecov\s*:\s*(?:disable|enable)\b)/.freeze
62
71
 
63
72
  # @!method guard_clause_branch?(node)
64
73
  def_node_matcher :guard_clause_branch?, <<~PATTERN
@@ -213,10 +222,10 @@ module RuboCop
213
222
  parent.begin_type? && same_line?(node, node.right_sibling)
214
223
  end
215
224
 
216
- # SimpleCov excludes code from the coverage report by wrapping it in `# :nocov:`:
225
+ # SimpleCov excludes code from the coverage report by wrapping it in directive comments:
217
226
  # https://github.com/simplecov-ruby/simplecov#ignoringskipping-code
218
227
  def simplecov_directive_comment?(comment)
219
- SIMPLE_DIRECTIVE_COMMENT_PATTERN.match?(comment.text)
228
+ SIMPLECOV_COMMENT_PATTERN.match?(comment.text)
220
229
  end
221
230
  end
222
231
  end
@@ -19,10 +19,10 @@ module RuboCop
19
19
  #
20
20
  # This `Layout/EndAlignment` cop aligns with keywords (e.g. `if`, `while`, `case`)
21
21
  # by default. On the other hand, `Layout/BeginEndAlignment` cop aligns with
22
- # `EnforcedStyleAlignWith: start_of_line` by default due to `||= begin` tends
22
+ # `EnforcedStyleAlignWith: start_of_line` by default because `||= begin` tends
23
23
  # to align with the start of the line. `Layout/DefEndAlignment` cop also aligns with
24
24
  # `EnforcedStyleAlignWith: start_of_line` by default.
25
- # These style can be configured by each cop.
25
+ # These styles can be configured by each cop.
26
26
  #
27
27
  # @example EnforcedStyleAlignWith: keyword (default)
28
28
  # # bad
@@ -473,8 +473,12 @@ module RuboCop
473
473
  end
474
474
 
475
475
  def block_body_indentation_base(node, end_loc)
476
- if style == :relative_to_receiver && dot_on_new_line?(node)
476
+ return end_loc unless style == :relative_to_receiver
477
+
478
+ if dot_on_new_line?(node)
477
479
  node.send_node.loc.dot
480
+ elsif selector_on_new_line?(node)
481
+ node.send_node.loc.selector
478
482
  else
479
483
  end_loc
480
484
  end
@@ -487,6 +491,14 @@ module RuboCop
487
491
  receiver = send_node.receiver
488
492
  receiver && receiver.last_line < send_node.loc.dot.line
489
493
  end
494
+
495
+ def selector_on_new_line?(node)
496
+ send_node = node.send_node
497
+ return false unless send_node.loc?(:dot) && send_node.loc?(:selector)
498
+
499
+ receiver = send_node.receiver
500
+ receiver && receiver.last_line < send_node.loc.selector.line
501
+ end
490
502
  end
491
503
  end
492
504
  end
@@ -124,7 +124,7 @@ module RuboCop
124
124
  def single_line_ignoring_receiver?(node)
125
125
  return false unless node.loc.begin && node.loc.end
126
126
 
127
- node.loc.begin.line == node.loc.end.line
127
+ same_line?(node.loc.begin, node.loc.end)
128
128
  end
129
129
  end
130
130
  end
@@ -158,7 +158,7 @@ module RuboCop
158
158
  @base = find_hash_pair_alignment_base(node)
159
159
  return false if !@base && inside_multiline_chain_arg?(node)
160
160
 
161
- @base ||= lhs.source_range
161
+ @base ||= first_dot_alignment_base(node, rhs) || lhs.source_range
162
162
  return if aligned_with_first_line_dot?(node, rhs)
163
163
 
164
164
  calculate_column_delta_offense(rhs, @base.column)
@@ -172,6 +172,31 @@ module RuboCop
172
172
  first_call.loc.dot.join(first_call.loc.selector)
173
173
  end
174
174
 
175
+ def first_dot_alignment_base(node, rhs)
176
+ return unless rhs.source.start_with?('.', '&.')
177
+
178
+ first_call = first_call_has_a_dot(node)
179
+ dot = first_call.loc.dot
180
+ return unless dot
181
+ return if first_call == node
182
+
183
+ after_block_base = after_multiline_block_base(first_call, node)
184
+ return after_block_base if after_block_base
185
+
186
+ return unless same_line?(dot, first_call.receiver.source_range)
187
+
188
+ dot.join(first_call.loc.selector)
189
+ end
190
+
191
+ def after_multiline_block_base(first_call, node)
192
+ return unless first_call.block_node&.multiline?
193
+
194
+ after_block = first_call.block_node.parent
195
+ return unless after_block&.call_type? && after_block.loc?(:dot) && after_block != node
196
+
197
+ after_block.loc.dot.join(after_block.loc.selector)
198
+ end
199
+
175
200
  def inside_multiline_chain_arg?(node)
176
201
  enclosing_call = find_enclosing_chain_call(node)
177
202
  return false unless enclosing_call
@@ -114,7 +114,9 @@ module RuboCop
114
114
 
115
115
  def other_cop_takes_precedence?(node)
116
116
  single_line_block_chain_enabled? && any_descendant?(node, :any_block) do |block_node|
117
- block_node.parent.send_type? && block_node.parent.loc.dot && block_node.single_line?
117
+ next unless (parent = block_node.parent)
118
+
119
+ parent.call_type? && parent.loc.dot && block_node.single_line?
118
120
  end
119
121
  end
120
122
 
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Layout
6
6
  # Checks for space between the name of a receiver and a left
7
- # brackets.
7
+ # bracket.
8
8
  #
9
9
  # @example
10
10
  #
@@ -7,7 +7,7 @@ module RuboCop
7
7
  # when param passed without parentheses.
8
8
  #
9
9
  # This cop can customize allowed methods with `AllowedMethods`.
10
- # By default, there are no methods to allowed.
10
+ # By default, there are no allowed methods.
11
11
  #
12
12
  # @example
13
13
  #
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for overwriting an exception with an exception result by use ``rescue =>``.
6
+ # Checks for overwriting an exception with an exception result by using ``rescue =>``.
7
7
  #
8
8
  # You intended to write as `rescue StandardError`.
9
9
  # However, you have written `rescue => StandardError`.
@@ -12,8 +12,13 @@ module RuboCop
12
12
  # class/module keyword definitions. It detects reassignment when a constant
13
13
  # is first defined one way and then redefined using the `NAME = value` syntax.
14
14
  #
15
- # The cop cannot catch all offenses, like, for example, when a constant
16
- # is reassigned in another file, or when using metaprogramming (`Module#const_set`).
15
+ # The cop cannot catch all offenses, like, for example, when using metaprogramming
16
+ # (`Module#const_set`).
17
+ #
18
+ # By default the cop also cannot detect reassignment across files.
19
+ # When `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is installed,
20
+ # the cop additionally consults the project-wide index and reports reassignments
21
+ # whose previous definition lives in another file.
17
22
  #
18
23
  # The cop only takes into account constants assigned in a "simple" way: directly
19
24
  # inside class/module definition, or within another constant. Other type of assignments
@@ -74,7 +79,10 @@ module RuboCop
74
79
  # end
75
80
  #
76
81
  class ConstantReassignment < Base
82
+ include ProjectIndexHelp
83
+
77
84
  MSG = 'Constant `%<constant>s` is already assigned in this namespace.'
85
+ CROSS_FILE_MSG = 'Constant `%<constant>s` is already assigned in `%<path>s`.'
78
86
 
79
87
  RESTRICT_ON_SEND = %i[remove_const].freeze
80
88
 
@@ -101,9 +109,14 @@ module RuboCop
101
109
  return unless simple_assignment?(node)
102
110
 
103
111
  name = fully_qualified_constant_name(node)
104
- return constant_definitions[name] = :casgn unless constant_definitions.key?(name)
105
112
 
106
- add_offense(node, message: format(MSG, constant: constant_display_name(node)))
113
+ if constant_definitions.key?(name)
114
+ add_offense(node, message: format(MSG, constant: constant_display_name(node)))
115
+ return
116
+ end
117
+
118
+ constant_definitions[name] = :casgn
119
+ report_cross_file_collision(node, name, constant_display_name(node))
107
120
  end
108
121
 
109
122
  def on_send(node)
@@ -192,6 +205,25 @@ module RuboCop
192
205
  def constant_definitions
193
206
  @constant_definitions ||= {}
194
207
  end
208
+
209
+ def report_cross_file_collision(node, fully_qualified_name, display_name)
210
+ return unless project_index
211
+ return unless (declaration = project_index[fully_qualified_name.delete_prefix('::')])
212
+ return unless (prior = prior_definition_in_other_file(declaration))
213
+
214
+ msg = format(CROSS_FILE_MSG, constant: display_name, path: prior.location.to_file_path)
215
+
216
+ add_offense(node, message: msg)
217
+ end
218
+
219
+ def prior_definition_in_other_file(declaration)
220
+ current = processed_source.file_path
221
+
222
+ declaration.definitions.find do |definition|
223
+ other = definition.location.to_file_path
224
+ !File.identical?(other, current)
225
+ end
226
+ end
195
227
  end
196
228
  end
197
229
  end
@@ -13,12 +13,12 @@ module RuboCop
13
13
  #
14
14
  # Large projects will over time end up with one or two constant names that
15
15
  # are problematic because of a conflict with a library or just internally
16
- # using the same name a namespace and a class. To avoid too many unnecessary
17
- # offenses, Enable this cop with `Only: [The, Constant, Names, Causing, Issues]`
16
+ # using the same name for a namespace and a class. To avoid too many unnecessary
17
+ # offenses, enable this cop with `Only: [The, Constant, Names, Causing, Issues]`
18
18
  #
19
- # NOTE: `Style/RedundantConstantBase` cop is disabled if this cop is enabled to prevent
20
- # conflicting rules. Because it respects user configurations that want to enable
21
- # this cop which is disabled by default.
19
+ # NOTE: `Style/RedundantConstantBase` cop is disabled if this cop is enabled,
20
+ # to prevent conflicting rules. This is because it respects user configurations
21
+ # that want to enable this cop which is disabled by default.
22
22
  #
23
23
  # @example
24
24
  # # By default checks every constant
@@ -14,7 +14,7 @@ module RuboCop
14
14
  # Alternative: 'alternative_value'
15
15
  # DeprecatedVersion: 'deprecated_version'
16
16
  #
17
- # By default, `NIL`, `TRUE`, `FALSE`, `Net::HTTPServerException, `Random::DEFAULT`,
17
+ # By default, `NIL`, `TRUE`, `FALSE`, `Net::HTTPServerException`, `Random::DEFAULT`,
18
18
  # `Struct::Group`, and `Struct::Passwd` are configured.
19
19
  #
20
20
  # @example
@@ -23,7 +23,7 @@ module RuboCop
23
23
  # `ERB.new` with non-keyword arguments is deprecated since ERB 2.2.0.
24
24
  # Use `:trim_mode` and `:eoutvar` keyword arguments to `ERB.new`.
25
25
  # This cop identifies places where `ERB.new(str, trim_mode, eoutvar)` can
26
- # be replaced by `ERB.new(str, :trim_mode: trim_mode, eoutvar: eoutvar)`.
26
+ # be replaced by `ERB.new(str, trim_mode: trim_mode, eoutvar: eoutvar)`.
27
27
  #
28
28
  # @example
29
29
  # # Target codes supports Ruby 2.6 and higher only
@@ -6,7 +6,7 @@ module RuboCop
6
6
  module Lint
7
7
  # Checks that there is an `# rubocop:enable ...` statement
8
8
  # after a `# rubocop:disable ...` statement. This will prevent leaving
9
- # cop disables on wide ranges of code, that latter contributors to
9
+ # cop disables on wide ranges of code, that later contributors to
10
10
  # a file wouldn't be aware of.
11
11
  #
12
12
  # You can set `MaximumRangeSize` to define the maximum number of
@@ -4,8 +4,8 @@ module RuboCop
4
4
  module Cop
5
5
  module Lint
6
6
  # In math and Python, we can use `x < y < z` style comparison to compare
7
- # multiple value. However, we can't use the comparison in Ruby. However,
8
- # the comparison is not syntax error. This cop checks the bad usage of
7
+ # multiple values. However, we can't use the comparison in Ruby. However,
8
+ # the comparison is not a syntax error. This cop checks the bad usage of
9
9
  # comparison operators.
10
10
  #
11
11
  # @example
@@ -12,7 +12,7 @@ module RuboCop
12
12
  # always sort the list.
13
13
  #
14
14
  # `Dir.glob` and `Dir[]` sort globbed results by default in Ruby 3.0.
15
- # So all bad cases are acceptable when Ruby 3.0 or higher are used.
15
+ # So all bad cases are acceptable when Ruby 3.0 or higher is used.
16
16
  #
17
17
  # NOTE: This cop will be deprecated and removed when supporting only Ruby 3.0 and higher.
18
18
  #
@@ -3,9 +3,9 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Warns the usage of unsafe number conversions. Unsafe
7
- # number conversion can cause unexpected error if auto type conversion
8
- # fails. Cop prefer parsing with number class instead.
6
+ # Warns against the usage of unsafe number conversions. Unsafe
7
+ # number conversion can cause an unexpected error if auto type conversion
8
+ # fails. The cop prefers parsing with a number class instead.
9
9
  #
10
10
  # Conversion with `Integer`, `Float`, etc. will raise an `ArgumentError`
11
11
  # if given input that is not numeric (eg. an empty string), whereas
@@ -14,10 +14,10 @@ module RuboCop
14
14
  # always correct to raise if a value is not numeric.
15
15
  #
16
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
17
+ # methods (for instance, `Time` and `DateTime` values are allowed by this
18
18
  # cop by default). Similarly, Rails' duration methods do not work well
19
19
  # with `Integer()` and can be allowed with `AllowedMethods`. By default,
20
- # there are no methods to allowed.
20
+ # there are no allowed methods.
21
21
  #
22
22
  # @safety
23
23
  # Autocorrection is unsafe because it is not guaranteed that the
@@ -16,7 +16,7 @@ module RuboCop
16
16
  # ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
17
17
  # -e:1: _1 is reserved for numbered parameter
18
18
  #
19
- # NOTE: The parametered parameters are from `_1` to `_9`. This cop checks `_0`, and over `_10`
19
+ # NOTE: The numbered parameters are from `_1` to `_9`. This cop checks `_0`, and over `_10`
20
20
  # as well to prevent confusion.
21
21
  #
22
22
  # @example
@@ -63,19 +63,9 @@ module RuboCop
63
63
  end
64
64
 
65
65
  def spaces_before_left_parenthesis(node)
66
- receiver = node.receiver
67
- receiver_length = if receiver
68
- receiver.source.length
69
- else
70
- 0
71
- end
72
- without_receiver = node.source[receiver_length..]
73
-
74
- # Escape question mark if any.
75
- method_regexp = Regexp.escape(node.method_name)
76
-
77
- match = without_receiver.match(/^\s*&?\.?\s*#{method_regexp}(\s+)\(/)
78
- match ? match.captures[0].length : 0
66
+ return 0 if node.parenthesized? || !node.first_argument.source.start_with?('(')
67
+
68
+ node.first_argument.source_range.begin_pos - node.loc.selector.end_pos
79
69
  end
80
70
 
81
71
  def space_range(expr, space_length)
@@ -6,8 +6,8 @@ module RuboCop
6
6
  # Detects instances of rubocop:enable comments that can be
7
7
  # removed.
8
8
  #
9
- # When comment enables all cops at once `rubocop:enable all`
10
- # that cop checks whether any cop was actually enabled.
9
+ # When a comment enables all cops at once `rubocop:enable all`
10
+ # the cop checks whether any cop was actually enabled.
11
11
  #
12
12
  # @example
13
13
  #
@@ -17,14 +17,14 @@ module RuboCop
17
17
  # or with `String.new` or `String()`.
18
18
  # * `to_sym` when called on a symbol literal or interpolated symbol.
19
19
  # * `to_i` when called on an integer literal or with `Integer()`.
20
- # * `to_f` when called on a float literal of with `Float()`.
20
+ # * `to_f` when called on a float literal or with `Float()`.
21
21
  # * `to_r` when called on a rational literal or with `Rational()`.
22
- # * `to_c` when called on a complex literal of with `Complex()`.
22
+ # * `to_c` when called on a complex literal or with `Complex()`.
23
23
  # * `to_a` when called on an array literal, or with `Array.new`, `Array()` or `Array[]`.
24
24
  # * `to_h` when called on a hash literal, or with `Hash.new`, `Hash()` or `Hash[]`.
25
25
  # * `to_set` when called on `Set.new` or `Set[]`.
26
26
  #
27
- # In all cases, chaining one same `to_*` conversion methods listed above is redundant.
27
+ # In all cases, chaining one of the same `to_*` conversion methods listed above is redundant.
28
28
  #
29
29
  # The cop can also register an offense for chaining conversion methods on methods that are
30
30
  # expected to return a specific type regardless of receiver (eg. `foo.inspect.to_s` and
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for uses a file requiring itself with `require_relative`.
6
+ # Checks for a file requiring itself with `require_relative`.
7
7
  #
8
8
  # @example
9
9
  #
@@ -38,6 +38,8 @@ module RuboCop
38
38
  private
39
39
 
40
40
  def same_file?(file_path, required_feature)
41
+ return false unless File.extname(file_path) == '.rb'
42
+
41
43
  file_path == required_feature || remove_ext(file_path) == required_feature
42
44
  end
43
45
 
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for a rescued exception that get shadowed by a
6
+ # Checks for a rescued exception that gets shadowed by a
7
7
  # less specific exception being rescued before a more specific
8
8
  # exception is rescued.
9
9
  #
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for Regexpes (both literals and via `Regexp.new` / `Regexp.compile`)
6
+ # Checks for Regexps (both literals and via `Regexp.new` / `Regexp.compile`)
7
7
  # that contain unescaped `]` characters.
8
8
  #
9
9
  # It emulates the following Ruby warning:
@@ -4,8 +4,8 @@ module RuboCop
4
4
  module Cop
5
5
  module Lint
6
6
  # Checks for unreachable code.
7
- # The check are based on the presence of flow of control
8
- # statement in non-final position in `begin` (implicit) blocks.
7
+ # The check is based on the presence of flow-of-control
8
+ # statements in non-final position in `begin` (implicit) blocks.
9
9
  #
10
10
  # @example
11
11
  #
@@ -40,8 +40,6 @@ module RuboCop
40
40
  class UselessAssignment < Base
41
41
  extend AutoCorrector
42
42
 
43
- include RangeHelp
44
-
45
43
  MSG = 'Useless assignment to variable - `%<variable>s`.'
46
44
 
47
45
  def self.joining_forces
@@ -189,12 +187,9 @@ module RuboCop
189
187
  # rubocop:enable Metrics/AbcSize
190
188
 
191
189
  def remove_exception_assignment_part(corrector, node)
192
- corrector.remove(
193
- range_between(
194
- (node.parent.children.first&.source_range || node.parent.location.keyword).end_pos,
195
- node.source_range.end_pos
196
- )
197
- )
190
+ range = node.parent.children.first&.source_range || node.parent.location.keyword
191
+
192
+ corrector.remove(range.end.join(node.source_range.end))
198
193
  end
199
194
 
200
195
  def rename_variable_with_underscore(corrector, node)
@@ -6,7 +6,7 @@ module RuboCop
6
6
  # Looks for `ruby2_keywords` calls for methods that do not need it.
7
7
  #
8
8
  # `ruby2_keywords` should only be called on methods that accept an argument splat
9
- # (`\*args`) but do not explicit keyword arguments (`k:` or `k: true`) or
9
+ # (`\*args`) but do not have explicit keyword arguments (`k:` or `k: true`) or
10
10
  # a keyword splat (`**kwargs`).
11
11
  #
12
12
  # @example
@@ -60,9 +60,7 @@ module RuboCop
60
60
  return true if _cant_be_nil?(node.expression, receiver)
61
61
  end
62
62
 
63
- # Due to how `if/else` are implemented (`elsif` is a child of `if` or another `elsif`),
64
- # using left_siblings will not work correctly for them.
65
- if !else_branch?(node) || (node.if_type? && !node.elsif?)
63
+ if sequentially_reached?(node)
66
64
  node.left_siblings.reverse_each do |sibling|
67
65
  next unless sibling.is_a?(AST::Node)
68
66
 
@@ -82,15 +80,17 @@ module RuboCop
82
80
  !NIL_METHODS.include?(method_name) && !@additional_nil_methods.include?(method_name)
83
81
  end
84
82
 
85
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
83
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
86
84
  def sole_condition_of_parent_if?(node)
87
85
  child = node
88
86
  parent = node.parent
89
87
 
90
88
  while parent
91
89
  if parent.if_type?
92
- condition = parent.condition
93
- return true if !child.equal?(condition) && non_nil_condition?(condition, node)
90
+ unless parent.unless?
91
+ condition = parent.condition
92
+ return true if !child.equal?(condition) && non_nil_condition?(condition, node)
93
+ end
94
94
 
95
95
  parent = find_top_if(parent) if parent.elsif?
96
96
  elsif else_branch?(parent)
@@ -104,7 +104,7 @@ module RuboCop
104
104
 
105
105
  false
106
106
  end
107
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
107
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
108
108
 
109
109
  def non_nil_condition?(condition, node)
110
110
  return true if condition == node
@@ -112,6 +112,17 @@ module RuboCop
112
112
  condition.csend_type? && csend_root_receiver(condition) == node
113
113
  end
114
114
 
115
+ # Whether control reaches `node` by falling through its left siblings rather than by
116
+ # a non-sequential entry. A `resbody` is entered via an exception, the `ensure` branch
117
+ # runs even after a partway raise, and the `else` arm of an `if/elsif` chain is reached by
118
+ # branching (its `if/case` siblings are walked via parent recursion instead).
119
+ def sequentially_reached?(node)
120
+ return false if node.resbody_type?
121
+ return false if node.parent&.ensure_type? && node.parent.branch.equal?(node)
122
+
123
+ !else_branch?(node) || (node.if_type? && !node.elsif?)
124
+ end
125
+
115
126
  def else_branch?(node)
116
127
  node.parent&.if_type? && node.parent.else_branch == node
117
128
  end
@@ -17,7 +17,7 @@ module RuboCop
17
17
  #
18
18
  # NOTE: The `ExcludedMethods` configuration is deprecated and only kept
19
19
  # for backwards compatibility. Please use `AllowedMethods` and `AllowedPatterns`
20
- # instead. By default, there are no methods to allowed.
20
+ # instead. By default, there are no allowed methods.
21
21
  #
22
22
  # @example CountAsOne: ['array', 'hash', 'heredoc', 'method_call']
23
23
  #
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # NOTE: The `ExcludedMethods` and `IgnoredMethods` configuration is
16
16
  # deprecated and only kept for backwards compatibility.
17
17
  # Please use `AllowedMethods` and `AllowedPatterns` instead.
18
- # By default, there are no methods to allowed.
18
+ # By default, there are no allowed methods.
19
19
  #
20
20
  # @example CountAsOne: ['array', 'hash', 'heredoc', 'method_call']
21
21
  #
@@ -43,7 +43,7 @@ module RuboCop
43
43
  end
44
44
  end
45
45
 
46
- # Returns true iff name is a known iterating type (e.g. :each, :transform_values)
46
+ # Returns true only when name is a known iterating type (e.g. :each, :transform_values).
47
47
  def iterating_method?(name)
48
48
  KNOWN_ITERATING_METHODS.include? name
49
49
  end
@@ -13,11 +13,12 @@ module RuboCop
13
13
  `max=` is deprecated. Use `exclude_limit <ParameterName>` instead.
14
14
  WARNING
15
15
 
16
- cfg = config_to_allow_offenses
17
- cfg[:exclude_limit] ||= {}
18
- current_max = cfg[:exclude_limit][max_parameter_name]
19
- value = [current_max, value].max if current_max
20
- cfg[:exclude_limit][max_parameter_name] = value
16
+ cop_dir = RuboCop::ExcludeLimit.cop_dir_for(self.class.badge.to_s)
17
+ return unless cop_dir
18
+
19
+ cop_dir.mkpath
20
+ filepath = cop_dir.join(max_parameter_name)
21
+ filepath.write("#{value}\n", mode: 'a')
21
22
  end
22
23
 
23
24
  def max_parameter_name