rubocop 1.66.0 → 1.67.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 (102) 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/comment_config.rb +4 -8
  8. data/lib/rubocop/config.rb +4 -16
  9. data/lib/rubocop/config_loader.rb +14 -8
  10. data/lib/rubocop/config_loader_resolver.rb +3 -3
  11. data/lib/rubocop/config_validator.rb +7 -10
  12. data/lib/rubocop/cop/base.rb +6 -2
  13. data/lib/rubocop/cop/bundler/gem_version.rb +1 -0
  14. data/lib/rubocop/cop/cop.rb +8 -0
  15. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  16. data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
  17. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  18. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  19. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +8 -1
  20. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
  21. data/lib/rubocop/cop/internal_affairs.rb +16 -0
  22. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +5 -1
  23. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  24. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
  25. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  26. data/lib/rubocop/cop/layout/indentation_width.rb +4 -5
  27. data/lib/rubocop/cop/layout/leading_comment_space.rb +28 -1
  28. data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
  29. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  30. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  31. data/lib/rubocop/cop/lint/duplicate_set_element.rb +74 -0
  32. data/lib/rubocop/cop/lint/ensure_return.rb +0 -3
  33. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  34. data/lib/rubocop/cop/lint/float_comparison.rb +1 -1
  35. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +10 -4
  36. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +5 -14
  37. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +25 -2
  38. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -6
  39. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -1
  40. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +105 -41
  41. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  42. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  43. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  44. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -2
  45. data/lib/rubocop/cop/naming/inclusive_language.rb +12 -3
  46. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  47. data/lib/rubocop/cop/offense.rb +2 -2
  48. data/lib/rubocop/cop/style/access_modifier_declarations.rb +12 -2
  49. data/lib/rubocop/cop/style/accessor_grouping.rb +10 -2
  50. data/lib/rubocop/cop/style/arguments_forwarding.rb +46 -6
  51. data/lib/rubocop/cop/style/block_delimiters.rb +14 -1
  52. data/lib/rubocop/cop/style/collection_compact.rb +10 -10
  53. data/lib/rubocop/cop/style/combinable_loops.rb +7 -0
  54. data/lib/rubocop/cop/style/commented_keyword.rb +7 -1
  55. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
  56. data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
  57. data/lib/rubocop/cop/style/empty_else.rb +1 -0
  58. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  59. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  60. data/lib/rubocop/cop/style/guard_clause.rb +1 -1
  61. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -0
  62. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  63. data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
  64. data/lib/rubocop/cop/style/if_with_semicolon.rb +16 -5
  65. data/lib/rubocop/cop/style/lambda.rb +1 -1
  66. data/lib/rubocop/cop/style/magic_comment_format.rb +3 -8
  67. data/lib/rubocop/cop/style/map_into_array.rb +54 -10
  68. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +12 -7
  69. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  70. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  71. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  72. data/lib/rubocop/cop/style/one_line_conditional.rb +4 -0
  73. data/lib/rubocop/cop/style/operator_method_call.rb +25 -6
  74. data/lib/rubocop/cop/style/redundant_begin.rb +4 -0
  75. data/lib/rubocop/cop/style/redundant_condition.rb +1 -1
  76. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +1 -1
  77. data/lib/rubocop/cop/style/redundant_line_continuation.rb +3 -3
  78. data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
  79. data/lib/rubocop/cop/style/require_order.rb +1 -1
  80. data/lib/rubocop/cop/style/rescue_modifier.rb +13 -1
  81. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
  82. data/lib/rubocop/cop/style/safe_navigation.rb +92 -50
  83. data/lib/rubocop/cop/style/select_by_regexp.rb +9 -6
  84. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  85. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  86. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  87. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  88. data/lib/rubocop/cop/team.rb +8 -1
  89. data/lib/rubocop/cop/util.rb +1 -1
  90. data/lib/rubocop/cops_documentation_generator.rb +73 -34
  91. data/lib/rubocop/file_finder.rb +9 -4
  92. data/lib/rubocop/lsp/runtime.rb +2 -0
  93. data/lib/rubocop/lsp/server.rb +0 -1
  94. data/lib/rubocop/rspec/expect_offense.rb +1 -0
  95. data/lib/rubocop/runner.rb +3 -0
  96. data/lib/rubocop/server/cache.rb +6 -1
  97. data/lib/rubocop/server/core.rb +1 -0
  98. data/lib/rubocop/target_ruby.rb +12 -12
  99. data/lib/rubocop/version.rb +3 -1
  100. data/lib/rubocop/yaml_duplication_checker.rb +20 -26
  101. data/lib/rubocop.rb +2 -0
  102. metadata +12 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 694e2b2b4a391c38f0afd3667beaf252adcf2fe68374a544cf14748cfc97dd80
4
- data.tar.gz: ad3c46e7dbeaf3c94d16c7427458d2079e28ef58d08463af37ae2a1f6561b345
3
+ metadata.gz: d8127fcc41c5b7ffb95a175f82e8a411dfdec0be2b126c7e0868114519d92d01
4
+ data.tar.gz: 2760fa954ef847d049bdd065dec77518c912f5b9050320fe419b9476393b58ea
5
5
  SHA512:
6
- metadata.gz: 8df7fd7e62c55adac6725b1d60e071c0021eed0434a84c40b86b9a32b27b3a5e9cd3debe9d3edd21fec732c0065553a7a8299f7810ffffde2d010f5231b657e5
7
- data.tar.gz: 24192e071f881b02ac9c766b3d0847e8fa77d9e4ff5942c9a2cc72dd0f4d77412c13337a1b76bcd7e250e5a7b737ddf613764c0dccbb49b09fdc0f27b6a8c732
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
@@ -4,6 +4,8 @@ module RuboCop
4
4
  # This class parses the special `rubocop:disable` comments in a source
5
5
  # and provides a way to check if each cop is enabled at arbitrary line.
6
6
  class CommentConfig
7
+ extend SimpleForwardable
8
+
7
9
  CONFIG_DISABLED_LINE_RANGE_MIN = -Float::INFINITY
8
10
 
9
11
  # This class provides an API compatible with RuboCop::DirectiveComment
@@ -27,19 +29,13 @@ module RuboCop
27
29
 
28
30
  attr_reader :processed_source
29
31
 
32
+ def_delegators :@processed_source, :config, :registry
33
+
30
34
  def initialize(processed_source)
31
35
  @processed_source = processed_source
32
36
  @no_directives = !processed_source.raw_source.include?('rubocop')
33
37
  end
34
38
 
35
- def config
36
- @processed_source.config
37
- end
38
-
39
- def registry
40
- @processed_source.registry
41
- end
42
-
43
39
  def cop_enabled_at_line?(cop, line_number)
44
40
  cop = cop.cop_name if cop.respond_to?(:cop_name)
45
41
  disabled_line_ranges = cop_disabled_line_ranges[cop]
@@ -12,6 +12,7 @@ module RuboCop
12
12
  class Config
13
13
  include PathUtil
14
14
  include FileFinder
15
+ extend SimpleForwardable
15
16
 
16
17
  CopConfig = Struct.new(:name, :metadata)
17
18
 
@@ -59,22 +60,9 @@ module RuboCop
59
60
  self
60
61
  end
61
62
 
62
- %i[[] []= delete dig each key? keys each_key fetch map merge replace to_h to_hash
63
- transform_values].each do |method|
64
- class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
65
- def #{method}(...) # def key?(...)
66
- @hash.#{method}(...) # @hash.key?(...)
67
- end # end
68
- RUBY
69
- end
70
-
71
- def validate(...)
72
- @validator.validate(...)
73
- end
74
-
75
- def target_ruby_version
76
- @validator.target_ruby_version
77
- end
63
+ def_delegators :@hash, :[], :[]=, :delete, :dig, :each, :key?, :keys, :each_key,
64
+ :fetch, :map, :merge, :replace, :to_h, :to_hash, :transform_values
65
+ def_delegators :@validator, :validate, :target_ruby_version
78
66
 
79
67
  def to_s
80
68
  @to_s ||= @hash.to_s
@@ -67,8 +67,8 @@ module RuboCop
67
67
  def load_yaml_configuration(absolute_path)
68
68
  file_contents = read_file(absolute_path)
69
69
  yaml_code = Dir.chdir(File.dirname(absolute_path)) { ERB.new(file_contents).result }
70
- check_duplication(yaml_code, absolute_path)
71
- hash = yaml_safe_load(yaml_code, absolute_path) || {}
70
+ yaml_tree = check_duplication(yaml_code, absolute_path)
71
+ hash = yaml_tree_to_hash(yaml_tree) || {}
72
72
 
73
73
  puts "configuration from #{absolute_path}" if debug?
74
74
 
@@ -235,8 +235,8 @@ module RuboCop
235
235
  raise ConfigNotFoundError, "Configuration file not found: #{absolute_path}"
236
236
  end
237
237
 
238
- def yaml_safe_load(yaml_code, filename)
239
- yaml_safe_load!(yaml_code, filename)
238
+ def yaml_tree_to_hash(yaml_tree)
239
+ yaml_tree_to_hash!(yaml_tree)
240
240
  rescue ::StandardError
241
241
  if defined?(::SafeYAML)
242
242
  raise 'SafeYAML is unmaintained, no longer needed and should be removed'
@@ -245,10 +245,16 @@ module RuboCop
245
245
  raise
246
246
  end
247
247
 
248
- def yaml_safe_load!(yaml_code, filename)
249
- YAML.safe_load(
250
- yaml_code, permitted_classes: [Regexp, Symbol], aliases: true, filename: filename
251
- )
248
+ def yaml_tree_to_hash!(yaml_tree)
249
+ return nil unless yaml_tree
250
+
251
+ # Optimization: Because we checked for duplicate keys, we already have the
252
+ # yaml tree and don't need to parse it again.
253
+ # Also see https://github.com/ruby/psych/blob/v5.1.2/lib/psych.rb#L322-L336
254
+ class_loader = YAML::ClassLoader::Restricted.new(%w[Regexp Symbol], [])
255
+ scanner = YAML::ScalarScanner.new(class_loader)
256
+ visitor = YAML::Visitors::ToRuby.new(scanner, class_loader)
257
+ visitor.accept(yaml_tree)
252
258
  end
253
259
  end
254
260
 
@@ -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)
@@ -3,9 +3,12 @@
3
3
  module RuboCop
4
4
  # Handles validation of configuration, for example cop names, parameter
5
5
  # names, and Ruby versions.
6
- class ConfigValidator # rubocop:disable Metrics/ClassLength
6
+ class ConfigValidator
7
+ extend SimpleForwardable
8
+
7
9
  # @api private
8
- 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
9
12
  # @api private
10
13
  INTERNAL_PARAMS = %w[Description StyleGuide
11
14
  VersionAdded VersionChanged VersionRemoved
@@ -19,20 +22,14 @@ module RuboCop
19
22
  CONFIG_CHECK_AUTOCORRECTS = %w[always contextual disabled].freeze
20
23
  private_constant :CONFIG_CHECK_KEYS, :CONFIG_CHECK_DEPARTMENTS
21
24
 
25
+ def_delegators :@config, :smart_loaded_path, :for_all_cops
26
+
22
27
  def initialize(config)
23
28
  @config = config
24
29
  @config_obsoletion = ConfigObsoletion.new(config)
25
30
  @target_ruby = TargetRuby.new(config)
26
31
  end
27
32
 
28
- def smart_loaded_path
29
- @config.smart_loaded_path
30
- end
31
-
32
- def for_all_cops
33
- @config.for_all_cops
34
- end
35
-
36
33
  def validate
37
34
  check_cop_config_value(@config)
38
35
  reject_conflicting_safe_settings
@@ -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
@@ -45,7 +45,7 @@ module RuboCop
45
45
  PATTERN
46
46
 
47
47
  def on_send(node)
48
- return if node.arguments.none?
48
+ return unless node.arguments.count == 2
49
49
  return unless valid_method_name?(node)
50
50
 
51
51
  actual_name = node.first_argument.value.to_s
@@ -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