rubocop 1.44.1 → 1.45.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +16 -31
  4. data/lib/rubocop/cli.rb +54 -8
  5. data/lib/rubocop/config_loader_resolver.rb +3 -4
  6. data/lib/rubocop/cop/base.rb +27 -9
  7. data/lib/rubocop/cop/commissioner.rb +8 -2
  8. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  9. data/lib/rubocop/cop/layout/class_structure.rb +2 -16
  10. data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -1
  11. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  12. data/lib/rubocop/cop/layout/space_around_operators.rb +1 -1
  13. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -11
  14. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +4 -4
  15. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +5 -4
  16. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +4 -1
  17. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  18. data/lib/rubocop/cop/lint/nested_method_definition.rb +8 -5
  19. data/lib/rubocop/cop/lint/useless_access_modifier.rb +7 -4
  20. data/lib/rubocop/cop/metrics/block_length.rb +1 -1
  21. data/lib/rubocop/cop/mixin/allowed_methods.rb +3 -1
  22. data/lib/rubocop/cop/mixin/comments_help.rb +5 -3
  23. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +13 -9
  24. data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -3
  25. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
  26. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +1 -1
  27. data/lib/rubocop/cop/style/access_modifier_declarations.rb +8 -1
  28. data/lib/rubocop/cop/style/arguments_forwarding.rb +1 -0
  29. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  30. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  31. data/lib/rubocop/cop/style/documentation.rb +1 -1
  32. data/lib/rubocop/cop/style/documentation_method.rb +6 -0
  33. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +18 -3
  34. data/lib/rubocop/cop/style/numbered_parameters_limit.rb +11 -3
  35. data/lib/rubocop/cop/style/operator_method_call.rb +1 -1
  36. data/lib/rubocop/cop/style/redundant_condition.rb +16 -1
  37. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +58 -0
  38. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  39. data/lib/rubocop/cop/style/word_array.rb +1 -1
  40. data/lib/rubocop/cop/style/yoda_condition.rb +12 -5
  41. data/lib/rubocop/cop/style/yoda_expression.rb +11 -2
  42. data/lib/rubocop/cop/team.rb +19 -14
  43. data/lib/rubocop/cop/variable_force/scope.rb +3 -3
  44. data/lib/rubocop/options.rb +22 -1
  45. data/lib/rubocop/runner.rb +40 -4
  46. data/lib/rubocop/server/cache.rb +7 -2
  47. data/lib/rubocop/server/cli.rb +37 -18
  48. data/lib/rubocop/server/client_command/exec.rb +1 -1
  49. data/lib/rubocop/server/client_command/start.rb +6 -1
  50. data/lib/rubocop/server/core.rb +23 -8
  51. data/lib/rubocop/version.rb +1 -1
  52. data/lib/rubocop.rb +1 -0
  53. metadata +8 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f6f58220d287e215fa9baaa9c274e89b128c0e42222595caa432132d27de274
4
- data.tar.gz: e3c547bef6b2803f80ba22013eae4cff56f6fb572aca19a886bb2fb52e8ba665
3
+ metadata.gz: b48bdf3e1c316571a4bd94150d56645a13044379b9932ebe8d21884b47b99113
4
+ data.tar.gz: 4bef483df24d39dd57877145a67ff68485b9b0d02b2e865a0cb9941c3ad7fc62
5
5
  SHA512:
6
- metadata.gz: f9d29df635f00839a5da2cee59c55d4a279129529e3f0b130b7ad8602058fa11e733562a8e253dfa03b45e716c406e425d6c1f28fbd5a4a0b06436404058aa91
7
- data.tar.gz: 4a80236cfa9402004dddf72346b395e944840da07525658de1a42ce5bbef7a030be86c38af798e6cf977b75b2c6153ecd7f33b9d91ab3cec1d631b68d21a4568
6
+ metadata.gz: 1628b1533fe7595ede88b51fbd581a04278d549cf21065e9d78534ee47cdffa23fda8709f48711b476879ab36b06d3ffec449a1f391378faaf676b5fe0ef4e7f
7
+ data.tar.gz: fcdba51766cf768940c9ebb770b8b8a40ed44384c00ba0ef8c8a903c0848816320fe53d0791da133ba607f8ab79fc36a68eaf833fdfdb5b0d179ff0ee9a0afc5
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.44', require: false
56
+ gem 'rubocop', '~> 1.45', require: false
57
57
  ```
58
58
 
59
59
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
data/config/default.yml CHANGED
@@ -271,8 +271,7 @@ Gemspec/DevelopmentDependencies:
271
271
  - Gemfile
272
272
  - gems.rb
273
273
  - gemspec
274
- AllowedGems:
275
- - bundler
274
+ AllowedGems: []
276
275
  Include:
277
276
  - '**/*.gemspec'
278
277
  - '**/Gemfile'
@@ -407,9 +406,8 @@ Layout/AssignmentIndentation:
407
406
  Checks the indentation of the first line of the
408
407
  right-hand-side of a multi-line assignment.
409
408
  Enabled: true
410
- SafeAutoCorrect: false
411
409
  VersionAdded: '0.49'
412
- VersionChanged: '1.40'
410
+ VersionChanged: '1.45'
413
411
  # By default the indentation width from `Layout/IndentationWidth` is used,
414
412
  # but it can be overridden by setting this parameter.
415
413
  IndentationWidth: ~
@@ -980,7 +978,6 @@ Layout/IndentationWidth:
980
978
  # Number of spaces for each indentation level.
981
979
  Width: 2
982
980
  AllowedPatterns: []
983
- IgnoredPatterns: [] # deprecated
984
981
 
985
982
  Layout/InitialIndentation:
986
983
  Description: >-
@@ -1008,10 +1005,8 @@ Layout/LineContinuationLeadingSpace:
1008
1005
  Use trailing spaces instead of leading spaces in strings
1009
1006
  broken over multiple lines (by a backslash).
1010
1007
  Enabled: pending
1011
- AutoCorrect: false
1012
- SafeAutoCorrect: false
1013
1008
  VersionAdded: '1.31'
1014
- VersionChanged: '1.32'
1009
+ VersionChanged: '1.45'
1015
1010
  EnforcedStyle: trailing
1016
1011
  SupportedStyles:
1017
1012
  - leading
@@ -1063,7 +1058,6 @@ Layout/LineLength:
1063
1058
  # elements. Strings will be converted to Regexp objects. A line that matches
1064
1059
  # any regular expression listed in this option will be ignored by LineLength.
1065
1060
  AllowedPatterns: []
1066
- IgnoredPatterns: [] # deprecated
1067
1061
 
1068
1062
  Layout/MultilineArrayBraceLayout:
1069
1063
  Description: >-
@@ -1542,7 +1536,6 @@ Lint/AmbiguousBlockAssociation:
1542
1536
  VersionChanged: '1.13'
1543
1537
  AllowedMethods: []
1544
1538
  AllowedPatterns: []
1545
- IgnoredMethods: [] # deprecated
1546
1539
 
1547
1540
  Lint/AmbiguousOperator:
1548
1541
  Description: >-
@@ -1579,7 +1572,9 @@ Lint/AssignmentInCondition:
1579
1572
  Description: "Don't use assignment in conditions."
1580
1573
  StyleGuide: '#safe-assignment-in-condition'
1581
1574
  Enabled: true
1575
+ SafeAutoCorrect: false
1582
1576
  VersionAdded: '0.9'
1577
+ VersionChanged: '1.45'
1583
1578
  AllowSafeAssignment: true
1584
1579
 
1585
1580
  Lint/BigDecimalNew:
@@ -1636,12 +1631,12 @@ Lint/Debugger:
1636
1631
  Enabled: true
1637
1632
  VersionAdded: '0.14'
1638
1633
  VersionChanged: '1.10'
1639
- DebuggerReceivers: [] # deprecated
1640
1634
  DebuggerMethods:
1641
1635
  # Groups are available so that a specific group can be disabled in
1642
1636
  # a user's configuration, but are otherwise not significant.
1643
1637
  Kernel:
1644
1638
  - binding.irb
1639
+ - p
1645
1640
  - Kernel.binding.irb
1646
1641
  Byebug:
1647
1642
  - byebug
@@ -1651,6 +1646,9 @@ Lint/Debugger:
1651
1646
  Capybara:
1652
1647
  - save_and_open_page
1653
1648
  - save_and_open_screenshot
1649
+ PP:
1650
+ - PP.pp
1651
+ - pp
1654
1652
  debug.rb:
1655
1653
  - binding.b
1656
1654
  - binding.break
@@ -2053,7 +2051,6 @@ Lint/NumberConversion:
2053
2051
  SafeAutoCorrect: false
2054
2052
  AllowedMethods: []
2055
2053
  AllowedPatterns: []
2056
- IgnoredMethods: [] # deprecated
2057
2054
  IgnoredClasses:
2058
2055
  - Time
2059
2056
  - DateTime
@@ -2404,7 +2401,6 @@ Lint/UnreachableLoop:
2404
2401
  # RSpec uses `times` in its message expectations
2405
2402
  # eg. `exactly(2).times`
2406
2403
  - !ruby/regexp /(exactly|at_least|at_most)\(\d+\)\.times/
2407
- IgnoredPatterns: [] # deprecated
2408
2404
 
2409
2405
  Lint/UnusedBlockArgument:
2410
2406
  Description: 'Checks for unused block arguments.'
@@ -2514,7 +2510,6 @@ Metrics/AbcSize:
2514
2510
  # a Float.
2515
2511
  AllowedMethods: []
2516
2512
  AllowedPatterns: []
2517
- IgnoredMethods: [] # deprecated
2518
2513
  CountRepeatedAttributes: true
2519
2514
  Max: 17
2520
2515
 
@@ -2526,13 +2521,11 @@ Metrics/BlockLength:
2526
2521
  CountComments: false # count full line comments?
2527
2522
  Max: 25
2528
2523
  CountAsOne: []
2529
- ExcludedMethods: [] # deprecated, retained for backwards compatibility
2530
2524
  AllowedMethods:
2531
2525
  # By default, exclude the `#refine` method, as it tends to have larger
2532
2526
  # associated blocks.
2533
2527
  - refine
2534
2528
  AllowedPatterns: []
2535
- IgnoredMethods: [] # deprecated
2536
2529
  Exclude:
2537
2530
  - '**/*.gemspec'
2538
2531
 
@@ -2564,7 +2557,6 @@ Metrics/CyclomaticComplexity:
2564
2557
  VersionChanged: '0.81'
2565
2558
  AllowedMethods: []
2566
2559
  AllowedPatterns: []
2567
- IgnoredMethods: [] # deprecated
2568
2560
  Max: 7
2569
2561
 
2570
2562
  Metrics/MethodLength:
@@ -2576,10 +2568,8 @@ Metrics/MethodLength:
2576
2568
  CountComments: false # count full line comments?
2577
2569
  Max: 10
2578
2570
  CountAsOne: []
2579
- ExcludedMethods: [] # deprecated, retained for backwards compatibility
2580
2571
  AllowedMethods: []
2581
2572
  AllowedPatterns: []
2582
- IgnoredMethods: [] # deprecated
2583
2573
 
2584
2574
  Metrics/ModuleLength:
2585
2575
  Description: 'Avoid modules longer than 100 lines of code.'
@@ -2609,7 +2599,6 @@ Metrics/PerceivedComplexity:
2609
2599
  VersionChanged: '0.81'
2610
2600
  AllowedMethods: []
2611
2601
  AllowedPatterns: []
2612
- IgnoredMethods: [] # deprecated
2613
2602
  Max: 8
2614
2603
 
2615
2604
  ################## Migration #############################
@@ -2780,7 +2769,7 @@ Naming/HeredocDelimiterNaming:
2780
2769
  Enabled: true
2781
2770
  VersionAdded: '0.50'
2782
2771
  ForbiddenDelimiters:
2783
- - !ruby/regexp '/(^|\s)(EO[A-Z]{1}|END)(\s|$)/'
2772
+ - !ruby/regexp '/(^|\s)(EO[A-Z]{1}|END)(\s|$)/i'
2784
2773
 
2785
2774
  Naming/InclusiveLanguage:
2786
2775
  Description: 'Recommend the use of inclusive language instead of problematic terms.'
@@ -2838,7 +2827,6 @@ Naming/MethodName:
2838
2827
  # - '\A\s*onSelectionCleared\s*'
2839
2828
  #
2840
2829
  AllowedPatterns: []
2841
- IgnoredPatterns: [] # deprecated
2842
2830
 
2843
2831
  Naming/MethodParameterName:
2844
2832
  Description: >-
@@ -3208,7 +3196,6 @@ Style/BlockDelimiters:
3208
3196
  - proc
3209
3197
  - it
3210
3198
  AllowedPatterns: []
3211
- IgnoredMethods: [] # deprecated
3212
3199
  # The AllowBracesOnProceduralOneLiners option is ignored unless the
3213
3200
  # EnforcedStyle is set to `semantic`. If so:
3214
3201
  #
@@ -3232,7 +3219,7 @@ Style/BlockDelimiters:
3232
3219
  # collection.each do |element| puts element end
3233
3220
  AllowBracesOnProceduralOneLiners: false
3234
3221
  # The BracesRequiredMethods overrides all other configurations except
3235
- # IgnoredMethods. It can be used to enforce that all blocks for specific
3222
+ # AllowedMethods. It can be used to enforce that all blocks for specific
3236
3223
  # methods use braces. For example, you can use this to enforce Sorbet
3237
3224
  # signatures use braces even when the rest of your codebase enforces
3238
3225
  # the `line_count_based` style.
@@ -3326,7 +3313,6 @@ Style/ClassEqualityComparison:
3326
3313
  - equal?
3327
3314
  - eql?
3328
3315
  AllowedPatterns: []
3329
- IgnoredMethods: [] # deprecated
3330
3316
 
3331
3317
  Style/ClassMethods:
3332
3318
  Description: 'Use self when defining module/class methods.'
@@ -3801,7 +3787,6 @@ Style/FormatStringToken:
3801
3787
  VersionChanged: '1.0'
3802
3788
  AllowedMethods: []
3803
3789
  AllowedPatterns: []
3804
- IgnoredMethods: [] # deprecated
3805
3790
 
3806
3791
  Style/FrozenStringLiteralComment:
3807
3792
  Description: >-
@@ -4180,9 +4165,7 @@ Style/MethodCallWithArgsParentheses:
4180
4165
  VersionChanged: '1.7'
4181
4166
  IgnoreMacros: true
4182
4167
  AllowedMethods: []
4183
- IgnoredMethods: [] # deprecated
4184
4168
  AllowedPatterns: []
4185
- IgnoredPatterns: [] # deprecated
4186
4169
  IncludedMacros: []
4187
4170
  AllowParenthesesInMultilineCall: false
4188
4171
  AllowParenthesesInChaining: false
@@ -4199,7 +4182,6 @@ Style/MethodCallWithoutArgsParentheses:
4199
4182
  Enabled: true
4200
4183
  AllowedMethods: []
4201
4184
  AllowedPatterns: []
4202
- IgnoredMethods: [] # deprecated
4203
4185
  VersionAdded: '0.47'
4204
4186
  VersionChanged: '0.55'
4205
4187
 
@@ -4578,7 +4560,6 @@ Style/NumericPredicate:
4578
4560
  - comparison
4579
4561
  AllowedMethods: []
4580
4562
  AllowedPatterns: []
4581
- IgnoredMethods: [] # deprecated
4582
4563
  # Exclude RSpec specs because assertions like `expect(1).to be > 0` cause
4583
4564
  # false positives.
4584
4565
  Exclude:
@@ -4858,6 +4839,11 @@ Style/RedundantFreeze:
4858
4839
  VersionAdded: '0.34'
4859
4840
  VersionChanged: '0.66'
4860
4841
 
4842
+ Style/RedundantHeredocDelimiterQuotes:
4843
+ Description: 'Checks for redundant heredoc delimiter quotes.'
4844
+ Enabled: pending
4845
+ VersionAdded: '1.45'
4846
+
4861
4847
  Style/RedundantInitialize:
4862
4848
  Description: 'Checks for redundant `initialize` methods.'
4863
4849
  Enabled: pending
@@ -5255,7 +5241,6 @@ Style/SymbolProc:
5255
5241
  AllowedMethods:
5256
5242
  - define_method
5257
5243
  AllowedPatterns: []
5258
- IgnoredMethods: [] # deprecated
5259
5244
  AllowComments: false
5260
5245
 
5261
5246
  Style/TernaryParentheses:
data/lib/rubocop/cli.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'fileutils'
4
+
3
5
  module RuboCop
4
6
  # The CLI is a class responsible of handling all the command line interface
5
7
  # logic.
@@ -38,14 +40,16 @@ module RuboCop
38
40
  @options, paths = Options.new.parse(args)
39
41
  @env = Environment.new(@options, @config_store, paths)
40
42
 
41
- if @options[:init]
42
- run_command(:init)
43
- else
44
- act_on_options
45
- validate_options_vs_config
46
- parallel_by_default!
47
- apply_default_formatter
48
- execute_runners
43
+ profile_if_needed do
44
+ if @options[:init]
45
+ run_command(:init)
46
+ else
47
+ act_on_options
48
+ validate_options_vs_config
49
+ parallel_by_default!
50
+ apply_default_formatter
51
+ execute_runners
52
+ end
49
53
  end
50
54
  rescue ConfigNotFoundError, IncorrectCopNameError, OptionArgumentError => e
51
55
  warn e.message
@@ -68,6 +72,48 @@ module RuboCop
68
72
 
69
73
  private
70
74
 
75
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
76
+ def profile_if_needed
77
+ return yield unless @options[:profile]
78
+
79
+ return STATUS_ERROR unless require_gem('stackprof')
80
+
81
+ with_memory = @options[:memory]
82
+ if with_memory
83
+ return STATUS_ERROR unless require_gem('memory_profiler')
84
+
85
+ MemoryProfiler.start
86
+ end
87
+
88
+ tmp_dir = File.join(ConfigFinder.project_root, 'tmp')
89
+ FileUtils.mkdir_p(tmp_dir)
90
+ status = nil
91
+
92
+ StackProf.run(out: File.join(tmp_dir, 'rubocop-stackprof.dump')) do
93
+ status = yield
94
+ end
95
+ puts 'Profile report generated'
96
+
97
+ if with_memory
98
+ puts 'Building memory report...'
99
+ report = MemoryProfiler.stop
100
+ report.pretty_print(
101
+ to_file: File.join(tmp_dir, 'rubocop-memory_profiler.txt'),
102
+ scale_bytes: true
103
+ )
104
+ end
105
+ status
106
+ end
107
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
108
+
109
+ def require_gem(name)
110
+ require name
111
+ true
112
+ rescue LoadError
113
+ warn("You don't have #{name} installed. Add it to your Gemfile and run `bundle install`")
114
+ false
115
+ end
116
+
71
117
  def run_command(name)
72
118
  @env.run(name)
73
119
  end
@@ -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, path, k, v) if v.key?('Include')
36
+ fix_include_paths(base_config.loaded_path, hash, k, v) if v.key?('Include')
37
37
  end
38
38
  end
39
39
  end
@@ -42,13 +42,12 @@ 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, path, key, value)
45
+ def fix_include_paths(base_config_path, hash, 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)
50
49
  hash[key]['Include'] = value['Include'].map do |include_path|
51
- PathUtil.relative_path(File.join(base_dir, include_path), derived_dir)
50
+ PathUtil.relative_path(File.join(base_dir, include_path), Dir.pwd)
52
51
  end
53
52
  end
54
53
 
@@ -180,6 +180,10 @@ module RuboCop
180
180
 
181
181
  status, corrector = enabled_line?(range.line) ? correct(range, &block) : :disabled
182
182
 
183
+ # Since this range may be generated from Ruby code embedded in some
184
+ # template file, we convert it to location info in the original file.
185
+ range = range_for_original(range)
186
+
183
187
  current_offenses << Offense.new(severity, range, message, name, status, corrector)
184
188
  end
185
189
 
@@ -286,6 +290,21 @@ module RuboCop
286
290
  end
287
291
  # rubocop:enable Layout/ClassStructure
288
292
 
293
+ # Called before any investigation
294
+ # @api private
295
+ def begin_investigation(processed_source, offset: 0, original: processed_source)
296
+ @current_offenses = nil
297
+ @current_offense_locations = nil
298
+ @currently_disabled_lines = nil
299
+ @processed_source = processed_source
300
+ @current_corrector = nil
301
+
302
+ # We need to keep track of the original source and offset,
303
+ # because `processed_source` here may be an embedded code in it.
304
+ @current_offset = offset
305
+ @current_original = original
306
+ end
307
+
289
308
  private
290
309
 
291
310
  ### Reserved for Cop::Cop
@@ -320,15 +339,6 @@ module RuboCop
320
339
  @restrict_on_send ||= self::RESTRICT_ON_SEND.to_a.freeze
321
340
  end
322
341
 
323
- # Called before any investigation
324
- def begin_investigation(processed_source)
325
- @current_offenses = nil
326
- @current_offense_locations = nil
327
- @currently_disabled_lines = nil
328
- @processed_source = processed_source
329
- @current_corrector = nil
330
- end
331
-
332
342
  EMPTY_OFFENSES = [].freeze
333
343
  private_constant :EMPTY_OFFENSES
334
344
  # Called to complete an investigation
@@ -459,6 +469,14 @@ module RuboCop
459
469
  warn(Rainbow(message).red)
460
470
  end
461
471
  end
472
+
473
+ def range_for_original(range)
474
+ ::Parser::Source::Range.new(
475
+ @current_original.buffer,
476
+ range.begin_pos + @current_offset,
477
+ range.end_pos + @current_offset
478
+ )
479
+ end
462
480
  end
463
481
  end
464
482
  end
@@ -76,10 +76,10 @@ module RuboCop
76
76
  end
77
77
 
78
78
  # @return [InvestigationReport]
79
- def investigate(processed_source)
79
+ def investigate(processed_source, offset: 0, original: processed_source)
80
80
  reset
81
81
 
82
- @cops.each { |cop| cop.send :begin_investigation, processed_source }
82
+ begin_investigation(processed_source, offset: offset, original: original)
83
83
  if processed_source.valid_syntax?
84
84
  invoke(:on_new_investigation, @cops)
85
85
  invoke_with_argument(:investigate, @forces, processed_source)
@@ -95,6 +95,12 @@ module RuboCop
95
95
 
96
96
  private
97
97
 
98
+ def begin_investigation(processed_source, offset:, original:)
99
+ @cops.each do |cop|
100
+ cop.begin_investigation(processed_source, offset: offset, original: original)
101
+ end
102
+ end
103
+
98
104
  def trigger_responding_cops(callback, node)
99
105
  @callbacks[callback]&.each do |cop|
100
106
  with_cop_error_handling(cop, node) do
@@ -76,7 +76,7 @@ module RuboCop
76
76
  end
77
77
 
78
78
  def target_method_lineno(node)
79
- node.loc.line
79
+ node.bracketed? ? node.loc.line : node.parent.loc.line
80
80
  end
81
81
  end
82
82
  end
@@ -134,6 +134,7 @@ module RuboCop
134
134
  #
135
135
  class ClassStructure < Base
136
136
  include VisibilityHelp
137
+ include CommentsHelp
137
138
  extend AutoCorrector
138
139
 
139
140
  HUMANIZED_NODE_TYPE = {
@@ -163,7 +164,7 @@ module RuboCop
163
164
 
164
165
  # Autocorrect by swapping between two nodes autocorrecting them
165
166
  def autocorrect(corrector, node)
166
- previous = node.left_siblings.find do |sibling|
167
+ previous = node.left_siblings.reverse.find do |sibling|
167
168
  !ignore_for_autocorrect?(node, sibling)
168
169
  end
169
170
  return unless previous
@@ -283,21 +284,6 @@ module RuboCop
283
284
  node.arguments.any? { |arg| (arg.sym_type? || arg.str_type?) && arg.value == name }
284
285
  end
285
286
 
286
- def source_range_with_comment(node)
287
- begin_pos, end_pos =
288
- if (node.def_type? && !node.method?(:initialize)) ||
289
- (node.send_type? && node.def_modifier?)
290
- start_node = find_visibility_start(node) || node
291
- end_node = find_visibility_end(node) || node
292
- [begin_pos_with_comment(start_node),
293
- end_position_for(end_node) + 1]
294
- else
295
- [begin_pos_with_comment(node), end_position_for(node)]
296
- end
297
-
298
- Parser::Source::Range.new(buffer, begin_pos, end_pos)
299
- end
300
-
301
287
  def end_position_for(node)
302
288
  heredoc = find_heredoc(node)
303
289
  return heredoc.location.heredoc_end.end_pos + 1 if heredoc
@@ -179,7 +179,7 @@ module RuboCop
179
179
 
180
180
  send_node = arg_node.parent
181
181
  text = base_range(send_node, arg_node).source.strip
182
- base = if !/\n/.match?(text) && special_inner_call_indentation?(send_node)
182
+ base = if !text.include?("\n") && special_inner_call_indentation?(send_node)
183
183
  "`#{text}`"
184
184
  elsif comment_line?(text.lines.reverse_each.first)
185
185
  'the start of the previous line (not counting the comment)'
@@ -241,7 +241,7 @@ module RuboCop
241
241
  end
242
242
 
243
243
  def accept_namespace_operator?(range)
244
- ACCEPT_NAMESPACE_OPERATOR == range.source
244
+ range.source == ACCEPT_NAMESPACE_OPERATOR
245
245
  end
246
246
 
247
247
  def safe_navigation_call?(range, pos)
@@ -177,7 +177,7 @@ module RuboCop
177
177
  end
178
178
 
179
179
  def autocorrect(corrector, range)
180
- if /\*\*/.match?(range.source) && !space_around_exponent_operator?
180
+ if range.source.include?('**') && !space_around_exponent_operator?
181
181
  corrector.replace(range, '**')
182
182
  elsif range.source.end_with?("\n")
183
183
  corrector.replace(range, " #{range.source.strip}\n")
@@ -78,8 +78,11 @@ module RuboCop
78
78
  def on_array(node)
79
79
  return unless node.square_brackets?
80
80
 
81
- left, right = array_brackets(node)
82
- return empty_offenses(node, left, right, EMPTY_MSG) if empty_brackets?(left, right)
81
+ tokens, left, right = array_brackets(node)
82
+
83
+ if empty_brackets?(left, right, tokens: tokens)
84
+ return empty_offenses(node, left, right, EMPTY_MSG)
85
+ end
83
86
 
84
87
  start_ok = next_to_newline?(node, left)
85
88
  end_ok = node.single_line? ? false : end_has_own_line?(right)
@@ -90,9 +93,9 @@ module RuboCop
90
93
  private
91
94
 
92
95
  def autocorrect(corrector, node)
93
- left, right = array_brackets(node)
96
+ tokens, left, right = array_brackets(node)
94
97
 
95
- if empty_brackets?(left, right)
98
+ if empty_brackets?(left, right, tokens: tokens)
96
99
  SpaceCorrector.empty_corrections(processed_source, corrector, empty_config, left, right)
97
100
  elsif style == :no_space
98
101
  SpaceCorrector.remove_space(processed_source, corrector, left, right)
@@ -104,15 +107,12 @@ module RuboCop
104
107
  end
105
108
 
106
109
  def array_brackets(node)
107
- [left_array_bracket(node), right_array_bracket(node)]
108
- end
110
+ tokens = processed_source.tokens_within(node)
109
111
 
110
- def left_array_bracket(node)
111
- processed_source.tokens_within(node).find(&:left_array_bracket?)
112
- end
112
+ left = tokens.find(&:left_array_bracket?)
113
+ right = tokens.reverse_each.find(&:right_bracket?)
113
114
 
114
- def right_array_bracket(node)
115
- processed_source.tokens_within(node).reverse.find(&:right_bracket?)
115
+ [tokens, left, right]
116
116
  end
117
117
 
118
118
  def empty_config
@@ -74,7 +74,7 @@ module RuboCop
74
74
 
75
75
  right_token = closing_bracket(tokens, left_token)
76
76
 
77
- if empty_brackets?(left_token, right_token)
77
+ if empty_brackets?(left_token, right_token, tokens: tokens)
78
78
  return empty_offenses(node, left_token, right_token, EMPTY_MSG)
79
79
  end
80
80
 
@@ -90,9 +90,9 @@ module RuboCop
90
90
  private
91
91
 
92
92
  def autocorrect(corrector, node)
93
- left, right = reference_brackets(node)
93
+ tokens, left, right = reference_brackets(node)
94
94
 
95
- if empty_brackets?(left, right)
95
+ if empty_brackets?(left, right, tokens: tokens)
96
96
  SpaceCorrector.empty_corrections(processed_source, corrector, empty_config, left, right)
97
97
  elsif style == :no_space
98
98
  SpaceCorrector.remove_space(processed_source, corrector, left, right)
@@ -104,7 +104,7 @@ module RuboCop
104
104
  def reference_brackets(node)
105
105
  tokens = processed_source.tokens_within(node)
106
106
  left = left_ref_bracket(node, tokens)
107
- [left, closing_bracket(tokens, left)]
107
+ [tokens, left, closing_bracket(tokens, left)]
108
108
  end
109
109
 
110
110
  def left_ref_bracket(node, tokens)
@@ -31,13 +31,14 @@ module RuboCop
31
31
  def on_interpolation(begin_node)
32
32
  return if begin_node.multiline?
33
33
 
34
- delims = delimiters(begin_node)
35
- return if empty_brackets?(*delims)
34
+ tokens = processed_source.tokens_within(begin_node)
35
+ left, right = delimiters(begin_node)
36
+ return if empty_brackets?(left, right, tokens: tokens)
36
37
 
37
38
  if style == :no_space
38
- no_space_offenses(begin_node, *delims, NO_SPACE_MSG)
39
+ no_space_offenses(begin_node, left, right, NO_SPACE_MSG)
39
40
  else
40
- space_offenses(begin_node, *delims, SPACE_MSG)
41
+ space_offenses(begin_node, left, right, SPACE_MSG)
41
42
  end
42
43
  end
43
44
 
@@ -80,7 +80,10 @@ module RuboCop
80
80
  num_of_format_args, num_of_expected_fields = count_matches(node)
81
81
 
82
82
  return false if num_of_format_args == :unknown
83
- return false if num_of_expected_fields.zero? && node.child_nodes.first.dstr_type?
83
+
84
+ first_arg = node.first_argument
85
+ return false if num_of_expected_fields.zero? &&
86
+ (first_arg.dstr_type? || first_arg.array_type?)
84
87
 
85
88
  matched_arguments_count?(num_of_expected_fields, num_of_format_args)
86
89
  end
@@ -81,7 +81,7 @@ module RuboCop
81
81
  end
82
82
 
83
83
  def display_str(node)
84
- if /\n/.match?(node.source)
84
+ if node.source.include?("\n")
85
85
  str_content(node).inspect
86
86
  else
87
87
  node.source