rubocop 1.66.1 → 1.68.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +55 -6
  4. data/config/internal_affairs.yml +11 -0
  5. data/lib/rubocop/cached_data.rb +12 -4
  6. data/lib/rubocop/cli/command/auto_generate_config.rb +6 -7
  7. data/lib/rubocop/cli/command/execute_runner.rb +1 -1
  8. data/lib/rubocop/cli/command/lsp.rb +2 -2
  9. data/lib/rubocop/cli/command/version.rb +2 -2
  10. data/lib/rubocop/config_loader_resolver.rb +3 -3
  11. data/lib/rubocop/config_validator.rb +2 -1
  12. data/lib/rubocop/cop/autocorrect_logic.rb +22 -2
  13. data/lib/rubocop/cop/base.rb +6 -2
  14. data/lib/rubocop/cop/bundler/gem_version.rb +1 -0
  15. data/lib/rubocop/cop/cop.rb +8 -0
  16. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  17. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  18. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  19. data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
  20. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  21. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +8 -1
  22. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
  23. data/lib/rubocop/cop/internal_affairs.rb +16 -0
  24. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +5 -1
  25. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  26. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
  27. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  28. data/lib/rubocop/cop/layout/indentation_width.rb +4 -5
  29. data/lib/rubocop/cop/layout/leading_comment_space.rb +56 -1
  30. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  31. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
  32. data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
  33. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  34. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  35. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  36. data/lib/rubocop/cop/lint/duplicate_set_element.rb +74 -0
  37. data/lib/rubocop/cop/lint/ensure_return.rb +0 -3
  38. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  39. data/lib/rubocop/cop/lint/float_comparison.rb +1 -1
  40. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +10 -4
  41. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +5 -14
  42. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +25 -2
  43. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +7 -0
  44. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -6
  45. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -1
  46. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +9 -0
  47. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +107 -41
  48. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  49. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  50. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  51. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +4 -1
  52. data/lib/rubocop/cop/mixin/check_line_breakable.rb +10 -0
  53. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  54. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +3 -1
  55. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  56. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -2
  57. data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
  58. data/lib/rubocop/cop/naming/inclusive_language.rb +12 -3
  59. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  60. data/lib/rubocop/cop/offense.rb +4 -5
  61. data/lib/rubocop/cop/style/access_modifier_declarations.rb +12 -2
  62. data/lib/rubocop/cop/style/accessor_grouping.rb +10 -2
  63. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  64. data/lib/rubocop/cop/style/arguments_forwarding.rb +46 -6
  65. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  66. data/lib/rubocop/cop/style/block_delimiters.rb +31 -3
  67. data/lib/rubocop/cop/style/collection_compact.rb +10 -10
  68. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  69. data/lib/rubocop/cop/style/combinable_loops.rb +7 -0
  70. data/lib/rubocop/cop/style/commented_keyword.rb +7 -1
  71. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
  72. data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
  73. data/lib/rubocop/cop/style/endless_method.rb +1 -14
  74. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  75. data/lib/rubocop/cop/style/guard_clause.rb +15 -2
  76. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -0
  77. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  78. data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
  79. data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -3
  80. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  81. data/lib/rubocop/cop/style/lambda.rb +1 -1
  82. data/lib/rubocop/cop/style/map_into_array.rb +59 -8
  83. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +12 -7
  84. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  85. data/lib/rubocop/cop/style/multiple_comparison.rb +28 -39
  86. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  87. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  88. data/lib/rubocop/cop/style/one_line_conditional.rb +4 -0
  89. data/lib/rubocop/cop/style/operator_method_call.rb +25 -6
  90. data/lib/rubocop/cop/style/redundant_begin.rb +4 -0
  91. data/lib/rubocop/cop/style/redundant_condition.rb +1 -1
  92. data/lib/rubocop/cop/style/redundant_line_continuation.rb +23 -5
  93. data/lib/rubocop/cop/style/redundant_parentheses.rb +9 -11
  94. data/lib/rubocop/cop/style/require_order.rb +1 -1
  95. data/lib/rubocop/cop/style/rescue_modifier.rb +13 -1
  96. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
  97. data/lib/rubocop/cop/style/safe_navigation.rb +104 -50
  98. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  99. data/lib/rubocop/cop/style/select_by_regexp.rb +9 -6
  100. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  101. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  102. data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
  103. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  104. data/lib/rubocop/cop/team.rb +8 -1
  105. data/lib/rubocop/cop/util.rb +1 -1
  106. data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
  107. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  108. data/lib/rubocop/cop/variable_force/variable.rb +5 -1
  109. data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
  110. data/lib/rubocop/cops_documentation_generator.rb +81 -40
  111. data/lib/rubocop/file_finder.rb +9 -4
  112. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
  113. data/lib/rubocop/lsp/runtime.rb +2 -0
  114. data/lib/rubocop/lsp/server.rb +0 -1
  115. data/lib/rubocop/rspec/expect_offense.rb +1 -0
  116. data/lib/rubocop/runner.rb +17 -6
  117. data/lib/rubocop/server/cache.rb +6 -1
  118. data/lib/rubocop/server/core.rb +1 -0
  119. data/lib/rubocop/target_ruby.rb +13 -13
  120. data/lib/rubocop/version.rb +28 -7
  121. data/lib/rubocop/yaml_duplication_checker.rb +20 -27
  122. data/lib/rubocop.rb +10 -0
  123. metadata +13 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a10568527197e80492a28c5b524fa524dbce965513daff4f47e260e03b49d98
4
- data.tar.gz: 8ea447437cbd36aa805b3941cf51b07eecc9dc538ed6a4584f09a1335e21cb48
3
+ metadata.gz: 7f0623068e9eac24fe4b1f5c7e4987d3a8adc7a2ec7f5f65c6cfb9d0ad9d1278
4
+ data.tar.gz: 9abb03dde6881cb7c11a21ee947c33a7d8874b9893f81e81cd7617f52f1bb714
5
5
  SHA512:
6
- metadata.gz: 1f292c70ffac1cb186e5be899582c4849a29866722c87ab92a60a723dd16fe86fdf12073c8a7190bba197d246eae3b25ba3cdc6b586b28061cef39ac22b3b438
7
- data.tar.gz: 2dbfc28779854fae0d28fd266ba269b92cb0e3b5c26200aa250df02ff9810804b7b1fcc289a43bac1913dc04c79f788487f9351444f7242cbcdad6854a821d69
6
+ metadata.gz: 3392244d7137845de4f7c9867695350666750b349879ac4796590d090b0b1a182f21fb9c96f6d284bfd9eaf21a7594f8b7de2d59da62458400a709430bb6f7a2
7
+ data.tar.gz: e2a5a3dd61755c091a91ea99828846fa875b3b7ca8ffaea67425245755e147159691c587a7a80089a428480b7ad07fef8da1be7dc209ac0a60bb46cff3a37d0f
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.68', 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,8 @@ Layout/LeadingCommentSpace:
1036
1037
  VersionChanged: '0.73'
1037
1038
  AllowDoxygenCommentStyle: false
1038
1039
  AllowGemfileRubyComment: false
1040
+ AllowRBSInlineAnnotation: false
1041
+ AllowSteepAnnotation: false
1039
1042
 
1040
1043
  Layout/LeadingEmptyLines:
1041
1044
  Description: Check for unnecessary blank lines at the beginning of a file.
@@ -1783,6 +1786,7 @@ Lint/DuplicateBranch:
1783
1786
  VersionChanged: '1.7'
1784
1787
  IgnoreLiteralBranches: false
1785
1788
  IgnoreConstantBranches: false
1789
+ IgnoreDuplicateElseBranch: false
1786
1790
 
1787
1791
  Lint/DuplicateCaseCondition:
1788
1792
  Description: 'Do not repeat values in case conditionals.'
@@ -1832,6 +1836,11 @@ Lint/DuplicateRescueException:
1832
1836
  Enabled: true
1833
1837
  VersionAdded: '0.89'
1834
1838
 
1839
+ Lint/DuplicateSetElement:
1840
+ Description: 'Checks for duplicate elements in Set.'
1841
+ Enabled: pending
1842
+ VersionAdded: '1.67'
1843
+
1835
1844
  Lint/EachWithObjectArgument:
1836
1845
  Description: 'Check for immutable argument given to each_with_object.'
1837
1846
  Enabled: true
@@ -2327,9 +2336,9 @@ Lint/SafeNavigationChain:
2327
2336
 
2328
2337
  Lint/SafeNavigationConsistency:
2329
2338
  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.
2339
+ Check to make sure that if safe navigation is used in an `&&` or `||` condition,
2340
+ consistent and appropriate safe navigation, without excess or deficiency,
2341
+ is used for all method calls on the same object.
2333
2342
  Enabled: true
2334
2343
  VersionAdded: '0.55'
2335
2344
  VersionChanged: '0.77'
@@ -2448,6 +2457,11 @@ Lint/UnderscorePrefixedVariableName:
2448
2457
  VersionAdded: '0.21'
2449
2458
  AllowKeywordBlockArguments: false
2450
2459
 
2460
+ Lint/UnescapedBracketInRegexp:
2461
+ Description: 'Checks for unescaped literal `]` in Regexp.'
2462
+ Enabled: pending
2463
+ VersionAdded: '1.68'
2464
+
2451
2465
  Lint/UnexpectedBlockArity:
2452
2466
  Description: 'Looks for blocks that have fewer arguments that the calling method expects.'
2453
2467
  Enabled: pending
@@ -3136,6 +3150,12 @@ Style/Alias:
3136
3150
  - prefer_alias
3137
3151
  - prefer_alias_method
3138
3152
 
3153
+ Style/AmbiguousEndlessMethodDefinition:
3154
+ Description: 'Checks for endless methods inside operators of lower precedence.'
3155
+ StyleGuide: '#ambiguous-endless-method-defintions'
3156
+ Enabled: pending
3157
+ VersionAdded: '1.68'
3158
+
3139
3159
  Style/AndOr:
3140
3160
  Description: 'Use &&/|| instead of and/or.'
3141
3161
  StyleGuide: '#no-and-or-or'
@@ -3243,6 +3263,13 @@ Style/BisectedAttrAccessor:
3243
3263
  Enabled: true
3244
3264
  VersionAdded: '0.87'
3245
3265
 
3266
+ Style/BitwisePredicate:
3267
+ Description: 'Prefer bitwise predicate methods over direct comparison operations.'
3268
+ StyleGuide: '#bitwise-predicate-methods'
3269
+ Enabled: pending
3270
+ Safe: false
3271
+ VersionAdded: '1.68'
3272
+
3246
3273
  Style/BlockComments:
3247
3274
  Description: 'Do not use block comments.'
3248
3275
  StyleGuide: '#no-block-comments'
@@ -3526,6 +3553,11 @@ Style/ColonMethodDefinition:
3526
3553
  Enabled: true
3527
3554
  VersionAdded: '0.52'
3528
3555
 
3556
+ Style/CombinableDefined:
3557
+ Description: 'Checks successive `defined?` calls that can be combined into a single call.'
3558
+ Enabled: pending
3559
+ VersionAdded: '1.68'
3560
+
3529
3561
  Style/CombinableLoops:
3530
3562
  Description: >-
3531
3563
  Checks for places where multiple consecutive loops over the same data
@@ -4069,7 +4101,7 @@ Style/HashSyntax:
4069
4101
  StyleGuide: '#hash-literals'
4070
4102
  Enabled: true
4071
4103
  VersionAdded: '0.9'
4072
- VersionChanged: '1.24'
4104
+ VersionChanged: '1.67'
4073
4105
  EnforcedStyle: ruby19
4074
4106
  SupportedStyles:
4075
4107
  # checks for 1.9 syntax (e.g. {a: 1}) for all symbol keys
@@ -4081,7 +4113,7 @@ Style/HashSyntax:
4081
4113
  # enforces both ruby19 and no_mixed_keys styles
4082
4114
  - ruby19_no_mixed_keys
4083
4115
  # Force hashes that have a hash value omission
4084
- EnforcedShorthandSyntax: always
4116
+ EnforcedShorthandSyntax: either
4085
4117
  SupportedShorthandSyntax:
4086
4118
  # forces use of the 3.1 syntax (e.g. {foo:}) when the hash key and value are the same.
4087
4119
  - always
@@ -4249,6 +4281,14 @@ Style/IpAddresses:
4249
4281
  - '**/gems.rb'
4250
4282
  - '**/*.gemspec'
4251
4283
 
4284
+ Style/KeywordArgumentsMerging:
4285
+ Description: >-
4286
+ When passing an existing hash as keyword arguments, provide additional arguments
4287
+ directly rather than using `merge`.
4288
+ StyleGuide: '#merging-keyword-arguments'
4289
+ Enabled: pending
4290
+ VersionAdded: '1.68'
4291
+
4252
4292
  Style/KeywordParametersOrder:
4253
4293
  Description: 'Enforces that optional keyword parameters are placed at the end of the parameters list.'
4254
4294
  StyleGuide: '#keyword-parameters-order'
@@ -4318,6 +4358,7 @@ Style/MapIntoArray:
4318
4358
  StyleGuide: '#functional-code'
4319
4359
  Enabled: pending
4320
4360
  VersionAdded: '1.63'
4361
+ VersionChanged: '1.67'
4321
4362
  Safe: false
4322
4363
 
4323
4364
  Style/MapToHash:
@@ -5208,6 +5249,7 @@ Style/ReturnNilInPredicateMethodDefinition:
5208
5249
  AllowedMethods: []
5209
5250
  AllowedPatterns: []
5210
5251
  VersionAdded: '1.53'
5252
+ VersionChanged: '1.67'
5211
5253
 
5212
5254
  Style/SafeNavigation:
5213
5255
  Description: >-
@@ -5218,7 +5260,7 @@ Style/SafeNavigation:
5218
5260
  be `nil` or truthy, but never `false`.
5219
5261
  Enabled: true
5220
5262
  VersionAdded: '0.43'
5221
- VersionChanged: '1.27'
5263
+ VersionChanged: '1.67'
5222
5264
  # Safe navigation may cause a statement to start returning `nil` in addition
5223
5265
  # to whatever it used to return.
5224
5266
  ConvertCodeThatCanStartToReturnNil: false
@@ -5232,6 +5274,13 @@ Style/SafeNavigation:
5232
5274
  # Maximum length of method chains for register an offense.
5233
5275
  MaxChainLength: 2
5234
5276
 
5277
+ Style/SafeNavigationChainLength:
5278
+ Description: 'Enforces safe navigation chains length to not exceed the configured maximum.'
5279
+ StyleGuide: '#safe-navigation'
5280
+ Enabled: pending
5281
+ VersionAdded: '1.68'
5282
+ Max: 2
5283
+
5235
5284
  Style/Sample:
5236
5285
  Description: >-
5237
5286
  Use `sample` instead of `shuffle.first`,
@@ -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'
@@ -45,15 +45,13 @@ module RuboCop
45
45
 
46
46
  # Restore an offense object loaded from a JSON file.
47
47
  def deserialize_offenses(offenses)
48
- source_buffer = Parser::Source::Buffer.new(@filename)
49
- source_buffer.source = File.read(@filename, encoding: Encoding::UTF_8)
50
48
  offenses.map! do |o|
51
- location = location_from_source_buffer(o, source_buffer)
49
+ location = location_from_source_buffer(o)
52
50
  Cop::Offense.new(o['severity'], location, o['message'], o['cop_name'], o['status'].to_sym)
53
51
  end
54
52
  end
55
53
 
56
- def location_from_source_buffer(offense, source_buffer)
54
+ def location_from_source_buffer(offense)
57
55
  begin_pos = offense['location']['begin_pos']
58
56
  end_pos = offense['location']['end_pos']
59
57
  if begin_pos.zero? && end_pos.zero?
@@ -62,5 +60,15 @@ module RuboCop
62
60
  Parser::Source::Range.new(source_buffer, begin_pos, end_pos)
63
61
  end
64
62
  end
63
+
64
+ # Delay creation until needed. Some type of offenses will have no buffer associated with them
65
+ # and be global only. For these, trying to create the buffer will likely fail, for example
66
+ # because of unknown encoding comments.
67
+ def source_buffer
68
+ @source_buffer ||= begin
69
+ source = File.read(@filename, encoding: Encoding::UTF_8)
70
+ Parser::Source::Buffer.new(@filename, source: source)
71
+ end
72
+ end
65
73
  end
66
74
  end
@@ -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
@@ -78,7 +78,7 @@ module RuboCop
78
78
  Please, report your problems to RuboCop's issue tracker.
79
79
  #{bug_tracker_uri}
80
80
  Mention the following information in the issue report:
81
- #{RuboCop::Version.version(debug: true)}
81
+ #{RuboCop::Version.verbose}
82
82
  WARNING
83
83
  end
84
84
 
@@ -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
@@ -9,8 +9,8 @@ module RuboCop
9
9
  self.command_name = :version
10
10
 
11
11
  def run
12
- puts RuboCop::Version.version(debug: false) if @options[:version]
13
- puts RuboCop::Version.version(debug: true, env: env) if @options[:verbose_version]
12
+ puts RuboCop::Version::STRING if @options[:version]
13
+ puts RuboCop::Version.verbose(env: env) if @options[:verbose_version]
14
14
  end
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
@@ -49,7 +49,9 @@ module RuboCop
49
49
  private
50
50
 
51
51
  def disable_offense(offense_range)
52
- range = surrounding_heredoc(offense_range) || surrounding_percent_array(offense_range)
52
+ range = surrounding_heredoc(offense_range) ||
53
+ surrounding_percent_array(offense_range) ||
54
+ string_continuation(offense_range)
53
55
 
54
56
  if range
55
57
  disable_offense_before_and_after(range_by_lines(range))
@@ -88,10 +90,28 @@ module RuboCop
88
90
  end
89
91
 
90
92
  percent_array.map(&:source_range).find do |range|
91
- offense_range.begin_pos > range.begin_pos && range.overlaps?(offense_range)
93
+ range_overlaps_offense?(offense_range, range)
92
94
  end
93
95
  end
94
96
 
97
+ def string_continuation(offense_range)
98
+ return nil if offense_range.empty?
99
+
100
+ string_continuation_nodes = processed_source.ast.each_descendant.filter_map do |node|
101
+ range_by_lines(node.source_range) if string_continuation?(node)
102
+ end
103
+
104
+ string_continuation_nodes.find { |range| range_overlaps_offense?(offense_range, range) }
105
+ end
106
+
107
+ def range_overlaps_offense?(offense_range, range)
108
+ offense_range.begin_pos > range.begin_pos && range.overlaps?(offense_range)
109
+ end
110
+
111
+ def string_continuation?(node)
112
+ (node.str_type? || node.dstr_type? || node.xstr_type?) && node.source.match?(/\\\s*$/)
113
+ end
114
+
95
115
  def range_of_first_line(range)
96
116
  begin_of_first_line = range.begin_pos - range.column
97
117
  end_of_first_line = begin_of_first_line + range.source_line.length
@@ -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
@@ -47,7 +47,7 @@ module RuboCop
47
47
  if column_delta.positive? && range.resize(1).source != "\n"
48
48
  corrector.insert_before(range, ' ' * column_delta)
49
49
  elsif /\A[ \t]+\z/.match?(range.source)
50
- remove(range, corrector)
50
+ corrector.remove(range)
51
51
  end
52
52
  end
53
53
 
@@ -96,17 +96,6 @@ module RuboCop
96
96
  end
97
97
  end
98
98
 
99
- def remove(range, corrector)
100
- original_stderr = $stderr
101
- $stderr = StringIO.new # Avoid error messages on console
102
- corrector.remove(range)
103
- rescue RuntimeError
104
- range = range_between(range.begin_pos + 1, range.end_pos + 1)
105
- retry if /^ +$/.match?(range.source)
106
- ensure
107
- $stderr = original_stderr
108
- end
109
-
110
99
  def each_line(expr)
111
100
  line_begin_pos = expr.begin_pos
112
101
  expr.source.each_line do |line|
@@ -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)
@@ -94,6 +94,16 @@ module RuboCop
94
94
  end
95
95
 
96
96
  def substitute_escaped_delimiters(content, delimiters)
97
+ if delimiters.first != delimiters.last
98
+ # With different delimiters (eg. `[]`, `()`), if there are the same
99
+ # number of each, escaping is not necessary
100
+ delimiter_counts = delimiters.each_with_object({}) do |delimiter, counts|
101
+ counts[delimiter] = content.count(delimiter)
102
+ end
103
+
104
+ return content if delimiter_counts[delimiters.first] == delimiter_counts[delimiters.last]
105
+ end
106
+
97
107
  delimiters.each { |delim| content.gsub!(delim, "\\#{delim}") }
98
108
  end
99
109
 
@@ -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: