rubocop 1.50.2 → 1.53.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 (141) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/config/default.yml +76 -6
  4. data/lib/rubocop/cli/command/lsp.rb +19 -0
  5. data/lib/rubocop/cli.rb +3 -0
  6. data/lib/rubocop/config.rb +4 -0
  7. data/lib/rubocop/config_loader_resolver.rb +4 -3
  8. data/lib/rubocop/config_obsoletion.rb +2 -2
  9. data/lib/rubocop/cop/base.rb +5 -1
  10. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  11. data/lib/rubocop/cop/bundler/gem_version.rb +2 -2
  12. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -1
  13. data/lib/rubocop/cop/gemspec/dependency_version.rb +2 -2
  14. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  15. data/lib/rubocop/cop/internal_affairs/cop_description.rb +32 -8
  16. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
  17. data/lib/rubocop/cop/layout/class_structure.rb +7 -0
  18. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
  19. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
  20. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
  21. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
  22. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  23. data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
  24. data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
  25. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +2 -0
  26. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  27. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -1
  28. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  29. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
  30. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +46 -19
  31. data/lib/rubocop/cop/lint/erb_new_arguments.rb +3 -4
  32. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +1 -1
  33. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  34. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
  35. data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
  36. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  37. data/lib/rubocop/cop/lint/missing_super.rb +34 -5
  38. data/lib/rubocop/cop/lint/mixed_case_range.rb +109 -0
  39. data/lib/rubocop/cop/lint/number_conversion.rb +5 -0
  40. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
  41. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
  42. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -2
  43. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +120 -0
  44. data/lib/rubocop/cop/lint/redundant_require_statement.rb +8 -3
  45. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +1 -1
  46. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
  47. data/lib/rubocop/cop/lint/shadowed_exception.rb +5 -11
  48. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  49. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
  50. data/lib/rubocop/cop/lint/useless_assignment.rb +59 -1
  51. data/lib/rubocop/cop/lint/void.rb +63 -7
  52. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
  53. data/lib/rubocop/cop/migration/department_name.rb +2 -2
  54. data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
  55. data/lib/rubocop/cop/mixin/comments_help.rb +7 -3
  56. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  57. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  58. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  59. data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
  60. data/lib/rubocop/cop/naming/constant_name.rb +1 -1
  61. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +25 -10
  62. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +11 -3
  63. data/lib/rubocop/cop/naming/variable_name.rb +6 -1
  64. data/lib/rubocop/cop/style/accessor_grouping.rb +5 -1
  65. data/lib/rubocop/cop/style/attr.rb +11 -1
  66. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  67. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  68. data/lib/rubocop/cop/style/block_delimiters.rb +3 -3
  69. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  70. data/lib/rubocop/cop/style/class_equality_comparison.rb +17 -39
  71. data/lib/rubocop/cop/style/collection_compact.rb +16 -6
  72. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  73. data/lib/rubocop/cop/style/combinable_loops.rb +26 -6
  74. data/lib/rubocop/cop/style/conditional_assignment.rb +5 -3
  75. data/lib/rubocop/cop/style/copyright.rb +5 -2
  76. data/lib/rubocop/cop/style/dir.rb +1 -1
  77. data/lib/rubocop/cop/style/dir_empty.rb +8 -14
  78. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
  79. data/lib/rubocop/cop/style/documentation.rb +1 -1
  80. data/lib/rubocop/cop/style/eval_with_location.rb +5 -5
  81. data/lib/rubocop/cop/style/exact_regexp_match.rb +68 -0
  82. data/lib/rubocop/cop/style/file_read.rb +2 -2
  83. data/lib/rubocop/cop/style/guard_clause.rb +2 -0
  84. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -22
  85. data/lib/rubocop/cop/style/hash_except.rb +19 -8
  86. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  87. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  88. data/lib/rubocop/cop/style/identical_conditional_branches.rb +6 -2
  89. data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
  90. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -0
  91. data/lib/rubocop/cop/style/invertible_unless_condition.rb +10 -6
  92. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +3 -4
  93. data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
  94. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  95. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  96. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
  97. data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
  98. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  99. data/lib/rubocop/cop/style/redundant_conditional.rb +1 -1
  100. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +38 -0
  101. data/lib/rubocop/cop/style/redundant_filter_chain.rb +101 -0
  102. data/lib/rubocop/cop/style/redundant_line_continuation.rb +7 -3
  103. data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
  104. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +86 -0
  105. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
  106. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +2 -1
  107. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +3 -1
  108. data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
  109. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -0
  110. data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
  111. data/lib/rubocop/cop/style/require_order.rb +11 -5
  112. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
  113. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +81 -0
  114. data/lib/rubocop/cop/style/select_by_regexp.rb +15 -5
  115. data/lib/rubocop/cop/style/semicolon.rb +12 -1
  116. data/lib/rubocop/cop/style/signal_exception.rb +1 -1
  117. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  118. data/lib/rubocop/cop/style/sole_nested_conditional.rb +3 -1
  119. data/lib/rubocop/cop/style/special_global_vars.rb +3 -4
  120. data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
  121. data/lib/rubocop/cop/team.rb +1 -1
  122. data/lib/rubocop/cop/util.rb +1 -1
  123. data/lib/rubocop/cop/utils/regexp_ranges.rb +100 -0
  124. data/lib/rubocop/cop/variable_force/assignment.rb +33 -1
  125. data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
  126. data/lib/rubocop/cop/variable_force.rb +1 -0
  127. data/lib/rubocop/cops_documentation_generator.rb +1 -1
  128. data/lib/rubocop/ext/regexp_parser.rb +4 -1
  129. data/lib/rubocop/lsp/logger.rb +22 -0
  130. data/lib/rubocop/lsp/routes.rb +223 -0
  131. data/lib/rubocop/lsp/runtime.rb +79 -0
  132. data/lib/rubocop/lsp/server.rb +62 -0
  133. data/lib/rubocop/lsp/severity.rb +27 -0
  134. data/lib/rubocop/options.rb +11 -1
  135. data/lib/rubocop/result_cache.rb +1 -1
  136. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  137. data/lib/rubocop/server/client_command/exec.rb +2 -1
  138. data/lib/rubocop/target_ruby.rb +3 -2
  139. data/lib/rubocop/version.rb +10 -6
  140. data/lib/rubocop.rb +13 -0
  141. metadata +38 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 67accbc10c4c2ae80033ab2a3713fce8a190d772234cbd52c5584e5c69895915
4
- data.tar.gz: 69e7f99ee66c192619b2dc26df6d0ac73c794bb088bade8182f3eceb1cb8d8c0
3
+ metadata.gz: 63ade8f6d7d93161d739cd557220bea89fc0320a2f8923f41cc092015dbcadef
4
+ data.tar.gz: bb608b076e84d18f317b1690a6f5ad0b0ecea1232977107ebca57b04d32b6abb
5
5
  SHA512:
6
- metadata.gz: 21005d0d16a207a998640686ee7dcf251683899ab8e746baa861888fd26f2e58791733b48869a085b1b365ce2b67e64b216b4cfe6c1a2e26a2ecc699da0ea085
7
- data.tar.gz: 461a588bb95269c194efee4ee8570c166ce009695664aa31181f1f0806220f451e4685d4feff8751d4135f196d3cb42ec100c171b905526e06ed968cd9bb47f9
6
+ metadata.gz: '0178518d0c9ab5eb1425395c4047f603f92e9d17ae9ef23d7e52ef9c9cfc51e8dda9abd0b08d39b84014c6f59f238673b5fe73de3c2eb649cd166c39cfc58081'
7
+ data.tar.gz: 752ee645c95115d20848ff2f00731597bd6106738bb6bded350a3348b392a471890d6f607e475245f81aae7746c23389ffd302e7884b2cba8476ca66d4d07ec7
data/README.md CHANGED
@@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
53
53
  in your `Gemfile`:
54
54
 
55
55
  ```rb
56
- gem 'rubocop', '~> 1.50', require: false
56
+ gem 'rubocop', '~> 1.53', require: false
57
57
  ```
58
58
 
59
59
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
@@ -75,8 +75,8 @@ You can read a lot more about RuboCop in its [official docs](https://docs.ruboco
75
75
 
76
76
  RuboCop officially supports the following runtime Ruby implementations:
77
77
 
78
- * MRI 2.6+
79
- * JRuby 9.3+
78
+ * MRI 2.7+
79
+ * JRuby 9.4+
80
80
 
81
81
  Targets Ruby 2.0+ code analysis.
82
82
 
data/config/default.yml CHANGED
@@ -140,7 +140,7 @@ AllCops:
140
140
  # or gems.locked file. (Although the Ruby version is specified in the Gemfile
141
141
  # or gems.rb file, RuboCop reads the final value from the lock file.) If the
142
142
  # Ruby version is still unresolved, RuboCop will use the oldest officially
143
- # supported Ruby version (currently Ruby 2.6).
143
+ # supported Ruby version (currently Ruby 2.7).
144
144
  TargetRubyVersion: ~
145
145
  # Determines if a notification for extension libraries should be shown when
146
146
  # rubocop is run. Keys are the name of the extension, and values are an array
@@ -154,6 +154,7 @@ AllCops:
154
154
  rubocop-rake: [rake]
155
155
  rubocop-graphql: [graphql]
156
156
  rubocop-capybara: [capybara]
157
+ rubocop-factory_bot: [factory_bot, factory_bot_rails]
157
158
  # Enable/Disable checking the methods extended by Active Support.
158
159
  ActiveSupportExtensionsEnabled: false
159
160
 
@@ -466,7 +467,9 @@ Layout/ClassStructure:
466
467
  Description: 'Enforces a configured order of definitions within a class body.'
467
468
  StyleGuide: '#consistent-classes'
468
469
  Enabled: false
470
+ SafeAutoCorrect: false
469
471
  VersionAdded: '0.52'
472
+ VersionChanged: '1.53'
470
473
  Categories:
471
474
  module_inclusion:
472
475
  - include
@@ -1529,7 +1532,6 @@ Lint/AmbiguousBlockAssociation:
1529
1532
  Description: >-
1530
1533
  Checks for ambiguous block association with method when param passed without
1531
1534
  parentheses.
1532
- StyleGuide: '#syntax'
1533
1535
  Enabled: true
1534
1536
  VersionAdded: '0.48'
1535
1537
  VersionChanged: '1.13'
@@ -1987,9 +1989,16 @@ Lint/MissingSuper:
1987
1989
  Checks for the presence of constructors and lifecycle callbacks
1988
1990
  without calls to `super`.
1989
1991
  Enabled: true
1992
+ AllowedParentClasses: []
1990
1993
  VersionAdded: '0.89'
1991
1994
  VersionChanged: '1.4'
1992
1995
 
1996
+ Lint/MixedCaseRange:
1997
+ Description: 'Checks for mixed-case character ranges since they include likely unintended characters.'
1998
+ Enabled: pending
1999
+ SafeAutoCorrect: false
2000
+ VersionAdded: '1.53'
2001
+
1993
2002
  Lint/MixedRegexpCaptureTypes:
1994
2003
  Description: 'Do not mix named captures and numbered captures in a Regexp literal.'
1995
2004
  Enabled: true
@@ -2139,6 +2148,11 @@ Lint/RedundantDirGlobSort:
2139
2148
  VersionChanged: '1.26'
2140
2149
  SafeAutoCorrect: false
2141
2150
 
2151
+ Lint/RedundantRegexpQuantifiers:
2152
+ Description: 'Checks for redundant quantifiers in Regexps.'
2153
+ Enabled: pending
2154
+ VersionAdded: '1.53'
2155
+
2142
2156
  Lint/RedundantRequireStatement:
2143
2157
  Description: 'Checks for unnecessary `require` statement.'
2144
2158
  Enabled: true
@@ -2343,6 +2357,9 @@ Lint/TopLevelReturnWithArgument:
2343
2357
  Description: 'Detects top level return statements with argument.'
2344
2358
  Enabled: true
2345
2359
  VersionAdded: '0.89'
2360
+ # These codes are `eval`-ed in method and their return values may be used.
2361
+ Exclude:
2362
+ - '**/*.jb'
2346
2363
 
2347
2364
  Lint/TrailingCommaInAttributeDeclaration:
2348
2365
  Description: 'Checks for trailing commas in attribute declarations.'
@@ -2451,6 +2468,8 @@ Lint/UselessAssignment:
2451
2468
  StyleGuide: '#underscore-unused-vars'
2452
2469
  Enabled: true
2453
2470
  VersionAdded: '0.11'
2471
+ VersionChanged: '1.51'
2472
+ SafeAutoCorrect: false
2454
2473
 
2455
2474
  Lint/UselessElseWithoutRescue:
2456
2475
  Description: 'Checks for useless `else` in `begin..end` without `rescue`.'
@@ -2478,10 +2497,9 @@ Lint/UselessRuby2Keywords:
2478
2497
  Lint/UselessSetterCall:
2479
2498
  Description: 'Checks for useless setter call to a local variable.'
2480
2499
  Enabled: true
2481
- SafeAutoCorrect: false
2500
+ Safe: false
2482
2501
  VersionAdded: '0.13'
2483
2502
  VersionChanged: '1.2'
2484
- Safe: false
2485
2503
 
2486
2504
  Lint/UselessTimes:
2487
2505
  Description: 'Checks for useless `Integer#times` calls.'
@@ -2942,7 +2960,9 @@ Naming/VariableNumber:
2942
2960
  Security/CompoundHash:
2943
2961
  Description: 'When overwriting Object#hash to combine values, prefer delegating to Array#hash over writing a custom implementation.'
2944
2962
  Enabled: pending
2963
+ Safe: false
2945
2964
  VersionAdded: '1.28'
2965
+ VersionChanged: '1.51'
2946
2966
 
2947
2967
  Security/Eval:
2948
2968
  Description: 'The use of eval represents a serious security risk.'
@@ -3355,6 +3375,7 @@ Style/CollectionCompact:
3355
3375
  Safe: false
3356
3376
  VersionAdded: '1.2'
3357
3377
  VersionChanged: '1.3'
3378
+ AllowedReceivers: []
3358
3379
 
3359
3380
  # Align with the style guide.
3360
3381
  Style/CollectionMethods:
@@ -3515,7 +3536,9 @@ Style/DataInheritance:
3515
3536
  Description: 'Checks for inheritance from Data.define.'
3516
3537
  StyleGuide: '#no-extend-data-define'
3517
3538
  Enabled: pending
3539
+ SafeAutoCorrect: false
3518
3540
  VersionAdded: '1.49'
3541
+ VersionChanged: '1.51'
3519
3542
 
3520
3543
  Style/DateTime:
3521
3544
  Description: 'Use Time over DateTime.'
@@ -3706,6 +3729,11 @@ Style/EvenOdd:
3706
3729
  VersionAdded: '0.12'
3707
3730
  VersionChanged: '0.29'
3708
3731
 
3732
+ Style/ExactRegexpMatch:
3733
+ Description: 'Checks for exact regexp match inside Regexp literals.'
3734
+ Enabled: pending
3735
+ VersionAdded: '1.51'
3736
+
3709
3737
  Style/ExpandPathArguments:
3710
3738
  Description: "Use `expand_path(__dir__)` instead of `expand_path('..', __FILE__)`."
3711
3739
  Enabled: true
@@ -4092,8 +4120,6 @@ Style/InvertibleUnlessCondition:
4092
4120
  # :blank?: :present?
4093
4121
  # :include?: :exclude?
4094
4122
  # :exclude?: :include?
4095
- # :one?: :many?
4096
- # :many?: :one?
4097
4123
 
4098
4124
  Style/IpAddresses:
4099
4125
  Description: "Don't include literal IP addresses in code."
@@ -4370,6 +4396,7 @@ Style/MultipleComparison:
4370
4396
  VersionAdded: '0.49'
4371
4397
  VersionChanged: '1.1'
4372
4398
  AllowMethodComparison: true
4399
+ ComparisonsThreshold: 2
4373
4400
 
4374
4401
  Style/MutableConstant:
4375
4402
  Description: 'Do not assign mutable objects to constants.'
@@ -4624,7 +4651,9 @@ Style/OpenStructUse:
4624
4651
  - https://docs.ruby-lang.org/en/3.0.0/OpenStruct.html#class-OpenStruct-label-Caveats
4625
4652
 
4626
4653
  Enabled: pending
4654
+ Safe: false
4627
4655
  VersionAdded: '1.23'
4656
+ VersionChanged: '1.51'
4628
4657
 
4629
4658
  Style/OperatorMethodCall:
4630
4659
  Description: 'Checks for redundant dot before operator method call.'
@@ -4790,6 +4819,11 @@ Style/RedundantArgument:
4790
4819
  # String#chomp!
4791
4820
  chomp!: "\n"
4792
4821
 
4822
+ Style/RedundantArrayConstructor:
4823
+ Description: 'Checks for the instantiation of array using redundant `Array` constructor.'
4824
+ Enabled: pending
4825
+ VersionAdded: '1.52'
4826
+
4793
4827
  Style/RedundantAssignment:
4794
4828
  Description: 'Checks for redundant assignment before returning.'
4795
4829
  Enabled: true
@@ -4822,6 +4856,11 @@ Style/RedundantConstantBase:
4822
4856
  Enabled: pending
4823
4857
  VersionAdded: '1.40'
4824
4858
 
4859
+ Style/RedundantCurrentDirectoryInPath:
4860
+ Description: 'Checks for uses a redundant current directory in path.'
4861
+ Enabled: pending
4862
+ VersionAdded: '1.53'
4863
+
4825
4864
  Style/RedundantDoubleSplatHashBraces:
4826
4865
  Description: 'Checks for redundant uses of double splat hash braces.'
4827
4866
  Enabled: pending
@@ -4861,6 +4900,13 @@ Style/RedundantFileExtensionInRequire:
4861
4900
  Enabled: true
4862
4901
  VersionAdded: '0.88'
4863
4902
 
4903
+ Style/RedundantFilterChain:
4904
+ Description: >-
4905
+ Identifies usages of `any?`, `empty?`, `none?` or `one?` predicate methods chained to
4906
+ `select`/`filter`/`find_all` and change them to use predicate method instead.
4907
+ Enabled: pending
4908
+ VersionAdded: '1.52'
4909
+
4864
4910
  Style/RedundantFreeze:
4865
4911
  Description: "Checks usages of Object#freeze on immutable objects."
4866
4912
  Enabled: true
@@ -4903,11 +4949,21 @@ Style/RedundantPercentQ:
4903
4949
  Enabled: true
4904
4950
  VersionAdded: '0.76'
4905
4951
 
4952
+ Style/RedundantRegexpArgument:
4953
+ Description: 'Identifies places where argument can be replaced from a deterministic regexp to a string.'
4954
+ Enabled: pending
4955
+ VersionAdded: '1.53'
4956
+
4906
4957
  Style/RedundantRegexpCharacterClass:
4907
4958
  Description: 'Checks for unnecessary single-element Regexp character classes.'
4908
4959
  Enabled: true
4909
4960
  VersionAdded: '0.85'
4910
4961
 
4962
+ Style/RedundantRegexpConstructor:
4963
+ Description: 'Checks for the instantiation of regexp using redundant `Regexp.new` or `Regexp.compile`.'
4964
+ Enabled: pending
4965
+ VersionAdded: '1.52'
4966
+
4911
4967
  Style/RedundantRegexpEscape:
4912
4968
  Description: 'Checks for redundant escapes in Regexps.'
4913
4969
  Enabled: true
@@ -5010,6 +5066,15 @@ Style/ReturnNil:
5010
5066
  - return_nil
5011
5067
  VersionAdded: '0.50'
5012
5068
 
5069
+ Style/ReturnNilInPredicateMethodDefinition:
5070
+ Description: 'Checks if uses of `return` or `return nil` in predicate method definition.'
5071
+ StyleGuide: '#bool-methods-qmark'
5072
+ Enabled: pending
5073
+ SafeAutoCorrect: false
5074
+ AllowedMethods: []
5075
+ AllowedPatterns: []
5076
+ VersionAdded: '1.53'
5077
+
5013
5078
  Style/SafeNavigation:
5014
5079
  Description: >-
5015
5080
  Transforms usages of a method call safeguarded by
@@ -5494,6 +5559,11 @@ Style/WordArray:
5494
5559
  # The regular expression `WordRegex` decides what is considered a word.
5495
5560
  WordRegex: !ruby/regexp '/\A(?:\p{Word}|\p{Word}-\p{Word}|\n|\t)+\z/'
5496
5561
 
5562
+ Style/YAMLFileRead:
5563
+ Description: 'Checks for the use of `YAML.load`, `YAML.safe_load`, and `YAML.parse` with `File.read` argument.'
5564
+ Enabled: pending
5565
+ VersionAdded: '1.53'
5566
+
5497
5567
  Style/YodaCondition:
5498
5568
  Description: 'Forbid or enforce yoda conditions.'
5499
5569
  Reference: 'https://en.wikipedia.org/wiki/Yoda_conditions'
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../lsp/server'
4
+
5
+ module RuboCop
6
+ class CLI
7
+ module Command
8
+ # Start Language Server Protocol of RuboCop.
9
+ # @api private
10
+ class Lsp < Base
11
+ self.command_name = :lsp
12
+
13
+ def run
14
+ RuboCop::Lsp::Server.new(@config_store).start
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/rubocop/cli.rb CHANGED
@@ -174,14 +174,17 @@ module RuboCop
174
174
  ConfigLoader.ignore_unrecognized_cops = @options[:ignore_unrecognized_cops]
175
175
  end
176
176
 
177
+ # rubocop:disable Metrics/CyclomaticComplexity
177
178
  def handle_exiting_options
178
179
  return unless Options::EXITING_OPTIONS.any? { |o| @options.key? o }
179
180
 
180
181
  run_command(:version) if @options[:version] || @options[:verbose_version]
181
182
  run_command(:show_cops) if @options[:show_cops]
182
183
  run_command(:show_docs_url) if @options[:show_docs_url]
184
+ run_command(:lsp) if @options[:lsp]
183
185
  raise Finished
184
186
  end
187
+ # rubocop:enable Metrics/CyclomaticComplexity
185
188
 
186
189
  def apply_default_formatter
187
190
  # This must be done after the options have already been processed,
@@ -284,6 +284,10 @@ module RuboCop
284
284
  end
285
285
  end
286
286
 
287
+ def inspect # :nodoc:
288
+ "#<#{self.class.name}:#{object_id} @loaded_path=#{loaded_path}>"
289
+ end
290
+
287
291
  private
288
292
 
289
293
  def target_rails_version_from_bundler_lock_file
@@ -33,7 +33,7 @@ module RuboCop
33
33
  inherit_mode: determine_inherit_mode(hash, k))
34
34
  end
35
35
  hash[k] = v
36
- fix_include_paths(base_config.loaded_path, hash, k, v) if v.key?('Include')
36
+ fix_include_paths(base_config.loaded_path, hash, path, k, v) if v.key?('Include')
37
37
  end
38
38
  end
39
39
  end
@@ -42,12 +42,13 @@ module RuboCop
42
42
  # base configuration are relative to the directory where the base configuration file is. For the
43
43
  # derived configuration, we need to make those paths relative to where the derived configuration
44
44
  # file is.
45
- def fix_include_paths(base_config_path, hash, key, value)
45
+ def fix_include_paths(base_config_path, hash, path, key, value)
46
46
  return unless File.basename(base_config_path).start_with?('.rubocop')
47
47
 
48
48
  base_dir = File.dirname(base_config_path)
49
+ derived_dir = File.dirname(path)
49
50
  hash[key]['Include'] = value['Include'].map do |include_path|
50
- PathUtil.relative_path(File.join(base_dir, include_path), Dir.pwd)
51
+ PathUtil.relative_path(File.join(base_dir, include_path), derived_dir)
51
52
  end
52
53
  end
53
54
 
@@ -68,11 +68,11 @@ module RuboCop
68
68
  # Cop rules are keyed by the name of the original cop
69
69
  def load_cop_rules(rules)
70
70
  rules.flat_map do |rule_type, data|
71
- data.map do |cop_name, configuration|
71
+ data.filter_map do |cop_name, configuration|
72
72
  next unless configuration # allow configurations to be disabled with `CopName: ~`
73
73
 
74
74
  COP_RULE_CLASSES[rule_type].new(@config, cop_name, configuration)
75
- end.compact
75
+ end
76
76
  end
77
77
  end
78
78
 
@@ -284,7 +284,7 @@ module RuboCop
284
284
  # @api private
285
285
  def self.callbacks_needed
286
286
  @callbacks_needed ||= public_instance_methods.select do |m|
287
- m.match?(/^on_|^after_/) &&
287
+ m.start_with?(/on_|after_/) &&
288
288
  !Base.method_defined?(m) # exclude standard "callbacks" like 'on_begin_investigation'
289
289
  end
290
290
  end
@@ -305,6 +305,10 @@ module RuboCop
305
305
  @current_original = original
306
306
  end
307
307
 
308
+ def inspect # :nodoc:
309
+ "#<#{self.class.name}:#{object_id} @config=#{@config} @options=#{@options}>"
310
+ end
311
+
308
312
  private
309
313
 
310
314
  ### Reserved for Cop::Cop
@@ -150,7 +150,7 @@ module RuboCop
150
150
  # Version specifications that restrict all updates going forward. This excludes versions
151
151
  # like ">= 1.0" or "!= 2.0.3".
152
152
  def restrictive_version_specified_gem?(node)
153
- return unless version_specified_gem?(node)
153
+ return false unless version_specified_gem?(node)
154
154
 
155
155
  node.arguments[1..]
156
156
  .any? { |arg| arg&.str_type? && RESTRICTIVE_VERSION_PATTERN.match?(arg.value) }
@@ -105,13 +105,13 @@ module RuboCop
105
105
  end
106
106
 
107
107
  def required_offense?(node)
108
- return unless required_style?
108
+ return false unless required_style?
109
109
 
110
110
  !includes_version_specification?(node) && !includes_commit_reference?(node)
111
111
  end
112
112
 
113
113
  def forbidden_offense?(node)
114
- return unless forbidden_style?
114
+ return false unless forbidden_style?
115
115
 
116
116
  includes_version_specification?(node) || includes_commit_reference?(node)
117
117
  end
@@ -54,7 +54,7 @@ module RuboCop
54
54
  def inside_string_ranges(node)
55
55
  return [] unless node.is_a?(Parser::AST::Node)
56
56
 
57
- node.each_node(:str, :dstr, :xstr).map { |n| inside_string_range(n) }.compact
57
+ node.each_node(:str, :dstr, :xstr).filter_map { |n| inside_string_range(n) }
58
58
  end
59
59
 
60
60
  def inside_string_range(node)
@@ -126,13 +126,13 @@ module RuboCop
126
126
  end
127
127
 
128
128
  def required_offense?(node)
129
- return unless required_style?
129
+ return false unless required_style?
130
130
 
131
131
  !includes_version_specification?(node) && !includes_commit_reference?(node)
132
132
  end
133
133
 
134
134
  def forbidden_offense?(node)
135
- return unless forbidden_style?
135
+ return false unless forbidden_style?
136
136
 
137
137
  includes_version_specification?(node) || includes_commit_reference?(node)
138
138
  end
@@ -75,7 +75,7 @@ module RuboCop
75
75
 
76
76
  # @!method add_development_dependency?(node)
77
77
  def_node_matcher :add_development_dependency?, <<~PATTERN
78
- (send _ :add_development_dependency (str #forbidden_gem? ...))
78
+ (send _ :add_development_dependency (str #forbidden_gem? ...) _? _?)
79
79
  PATTERN
80
80
 
81
81
  # @!method gem?(node)
@@ -12,6 +12,13 @@ module RuboCop
12
12
  # ....
13
13
  # end
14
14
  #
15
+ # # bad
16
+ # #
17
+ # # Checks ...
18
+ # class SomeCop < Base
19
+ # ...
20
+ # end
21
+ #
15
22
  # # good
16
23
  # # Checks ...
17
24
  # class SomeCop < Base
@@ -21,27 +28,47 @@ module RuboCop
21
28
  class CopDescription < Base
22
29
  extend AutoCorrector
23
30
 
24
- MSG = 'Description should be started with %<suggestion>s instead of `This cop ...`.'
31
+ MSG_STARTS_WITH_WRONG_WORD =
32
+ 'Description should be started with %<suggestion>s instead of `This cop ...`.'
33
+ MSG_STARTS_WITH_EMPTY_COMMENT_LINE =
34
+ 'Description should not start with an empty comment line.'
25
35
 
26
36
  SPECIAL_WORDS = %w[is can could should will would must may].freeze
27
37
  COP_DESC_OFFENSE_REGEX =
28
38
  /^\s+# This cop (?<special>#{SPECIAL_WORDS.join('|')})?\s*(?<word>.+?) .*/.freeze
29
39
  REPLACEMENT_REGEX = /^\s+# This cop (#{SPECIAL_WORDS.join('|')})?\s*(.+?) /.freeze
40
+ EMPTY_COMMENT_LINE_REGEX = /\A\s*#\s*\n\z/.freeze
30
41
 
31
- # rubocop:disable Metrics/CyclomaticComplexity
32
42
  def on_class(node)
33
43
  return unless (module_node = node.parent) && node.parent_class
34
44
 
35
45
  description_beginning = first_comment_line(module_node)
36
46
  return unless description_beginning
37
47
 
38
- start_with_subject = description_beginning.match(COP_DESC_OFFENSE_REGEX)
39
- return unless start_with_subject
48
+ if description_beginning.match?(EMPTY_COMMENT_LINE_REGEX)
49
+ register_offense_for_empty_comment_line(module_node, description_beginning)
50
+ else
51
+ start_with_subject = description_beginning.match(COP_DESC_OFFENSE_REGEX)
52
+ return unless start_with_subject
53
+
54
+ register_offense_for_wrong_word(module_node, description_beginning, start_with_subject)
55
+ end
56
+ end
57
+
58
+ private
40
59
 
60
+ def register_offense_for_empty_comment_line(module_node, description_beginning)
61
+ range = range(module_node, description_beginning)
62
+ add_offense(range, message: MSG_STARTS_WITH_EMPTY_COMMENT_LINE) do |corrector|
63
+ corrector.remove(range)
64
+ end
65
+ end
66
+
67
+ def register_offense_for_wrong_word(module_node, description_beginning, start_with_subject)
41
68
  suggestion = start_with_subject['word']&.capitalize
42
69
  range = range(module_node, description_beginning)
43
70
  suggestion_for_message = suggestion_for_message(suggestion, start_with_subject)
44
- message = format(MSG, suggestion: suggestion_for_message)
71
+ message = format(MSG_STARTS_WITH_WRONG_WORD, suggestion: suggestion_for_message)
45
72
 
46
73
  add_offense(range, message: message) do |corrector|
47
74
  if suggestion && !start_with_subject['special']
@@ -49,9 +76,6 @@ module RuboCop
49
76
  end
50
77
  end
51
78
  end
52
- # rubocop:enable Metrics/CyclomaticComplexity
53
-
54
- private
55
79
 
56
80
  def replace_with_suggestion(corrector, range, suggestion, description_beginning)
57
81
  replacement = description_beginning.gsub(REPLACEMENT_REGEX, "#{suggestion} ")
@@ -59,12 +59,12 @@ module RuboCop
59
59
  def method_directives(node)
60
60
  comments = processed_source.ast_with_comments[node]
61
61
 
62
- comments.map do |comment|
62
+ comments.filter_map do |comment|
63
63
  match = comment.text.match(REGEXP)
64
64
  next unless match
65
65
 
66
66
  { node: comment, method_name: match[:method_name], args: match[:args] }
67
- end.compact
67
+ end
68
68
  end
69
69
 
70
70
  def too_many_directives(node)
@@ -117,11 +117,11 @@ module RuboCop
117
117
  def add_newline?(node)
118
118
  # Determine if a blank line should be inserted before the new directive
119
119
  # in order to spread out pattern matchers
120
- return if node.sibling_index&.zero?
121
- return unless node.parent
120
+ return false if node.sibling_index&.zero?
121
+ return false unless node.parent
122
122
 
123
123
  prev_sibling = node.parent.child_nodes[node.sibling_index - 1]
124
- return unless prev_sibling && pattern_matcher?(prev_sibling)
124
+ return false unless prev_sibling && pattern_matcher?(prev_sibling)
125
125
 
126
126
  node.loc.line == last_line(prev_sibling) + 1
127
127
  end
@@ -68,6 +68,13 @@ module RuboCop
68
68
  # - extend
69
69
  # ----
70
70
  #
71
+ # @safety
72
+ # Autocorrection is unsafe because class methods and module inclusion
73
+ # can behave differently, based on which methods or constants have
74
+ # already been defined.
75
+ #
76
+ # Constants will only be moved when they are assigned with literals.
77
+ #
71
78
  # @example
72
79
  # # bad
73
80
  # # Expect extend be before constant
@@ -3,7 +3,6 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- #
7
6
  # Checks the indentation of here document closings.
8
7
  #
9
8
  # @example
@@ -73,7 +72,7 @@ module RuboCop
73
72
  end
74
73
 
75
74
  def argument_indentation_correct?(node)
76
- return unless node.argument? || node.chained?
75
+ return false unless node.argument? || node.chained?
77
76
 
78
77
  opening_indentation(
79
78
  find_node_used_heredoc_argument(node.parent)
@@ -160,7 +160,7 @@ module RuboCop
160
160
  private
161
161
 
162
162
  def candidate?(node)
163
- return unless node
163
+ return false unless node
164
164
 
165
165
  method_candidate?(node) || class_candidate?(node) || module_candidate?(node)
166
166
  end
@@ -68,6 +68,8 @@ module RuboCop
68
68
  check_body(node.body, node.loc.line)
69
69
  end
70
70
  alias on_defs on_def
71
+ alias on_block on_def
72
+ alias on_numblock on_def
71
73
 
72
74
  def on_kwbegin(node)
73
75
  body, = *node
@@ -228,9 +228,9 @@ module RuboCop
228
228
  end
229
229
 
230
230
  def find_most_bottom_of_heredoc_end(arguments)
231
- arguments.map do |argument|
231
+ arguments.filter_map do |argument|
232
232
  argument.loc.heredoc_end.end_pos if argument.loc.respond_to?(:heredoc_end)
233
- end.compact.max
233
+ end.max
234
234
  end
235
235
 
236
236
  # Internal trailing comma helpers.
@@ -76,7 +76,7 @@ module RuboCop
76
76
 
77
77
  def autocorrect_lambda_for_tabs(corrector, range)
78
78
  spaces = ' ' * configured_indentation_width
79
- corrector.replace(range, range.source.gsub(/\t/, spaces))
79
+ corrector.replace(range, range.source.gsub("\t", spaces))
80
80
  end
81
81
 
82
82
  def autocorrect_lambda_for_spaces(corrector, range)
@@ -366,10 +366,10 @@ module RuboCop
366
366
  end
367
367
 
368
368
  def starts_with_access_modifier?(body_node)
369
- return unless body_node.begin_type?
369
+ return false unless body_node.begin_type?
370
370
 
371
371
  starting_node = body_node.children.first
372
- return unless starting_node
372
+ return false unless starting_node
373
373
 
374
374
  starting_node.send_type? && starting_node.bare_access_modifier?
375
375
  end
@@ -99,7 +99,7 @@ module RuboCop
99
99
  def suitable_as_single_line?(node)
100
100
  !comment_within?(node) &&
101
101
  node.each_descendant(:if, :case, :kwbegin, :def).none? &&
102
- node.each_descendant(:dstr, :str).none?(&:heredoc?) &&
102
+ node.each_descendant(:dstr, :str).none? { |n| n.heredoc? || n.value.include?("\n") } &&
103
103
  node.each_descendant(:begin).none? { |b| !b.single_line? }
104
104
  end
105
105
 
@@ -236,6 +236,8 @@ module RuboCop
236
236
  end
237
237
 
238
238
  def offense(begin_pos, end_pos, msg, style_param = 'EnforcedStyle')
239
+ return if begin_pos > end_pos
240
+
239
241
  range = range_between(begin_pos, end_pos)
240
242
  add_offense(range, message: msg) do |corrector|
241
243
  case range.source