rubocop 1.50.2 → 1.53.0

Sign up to get free protection for your applications and to get access to all the features.
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