rubocop 1.57.2 → 1.60.1

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 (139) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +46 -3
  5. data/lib/rubocop/config.rb +0 -2
  6. data/lib/rubocop/config_loader.rb +0 -1
  7. data/lib/rubocop/config_obsoletion.rb +11 -8
  8. data/lib/rubocop/config_validator.rb +0 -2
  9. data/lib/rubocop/cop/base.rb +6 -0
  10. data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
  11. data/lib/rubocop/cop/exclude_limit.rb +1 -1
  12. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +2 -2
  13. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
  14. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
  15. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +2 -2
  16. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  17. data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
  18. data/lib/rubocop/cop/layout/end_alignment.rb +5 -1
  19. data/lib/rubocop/cop/layout/extra_spacing.rb +4 -10
  20. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +22 -7
  21. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
  22. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
  23. data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -1
  24. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
  25. data/lib/rubocop/cop/layout/redundant_line_break.rb +2 -1
  26. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -4
  27. data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
  28. data/lib/rubocop/cop/layout/space_around_operators.rb +50 -20
  29. data/lib/rubocop/cop/lint/assignment_in_condition.rb +4 -4
  30. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
  31. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
  32. data/lib/rubocop/cop/lint/debugger.rb +2 -1
  33. data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
  34. data/lib/rubocop/cop/lint/erb_new_arguments.rb +3 -3
  35. data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
  36. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
  37. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
  38. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
  39. data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -21
  40. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -5
  41. data/lib/rubocop/cop/lint/number_conversion.rb +9 -4
  42. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +43 -0
  43. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
  44. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  45. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -4
  46. data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
  47. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  48. data/lib/rubocop/cop/lint/symbol_conversion.rb +7 -2
  49. data/lib/rubocop/cop/lint/syntax.rb +6 -3
  50. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
  51. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -2
  52. data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
  53. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  54. data/lib/rubocop/cop/lint/void.rb +14 -1
  55. data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
  56. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  57. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  58. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
  59. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  60. data/lib/rubocop/cop/naming/block_forwarding.rb +12 -4
  61. data/lib/rubocop/cop/naming/constant_name.rb +1 -2
  62. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  63. data/lib/rubocop/cop/security/open.rb +2 -2
  64. data/lib/rubocop/cop/style/access_modifier_declarations.rb +2 -2
  65. data/lib/rubocop/cop/style/accessor_grouping.rb +1 -1
  66. data/lib/rubocop/cop/style/arguments_forwarding.rb +120 -17
  67. data/lib/rubocop/cop/style/array_first_last.rb +64 -0
  68. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
  69. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
  70. data/lib/rubocop/cop/style/case_like_if.rb +4 -4
  71. data/lib/rubocop/cop/style/class_check.rb +1 -0
  72. data/lib/rubocop/cop/style/collection_compact.rb +18 -8
  73. data/lib/rubocop/cop/style/combinable_loops.rb +13 -7
  74. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -0
  75. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
  76. data/lib/rubocop/cop/style/date_time.rb +5 -4
  77. data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
  78. data/lib/rubocop/cop/style/each_with_object.rb +2 -2
  79. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  80. data/lib/rubocop/cop/style/eval_with_location.rb +3 -14
  81. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -1
  82. data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
  83. data/lib/rubocop/cop/style/hash_each_methods.rb +83 -10
  84. data/lib/rubocop/cop/style/hash_except.rb +2 -1
  85. data/lib/rubocop/cop/style/identical_conditional_branches.rb +4 -1
  86. data/lib/rubocop/cop/style/inverse_methods.rb +6 -5
  87. data/lib/rubocop/cop/style/invertible_unless_condition.rb +39 -2
  88. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +3 -2
  89. data/lib/rubocop/cop/style/map_to_hash.rb +17 -7
  90. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +14 -5
  91. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
  92. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +20 -0
  93. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  94. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
  95. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -3
  96. data/lib/rubocop/cop/style/next.rb +1 -1
  97. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  98. data/lib/rubocop/cop/style/operator_method_call.rb +2 -2
  99. data/lib/rubocop/cop/style/parallel_assignment.rb +2 -2
  100. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
  101. data/lib/rubocop/cop/style/redundant_argument.rb +3 -2
  102. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +3 -3
  103. data/lib/rubocop/cop/style/redundant_each.rb +7 -4
  104. data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -3
  105. data/lib/rubocop/cop/style/redundant_line_continuation.rb +10 -1
  106. data/lib/rubocop/cop/style/redundant_parentheses.rb +33 -10
  107. data/lib/rubocop/cop/style/redundant_return.rb +1 -1
  108. data/lib/rubocop/cop/style/redundant_self.rb +17 -2
  109. data/lib/rubocop/cop/style/redundant_sort.rb +9 -8
  110. data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
  111. data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -1
  112. data/lib/rubocop/cop/style/sample.rb +2 -1
  113. data/lib/rubocop/cop/style/select_by_regexp.rb +7 -6
  114. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  115. data/lib/rubocop/cop/style/semicolon.rb +8 -0
  116. data/lib/rubocop/cop/style/single_argument_dig.rb +5 -2
  117. data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
  118. data/lib/rubocop/cop/style/string_chars.rb +1 -0
  119. data/lib/rubocop/cop/style/strip.rb +7 -4
  120. data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
  121. data/lib/rubocop/cop/style/symbol_proc.rb +36 -0
  122. data/lib/rubocop/cop/style/unpack_first.rb +11 -14
  123. data/lib/rubocop/cops_documentation_generator.rb +11 -1
  124. data/lib/rubocop/ext/regexp_node.rb +9 -4
  125. data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
  126. data/lib/rubocop/formatter/html_formatter.rb +1 -2
  127. data/lib/rubocop/formatter/json_formatter.rb +0 -1
  128. data/lib/rubocop/formatter.rb +1 -1
  129. data/lib/rubocop/lsp/routes.rb +1 -1
  130. data/lib/rubocop/options.rb +0 -8
  131. data/lib/rubocop/result_cache.rb +0 -1
  132. data/lib/rubocop/rspec/shared_contexts.rb +6 -0
  133. data/lib/rubocop/rspec/support.rb +1 -0
  134. data/lib/rubocop/runner.rb +1 -1
  135. data/lib/rubocop/server/cache.rb +1 -2
  136. data/lib/rubocop/version.rb +1 -1
  137. data/lib/rubocop.rb +4 -0
  138. metadata +15 -10
  139. /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: adf1db90b03283f492e0e10f234d54d6efc215a8b182965087313e3954d533dd
4
- data.tar.gz: fa84dfd9d61e4834df9287e0ba0619622f4b7eb9e229e8de1172bc1742c04df5
3
+ metadata.gz: e1a3d23f54a884c339ea9572297b0c8327493b96f2285cdb0db4585d1b76f9e3
4
+ data.tar.gz: c0df01858756b5b0c18a786c576ce2a21b6f36ffa99947111b8a03d5296c24eb
5
5
  SHA512:
6
- metadata.gz: 44a683eed5e4b9d26caf4d0c775a6f4ba00960b6aaeee29c3f610320d1471326d650e8fc41ee2725af07b4e6a50bf17d442232134522709ebb2a46ec5b80bf40
7
- data.tar.gz: d4f5dda0dbf7689c55b39de3922c2bd1a0c40aa62ac1046f06c98a19e7f2719cfea11babd480ba4e9b9ff2203d20422a51f096165d5919bf564e009c3a91c087
6
+ metadata.gz: 22ae311355c3b238f17df4d3e078920e531d706630ee41e2bd58543f082714da1b19948a81a377c83a34b2a7845b2eb2024cc64f7df97f9df5b5111b6be39541
7
+ data.tar.gz: a60635fbaec51410dd057156d80f07e533c4ce18a7ff83cf1a10d448e80fecbb33fbf3f074ee8172bce997c46c0c0b3019d4d21e19aede283cf5ea7e1f21c95d
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-23 Bozhidar Batsov
1
+ Copyright (c) 2012-24 Bozhidar Batsov
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://raw.githubusercontent.com/rubocop/rubocop/master/logo/rubo-logo-horizontal.png" alt="RuboCop Logo"/>
2
+ <img src="https://raw.githubusercontent.com/rubocop/rubocop/master/logo/rubo-logo-horizontal-white.png" alt="RuboCop Logo"/>
3
3
  </p>
4
4
 
5
5
  ----------
@@ -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.57', require: false
56
+ gem 'rubocop', '~> 1.60', require: false
57
57
  ```
58
58
 
59
59
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
@@ -67,7 +67,7 @@ $ cd my/cool/ruby/project
67
67
  $ rubocop
68
68
  ```
69
69
 
70
- You can also use this magic in your favorite editor with RuboCop's [built-in LSP](https://docs.rubocop.org/rubocop/usage/lsp.html).
70
+ You can also use this magic in your favorite editor with RuboCop's [built-in LSP server](https://docs.rubocop.org/rubocop/usage/lsp.html).
71
71
 
72
72
  ## Documentation
73
73
 
@@ -248,5 +248,5 @@ RuboCop's changelog is available [here](CHANGELOG.md).
248
248
 
249
249
  ## Copyright
250
250
 
251
- Copyright (c) 2012-2023 Bozhidar Batsov. See [LICENSE.txt](LICENSE.txt) for
251
+ Copyright (c) 2012-2024 Bozhidar Batsov. See [LICENSE.txt](LICENSE.txt) for
252
252
  further details.
data/config/default.yml CHANGED
@@ -1351,6 +1351,10 @@ Layout/SpaceAroundOperators:
1351
1351
  SupportedStylesForExponentOperator:
1352
1352
  - space
1353
1353
  - no_space
1354
+ EnforcedStyleForRationalLiterals: no_space
1355
+ SupportedStylesForRationalLiterals:
1356
+ - space
1357
+ - no_space
1354
1358
 
1355
1359
  Layout/SpaceBeforeBlockBraces:
1356
1360
  Description: >-
@@ -1959,6 +1963,12 @@ Lint/InterpolationCheck:
1959
1963
  VersionAdded: '0.50'
1960
1964
  VersionChanged: '1.40'
1961
1965
 
1966
+ Lint/ItWithoutArgumentsInBlock:
1967
+ Description: 'Checks uses of `it` calls without arguments in block.'
1968
+ Reference: 'https://bugs.ruby-lang.org/issues/18980'
1969
+ Enabled: pending
1970
+ VersionAdded: '1.59'
1971
+
1962
1972
  Lint/LambdaWithoutLiteralBlock:
1963
1973
  Description: 'Checks uses of lambda without a literal block.'
1964
1974
  Enabled: pending
@@ -1969,6 +1979,11 @@ Lint/LiteralAsCondition:
1969
1979
  Enabled: true
1970
1980
  VersionAdded: '0.51'
1971
1981
 
1982
+ Lint/LiteralAssignmentInCondition:
1983
+ Description: 'Checks for literal assignments in the conditions.'
1984
+ Enabled: pending
1985
+ VersionAdded: '1.58'
1986
+
1972
1987
  Lint/LiteralInInterpolation:
1973
1988
  Description: 'Checks for literals used in interpolation.'
1974
1989
  Enabled: true
@@ -3085,7 +3100,19 @@ Style/ArgumentsForwarding:
3085
3100
  Enabled: pending
3086
3101
  AllowOnlyRestArgument: true
3087
3102
  UseAnonymousForwarding: true
3103
+ RedundantRestArgumentNames:
3104
+ - args
3105
+ - arguments
3106
+ RedundantKeywordRestArgumentNames:
3107
+ - kwargs
3108
+ - options
3109
+ - opts
3110
+ RedundantBlockArgumentNames:
3111
+ - blk
3112
+ - block
3113
+ - proc
3088
3114
  VersionAdded: '1.1'
3115
+ VersionChanged: '1.58'
3089
3116
 
3090
3117
  Style/ArrayCoercion:
3091
3118
  Description: >-
@@ -3096,6 +3123,13 @@ Style/ArrayCoercion:
3096
3123
  Enabled: false
3097
3124
  VersionAdded: '0.88'
3098
3125
 
3126
+ Style/ArrayFirstLast:
3127
+ Description: 'Use `arr.first` and `arr.last` instead of `arr[0]` and `arr[-1]`.'
3128
+ Reference: '#first-and-last'
3129
+ Enabled: false
3130
+ VersionAdded: '1.58'
3131
+ Safe: false
3132
+
3099
3133
  Style/ArrayIntersect:
3100
3134
  Description: 'Use `array1.intersect?(array2)` instead of `(array1 & array2).any?`.'
3101
3135
  Enabled: 'pending'
@@ -4678,6 +4712,7 @@ Style/OperatorMethodCall:
4678
4712
 
4679
4713
  Style/OptionHash:
4680
4714
  Description: "Don't use option hashes when you can use keyword arguments."
4715
+ StyleGuide: '#keyword-arguments-vs-option-hashes'
4681
4716
  Enabled: false
4682
4717
  VersionAdded: '0.33'
4683
4718
  VersionChanged: '0.34'
@@ -4902,7 +4937,7 @@ Style/RedundantFetchBlock:
4902
4937
  Description: >-
4903
4938
  Use `fetch(key, value)` instead of `fetch(key) { value }`
4904
4939
  when value has Numeric, Rational, Complex, Symbol or String type, `false`, `true`, `nil` or is a constant.
4905
- Reference: 'https://github.com/JuanitoFatas/fast-ruby#hashfetch-with-argument-vs-hashfetch--block-code'
4940
+ Reference: 'https://github.com/fastruby/fast-ruby#hashfetch-with-argument-vs-hashfetch--block-code'
4906
4941
  Enabled: true
4907
4942
  Safe: false
4908
4943
  # If enabled, this cop will autocorrect usages of
@@ -5123,7 +5158,7 @@ Style/Sample:
5123
5158
  Description: >-
5124
5159
  Use `sample` instead of `shuffle.first`,
5125
5160
  `shuffle.last`, and `shuffle[Integer]`.
5126
- Reference: 'https://github.com/JuanitoFatas/fast-ruby#arrayshufflefirst-vs-arraysample-code'
5161
+ Reference: 'https://github.com/fastruby/fast-ruby#arrayshufflefirst-vs-arraysample-code'
5127
5162
  Enabled: true
5128
5163
  VersionAdded: '0.30'
5129
5164
 
@@ -5190,6 +5225,7 @@ Style/SingleLineBlockParams:
5190
5225
 
5191
5226
  Style/SingleLineDoEndBlock:
5192
5227
  Description: 'Checks for single-line `do`...`end` blocks.'
5228
+ StyleGuide: '#single-line-do-end-block'
5193
5229
  Enabled: pending
5194
5230
  VersionAdded: '1.57'
5195
5231
 
@@ -5202,7 +5238,8 @@ Style/SingleLineMethods:
5202
5238
  AllowIfMethodIsEmpty: true
5203
5239
 
5204
5240
  Style/SlicingWithRange:
5205
- Description: 'Checks array slicing is done with endless ranges when suitable.'
5241
+ Description: 'Checks array slicing is done with redundant, endless, and beginless ranges when suitable.'
5242
+ StyleGuide: '#slicing-with-ranges'
5206
5243
  Enabled: true
5207
5244
  VersionAdded: '0.83'
5208
5245
  Safe: false
@@ -5329,6 +5366,12 @@ Style/StructInheritance:
5329
5366
  VersionAdded: '0.29'
5330
5367
  VersionChanged: '1.20'
5331
5368
 
5369
+ Style/SuperWithArgsParentheses:
5370
+ Description: 'Use parentheses for `super` with arguments.'
5371
+ StyleGuide: '#super-with-args'
5372
+ Enabled: pending
5373
+ VersionAdded: '1.58'
5374
+
5332
5375
  Style/SwapValues:
5333
5376
  Description: 'Enforces the use of shorthand-style swapping of 2 variables.'
5334
5377
  StyleGuide: '#values-swapping'
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pathname'
4
-
5
3
  # FIXME: Moving Rails department code to RuboCop Rails will remove
6
4
  # the following rubocop:disable comment.
7
5
  # rubocop:disable Metrics/ClassLength
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'erb'
4
- require 'pathname'
5
4
  require 'yaml'
6
5
  require_relative 'config_finder'
7
6
 
@@ -15,6 +15,8 @@ module RuboCop
15
15
  'changed_parameters' => ChangedParameter,
16
16
  'changed_enforced_styles' => ChangedEnforcedStyles
17
17
  }.freeze
18
+ LOAD_RULES_CACHE = {} # rubocop:disable Style/MutableConstant
19
+ private_constant :LOAD_RULES_CACHE
18
20
 
19
21
  attr_reader :rules, :warnings
20
22
 
@@ -48,16 +50,17 @@ module RuboCop
48
50
  # Default rules for obsoletions are in config/obsoletion.yml
49
51
  # Additional rules files can be added with `RuboCop::ConfigObsoletion.files << filename`
50
52
  def load_rules # rubocop:disable Metrics/AbcSize
51
- rules = self.class.files.each_with_object({}) do |filename, hash|
52
- hash.merge!(YAML.safe_load(File.read(filename))) do |_key, first, second|
53
- case first
54
- when Hash
55
- first.merge(second)
56
- when Array
57
- first.concat(second)
53
+ rules = LOAD_RULES_CACHE[self.class.files] ||=
54
+ self.class.files.each_with_object({}) do |filename, hash|
55
+ hash.merge!(YAML.safe_load(File.read(filename))) do |_key, first, second|
56
+ case first
57
+ when Hash
58
+ first.merge(second)
59
+ when Array
60
+ first.concat(second)
61
+ end
58
62
  end
59
63
  end
60
- end
61
64
 
62
65
  cop_rules = rules.slice(*COP_RULE_CLASSES.keys)
63
66
  parameter_rules = rules.slice(*PARAMETER_RULE_CLASSES.keys)
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pathname'
4
-
5
3
  module RuboCop
6
4
  # Handles validation of configuration, for example cop names, parameter
7
5
  # names, and Ruby versions.
@@ -481,6 +481,12 @@ module RuboCop
481
481
  range.end_pos + @current_offset
482
482
  )
483
483
  end
484
+
485
+ # This experimental feature has been under consideration for a while.
486
+ # @api private
487
+ def lsp_mode?
488
+ ARGV.include?('--lsp')
489
+ end
484
490
  end
485
491
  end
486
492
  end
@@ -161,9 +161,9 @@ module RuboCop
161
161
  end
162
162
 
163
163
  def gem_options(node)
164
- return [] unless node.arguments.last&.type == :hash
164
+ return [] unless node.last_argument&.type == :hash
165
165
 
166
- node.arguments.last.keys.map(&:value)
166
+ node.last_argument.keys.map(&:value)
167
167
  end
168
168
  end
169
169
  end
@@ -8,7 +8,7 @@ module RuboCop
8
8
  # The parameter name given is transformed into a method name (eg. `Max`
9
9
  # becomes `self.max=` and `MinDigits` becomes `self.min_digits=`).
10
10
  def exclude_limit(parameter_name, method_name: transform(parameter_name))
11
- define_method("#{method_name}=") do |value|
11
+ define_method(:"#{method_name}=") do |value|
12
12
  cfg = config_to_allow_offenses
13
13
  cfg[:exclude_limit] ||= {}
14
14
  current_max = cfg[:exclude_limit][parameter_name]
@@ -43,7 +43,7 @@ module RuboCop
43
43
  def on_block(block_node)
44
44
  return unless gem_specification(block_node)
45
45
 
46
- block_parameter = block_node.arguments.first.source
46
+ block_parameter = block_node.first_argument.source
47
47
 
48
48
  assignment = block_node.descendants.detect do |node|
49
49
  use_deprecated_attributes?(node, block_parameter)
@@ -65,7 +65,7 @@ module RuboCop
65
65
  lhs, _op, _rhs = *node
66
66
  [lhs, attribute]
67
67
  else
68
- [node, "#{attribute}=".to_sym]
68
+ [node, :"#{attribute}="]
69
69
  end
70
70
  end
71
71
 
@@ -12,38 +12,37 @@ module RuboCop
12
12
  # # good
13
13
  # node.method?(:do_something)
14
14
  #
15
+ # # bad
16
+ # node.method_name != :do_something
17
+ #
18
+ # # good
19
+ # !node.method?(:do_something)
20
+ #
15
21
  class MethodNameEqual < Base
16
- include RangeHelp
17
22
  extend AutoCorrector
18
23
 
19
- MSG = 'Use `method?(%<method_name>s)` instead of `method_name == %<method_name>s`.'
20
- RESTRICT_ON_SEND = %i[==].freeze
24
+ MSG = 'Use `%<prefer>s` instead.'
25
+ RESTRICT_ON_SEND = %i[== !=].freeze
21
26
 
22
- # @!method method_name?(node)
23
- def_node_matcher :method_name?, <<~PATTERN
27
+ # @!method method_name(node)
28
+ def_node_matcher :method_name, <<~PATTERN
24
29
  (send
25
- $(send
26
- (...) :method_name) :==
27
- $...)
30
+ (send
31
+ (...) :method_name) {:== :!=}
32
+ $_)
28
33
  PATTERN
29
34
 
30
35
  def on_send(node)
31
- method_name?(node) do |method_name_node, method_name_arg|
32
- message = format(MSG, method_name: method_name_arg.first.source)
36
+ method_name(node) do |method_name_arg|
37
+ bang = node.method?(:!=) ? '!' : ''
38
+ prefer = "#{bang}#{node.receiver.receiver.source}.method?(#{method_name_arg.source})"
39
+ message = format(MSG, prefer: prefer)
33
40
 
34
- range = range(method_name_node, node)
35
-
36
- add_offense(range, message: message) do |corrector|
37
- corrector.replace(range, "method?(#{method_name_arg.first.source})")
41
+ add_offense(node, message: message) do |corrector|
42
+ corrector.replace(node, prefer)
38
43
  end
39
44
  end
40
45
  end
41
-
42
- private
43
-
44
- def range(method_name_node, node)
45
- range_between(method_name_node.loc.selector.begin_pos, node.source_range.end_pos)
46
- end
47
46
  end
48
47
  end
49
48
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # Checks for the use of `node.arguments.first` or `node.arguments.last` and
7
+ # suggests the use of `node.first_argument` or `node.last_argument` instead.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # node.arguments.first
12
+ # node.arguments[0]
13
+ # node.arguments.last
14
+ # node.arguments[-1]
15
+ #
16
+ # # good
17
+ # node.first_argument
18
+ # node.last_argument
19
+ #
20
+ class NodeFirstOrLastArgument < Base
21
+ extend AutoCorrector
22
+ include RangeHelp
23
+
24
+ MSG = 'Use `#%<correct>s` instead of `#%<incorrect>s`.'
25
+ RESTRICT_ON_SEND = %i[arguments].freeze
26
+
27
+ # @!method arguments_first_or_last?(node)
28
+ def_node_matcher :arguments_first_or_last?, <<~PATTERN
29
+ {
30
+ (send (send !nil? :arguments) ${:first :last})
31
+ (send (send !nil? :arguments) :[] (int ${0 -1}))
32
+ }
33
+ PATTERN
34
+
35
+ def on_send(node)
36
+ arguments_first_or_last?(node.parent) do |end_or_index|
37
+ range = range_between(node.loc.selector.begin_pos, node.parent.source_range.end_pos)
38
+ correct = case end_or_index
39
+ when :first, 0 then 'first_argument'
40
+ when :last, -1 then 'last_argument'
41
+ else raise "Unknown end_or_index: #{end_or_index}"
42
+ end
43
+ message = format(MSG, correct: correct, incorrect: range.source)
44
+
45
+ add_offense(range, message: message) do |corrector|
46
+ corrector.replace(range, correct)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -40,7 +40,7 @@ module RuboCop
40
40
  return if node.arguments.none?
41
41
  return unless valid_method_name?(node)
42
42
 
43
- actual_name = node.arguments.first.value
43
+ actual_name = node.first_argument.value
44
44
  directives = method_directives(node)
45
45
  return too_many_directives(node) if directives.size > 1
46
46
 
@@ -53,7 +53,7 @@ module RuboCop
53
53
  private
54
54
 
55
55
  def valid_method_name?(node)
56
- node.arguments.first.str_type? || node.arguments.first.sym_type?
56
+ node.first_argument.str_type? || node.first_argument.sym_type?
57
57
  end
58
58
 
59
59
  def method_directives(node)
@@ -12,6 +12,7 @@ require_relative 'internal_affairs/location_line_equality_comparison'
12
12
  require_relative 'internal_affairs/method_name_end_with'
13
13
  require_relative 'internal_affairs/method_name_equal'
14
14
  require_relative 'internal_affairs/node_destructuring'
15
+ require_relative 'internal_affairs/node_first_or_last_argument'
15
16
  require_relative 'internal_affairs/node_matcher_directive'
16
17
  require_relative 'internal_affairs/node_type_predicate'
17
18
  require_relative 'internal_affairs/numblock_handler'
@@ -79,7 +79,7 @@ module RuboCop
79
79
 
80
80
  def arguments_with_last_arg_pairs(node)
81
81
  items = node.arguments[0..-2]
82
- last_arg = node.arguments.last
82
+ last_arg = node.last_argument
83
83
 
84
84
  if last_arg.hash_type? && !last_arg.braces?
85
85
  items += last_arg.pairs
@@ -83,7 +83,11 @@ module RuboCop
83
83
  end
84
84
 
85
85
  def on_sclass(node)
86
- check_other_alignment(node)
86
+ if node.parent&.assignment?
87
+ check_asgn_alignment(node.parent, node)
88
+ else
89
+ check_other_alignment(node)
90
+ end
87
91
  end
88
92
 
89
93
  def on_module(node)
@@ -49,19 +49,13 @@ module RuboCop
49
49
 
50
50
  private
51
51
 
52
- def aligned_locations(locs) # rubocop:disable Metrics/AbcSize
52
+ def aligned_locations(locs)
53
53
  return [] if locs.empty?
54
54
 
55
- aligned = Set[locs.first.line, locs.last.line]
56
- locs.each_cons(3) do |before, loc, after|
57
- col = loc.column
58
- aligned << loc.line if col == before.column || col == after.column
55
+ aligned = Set.new
56
+ locs.each_cons(2) do |loc1, loc2|
57
+ aligned << loc1.line << loc2.line if loc1.column == loc2.column
59
58
  end
60
-
61
- # if locs.size > 2 and the size of variable `aligned`
62
- # has not increased from its initial value, there are not aligned lines.
63
- return [] if locs.size > 2 && aligned.size == 2
64
-
65
59
  aligned
66
60
  end
67
61
 
@@ -5,7 +5,10 @@ module RuboCop
5
5
  module Layout
6
6
  # Checks the indentation of the first element in an array literal
7
7
  # where the opening bracket and the first element are on separate lines.
8
- # The other elements' indentations are handled by the ArrayAlignment cop.
8
+ # The other elements' indentations are handled by `Layout/ArrayAlignment` cop.
9
+ #
10
+ # This cop will respect `Layout/ArrayAlignment` and will not work when
11
+ # `EnforcedStyle: with_fixed_indentation` is specified for `Layout/ArrayAlignment`.
9
12
  #
10
13
  # By default, array literals that are arguments in a method call with
11
14
  # parentheses, and where the opening square bracket of the array is on the
@@ -25,7 +28,7 @@ module RuboCop
25
28
  # # element are on separate lines is indented one step (two spaces) more
26
29
  # # than the position inside the opening parenthesis.
27
30
  #
28
- # #bad
31
+ # # bad
29
32
  # array = [
30
33
  # :value
31
34
  # ]
@@ -33,7 +36,7 @@ module RuboCop
33
36
  # :no_difference
34
37
  # ])
35
38
  #
36
- # #good
39
+ # # good
37
40
  # array = [
38
41
  # :value
39
42
  # ]
@@ -47,7 +50,7 @@ module RuboCop
47
50
  # # separate lines is indented the same as an array literal which is not
48
51
  # # defined inside a method call.
49
52
  #
50
- # #bad
53
+ # # bad
51
54
  # # consistent
52
55
  # array = [
53
56
  # :value
@@ -56,7 +59,7 @@ module RuboCop
56
59
  # :its_like_this
57
60
  # ])
58
61
  #
59
- # #good
62
+ # # good
60
63
  # array = [
61
64
  # :value
62
65
  # ]
@@ -68,13 +71,13 @@ module RuboCop
68
71
  # # The `align_brackets` style enforces that the opening and closing
69
72
  # # brackets are indented to the same position.
70
73
  #
71
- # #bad
74
+ # # bad
72
75
  # # align_brackets
73
76
  # and_now_for_something = [
74
77
  # :completely_different
75
78
  # ]
76
79
  #
77
- # #good
80
+ # # good
78
81
  # # align_brackets
79
82
  # and_now_for_something = [
80
83
  # :completely_different
@@ -93,6 +96,8 @@ module RuboCop
93
96
  end
94
97
 
95
98
  def on_send(node)
99
+ return if style != :consistent && enforce_first_argument_with_fixed_indentation?
100
+
96
101
  each_argument_node(node, :array) do |array_node, left_parenthesis|
97
102
  check(array_node, left_parenthesis)
98
103
  end
@@ -174,6 +179,16 @@ module RuboCop
174
179
  'where the left bracket is.'
175
180
  end
176
181
  end
182
+
183
+ def enforce_first_argument_with_fixed_indentation?
184
+ return false unless array_alignment_config['Enabled']
185
+
186
+ array_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
187
+ end
188
+
189
+ def array_alignment_config
190
+ config.for_cop('Layout/ArrayAlignment')
191
+ end
177
192
  end
178
193
  end
179
194
  end
@@ -72,7 +72,7 @@ module RuboCop
72
72
  return if ignored_node?(def_node)
73
73
 
74
74
  left_parenthesis = def_node.arguments.loc.begin
75
- first_elem = def_node.arguments.first
75
+ first_elem = def_node.first_argument
76
76
  return unless first_elem
77
77
  return if same_line?(first_elem, left_parenthesis)
78
78
 
@@ -182,7 +182,7 @@ module RuboCop
182
182
  end
183
183
 
184
184
  def add_correct_closing_paren(node, corrector)
185
- corrector.insert_after(node.arguments.last, ')')
185
+ corrector.insert_after(node.last_argument, ')')
186
186
  end
187
187
 
188
188
  def remove_incorrect_closing_paren(node, corrector)
@@ -271,7 +271,7 @@ module RuboCop
271
271
  def add_correct_external_trailing_comma(node, corrector)
272
272
  return unless external_trailing_comma?(node)
273
273
 
274
- corrector.insert_after(node.arguments.last, ',')
274
+ corrector.insert_after(node.last_argument, ',')
275
275
  end
276
276
 
277
277
  def remove_incorrect_external_trailing_comma(node, corrector)
@@ -8,7 +8,7 @@ module RuboCop
8
8
  #
9
9
  # Note: When ``Layout/LineLength``'s `AllowHeredoc` is false (not default),
10
10
  # this cop does not add any offenses for long here documents to
11
- # avoid `Layout/LineLength`'s offenses.
11
+ # avoid ``Layout/LineLength``'s offenses.
12
12
  #
13
13
  # @example
14
14
  # # bad
@@ -107,7 +107,7 @@ module RuboCop
107
107
  return false unless line.end_with?("\\\n")
108
108
 
109
109
  # Ensure backslash isn't part of a token spanning to the next line.
110
- node.children.none? { |c| c.first_line == line_num && c.multiline? }
110
+ node.children.none? { |c| (c.first_line...c.last_line).cover?(line_num) && c.multiline? }
111
111
  end
112
112
 
113
113
  def autocorrect(corrector, offense_range, insert_pos, spaces)
@@ -62,6 +62,7 @@ module RuboCop
62
62
 
63
63
  register_offense(node)
64
64
  end
65
+ alias on_csend on_send
65
66
 
66
67
  private
67
68
 
@@ -135,7 +136,7 @@ module RuboCop
135
136
  .gsub(/" *\\\n\s*'/, %q(" + ')) # Double quote, backslash, and then single quote
136
137
  .gsub(/' *\\\n\s*"/, %q(' + ")) # Single quote, backslash, and then double quote
137
138
  .gsub(/(["']) *\\\n\s*\1/, '') # Double or single quote, backslash, then same quote
138
- .gsub(/\n\s*(?=\.\w)/, '') # Extra space within method chaining
139
+ .gsub(/\n\s*(?=(&)?\.\w)/, '') # Extra space within method chaining which includes `&.`
139
140
  .gsub(/\s*\\?\n\s*/, ' ') # Any other line break, with or without backslash
140
141
  end
141
142
 
@@ -29,7 +29,7 @@ module RuboCop
29
29
  MSG = '`%<kw_loc>s` at %<kw_loc_line>d, %<kw_loc_column>d is not ' \
30
30
  'aligned with `%<beginning>s` at ' \
31
31
  '%<begin_loc_line>d, %<begin_loc_column>d.'
32
- ANCESTOR_TYPES = %i[kwbegin def defs class module block].freeze
32
+ ANCESTOR_TYPES = %i[kwbegin def defs class module block numblock].freeze
33
33
  ANCESTOR_TYPES_WITH_ACCESS_MODIFIERS = %i[def defs].freeze
34
34
  ALTERNATIVE_ACCESS_MODIFIERS = %i[public_class_method private_class_method].freeze
35
35
 
@@ -95,7 +95,7 @@ module RuboCop
95
95
  def alignment_source(node, starting_loc)
96
96
  ending_loc =
97
97
  case node.type
98
- when :block, :kwbegin
98
+ when :block, :numblock, :kwbegin
99
99
  node.loc.begin
100
100
  when :def, :defs, :class, :module,
101
101
  :lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
@@ -104,8 +104,8 @@ module RuboCop
104
104
  mlhs_node, = *node
105
105
  mlhs_node.source_range
106
106
  else
107
- # It is a wrapper with access modifier.
108
- node.child_nodes.first.loc.name
107
+ # It is a wrapper with receiver of object attribute or access modifier.
108
+ node.receiver&.source_range || node.child_nodes.first.loc.name
109
109
  end
110
110
 
111
111
  range_between(starting_loc.begin_pos, ending_loc.end_pos).source