rubocop 1.66.1 → 1.67.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +15 -6
  4. data/config/internal_affairs.yml +11 -0
  5. data/lib/rubocop/cli/command/auto_generate_config.rb +6 -7
  6. data/lib/rubocop/cli/command/lsp.rb +2 -2
  7. data/lib/rubocop/config_loader_resolver.rb +3 -3
  8. data/lib/rubocop/config_validator.rb +2 -1
  9. data/lib/rubocop/cop/base.rb +6 -2
  10. data/lib/rubocop/cop/bundler/gem_version.rb +1 -0
  11. data/lib/rubocop/cop/cop.rb +8 -0
  12. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  13. data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
  14. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  15. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +8 -1
  16. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
  17. data/lib/rubocop/cop/internal_affairs.rb +16 -0
  18. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +5 -1
  19. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  20. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
  21. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  22. data/lib/rubocop/cop/layout/indentation_width.rb +4 -5
  23. data/lib/rubocop/cop/layout/leading_comment_space.rb +28 -1
  24. data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
  25. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  26. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  27. data/lib/rubocop/cop/lint/duplicate_set_element.rb +74 -0
  28. data/lib/rubocop/cop/lint/ensure_return.rb +0 -3
  29. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  30. data/lib/rubocop/cop/lint/float_comparison.rb +1 -1
  31. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +10 -4
  32. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +5 -14
  33. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +25 -2
  34. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -6
  35. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -1
  36. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +105 -41
  37. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  38. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  39. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  40. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -2
  41. data/lib/rubocop/cop/naming/inclusive_language.rb +12 -3
  42. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  43. data/lib/rubocop/cop/offense.rb +2 -2
  44. data/lib/rubocop/cop/style/access_modifier_declarations.rb +12 -2
  45. data/lib/rubocop/cop/style/accessor_grouping.rb +10 -2
  46. data/lib/rubocop/cop/style/arguments_forwarding.rb +46 -6
  47. data/lib/rubocop/cop/style/block_delimiters.rb +14 -1
  48. data/lib/rubocop/cop/style/collection_compact.rb +10 -10
  49. data/lib/rubocop/cop/style/combinable_loops.rb +7 -0
  50. data/lib/rubocop/cop/style/commented_keyword.rb +7 -1
  51. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
  52. data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
  53. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  54. data/lib/rubocop/cop/style/guard_clause.rb +1 -1
  55. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -0
  56. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  57. data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
  58. data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -3
  59. data/lib/rubocop/cop/style/lambda.rb +1 -1
  60. data/lib/rubocop/cop/style/map_into_array.rb +53 -7
  61. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +12 -7
  62. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  63. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  64. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  65. data/lib/rubocop/cop/style/one_line_conditional.rb +4 -0
  66. data/lib/rubocop/cop/style/operator_method_call.rb +25 -6
  67. data/lib/rubocop/cop/style/redundant_begin.rb +4 -0
  68. data/lib/rubocop/cop/style/redundant_condition.rb +1 -1
  69. data/lib/rubocop/cop/style/redundant_line_continuation.rb +3 -3
  70. data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
  71. data/lib/rubocop/cop/style/require_order.rb +1 -1
  72. data/lib/rubocop/cop/style/rescue_modifier.rb +13 -1
  73. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
  74. data/lib/rubocop/cop/style/safe_navigation.rb +92 -50
  75. data/lib/rubocop/cop/style/select_by_regexp.rb +9 -6
  76. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  77. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  78. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  79. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  80. data/lib/rubocop/cop/team.rb +8 -1
  81. data/lib/rubocop/cop/util.rb +1 -1
  82. data/lib/rubocop/cops_documentation_generator.rb +73 -34
  83. data/lib/rubocop/file_finder.rb +9 -4
  84. data/lib/rubocop/lsp/runtime.rb +2 -0
  85. data/lib/rubocop/lsp/server.rb +0 -1
  86. data/lib/rubocop/rspec/expect_offense.rb +1 -0
  87. data/lib/rubocop/runner.rb +3 -0
  88. data/lib/rubocop/server/cache.rb +6 -1
  89. data/lib/rubocop/server/core.rb +1 -0
  90. data/lib/rubocop/target_ruby.rb +12 -12
  91. data/lib/rubocop/version.rb +3 -1
  92. data/lib/rubocop/yaml_duplication_checker.rb +20 -27
  93. data/lib/rubocop.rb +2 -0
  94. metadata +10 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a10568527197e80492a28c5b524fa524dbce965513daff4f47e260e03b49d98
4
- data.tar.gz: 8ea447437cbd36aa805b3941cf51b07eecc9dc538ed6a4584f09a1335e21cb48
3
+ metadata.gz: d8127fcc41c5b7ffb95a175f82e8a411dfdec0be2b126c7e0868114519d92d01
4
+ data.tar.gz: 2760fa954ef847d049bdd065dec77518c912f5b9050320fe419b9476393b58ea
5
5
  SHA512:
6
- metadata.gz: 1f292c70ffac1cb186e5be899582c4849a29866722c87ab92a60a723dd16fe86fdf12073c8a7190bba197d246eae3b25ba3cdc6b586b28061cef39ac22b3b438
7
- data.tar.gz: 2dbfc28779854fae0d28fd266ba269b92cb0e3b5c26200aa250df02ff9810804b7b1fcc289a43bac1913dc04c79f788487f9351444f7242cbcdad6854a821d69
6
+ metadata.gz: 87ac1904b5fac462a0b76627aac384ddb57493a3620c3ebc929efa9429ee8ad355038caaef2d41192abfcb726d70d85309a442eb93feab8d034544368be32dfd
7
+ data.tar.gz: a011cbaced00ecab1ba1f6ea57983e92c7c872a08c88e450b9aea054bad61cc0f6acae3e1a50c4e4bf545e86ff339000d19995527ff906f0282e2613e7b2638d
data/README.md CHANGED
@@ -52,7 +52,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
52
52
  in your `Gemfile`:
53
53
 
54
54
  ```rb
55
- gem 'rubocop', '~> 1.66', require: false
55
+ gem 'rubocop', '~> 1.67', require: false
56
56
  ```
57
57
 
58
58
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
data/config/default.yml CHANGED
@@ -861,6 +861,7 @@ Layout/FirstMethodArgumentLineBreak:
861
861
  Enabled: false
862
862
  VersionAdded: '0.49'
863
863
  AllowMultilineFinalElement: false
864
+ AllowedMethods: []
864
865
 
865
866
  Layout/FirstMethodParameterLineBreak:
866
867
  Description: >-
@@ -1036,6 +1037,7 @@ Layout/LeadingCommentSpace:
1036
1037
  VersionChanged: '0.73'
1037
1038
  AllowDoxygenCommentStyle: false
1038
1039
  AllowGemfileRubyComment: false
1040
+ AllowRBSInlineAnnotation: false
1039
1041
 
1040
1042
  Layout/LeadingEmptyLines:
1041
1043
  Description: Check for unnecessary blank lines at the beginning of a file.
@@ -1832,6 +1834,11 @@ Lint/DuplicateRescueException:
1832
1834
  Enabled: true
1833
1835
  VersionAdded: '0.89'
1834
1836
 
1837
+ Lint/DuplicateSetElement:
1838
+ Description: 'Checks for duplicate elements in Set.'
1839
+ Enabled: pending
1840
+ VersionAdded: '1.67'
1841
+
1835
1842
  Lint/EachWithObjectArgument:
1836
1843
  Description: 'Check for immutable argument given to each_with_object.'
1837
1844
  Enabled: true
@@ -2327,9 +2334,9 @@ Lint/SafeNavigationChain:
2327
2334
 
2328
2335
  Lint/SafeNavigationConsistency:
2329
2336
  Description: >-
2330
- Check to make sure that if safe navigation is used for a method
2331
- call in an `&&` or `||` condition that safe navigation is used
2332
- for all method calls on that same object.
2337
+ Check to make sure that if safe navigation is used in an `&&` or `||` condition,
2338
+ consistent and appropriate safe navigation, without excess or deficiency,
2339
+ is used for all method calls on the same object.
2333
2340
  Enabled: true
2334
2341
  VersionAdded: '0.55'
2335
2342
  VersionChanged: '0.77'
@@ -4069,7 +4076,7 @@ Style/HashSyntax:
4069
4076
  StyleGuide: '#hash-literals'
4070
4077
  Enabled: true
4071
4078
  VersionAdded: '0.9'
4072
- VersionChanged: '1.24'
4079
+ VersionChanged: '1.67'
4073
4080
  EnforcedStyle: ruby19
4074
4081
  SupportedStyles:
4075
4082
  # checks for 1.9 syntax (e.g. {a: 1}) for all symbol keys
@@ -4081,7 +4088,7 @@ Style/HashSyntax:
4081
4088
  # enforces both ruby19 and no_mixed_keys styles
4082
4089
  - ruby19_no_mixed_keys
4083
4090
  # Force hashes that have a hash value omission
4084
- EnforcedShorthandSyntax: always
4091
+ EnforcedShorthandSyntax: either
4085
4092
  SupportedShorthandSyntax:
4086
4093
  # forces use of the 3.1 syntax (e.g. {foo:}) when the hash key and value are the same.
4087
4094
  - always
@@ -4318,6 +4325,7 @@ Style/MapIntoArray:
4318
4325
  StyleGuide: '#functional-code'
4319
4326
  Enabled: pending
4320
4327
  VersionAdded: '1.63'
4328
+ VersionChanged: '1.67'
4321
4329
  Safe: false
4322
4330
 
4323
4331
  Style/MapToHash:
@@ -5208,6 +5216,7 @@ Style/ReturnNilInPredicateMethodDefinition:
5208
5216
  AllowedMethods: []
5209
5217
  AllowedPatterns: []
5210
5218
  VersionAdded: '1.53'
5219
+ VersionChanged: '1.67'
5211
5220
 
5212
5221
  Style/SafeNavigation:
5213
5222
  Description: >-
@@ -5218,7 +5227,7 @@ Style/SafeNavigation:
5218
5227
  be `nil` or truthy, but never `false`.
5219
5228
  Enabled: true
5220
5229
  VersionAdded: '0.43'
5221
- VersionChanged: '1.27'
5230
+ VersionChanged: '1.67'
5222
5231
  # Safe navigation may cause a statement to start returning `nil` in addition
5223
5232
  # to whatever it used to return.
5224
5233
  ConvertCodeThatCanStartToReturnNil: false
@@ -0,0 +1,11 @@
1
+ # Configuration for InternalAffairs cops. This file will be
2
+ # automatically loaded when `rubocop/cop/internal_affairs` is required.
3
+ # Only do this when developing custom cops or a RuboCop extension.
4
+
5
+ InternalAffairs/CopDescription:
6
+ Include:
7
+ - 'lib/rubocop/cop/**/*.rb'
8
+
9
+ InternalAffairs/UselessMessageAssertion:
10
+ Include:
11
+ - '**/*_spec.rb'
@@ -151,16 +151,15 @@ module RuboCop
151
151
  end
152
152
 
153
153
  def relative_path_to_todo_from_options_config
154
- return AUTO_GENERATED_FILE if !@options[:config] || options_config_in_root?
154
+ return AUTO_GENERATED_FILE unless @options[:config]
155
155
 
156
- base = Pathname.new('.')
157
- config_dir = Pathname.new(File.dirname(@options[:config]))
156
+ base = Pathname.new(Dir.pwd)
157
+ config_dir = Pathname.new(@options[:config]).realpath.dirname
158
158
 
159
- "#{base.relative_path_from(config_dir)}/#{AUTO_GENERATED_FILE}"
160
- end
159
+ # Don't have the path start with `/`
160
+ return AUTO_GENERATED_FILE if config_dir == base
161
161
 
162
- def options_config_in_root?
163
- File.dirname(@options[:config]) == '.'
162
+ "#{base.relative_path_from(config_dir)}/#{AUTO_GENERATED_FILE}"
164
163
  end
165
164
  end
166
165
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../lsp/server'
4
-
5
3
  module RuboCop
6
4
  class CLI
7
5
  module Command
@@ -11,6 +9,8 @@ module RuboCop
11
9
  self.command_name = :lsp
12
10
 
13
11
  def run
12
+ # Load on demand, `languge-server-protocol` is heavy to require.
13
+ require_relative '../../lsp/server'
14
14
  RuboCop::LSP::Server.new(@config_store).start
15
15
  end
16
16
  end
@@ -166,7 +166,7 @@ module RuboCop
166
166
  return unless duplicate_setting?(base_hash, derived_hash, key, opts[:inherited_file])
167
167
 
168
168
  inherit_mode = opts[:inherit_mode]['merge'] || opts[:inherit_mode]['override']
169
- return if base_hash[key].is_a?(Array) && inherit_mode && inherit_mode.include?(key)
169
+ return if base_hash[key].is_a?(Array) && inherit_mode&.include?(key)
170
170
 
171
171
  puts "#{PathUtil.smart_path(opts[:file])}: " \
172
172
  "#{opts[:cop_name]}:#{key} overrides " \
@@ -194,11 +194,11 @@ module RuboCop
194
194
  end
195
195
 
196
196
  def should_merge?(mode, key)
197
- mode && mode['merge'] && mode['merge'].include?(key)
197
+ mode && mode['merge']&.include?(key)
198
198
  end
199
199
 
200
200
  def should_override?(mode, key)
201
- mode && mode['override'] && mode['override'].include?(key)
201
+ mode && mode['override']&.include?(key)
202
202
  end
203
203
 
204
204
  def merge_hashes?(base_hash, derived_hash, key)
@@ -7,7 +7,8 @@ module RuboCop
7
7
  extend SimpleForwardable
8
8
 
9
9
  # @api private
10
- COMMON_PARAMS = %w[Exclude Include Severity inherit_mode AutoCorrect StyleGuide Details].freeze
10
+ COMMON_PARAMS = %w[Exclude Include Severity inherit_mode AutoCorrect StyleGuide Details
11
+ Enabled].freeze
11
12
  # @api private
12
13
  INTERNAL_PARAMS = %w[Description StyleGuide
13
14
  VersionAdded VersionChanged VersionRemoved
@@ -322,8 +322,12 @@ module RuboCop
322
322
  # @api private
323
323
  def self.callbacks_needed
324
324
  @callbacks_needed ||= public_instance_methods.select do |m|
325
- m.start_with?(/on_|after_/) &&
326
- !Base.method_defined?(m) # exclude standard "callbacks" like 'on_begin_investigation'
325
+ # OPTIMIZE: Check method existence first to make fewer `start_with?` calls.
326
+ # At the time of writing this comment, this excludes 98 of ~104 methods.
327
+ # `start_with?` with two string arguments instead of a regex is faster
328
+ # in this specific case as well.
329
+ !Base.method_defined?(m) && # exclude standard "callbacks" like 'on_begin_investigation'
330
+ m.start_with?('on_', 'after_')
327
331
  end
328
332
  end
329
333
  # rubocop:enable Layout/ClassStructure
@@ -56,6 +56,7 @@ module RuboCop
56
56
 
57
57
  REQUIRED_MSG = 'Gem version specification is required.'
58
58
  FORBIDDEN_MSG = 'Gem version specification is forbidden.'
59
+ RESTRICT_ON_SEND = %i[gem].freeze
59
60
  VERSION_SPECIFICATION_REGEX = /^\s*[~<>=]*\s*[0-9.]+/.freeze
60
61
 
61
62
  # @!method includes_version_specification?(node)
@@ -22,6 +22,14 @@ module RuboCop
22
22
  end
23
23
  end
24
24
 
25
+ def self.inherited(_subclass)
26
+ super
27
+ warn Rainbow(<<~WARNING).yellow, uplevel: 1
28
+ Inheriting from `RuboCop::Cop::Cop` is deprecated. Use `RuboCop::Cop::Base` instead.
29
+ For more information, see https://docs.rubocop.org/rubocop/v1_upgrade_notes.html.
30
+ WARNING
31
+ end
32
+
25
33
  def self.support_autocorrect?
26
34
  method_defined?(:autocorrect)
27
35
  end
@@ -22,7 +22,7 @@ module RuboCop
22
22
  private
23
23
 
24
24
  def ternary_condition?(node)
25
- node.parent&.if_type? && node.parent&.ternary?
25
+ node.parent&.if_type? && node.parent.ternary?
26
26
  end
27
27
 
28
28
  def next_char_is_question_mark?(node)
@@ -112,10 +112,6 @@ module RuboCop
112
112
  body = comment_body(comment_line)
113
113
  node.source.index(body)
114
114
  end
115
-
116
- def relevant_file?(file)
117
- file.match?(%r{/cop/.*\.rb\z})
118
- end
119
115
  end
120
116
  end
121
117
  end
@@ -11,13 +11,9 @@ module RuboCop
11
11
  #
12
12
  # # bad
13
13
  # add_offense(node, message: MSG)
14
- # add_offense(node, message: message)
15
- # add_offense(node, message: message(node))
16
14
  #
17
15
  # # good
18
16
  # add_offense(node)
19
- # add_offense(node, message: CUSTOM_MSG)
20
- # add_offense(node, message: message(other_node))
21
17
  #
22
18
  class RedundantMessageArgument < Base
23
19
  include RangeHelp
@@ -28,22 +24,21 @@ module RuboCop
28
24
 
29
25
  # @!method node_type_check(node)
30
26
  def_node_matcher :node_type_check, <<~PATTERN
31
- (send nil? :add_offense $_node $hash)
27
+ (send nil? :add_offense _node $hash)
32
28
  PATTERN
33
29
 
34
30
  # @!method redundant_message_argument(node)
35
31
  def_node_matcher :redundant_message_argument, <<~PATTERN
36
32
  (pair
37
33
  (sym :message)
38
- ${(const nil? :MSG) (send nil? :message) (send nil? :message _)})
34
+ $(const nil? :MSG))
39
35
  PATTERN
40
36
 
41
- # @!method message_method_call(node)
42
- def_node_matcher :message_method_call, '(send nil? :message $_node)'
43
-
44
37
  def on_send(node)
45
- node_type_check(node) do |node_arg, kwargs|
46
- find_offending_argument(node_arg, kwargs) do |pair|
38
+ return unless (kwargs = node_type_check(node))
39
+
40
+ kwargs.pairs.each do |pair|
41
+ redundant_message_argument(pair) do
47
42
  add_offense(pair) do |corrector|
48
43
  range = offending_range(pair)
49
44
 
@@ -60,16 +55,6 @@ module RuboCop
60
55
 
61
56
  range_with_surrounding_comma(with_space, :left)
62
57
  end
63
-
64
- def find_offending_argument(searched_node, kwargs)
65
- kwargs.pairs.each do |pair|
66
- redundant_message_argument(pair) do |message_argument|
67
- node = message_method_call(message_argument)
68
-
69
- yield pair if !node || node == searched_node
70
- end
71
- end
72
- end
73
58
  end
74
59
  end
75
60
  end
@@ -14,6 +14,12 @@ module RuboCop
14
14
  # node.source
15
15
  #
16
16
  # # bad
17
+ # add_offense(node.source_range)
18
+ #
19
+ # # good
20
+ # add_offense(node)
21
+ #
22
+ # # bad
17
23
  # add_offense(node) { |corrector| corrector.replace(node.source_range, prefer) }
18
24
  # add_offense(node) { |corrector| corrector.insert_before(node.source_range, prefer) }
19
25
  # add_offense(node) { |corrector| corrector.insert_before_multi(node.source_range, prefer) }
@@ -34,7 +40,7 @@ module RuboCop
34
40
 
35
41
  MSG = 'Remove the redundant `source_range`.'
36
42
  RESTRICT_ON_SEND = %i[
37
- source
43
+ source add_offense
38
44
  replace remove insert_before insert_before_multi insert_after insert_after_multi swap
39
45
  ].freeze
40
46
 
@@ -42,6 +48,7 @@ module RuboCop
42
48
  def_node_matcher :redundant_source_range, <<~PATTERN
43
49
  {
44
50
  (send $(send _ :source_range) :source)
51
+ (send nil? :add_offense $(send _ :source_range) ...)
45
52
  (send _ {
46
53
  :replace :insert_before :insert_before_multi :insert_after :insert_after_multi
47
54
  } $(send _ :source_range) _)
@@ -43,11 +43,6 @@ module RuboCop
43
43
  node.ancestors.any? { |ancestor| rspec_expectation_on_msg?(ancestor) }
44
44
  end
45
45
  end
46
-
47
- # Only process spec files
48
- def relevant_file?(file)
49
- file.end_with?('_spec.rb')
50
- end
51
46
  end
52
47
  end
53
48
  end
@@ -31,3 +31,19 @@ require_relative 'internal_affairs/style_detected_api_use'
31
31
  require_relative 'internal_affairs/undefined_config'
32
32
  require_relative 'internal_affairs/useless_message_assertion'
33
33
  require_relative 'internal_affairs/useless_restrict_on_send'
34
+
35
+ module RuboCop
36
+ # Patch in the InternalAffairs specific config values
37
+ module InternalAffairs
38
+ def self.inject!
39
+ path = File.join(ConfigLoader::RUBOCOP_HOME, 'config', 'internal_affairs.yml')
40
+ hash = ConfigLoader.load_yaml_configuration(path)
41
+ config = Config.new(hash, path)
42
+ puts "configuration from #{path}" if ConfigLoader.debug?
43
+ config = ConfigLoader.merge_with_default(config, path)
44
+ ConfigLoader.instance_variable_set(:@default_configuration, config)
45
+ end
46
+ end
47
+ end
48
+
49
+ RuboCop::InternalAffairs.inject!
@@ -59,7 +59,11 @@ module RuboCop
59
59
  modifiers = body.each_child_node(:send).select(&:bare_access_modifier?)
60
60
  end_range = node.loc.end
61
61
 
62
- modifiers.each { |modifier| check_modifier(modifier, end_range) }
62
+ modifiers.each do |modifier|
63
+ next if same_line?(node, modifier)
64
+
65
+ check_modifier(modifier, end_range)
66
+ end
63
67
  end
64
68
 
65
69
  def check_modifier(send_node, end_range)
@@ -61,7 +61,7 @@ module RuboCop
61
61
  private
62
62
 
63
63
  def autocorrect(corrector, node)
64
- if style == :start_of_line && node.parent && node.parent.send_type?
64
+ if style == :start_of_line && node.parent&.send_type?
65
65
  AlignmentCorrector.align_end(corrector, processed_source, node, node.parent)
66
66
  else
67
67
  AlignmentCorrector.align_end(corrector, processed_source, node, node)
@@ -135,7 +135,7 @@ module RuboCop
135
135
 
136
136
  parent = next_sibling.parent
137
137
 
138
- parent&.if_type? && parent&.else?
138
+ parent&.if_type? && parent.else?
139
139
  end
140
140
 
141
141
  def next_sibling_empty_or_guard_clause?(node)
@@ -63,13 +63,21 @@ module RuboCop
63
63
  # }
64
64
  # )
65
65
  #
66
+ # @example AllowedMethods: ['some_method']
67
+ #
68
+ # # good
69
+ # some_method(foo, bar,
70
+ # baz)
66
71
  class FirstMethodArgumentLineBreak < Base
67
72
  include FirstElementLineBreak
73
+ include AllowedMethods
68
74
  extend AutoCorrector
69
75
 
70
76
  MSG = 'Add a line break before the first argument of a multi-line method argument list.'
71
77
 
72
78
  def on_send(node)
79
+ return if allowed_method?(node.method_name)
80
+
73
81
  args = node.arguments.dup
74
82
 
75
83
  # If there is a trailing hash arg without explicit braces, like this:
@@ -3,13 +3,12 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # Checks for indentation that doesn't use the specified number
7
- # of spaces.
6
+ # Checks for indentation that doesn't use the specified number of spaces.
7
+ # The indentation width can be configured using the `Width` setting. The default width is 2.
8
8
  #
9
- # See also the IndentationConsistency cop which is the companion to this
10
- # one.
9
+ # See also the `Layout/IndentationConsistency` cop which is the companion to this one.
11
10
  #
12
- # @example
11
+ # @example Width: 2 (default)
13
12
  # # bad
14
13
  # class A
15
14
  # def test
@@ -49,18 +49,37 @@ module RuboCop
49
49
  # #ruby=2.7.0
50
50
  # #ruby-gemset=myproject
51
51
  #
52
+ # @example AllowRBSInlineAnnotation: false (default)
53
+ #
54
+ # # bad
55
+ #
56
+ # include Enumerable #[Integer]
57
+ #
58
+ # attr_reader :name #: String
59
+ # attr_reader :age #: Integer?
60
+ #
61
+ # @example AllowRBSInlineAnnotation: true
62
+ #
63
+ # # good
64
+ #
65
+ # include Enumerable #[Integer]
66
+ #
67
+ # attr_reader :name #: String
68
+ # attr_reader :age #: Integer?
69
+ #
52
70
  class LeadingCommentSpace < Base
53
71
  include RangeHelp
54
72
  extend AutoCorrector
55
73
 
56
74
  MSG = 'Missing space after `#`.'
57
75
 
58
- def on_new_investigation
76
+ def on_new_investigation # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
59
77
  processed_source.comments.each do |comment|
60
78
  next unless /\A(?!#\+\+|#--)(#+[^#\s=])/.match?(comment.text)
61
79
  next if comment.loc.line == 1 && allowed_on_first_line?(comment)
62
80
  next if doxygen_comment_style?(comment)
63
81
  next if gemfile_ruby_comment?(comment)
82
+ next if rbs_inline_annotation?(comment)
64
83
 
65
84
  add_offense(comment) do |corrector|
66
85
  expr = comment.source_range
@@ -115,6 +134,14 @@ module RuboCop
115
134
  def gemfile_ruby_comment?(comment)
116
135
  allow_gemfile_ruby_comment? && ruby_comment_in_gemfile?(comment)
117
136
  end
137
+
138
+ def allow_rbs_inline_annotation?
139
+ cop_config['AllowRBSInlineAnnotation']
140
+ end
141
+
142
+ def rbs_inline_annotation?(comment)
143
+ allow_rbs_inline_annotation? && comment.text.start_with?(/#:|#\[.+\]/)
144
+ end
118
145
  end
119
146
  end
120
147
  end
@@ -57,6 +57,7 @@ module RuboCop
57
57
  # # good
58
58
  # (a.foo)..(b.bar)
59
59
  class AmbiguousRange < Base
60
+ include RationalLiteral
60
61
  extend AutoCorrector
61
62
 
62
63
  MSG = 'Wrap complex range boundaries with parentheses to avoid ambiguity.'
@@ -79,12 +80,14 @@ module RuboCop
79
80
  yield range.end if range.end
80
81
  end
81
82
 
83
+ # rubocop:disable Metrics/CyclomaticComplexity
82
84
  def acceptable?(node)
83
85
  node.begin_type? ||
84
- node.literal? ||
86
+ node.literal? || rational_literal?(node) ||
85
87
  node.variable? || node.const_type? || node.self_type? ||
86
88
  (node.call_type? && acceptable_call?(node))
87
89
  end
90
+ # rubocop:enable Metrics/CyclomaticComplexity
88
91
 
89
92
  def acceptable_call?(node)
90
93
  return true if node.unary_operation?
@@ -17,8 +17,7 @@ module RuboCop
17
17
  class BigDecimalNew < Base
18
18
  extend AutoCorrector
19
19
 
20
- MSG = '`%<double_colon>sBigDecimal.new()` is deprecated. ' \
21
- 'Use `%<double_colon>sBigDecimal()` instead.'
20
+ MSG = '`BigDecimal.new()` is deprecated. Use `BigDecimal()` instead.'
22
21
  RESTRICT_ON_SEND = %i[new].freeze
23
22
 
24
23
  # @!method big_decimal_new(node)
@@ -28,13 +27,11 @@ module RuboCop
28
27
  PATTERN
29
28
 
30
29
  def on_send(node)
31
- big_decimal_new(node) do |captured_value|
32
- double_colon = captured_value ? '::' : ''
33
- message = format(MSG, double_colon: double_colon)
34
-
35
- add_offense(node.loc.selector, message: message) do |corrector|
30
+ big_decimal_new(node) do |cbase|
31
+ add_offense(node.loc.selector) do |corrector|
36
32
  corrector.remove(node.loc.selector)
37
33
  corrector.remove(node.loc.dot)
34
+ corrector.remove(cbase) if cbase
38
35
  end
39
36
  end
40
37
  end
@@ -36,7 +36,7 @@ module RuboCop
36
36
  return unless boolean_symbol?(node)
37
37
 
38
38
  parent = node.parent
39
- return if parent&.array_type? && parent&.percent_literal?(:symbol)
39
+ return if parent&.array_type? && parent.percent_literal?(:symbol)
40
40
 
41
41
  add_offense(node, message: format(MSG, boolean: node.value)) do |corrector|
42
42
  autocorrect(corrector, node)
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Checks for duplicate literal, constant, or variable elements in Set.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # Set[:foo, :bar, :foo]
12
+ #
13
+ # # good
14
+ # Set[:foo, :bar]
15
+ #
16
+ # # bad
17
+ # Set.new([:foo, :bar, :foo])
18
+ #
19
+ # # good
20
+ # Set.new([:foo, :bar])
21
+ #
22
+ # # bad
23
+ # [:foo, :bar, :foo].to_set
24
+ #
25
+ # # good
26
+ # [:foo, :bar].to_set
27
+ #
28
+ class DuplicateSetElement < Base
29
+ extend AutoCorrector
30
+
31
+ MSG = 'Remove the duplicate element in Set.'
32
+ RESTRICT_ON_SEND = %i[\[\] new to_set].freeze
33
+
34
+ # @!method set_init_elements(node)
35
+ def_node_matcher :set_init_elements, <<~PATTERN
36
+ {
37
+ (send (const {nil? cbase} :Set) :[] $...)
38
+ (send (const {nil? cbase} :Set) :new (array $...))
39
+ (call (array $...) :to_set)
40
+ }
41
+ PATTERN
42
+
43
+ def on_send(node)
44
+ return unless (set_elements = set_init_elements(node))
45
+
46
+ seen_elements = Set[]
47
+
48
+ set_elements.each_with_index do |set_element, index|
49
+ # NOTE: Skip due to the possibility of corner cases where Set elements
50
+ # may have changing return values if they are not literals, constants, or variables.
51
+ next if !set_element.literal? && !set_element.const_type? && !set_element.variable?
52
+
53
+ if seen_elements.include?(set_element)
54
+ register_offense(set_element, set_elements[index - 1])
55
+ else
56
+ seen_elements << set_element
57
+ end
58
+ end
59
+ end
60
+ alias on_csend on_send
61
+
62
+ private
63
+
64
+ def register_offense(current_element, prev_element)
65
+ add_offense(current_element) do |corrector|
66
+ range = prev_element.source_range.end.join(current_element.source_range.end)
67
+
68
+ corrector.remove(range)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -40,9 +40,6 @@ module RuboCop
40
40
  # cleanup
41
41
  # end
42
42
  class EnsureReturn < Base
43
- extend AutoCorrector
44
- include RangeHelp
45
-
46
43
  MSG = 'Do not return from an `ensure` block.'
47
44
 
48
45
  def on_ensure(node)