rubocop 1.68.0 → 1.69.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 (148) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +41 -6
  4. data/lib/rubocop/cop/base.rb +1 -1
  5. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  6. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  7. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  8. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  9. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  10. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +2 -4
  11. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  12. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +46 -0
  13. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  14. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  15. data/lib/rubocop/cop/layout/argument_alignment.rb +1 -2
  16. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  17. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  18. data/lib/rubocop/cop/layout/block_alignment.rb +1 -2
  19. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
  20. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -3
  21. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +3 -4
  22. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +3 -1
  23. data/lib/rubocop/cop/layout/indentation_width.rb +7 -7
  24. data/lib/rubocop/cop/layout/leading_comment_space.rb +15 -0
  25. data/lib/rubocop/cop/layout/line_length.rb +118 -4
  26. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
  27. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  28. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -3
  29. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  30. data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -35
  31. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -2
  32. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  33. data/lib/rubocop/cop/layout/space_around_operators.rb +16 -17
  34. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +6 -0
  35. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -0
  36. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  37. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +11 -12
  38. data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -0
  39. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
  40. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  41. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  42. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  43. data/lib/rubocop/cop/lint/float_comparison.rb +14 -6
  44. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -3
  45. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  46. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  47. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  48. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  49. data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -5
  50. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
  51. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  52. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +1 -1
  53. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  54. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  55. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +106 -0
  56. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
  57. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -1
  58. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  59. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
  60. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  61. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  62. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  63. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +2 -0
  64. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  65. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  66. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  67. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  68. data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
  69. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  70. data/lib/rubocop/cop/lint/void.rb +3 -2
  71. data/lib/rubocop/cop/metrics/class_length.rb +7 -7
  72. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  73. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -2
  74. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  75. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  76. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  77. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
  78. data/lib/rubocop/cop/mixin/range_help.rb +0 -1
  79. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  80. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  81. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  82. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
  83. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +3 -11
  84. data/lib/rubocop/cop/naming/variable_name.rb +3 -4
  85. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  86. data/lib/rubocop/cop/style/access_modifier_declarations.rb +53 -24
  87. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +1 -1
  88. data/lib/rubocop/cop/style/array_intersect.rb +5 -4
  89. data/lib/rubocop/cop/style/bitwise_predicate.rb +1 -1
  90. data/lib/rubocop/cop/style/block_delimiters.rb +1 -1
  91. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  92. data/lib/rubocop/cop/style/commented_keyword.rb +11 -1
  93. data/lib/rubocop/cop/style/conditional_assignment.rb +19 -21
  94. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  95. data/lib/rubocop/cop/style/dig_chain.rb +90 -0
  96. data/lib/rubocop/cop/style/file_null.rb +73 -0
  97. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  98. data/lib/rubocop/cop/style/for.rb +0 -1
  99. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  100. data/lib/rubocop/cop/style/guard_clause.rb +1 -1
  101. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  102. data/lib/rubocop/cop/style/if_inside_else.rb +0 -1
  103. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -2
  104. data/lib/rubocop/cop/style/if_with_semicolon.rb +14 -5
  105. data/lib/rubocop/cop/style/inverse_methods.rb +0 -1
  106. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +2 -2
  107. data/lib/rubocop/cop/style/lambda_call.rb +0 -1
  108. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +1 -1
  109. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +7 -11
  110. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  111. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  112. data/lib/rubocop/cop/style/mutable_constant.rb +4 -5
  113. data/lib/rubocop/cop/style/negated_if_else_condition.rb +6 -4
  114. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  115. data/lib/rubocop/cop/style/not.rb +1 -1
  116. data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
  117. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  118. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  119. data/lib/rubocop/cop/style/parallel_assignment.rb +8 -13
  120. data/lib/rubocop/cop/style/raise_args.rb +1 -1
  121. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  122. data/lib/rubocop/cop/style/redundant_condition.rb +36 -21
  123. data/lib/rubocop/cop/style/redundant_line_continuation.rb +7 -6
  124. data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
  125. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +1 -0
  126. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  127. data/lib/rubocop/cop/style/redundant_self.rb +7 -14
  128. data/lib/rubocop/cop/style/redundant_self_assignment.rb +7 -5
  129. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  130. data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
  131. data/lib/rubocop/cop/style/rescue_modifier.rb +2 -3
  132. data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
  133. data/lib/rubocop/cop/style/select_by_regexp.rb +1 -1
  134. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  135. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  136. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  137. data/lib/rubocop/cop/style/single_line_do_end_block.rb +13 -3
  138. data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -3
  139. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  140. data/lib/rubocop/cop/style/string_concatenation.rb +0 -1
  141. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  142. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  143. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  144. data/lib/rubocop/cop/variable_force.rb +4 -10
  145. data/lib/rubocop/cops_documentation_generator.rb +9 -1
  146. data/lib/rubocop/version.rb +1 -1
  147. data/lib/rubocop.rb +8 -0
  148. metadata +17 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f0623068e9eac24fe4b1f5c7e4987d3a8adc7a2ec7f5f65c6cfb9d0ad9d1278
4
- data.tar.gz: 9abb03dde6881cb7c11a21ee947c33a7d8874b9893f81e81cd7617f52f1bb714
3
+ metadata.gz: 97d8db05a66f5153d186df8720a9ea65237569f976c572053b4830925df4a825
4
+ data.tar.gz: a2864b5abc210251dc57f5ff1180043fd99069a3151cec6ab43824f9d4a40758
5
5
  SHA512:
6
- metadata.gz: 3392244d7137845de4f7c9867695350666750b349879ac4796590d090b0b1a182f21fb9c96f6d284bfd9eaf21a7594f8b7de2d59da62458400a709430bb6f7a2
7
- data.tar.gz: e2a5a3dd61755c091a91ea99828846fa875b3b7ca8ffaea67425245755e147159691c587a7a80089a428480b7ad07fef8da1be7dc209ac0a60bb46cff3a37d0f
6
+ metadata.gz: 7ab8930edd85daa8e4eddbbedd1e6baa129875798644bcbb3b5e8d8359278d5f58fdc4f372d671654b21d7088606bab5202ef4c5fe34e38ad09e6590f5825339
7
+ data.tar.gz: 336decf7113d831b30a5ca8c8c71d324827853fb8f7102c646a1420957f8d3022f56d2f02c9e21791b280a9659138d0fe041202fff66cb33de9ea3d08548a876
data/README.md CHANGED
@@ -52,7 +52,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
52
52
  in your `Gemfile`:
53
53
 
54
54
  ```rb
55
- gem 'rubocop', '~> 1.68', require: false
55
+ gem 'rubocop', '~> 1.69', require: false
56
56
  ```
57
57
 
58
58
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
data/config/default.yml CHANGED
@@ -1086,11 +1086,11 @@ Layout/LineLength:
1086
1086
  StyleGuide: '#max-line-length'
1087
1087
  Enabled: true
1088
1088
  VersionAdded: '0.25'
1089
- VersionChanged: '1.4'
1089
+ VersionChanged: '1.69'
1090
1090
  Max: 120
1091
+ AllowHeredoc: true
1091
1092
  # To make it possible to copy or click on URIs in the code, we allow lines
1092
1093
  # containing a URI to be longer than Max.
1093
- AllowHeredoc: true
1094
1094
  AllowURI: true
1095
1095
  URISchemes:
1096
1096
  - http
@@ -1102,6 +1102,8 @@ Layout/LineLength:
1102
1102
  # elements. Strings will be converted to Regexp objects. A line that matches
1103
1103
  # any regular expression listed in this option will be ignored by LineLength.
1104
1104
  AllowedPatterns: []
1105
+ # If SplitStrings is true, long strings will be split using continuations
1106
+ SplitStrings: false
1105
1107
 
1106
1108
  Layout/MultilineArrayBraceLayout:
1107
1109
  Description: >-
@@ -1499,7 +1501,6 @@ Layout/SpaceInsideHashLiteralBraces:
1499
1501
  - space
1500
1502
  - no_space
1501
1503
 
1502
-
1503
1504
  Layout/SpaceInsideParens:
1504
1505
  Description: 'No spaces after ( or before ).'
1505
1506
  StyleGuide: '#spaces-braces'
@@ -1634,7 +1635,7 @@ Lint/BinaryOperatorWithIdenticalOperands:
1634
1635
  Enabled: true
1635
1636
  Safe: false
1636
1637
  VersionAdded: '0.89'
1637
- VersionChanged: '1.7'
1638
+ VersionChanged: '1.69'
1638
1639
 
1639
1640
  Lint/BooleanSymbol:
1640
1641
  Description: 'Check for `:true` and `:false` symbols.'
@@ -1956,6 +1957,11 @@ Lint/HashCompareByIdentity:
1956
1957
  Safe: false
1957
1958
  VersionAdded: '0.93'
1958
1959
 
1960
+ Lint/HashNewWithKeywordArgumentsAsDefault:
1961
+ Description: 'Checks for the deprecated use of keyword arguments for hash default in `Hash.new`.'
1962
+ Enabled: pending
1963
+ VersionAdded: '1.69'
1964
+
1959
1965
  Lint/HeredocMethodCallPosition:
1960
1966
  Description: >-
1961
1967
  Checks for the ordering of a method call where
@@ -2146,6 +2152,11 @@ Lint/NumberedParameterAssignment:
2146
2152
  Enabled: pending
2147
2153
  VersionAdded: '1.9'
2148
2154
 
2155
+ Lint/NumericOperationWithConstantResult:
2156
+ Description: 'Checks for numeric operations with constant results.'
2157
+ Enabled: pending
2158
+ VersionAdded: '1.69'
2159
+
2149
2160
  Lint/OrAssignmentToConstant:
2150
2161
  Description: 'Checks unintended or-assignment to constant.'
2151
2162
  Enabled: pending
@@ -2377,7 +2388,6 @@ Lint/ShadowedArgument:
2377
2388
  VersionAdded: '0.52'
2378
2389
  IgnoreImplicitReferences: false
2379
2390
 
2380
-
2381
2391
  Lint/ShadowedException:
2382
2392
  Description: >-
2383
2393
  Avoid rescuing a higher level exception
@@ -2521,10 +2531,12 @@ Lint/UnusedMethodArgument:
2521
2531
  Enabled: true
2522
2532
  AutoCorrect: contextual
2523
2533
  VersionAdded: '0.21'
2524
- VersionChanged: '1.61'
2534
+ VersionChanged: '1.69'
2525
2535
  AllowUnusedKeywordArguments: false
2526
2536
  IgnoreEmptyMethods: true
2527
2537
  IgnoreNotImplementedMethods: true
2538
+ NotImplementedExceptions:
2539
+ - NotImplementedError
2528
2540
 
2529
2541
  Lint/UriEscapeUnescape:
2530
2542
  Description: >-
@@ -2559,6 +2571,11 @@ Lint/UselessAssignment:
2559
2571
  VersionAdded: '0.11'
2560
2572
  VersionChanged: '1.66'
2561
2573
 
2574
+ Lint/UselessDefined:
2575
+ Description: 'Checks for calls to `defined?` with strings and symbols. The result of such a call will always be truthy.'
2576
+ Enabled: pending
2577
+ VersionAdded: '1.69'
2578
+
2562
2579
  Lint/UselessElseWithoutRescue:
2563
2580
  Description: 'Checks for useless `else` in `begin..end` without `rescue`.'
2564
2581
  Enabled: true
@@ -3698,6 +3715,12 @@ Style/DefWithParentheses:
3698
3715
  VersionAdded: '0.9'
3699
3716
  VersionChanged: '0.12'
3700
3717
 
3718
+ Style/DigChain:
3719
+ Description: 'Use `dig` with multiple parameters instead of chaining multiple calls.'
3720
+ Enabled: pending
3721
+ Safe: false
3722
+ VersionAdded: '1.69'
3723
+
3701
3724
  Style/Dir:
3702
3725
  Description: >-
3703
3726
  Use the `__dir__` method to retrieve the canonicalized
@@ -3924,12 +3947,24 @@ Style/FileEmpty:
3924
3947
  Safe: false
3925
3948
  VersionAdded: '1.48'
3926
3949
 
3950
+ Style/FileNull:
3951
+ Description: 'Use `File::NULL` instead of hardcoding "dev/null".'
3952
+ Enabled: pending
3953
+ SafeAutoCorrect: false
3954
+ VersionAdded: '1.69'
3955
+
3927
3956
  Style/FileRead:
3928
3957
  Description: 'Favor `File.(bin)read` convenience methods.'
3929
3958
  StyleGuide: '#file-read'
3930
3959
  Enabled: pending
3931
3960
  VersionAdded: '1.24'
3932
3961
 
3962
+ Style/FileTouch:
3963
+ Description: 'Favor `FileUtils.touch` for touching files.'
3964
+ Enabled: pending
3965
+ VersionAdded: '1.69'
3966
+ SafeAutoCorrect: false
3967
+
3933
3968
  Style/FileWrite:
3934
3969
  Description: 'Favor `File.(bin)write` convenience methods.'
3935
3970
  StyleGuide: '#file-write'
@@ -60,7 +60,7 @@ module RuboCop
60
60
  []
61
61
  end
62
62
 
63
- # Returns an url to view this cops documentation online.
63
+ # Returns a url to view this cops documentation online.
64
64
  # Requires 'DocumentationBaseURL' to be set for your department.
65
65
  # Will follow the convention of RuboCops own documentation structure,
66
66
  # overwrite this method to accommodate your custom layout.
@@ -27,7 +27,6 @@ module RuboCop
27
27
  # Project contains gems.rb and gems.locked files
28
28
  class GemFilename < Base
29
29
  include ConfigurableEnforcedStyle
30
- include RangeHelp
31
30
 
32
31
  MSG_GEMFILE_REQUIRED = '`gems.rb` file was found but `Gemfile` is required ' \
33
32
  '(file path: %<file_path>s).'
@@ -39,7 +39,6 @@ module RuboCop
39
39
  # source 'http://rubygems.org'
40
40
  #
41
41
  class InsecureProtocolSource < Base
42
- include RangeHelp
43
42
  extend AutoCorrector
44
43
 
45
44
  MSG = 'The source `:%<source>s` is deprecated because HTTP requests ' \
@@ -39,7 +39,7 @@ module RuboCop
39
39
  def requires_parentheses?
40
40
  return true if collection_node.send_type? && collection_node.operator_method?
41
41
 
42
- collection_node.range_type? || collection_node.or_type? || collection_node.and_type?
42
+ collection_node.range_type? || collection_node.operator_keyword?
43
43
  end
44
44
 
45
45
  def end_range
@@ -62,8 +62,7 @@ module RuboCop
62
62
 
63
63
  def node_and_method_name(node, attribute)
64
64
  if node.op_asgn_type?
65
- lhs, _op, _rhs = *node
66
- [lhs, attribute]
65
+ [node.lhs, attribute]
67
66
  else
68
67
  [node, :"#{attribute}="]
69
68
  end
@@ -53,8 +53,6 @@ module RuboCop
53
53
  # spec.required_ruby_version = '~> 2.5'
54
54
  # end
55
55
  class RequiredRubyVersion < Base
56
- include RangeHelp
57
-
58
56
  RESTRICT_ON_SEND = %i[required_ruby_version=].freeze
59
57
  NOT_EQUAL_MSG = '`required_ruby_version` and `TargetRubyVersion` ' \
60
58
  '(%<target_ruby_version>s, which may be specified in ' \
@@ -36,10 +36,8 @@ module RuboCop
36
36
  def on_send(node)
37
37
  return unless location_line_equality_comparison?(node)
38
38
 
39
- lhs, _op, rhs = *node
40
-
41
- lhs_receiver = extract_receiver(lhs)
42
- rhs_receiver = extract_receiver(rhs)
39
+ lhs_receiver = extract_receiver(node.receiver)
40
+ rhs_receiver = extract_receiver(node.first_argument)
43
41
  preferred = "same_line?(#{lhs_receiver}, #{rhs_receiver})"
44
42
 
45
43
  add_offense(node, message: format(MSG, preferred: preferred)) do |corrector|
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module InternalAffairs
6
- # Checks for missing `numblock handlers. The blocks with numbered
6
+ # Checks for missing `numblock` handlers. The blocks with numbered
7
7
  # arguments introduced in Ruby 2.7 are parsed with a node type of
8
8
  # `numblock` instead of block. Cops that define `block` handlers
9
9
  # need to define `numblock` handlers or disable this cope for them.
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # Enforces the use of `node.operator_keyword?` instead of `node.and_type? || node.or_type?`.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # node.and_type? || node.or_type?
11
+ # node.or_type? || node.and_type?
12
+ #
13
+ # # good
14
+ # node.operator_keyword?
15
+ #
16
+ class OperatorKeyword < Base
17
+ extend AutoCorrector
18
+
19
+ MSG = 'Use `%<prefer>s`.'
20
+
21
+ # @!method and_or_type(node)
22
+ def_node_matcher :and_or_type, <<~PATTERN
23
+ {
24
+ (or $(send _node :and_type?) $(send _node :or_type?))
25
+ (or $(send _node :or_type?) $(send _node :and_type?))
26
+ (or
27
+ (or _ $(send _node :and_type?)) $(send _node :or_type?))
28
+ (or
29
+ (or _ $(send _node :or_type?)) $(send _node :and_type?))
30
+ }
31
+ PATTERN
32
+
33
+ def on_or(node)
34
+ return unless (lhs, rhs = and_or_type(node))
35
+
36
+ offense = lhs.receiver.source_range.join(rhs.source_range.end)
37
+ prefer = "#{lhs.receiver.source}.operator_keyword?"
38
+
39
+ add_offense(offense, message: format(MSG, prefer: prefer)) do |corrector|
40
+ corrector.replace(offense, prefer)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -50,8 +50,6 @@ module RuboCop
50
50
  # end
51
51
  #
52
52
  class StyleDetectedApiUse < Base
53
- include RangeHelp
54
-
55
53
  MSG_FOR_POSITIVE_WITHOUT_NEGATIVE =
56
54
  '`correct_style_detected` method called without ' \
57
55
  'calling a negative `*_style_detected` method.'
@@ -17,6 +17,7 @@ require_relative 'internal_affairs/node_matcher_directive'
17
17
  require_relative 'internal_affairs/node_type_predicate'
18
18
  require_relative 'internal_affairs/numblock_handler'
19
19
  require_relative 'internal_affairs/offense_location_keyword'
20
+ require_relative 'internal_affairs/operator_keyword'
20
21
  require_relative 'internal_affairs/processed_source_buffer_name'
21
22
  require_relative 'internal_affairs/redundant_context_config_parameter'
22
23
  require_relative 'internal_affairs/redundant_described_class_as_subject'
@@ -3,8 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # Here we check if the arguments on a multi-line method
7
- # definition are aligned.
6
+ # Check that the arguments on a multi-line method definition are aligned.
8
7
  #
9
8
  # @example EnforcedStyle: with_first_argument (default)
10
9
  # # good
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # Here we check if the elements of a multi-line array literal are
6
+ # Check that the elements of a multi-line array literal are
7
7
  # aligned.
8
8
  #
9
9
  # @example EnforcedStyle: with_first_element (default)
@@ -40,7 +40,6 @@ module RuboCop
40
40
  #
41
41
  class BeginEndAlignment < Base
42
42
  include EndKeywordAlignment
43
- include RangeHelp
44
43
  extend AutoCorrector
45
44
 
46
45
  MSG = '`end` at %d, %d is not aligned with `%s` at %d, %d.'
@@ -127,7 +127,6 @@ module RuboCop
127
127
  start_loc,
128
128
  end_loc,
129
129
  do_source_line_column)
130
-
131
130
  error_source_line_column = if style == :start_of_block
132
131
  do_source_line_column
133
132
  else
@@ -189,7 +188,7 @@ module RuboCop
189
188
  # In offense message, we want to show the assignment LHS rather than
190
189
  # the entire assignment.
191
190
  def find_lhs_node(node)
192
- node, = *node while node.op_asgn_type? || node.masgn_type?
191
+ node = node.lhs while node.op_asgn_type? || node.masgn_type?
193
192
  node
194
193
  end
195
194
 
@@ -200,7 +200,7 @@ module RuboCop
200
200
  parent = node.parent
201
201
  return false unless parent
202
202
 
203
- parent.begin_type? && parent.single_line?
203
+ parent.begin_type? && same_line?(node, node.right_sibling)
204
204
  end
205
205
 
206
206
  # SimpleCov excludes code from the coverage report by wrapping it in `# :nocov:`:
@@ -84,9 +84,8 @@ module RuboCop
84
84
 
85
85
  alias on_numblock on_block
86
86
 
87
- def on_send(node) # rubocop:disable Metrics/CyclomaticComplexity
88
- return unless node.bare_access_modifier? &&
89
- !(node.parent&.block_type? || node.parent&.numblock_type?)
87
+ def on_send(node)
88
+ return unless node.bare_access_modifier? && !node.block_literal?
90
89
  return if expected_empty_lines?(node)
91
90
 
92
91
  message = message(node)
@@ -72,8 +72,7 @@ module RuboCop
72
72
  alias on_numblock on_def
73
73
 
74
74
  def on_kwbegin(node)
75
- body, = *node
76
- check_body(body, node.loc.line)
75
+ check_body(node.children.first, node.loc.line)
77
76
  end
78
77
 
79
78
  private
@@ -128,10 +127,10 @@ module RuboCop
128
127
  end
129
128
 
130
129
  def keyword_locations_in_ensure(node)
131
- ensure_body, = *node
130
+ rescue_body_without_ensure = node.children.first
132
131
  [
133
132
  node.loc.keyword,
134
- *keyword_locations(ensure_body)
133
+ *keyword_locations(rescue_body_without_ensure)
135
134
  ]
136
135
  end
137
136
  end
@@ -27,7 +27,9 @@ module RuboCop
27
27
  KIND = 'method'
28
28
 
29
29
  def on_def(node)
30
- check(node, node.body)
30
+ first_line = node.arguments.source_range&.last_line
31
+
32
+ check(node, node.body, adjusted_first_line: first_line)
31
33
  end
32
34
  alias on_defs on_def
33
35
 
@@ -58,16 +58,17 @@ module RuboCop
58
58
  PATTERN
59
59
 
60
60
  def on_rescue(node)
61
- _begin_node, *_rescue_nodes, else_node = *node
62
- check_indentation(node.loc.else, else_node)
61
+ check_indentation(node.loc.else, node.else_branch)
63
62
  end
64
63
 
65
- def on_ensure(node)
64
+ def on_resbody(node)
66
65
  check_indentation(node.loc.keyword, node.body)
67
66
  end
67
+ alias on_for on_resbody
68
68
 
69
- alias on_resbody on_ensure
70
- alias on_for on_ensure
69
+ def on_ensure(node)
70
+ check_indentation(node.loc.keyword, node.branch)
71
+ end
71
72
 
72
73
  def on_kwbegin(node)
73
74
  # Check indentation against end keyword but only if it's first on its
@@ -325,8 +326,7 @@ module RuboCop
325
326
  if body_node.rescue_type?
326
327
  check_rescue?(body_node)
327
328
  elsif body_node.ensure_type?
328
- block_body, = *body_node
329
-
329
+ block_body, = *body_node # rubocop:disable InternalAffairs/NodeDestructuring
330
330
  if block_body&.rescue_type?
331
331
  check_rescue?(block_body)
332
332
  else
@@ -96,6 +96,7 @@ module RuboCop
96
96
  processed_source.comments.each do |comment|
97
97
  next unless /\A(?!#\+\+|#--)(#+[^#\s=])/.match?(comment.text)
98
98
  next if comment.loc.line == 1 && allowed_on_first_line?(comment)
99
+ next if shebang_continuation?(comment)
99
100
  next if doxygen_comment_style?(comment)
100
101
  next if gemfile_ruby_comment?(comment)
101
102
  next if rbs_inline_annotation?(comment)
@@ -123,6 +124,20 @@ module RuboCop
123
124
  comment.text.start_with?('#!')
124
125
  end
125
126
 
127
+ def shebang_continuation?(comment)
128
+ return false unless shebang?(comment)
129
+ return true if comment.loc.line == 1
130
+
131
+ previous_line_comment = processed_source.comment_at_line(comment.loc.line - 1)
132
+ return false unless previous_line_comment
133
+
134
+ # If the comment is a shebang but not on the first line, check if the previous
135
+ # line has a shebang comment that wasn't marked as an offense; if so, this comment
136
+ # continues the shebang and is acceptable.
137
+ shebang?(previous_line_comment) &&
138
+ !current_offense_locations.include?(previous_line_comment.source_range)
139
+ end
140
+
126
141
  def rackup_options?(comment)
127
142
  comment.text.start_with?('#\\')
128
143
  end
@@ -38,7 +38,7 @@ module RuboCop
38
38
  # * `Layout/MultilineHashKeyLineBreaks`
39
39
  # * `Layout/MultilineMethodArgumentLineBreaks`
40
40
  # * `Layout/MultilineMethodParameterLineBreaks`
41
- # * `Layout//ParameterAlignment`
41
+ # * `Layout/ParameterAlignment`
42
42
  # * `Style/BlockDelimiters`
43
43
  #
44
44
  # Together, these cops will pretty print hashes, arrays,
@@ -60,7 +60,7 @@ module RuboCop
60
60
  # bar: "0000000000",
61
61
  # baz: "0000000000",
62
62
  # }
63
- class LineLength < Base
63
+ class LineLength < Base # rubocop:disable Metrics/ClassLength
64
64
  include CheckLineBreakable
65
65
  include AllowedPattern
66
66
  include RangeHelp
@@ -74,9 +74,16 @@ module RuboCop
74
74
  def on_block(node)
75
75
  check_for_breakable_block(node)
76
76
  end
77
-
78
77
  alias on_numblock on_block
79
78
 
79
+ def on_str(node)
80
+ check_for_breakable_str(node)
81
+ end
82
+
83
+ def on_dstr(node)
84
+ check_for_breakable_dstr(node)
85
+ end
86
+
80
87
  def on_potential_breakable_node(node)
81
88
  check_for_breakable_node(node)
82
89
  end
@@ -132,6 +139,42 @@ module RuboCop
132
139
  breakable_range_by_line_index[line_index] = range_between(pos, pos + 1)
133
140
  end
134
141
 
142
+ def check_for_breakable_str(node)
143
+ line_index = node.loc.line - 1
144
+ return if breakable_range_by_line_index[line_index]
145
+
146
+ return unless breakable_string?(node)
147
+ return unless (delimiter = string_delimiter(node))
148
+ return unless (pos = breakable_string_position(node))
149
+
150
+ breakable_range_by_line_index[line_index] = range_between(pos, pos + 1)
151
+ breakable_string_delimiters[line_index] = delimiter
152
+ end
153
+
154
+ def check_for_breakable_dstr(node) # rubocop:disable Metrics/AbcSize
155
+ line_index = node.loc.line - 1
156
+ return if breakable_range_by_line_index[line_index]
157
+
158
+ return unless breakable_dstr?(node)
159
+ return unless (delimiter = string_delimiter(node))
160
+
161
+ node.each_child_node(:begin).detect do |begin_node|
162
+ next unless (pos = breakable_dstr_begin_position(begin_node))
163
+
164
+ breakable_range_by_line_index[line_index] = range_between(pos, pos + 1)
165
+ breakable_string_delimiters[line_index] = delimiter
166
+ end
167
+ end
168
+
169
+ def breakable_string?(node)
170
+ allow_string_split? &&
171
+ node.single_line? &&
172
+ !node.heredoc? &&
173
+ # TODO: strings inside hashes, kwargs and arrays are currently ignored,
174
+ # but could be considered in the future
175
+ !node.parent&.type?(:pair, :kwoptarg, :array)
176
+ end
177
+
135
178
  def breakable_block_range(block_node)
136
179
  if block_node.arguments? && !block_node.lambda?
137
180
  block_node.arguments.loc.end
@@ -153,10 +196,47 @@ module RuboCop
153
196
  next_range
154
197
  end
155
198
 
199
+ def breakable_string_position(node)
200
+ source_range = node.source_range
201
+ return if source_range.last_column < max
202
+ return unless (pos = breakable_string_range(node))
203
+
204
+ pos.end_pos unless pos.end_pos == source_range.begin_pos
205
+ end
206
+
207
+ # Locate where to break a string that is too long, ensuring that escape characters
208
+ # are not bisected.
209
+ # If the string contains spaces, use them to determine a place for a clean break;
210
+ # otherwise, the string will be broken at the line length limit.
211
+ def breakable_string_range(node) # rubocop:disable Metrics/AbcSize
212
+ source_range = node.source_range
213
+ relevant_substr = largest_possible_string(node)
214
+
215
+ if (space_pos = relevant_substr.rindex(/\s/))
216
+ source_range.resize(space_pos + 1)
217
+ elsif (escape_pos = relevant_substr.rindex(/\\(u[\da-f]{0,4}|x[\da-f]{0,2})?\z/))
218
+ source_range.resize(escape_pos)
219
+ else
220
+ adjustment = max - source_range.last_column - 3
221
+ return if adjustment.abs > source_range.size
222
+
223
+ source_range.adjust(end_pos: max - source_range.last_column - 3)
224
+ end
225
+ end
226
+
227
+ def breakable_dstr_begin_position(node)
228
+ source_range = node.source_range
229
+ source_range.begin_pos if source_range.begin_pos < max && source_range.end_pos >= max
230
+ end
231
+
156
232
  def breakable_range_by_line_index
157
233
  @breakable_range_by_line_index ||= {}
158
234
  end
159
235
 
236
+ def breakable_string_delimiters
237
+ @breakable_string_delimiters ||= {}
238
+ end
239
+
160
240
  def heredocs
161
241
  @heredocs ||= extract_heredocs(processed_source.ast)
162
242
  end
@@ -197,7 +277,14 @@ module RuboCop
197
277
 
198
278
  add_offense(loc, message: message) do |corrector|
199
279
  self.max = line_length(line)
200
- corrector.insert_before(breakable_range, "\n") unless breakable_range.nil?
280
+
281
+ insertion = if (delimiter = breakable_string_delimiters[line_index])
282
+ [delimiter, " \\\n", delimiter].join
283
+ else
284
+ "\n"
285
+ end
286
+
287
+ corrector.insert_before(breakable_range, insertion) unless breakable_range.nil?
201
288
  end
202
289
  end
203
290
 
@@ -224,6 +311,10 @@ module RuboCop
224
311
  cop_config['AllowHeredoc']
225
312
  end
226
313
 
314
+ def allow_string_split?
315
+ cop_config['SplitStrings']
316
+ end
317
+
227
318
  def extract_heredocs(ast)
228
319
  return [] unless ast
229
320
 
@@ -270,6 +361,29 @@ module RuboCop
270
361
 
271
362
  register_offense(excess_range(uri_range, line, line_index), line, line_index)
272
363
  end
364
+
365
+ def breakable_dstr?(node)
366
+ # If the `dstr` only contains one child, it cannot be broken
367
+ breakable_string?(node) && !node.child_nodes.one?
368
+ end
369
+
370
+ def string_delimiter(node)
371
+ delimiter = node.loc.begin
372
+ delimiter ||= node.parent.loc.begin if node.parent&.dstr_type?
373
+ delimiter = delimiter&.source
374
+
375
+ delimiter if %w[' "].include?(delimiter)
376
+ end
377
+
378
+ # Find the largest possible substring of a string node to retain before a break
379
+ def largest_possible_string(node)
380
+ # The maximum allowed length of a string value is:
381
+ # `Max` - end delimiter (quote) - continuation characters (space and slash)
382
+ max_length = max - 3
383
+ # If the string doesn't start at the beginning of the line, the max length is offset
384
+ max_length -= column_offset_between(node.loc, node.parent.loc) if node.parent
385
+ node.source[0...(max_length)]
386
+ end
273
387
  end
274
388
  end
275
389
  end
@@ -12,7 +12,7 @@ module RuboCop
12
12
  # argument of the call, then the closing brace should be on the same
13
13
  # line as the last argument of the call.
14
14
  #
15
- # If an method call's opening brace is on the line above the first
15
+ # If a method call's opening brace is on the line above the first
16
16
  # argument of the call, then the closing brace should be on the line
17
17
  # below the last argument of the call.
18
18
  #