rubocop 1.71.1 → 1.72.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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +28 -0
  4. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  5. data/lib/rubocop/comment_config.rb +1 -1
  6. data/lib/rubocop/config.rb +4 -0
  7. data/lib/rubocop/config_loader.rb +44 -8
  8. data/lib/rubocop/config_loader_resolver.rb +21 -7
  9. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  10. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -1
  11. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  12. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
  13. data/lib/rubocop/cop/internal_affairs.rb +1 -16
  14. data/lib/rubocop/cop/layout/block_alignment.rb +2 -0
  15. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  16. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
  17. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +0 -6
  18. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
  19. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +1 -1
  20. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +2 -2
  21. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  22. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  23. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  24. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
  25. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +231 -0
  26. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  27. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  28. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +74 -0
  29. data/lib/rubocop/cop/lint/void.rb +1 -6
  30. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  31. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  32. data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
  33. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +18 -18
  34. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  35. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  36. data/lib/rubocop/cop/mixin/range_help.rb +3 -3
  37. data/lib/rubocop/cop/mixin/string_help.rb +1 -1
  38. data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
  39. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  40. data/lib/rubocop/cop/style/explicit_block_argument.rb +14 -1
  41. data/lib/rubocop/cop/style/redundant_format.rb +222 -0
  42. data/lib/rubocop/cop/style/redundant_parentheses.rb +19 -3
  43. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  44. data/lib/rubocop/cop/util.rb +1 -1
  45. data/lib/rubocop/cop/utils/format_string.rb +7 -5
  46. data/lib/rubocop/cop/variable_force/variable.rb +13 -1
  47. data/lib/rubocop/directive_comment.rb +35 -2
  48. data/lib/rubocop/lsp/runtime.rb +2 -0
  49. data/lib/rubocop/lsp/server.rb +0 -2
  50. data/lib/rubocop/options.rb +26 -11
  51. data/lib/rubocop/path_util.rb +4 -0
  52. data/lib/rubocop/plugin/configuration_integrator.rb +141 -0
  53. data/lib/rubocop/plugin/load_error.rb +26 -0
  54. data/lib/rubocop/plugin/loader.rb +100 -0
  55. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  56. data/lib/rubocop/plugin.rb +39 -0
  57. data/lib/rubocop/rake_task.rb +4 -1
  58. data/lib/rubocop/rspec/cop_helper.rb +7 -0
  59. data/lib/rubocop/server/cache.rb +35 -2
  60. data/lib/rubocop/server/cli.rb +2 -2
  61. data/lib/rubocop/version.rb +17 -2
  62. data/lib/rubocop.rb +5 -0
  63. data/lib/ruby_lsp/rubocop/addon.rb +7 -10
  64. data/lib/ruby_lsp/rubocop/{wraps_built_in_lsp_runtime.rb → runtime_adapter.rb} +5 -8
  65. metadata +35 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a6e4d1daf086c733bdbc26101d597970c6db01884a84b1688fcdcb1d35790a93
4
- data.tar.gz: d21d0251334f815c178e4f3654e0884857a4bfb9f13395c96c27dc26d44b735a
3
+ metadata.gz: 9909c26bded9ccffc98132b899b68773a19b0e1259d834d2cd147abf2ca8534e
4
+ data.tar.gz: d6e58861b573240488aebcdaab3ec984a8c6fe75fd0da8cb51bfa8be3c4469ba
5
5
  SHA512:
6
- metadata.gz: befa7c474d65523d27c5a309f66d5c9b90d8656c2aff30f153ef764b6ce489ece67f6851e9be3484111cf4da59cea023eedfa502ccd9407814bf0ea6e21fa146
7
- data.tar.gz: '088876817707413c841fb293784228563caa287ac7785a53d7b60322762c2bf971f36c1d8d5ede445d2fbaaaf48360eef9a2196be154696572af820a07576a2d'
6
+ metadata.gz: 235ed1dea8218bf39fff25ebcb297391ced4a9aeb4c582979711c095958c0aaab44dcead59108f7463f0f0d7da046b4b9f88be0be4016bdc369259ef89c37162
7
+ data.tar.gz: b80078b908cbf8b75b0b9b047e7806521a65ca83cce802b38172d946cc625ffdd9bc255f91b1eba6e22d42670fee6aaa7d1ef2a81653a39ee1b1e869a7d0797b
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.71', require: false
55
+ gem 'rubocop', '~> 1.72', 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
@@ -1685,6 +1685,11 @@ Lint/ConstantResolution:
1685
1685
  # Restrict this cop from only looking at certain names
1686
1686
  Ignore: []
1687
1687
 
1688
+ Lint/CopDirectiveSyntax:
1689
+ Description: 'Checks that `# rubocop:` directives are strictly formatted.'
1690
+ Enabled: pending
1691
+ VersionAdded: '1.72'
1692
+
1688
1693
  Lint/Debugger:
1689
1694
  Description: 'Check for debugger calls.'
1690
1695
  Enabled: true
@@ -2285,6 +2290,11 @@ Lint/RedundantStringCoercion:
2285
2290
  VersionAdded: '0.19'
2286
2291
  VersionChanged: '0.77'
2287
2292
 
2293
+ Lint/RedundantTypeConversion:
2294
+ Description: 'Checks for redundantly converting a literal to the same type.'
2295
+ Enabled: pending
2296
+ VersionAdded: '1.72'
2297
+
2288
2298
  Lint/RedundantWithIndex:
2289
2299
  Description: 'Checks for redundant `with_index`.'
2290
2300
  Enabled: true
@@ -2433,6 +2443,12 @@ Lint/SuppressedException:
2433
2443
  VersionAdded: '0.9'
2434
2444
  VersionChanged: '1.12'
2435
2445
 
2446
+ Lint/SuppressedExceptionInNumberConversion:
2447
+ Description: 'Checks for cases where exceptions unrelated to the numeric constructors may be unintentionally swallowed.'
2448
+ Enabled: pending
2449
+ SafeAutoCorrect: false
2450
+ VersionAdded: '1.72'
2451
+
2436
2452
  Lint/SymbolConversion:
2437
2453
  Description: 'Checks for unnecessary symbol conversions.'
2438
2454
  Enabled: pending
@@ -2588,6 +2604,11 @@ Lint/UselessAssignment:
2588
2604
  VersionAdded: '0.11'
2589
2605
  VersionChanged: '1.66'
2590
2606
 
2607
+ Lint/UselessConstantScoping:
2608
+ Description: 'Checks for useless constant scoping.'
2609
+ Enabled: pending
2610
+ VersionAdded: '1.72'
2611
+
2591
2612
  Lint/UselessDefined:
2592
2613
  Description: 'Checks for calls to `defined?` with strings and symbols. The result of such a call will always be truthy.'
2593
2614
  Enabled: pending
@@ -3041,6 +3062,8 @@ Naming/PredicateName:
3041
3062
  MethodDefinitionMacros:
3042
3063
  - define_method
3043
3064
  - define_singleton_method
3065
+ # Use Sorbet's T::Boolean return type to detect predicate methods.
3066
+ UseSorbetSigs: false
3044
3067
  # Exclude Rspec specs because there is a strong convention to write spec
3045
3068
  # helpers in the form of `have_something` or `be_something`.
3046
3069
  Exclude:
@@ -5145,6 +5168,11 @@ Style/RedundantFilterChain:
5145
5168
  VersionAdded: '1.52'
5146
5169
  VersionChanged: '1.57'
5147
5170
 
5171
+ Style/RedundantFormat:
5172
+ Description: 'Checks for usages of `Kernel#format` or `Kernel#sprintf` with only a single argument.'
5173
+ Enabled: pending
5174
+ VersionAdded: '1.72'
5175
+
5148
5176
  Style/RedundantFreeze:
5149
5177
  Description: "Checks usages of Object#freeze on immutable objects."
5150
5178
  Enabled: true
@@ -97,7 +97,13 @@ module RuboCop
97
97
  end
98
98
 
99
99
  def loaded_extensions
100
- @config_store.for_pwd.loaded_features.to_a
100
+ rubocop_config = @config_store.for_pwd
101
+
102
+ plugin_names = rubocop_config.loaded_plugins.map do |plugin|
103
+ plugin.about.name
104
+ end
105
+
106
+ plugin_names + rubocop_config.loaded_features.to_a
101
107
  end
102
108
 
103
109
  def installed_and_not_loaded_extensions
@@ -205,7 +205,7 @@ module RuboCop
205
205
  directive.cop_names.each do |name|
206
206
  if directive.disabled?
207
207
  names[name] += 1
208
- elsif (names[name]).positive?
208
+ elsif names[name].positive?
209
209
  names[name] -= 1
210
210
  else
211
211
  extras[directive.comment] << name
@@ -45,6 +45,10 @@ module RuboCop
45
45
  end
46
46
  # rubocop:enable Metrics/AbcSize
47
47
 
48
+ def loaded_plugins
49
+ @loaded_plugins ||= ConfigLoader.loaded_plugins
50
+ end
51
+
48
52
  def loaded_features
49
53
  @loaded_features ||= ConfigLoader.loaded_features
50
54
  end
@@ -33,13 +33,14 @@ module RuboCop
33
33
  attr_accessor :debug, :ignore_parent_exclusion, :disable_pending_cops, :enable_pending_cops,
34
34
  :ignore_unrecognized_cops
35
35
  attr_writer :default_configuration
36
- attr_reader :loaded_features
36
+ attr_reader :loaded_plugins, :loaded_features
37
37
 
38
38
  alias debug? debug
39
39
  alias ignore_parent_exclusion? ignore_parent_exclusion
40
40
 
41
41
  def clear_options
42
42
  @debug = nil
43
+ @loaded_plugins = Set.new
43
44
  @loaded_features = Set.new
44
45
  @disable_pending_cops = nil
45
46
  @enable_pending_cops = nil
@@ -48,11 +49,17 @@ module RuboCop
48
49
  FileFinder.root_level = nil
49
50
  end
50
51
 
52
+ # rubocop:disable Metrics/AbcSize
51
53
  def load_file(file, check: true)
52
54
  path = file_path(file)
53
55
 
54
56
  hash = load_yaml_configuration(path)
55
57
 
58
+ rubocop_config = Config.create(hash, path, check: false)
59
+ plugins = hash.delete('plugins')
60
+ loaded_plugins = resolver.resolve_plugins(rubocop_config, plugins)
61
+ add_loaded_plugins(loaded_plugins)
62
+
56
63
  loaded_features = resolver.resolve_requires(path, hash)
57
64
  add_loaded_features(loaded_features)
58
65
 
@@ -67,6 +74,7 @@ module RuboCop
67
74
 
68
75
  Config.create(hash, path, check: check)
69
76
  end
77
+ # rubocop:enable Metrics/AbcSize
70
78
 
71
79
  def load_yaml_configuration(absolute_path)
72
80
  file_contents = read_file(absolute_path)
@@ -155,14 +163,35 @@ module RuboCop
155
163
  end
156
164
  end
157
165
 
158
- # @api private
159
- def inject_defaults!(project_root)
160
- path = File.join(project_root, 'config', 'default.yml')
161
- config = load_file(path)
162
- new_config = ConfigLoader.merge_with_default(config, path)
163
- puts "configuration from #{path}" if debug?
164
- @default_configuration = new_config
166
+ # This API is primarily intended for testing and documenting plugins.
167
+ # When testing a plugin using `rubocop/rspec/support`, the plugin is loaded automatically,
168
+ # so this API is usually not needed. It is intended to be used only when implementing tests
169
+ # that do not use `rubocop/rspec/support`.
170
+ # rubocop:disable Metrics/MethodLength
171
+ def inject_defaults!(config_yml_path)
172
+ if Pathname(config_yml_path).directory?
173
+ # TODO: Since the warning noise is expected to be high until some time after the release,
174
+ # warnings will only be issued when `RUBYOPT=-w` is specified.
175
+ # To proceed step by step, the next step is to remove `$VERBOSE` and always issue warning.
176
+ # Eventually, `project_root` will no longer be accepted.
177
+ if $VERBOSE
178
+ warn Rainbow(<<~MESSAGE).yellow, uplevel: 1
179
+ Use config YAML file path instead of project root directory.
180
+ e.g., `path/to/config/default.yml`
181
+ MESSAGE
182
+ end
183
+ # NOTE: For compatibility.
184
+ project_root = config_yml_path
185
+ path = File.join(project_root, 'config', 'default.yml')
186
+ config = load_file(path)
187
+ else
188
+ hash = ConfigLoader.load_yaml_configuration(config_yml_path.to_s)
189
+ config = Config.new(hash, config_yml_path).tap(&:make_excludes_absolute)
190
+ end
191
+
192
+ @default_configuration = ConfigLoader.merge_with_default(config, path)
165
193
  end
194
+ # rubocop:enable Metrics/MethodLength
166
195
 
167
196
  # Returns the path RuboCop inferred as the root of the project. No file
168
197
  # searches will go past this directory.
@@ -196,6 +225,13 @@ module RuboCop
196
225
  resolver.merge_with_default(config, config_file, unset_nil: unset_nil)
197
226
  end
198
227
 
228
+ # @api private
229
+ # Used to add plugins that were required inside a config or from
230
+ # the CLI using `--plugin`.
231
+ def add_loaded_plugins(loaded_plugins)
232
+ @loaded_plugins.merge(Array(loaded_plugins))
233
+ end
234
+
199
235
  # @api private
200
236
  # Used to add features that were required inside a config or from
201
237
  # the CLI using `--require`.
@@ -2,16 +2,34 @@
2
2
 
3
3
  require 'pathname'
4
4
  require 'yaml'
5
+ require_relative 'plugin'
5
6
 
6
7
  module RuboCop
7
8
  # A help class for ConfigLoader that handles configuration resolution.
8
9
  # @api private
9
10
  class ConfigLoaderResolver # rubocop:disable Metrics/ClassLength
11
+ def resolve_plugins(rubocop_config, plugins)
12
+ return if (plugins = Array(plugins)).empty?
13
+
14
+ Plugin.integrate_plugins(rubocop_config, plugins)
15
+ end
16
+
10
17
  def resolve_requires(path, hash)
11
18
  config_dir = File.dirname(path)
12
19
  hash.delete('require').tap do |loaded_features|
13
20
  Array(loaded_features).each do |feature|
14
- FeatureLoader.load(config_directory_path: config_dir, feature: feature)
21
+ if Plugin.plugin_capable?(feature)
22
+ # NOTE: Compatibility for before plugins style.
23
+ warn Rainbow(<<~MESSAGE).yellow
24
+ #{feature} extension supports plugin, specify `plugins: #{feature}` instead of `require: #{feature}` in #{path}.
25
+ For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
26
+ MESSAGE
27
+ rubocop_config = Config.create(hash, path, check: false)
28
+
29
+ resolve_plugins(rubocop_config, feature)
30
+ else
31
+ FeatureLoader.load(config_directory_path: config_dir, feature: feature)
32
+ end
15
33
  end
16
34
  end
17
35
  end
@@ -157,7 +175,7 @@ module RuboCop
157
175
  return false if inherited_file.nil? # Not inheritance resolving merge
158
176
  return false if inherited_file.start_with?('..') # Legitimate override
159
177
  return false if base_hash[key] == derived_hash[key] # Same value
160
- return false if remote_file?(inherited_file) # Can't change
178
+ return false if PathUtil.remote_file?(inherited_file) # Can't change
161
179
 
162
180
  Gem.path.none? { |dir| inherited_file.start_with?(dir) } # Can change?
163
181
  end
@@ -225,7 +243,7 @@ module RuboCop
225
243
  end
226
244
 
227
245
  def inherited_file(path, inherit_from, file)
228
- if remote_file?(inherit_from)
246
+ if PathUtil.remote_file?(inherit_from)
229
247
  # A remote configuration, e.g. `inherit_from: http://example.com/rubocop.yml`.
230
248
  RemoteConfig.new(inherit_from, File.dirname(path))
231
249
  elsif Pathname.new(inherit_from).absolute?
@@ -245,10 +263,6 @@ module RuboCop
245
263
  end
246
264
  end
247
265
 
248
- def remote_file?(uri)
249
- uri.start_with?('http://', 'https://')
250
- end
251
-
252
266
  def remote_config?(file)
253
267
  file.is_a?(RemoteConfig)
254
268
  end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # When a node location may not exist, `Node#loc?` or `Node#loc_is?`
7
+ # can be used instead of calling `Node#respond_to?` before using
8
+ # the value.
9
+ #
10
+ # @example
11
+ # # bad
12
+ # node.loc.respond_to?(:begin) && node.loc.begin
13
+ #
14
+ # # good
15
+ # node.loc?(:begin)
16
+ #
17
+ # # bad
18
+ # node.loc.respond_to?(:begin) && node.loc.begin.is?('(')
19
+ #
20
+ # # good
21
+ # node.loc_is?(:begin, '(')
22
+ #
23
+ # # bad
24
+ # node.loc.respond_to?(:begin) && node.loc.begin.source == '('
25
+ #
26
+ # # good
27
+ # node.loc_is?(:begin, '(')
28
+ #
29
+ class LocationExists < Base
30
+ extend AutoCorrector
31
+
32
+ MSG = 'Use `%<replacement>s` instead of `%<source>s`.'
33
+
34
+ # @!method replaceable_with_loc_is(node)
35
+ def_node_matcher :replaceable_with_loc_is, <<~PATTERN
36
+ (and
37
+ (call
38
+ (call $_receiver :loc) :respond_to?
39
+ $(sym _location))
40
+ {
41
+ (call
42
+ (call
43
+ (call _receiver :loc) _location) :is?
44
+ $(str _))
45
+ (call
46
+ (call
47
+ (call
48
+ (call _receiver :loc) _location) :source) :==
49
+ $(str _))
50
+ })
51
+ PATTERN
52
+
53
+ # @!method replaceable_with_loc(node)
54
+ def_node_matcher :replaceable_with_loc, <<~PATTERN
55
+ (and
56
+ (call
57
+ (call $_receiver :loc) :respond_to?
58
+ $(sym _location))
59
+ (call
60
+ (call _receiver :loc) _location))
61
+ PATTERN
62
+
63
+ def on_and(node)
64
+ replace_with_loc(node) || replace_with_loc_is(node)
65
+ end
66
+
67
+ private
68
+
69
+ def replace_with_loc(node)
70
+ replaceable_with_loc(node) do |receiver, location|
71
+ if node.parent&.assignment?
72
+ register_offense(node, replace_assignment(receiver, location))
73
+ else
74
+ register_offense(node, replacement(receiver, "loc?(#{location.source})"))
75
+ end
76
+ end
77
+ end
78
+
79
+ def replace_with_loc_is(node)
80
+ replaceable_with_loc_is(node) do |receiver, location, value|
81
+ replacement = replacement(receiver, "loc_is?(#{location.source}, #{value.source})")
82
+ register_offense(node, replacement)
83
+ end
84
+ end
85
+
86
+ def register_offense(node, replacement)
87
+ message = format(MSG, replacement: replacement, source: node.source)
88
+
89
+ add_offense(node, message: message) do |corrector|
90
+ corrector.replace(node, replacement)
91
+ end
92
+ end
93
+
94
+ def replacement(receiver, rest)
95
+ "#{replace_receiver(receiver)}#{rest}"
96
+ end
97
+
98
+ def replace_assignment(receiver, location)
99
+ prefix = replace_receiver(receiver)
100
+
101
+ "#{prefix}loc#{dot(receiver)}#{location.value} if #{prefix}loc?(#{location.source})"
102
+ end
103
+
104
+ def replace_receiver(receiver)
105
+ return '' unless receiver
106
+
107
+ "#{receiver.source}#{dot(receiver)}"
108
+ end
109
+
110
+ def dot(node)
111
+ node.parent.loc.dot.source
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module InternalAffairs
6
- # rubocop:disable InternalAffairs/RedundantSourceRange - node here is a `NodePattern::Node`
6
+ # rubocop:disable InternalAffairs/RedundantSourceRange -- node here is a `NodePattern::Node`
7
7
  class NodePatternGroups
8
8
  # Walks an AST that has been processed by `InternalAffairs::NodePatternGroups::Processor`
9
9
  # in order to find `node_type` and `node_sequence` nodes that can be replaced with a node
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lint_roller'
4
+
5
+ module RuboCop
6
+ module InternalAffairs
7
+ # A Plugin for `InternalAffairs` department, which has internal cops.
8
+ class Plugin < LintRoller::Plugin
9
+ def about
10
+ LintRoller::About.new(
11
+ name: 'rubocop-internal_affairs',
12
+ version: Version::STRING,
13
+ homepage: 'https://github.com/rubocop/rubocop/tree/master/lib/rubocop/cop/internal_affairs',
14
+ description: 'A collection of RuboCop cops to check for internal affairs.'
15
+ )
16
+ end
17
+
18
+ def supported?(context)
19
+ context.engine == :rubocop
20
+ end
21
+
22
+ def rules(_context)
23
+ require_relative '../internal_affairs'
24
+
25
+ LintRoller::Rules.new(
26
+ type: :path,
27
+ config_format: :rubocop,
28
+ value: Pathname.new(__dir__).join('../../../../config/internal_affairs.yml')
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
@@ -17,7 +17,13 @@ module RuboCop
17
17
  'in `config/default.yml`.'
18
18
  CONFIG_PATH = find_file_upwards('config/default.yml', Dir.pwd)
19
19
  CONFIG = if CONFIG_PATH
20
- ConfigLoader.load_yaml_configuration(CONFIG_PATH)
20
+ begin
21
+ original_debug = ConfigLoader.debug
22
+ ConfigLoader.debug = false
23
+ ConfigLoader.load_yaml_configuration(CONFIG_PATH)
24
+ ensure
25
+ ConfigLoader.debug = original_debug
26
+ end
21
27
  else
22
28
  {}
23
29
  end
@@ -8,6 +8,7 @@ require_relative 'internal_affairs/example_description'
8
8
  require_relative 'internal_affairs/example_heredoc_delimiter'
9
9
  require_relative 'internal_affairs/inherit_deprecated_cop_class'
10
10
  require_relative 'internal_affairs/lambda_or_proc'
11
+ require_relative 'internal_affairs/location_exists'
11
12
  require_relative 'internal_affairs/location_expression'
12
13
  require_relative 'internal_affairs/location_line_equality_comparison'
13
14
  require_relative 'internal_affairs/method_name_end_with'
@@ -36,19 +37,3 @@ require_relative 'internal_affairs/style_detected_api_use'
36
37
  require_relative 'internal_affairs/undefined_config'
37
38
  require_relative 'internal_affairs/useless_message_assertion'
38
39
  require_relative 'internal_affairs/useless_restrict_on_send'
39
-
40
- module RuboCop
41
- # Patch in the InternalAffairs specific config values
42
- module InternalAffairs
43
- def self.inject!
44
- path = File.join(ConfigLoader::RUBOCOP_HOME, 'config', 'internal_affairs.yml')
45
- hash = ConfigLoader.load_yaml_configuration(path)
46
- config = Config.new(hash, path)
47
- puts "configuration from #{path}" if ConfigLoader.debug?
48
- config = ConfigLoader.merge_with_default(config, path)
49
- ConfigLoader.instance_variable_set(:@default_configuration, config)
50
- end
51
- end
52
- end
53
-
54
- RuboCop::InternalAffairs.inject!
@@ -73,6 +73,8 @@ module RuboCop
73
73
  # @!method block_end_align_target?(node, child)
74
74
  def_node_matcher :block_end_align_target?, <<~PATTERN
75
75
  {assignment?
76
+ def
77
+ defs
76
78
  splat
77
79
  and
78
80
  or
@@ -49,7 +49,7 @@ module RuboCop
49
49
  end
50
50
 
51
51
  def on_rescue(node)
52
- return unless node.loc.respond_to?(:else) && node.loc.else
52
+ return unless node.loc?(:else)
53
53
 
54
54
  check_alignment(base_range_of_rescue(node), node.loc.else)
55
55
  end
@@ -92,7 +92,7 @@ module RuboCop
92
92
  case parent.type
93
93
  when :def, :defs then base_for_method_definition(parent)
94
94
  when :kwbegin then parent.loc.begin
95
- when :block
95
+ when :block, :numblock
96
96
  assignment_node = assignment_node(parent)
97
97
  if same_line?(parent, assignment_node)
98
98
  assignment_node.source_range
@@ -189,7 +189,7 @@ module RuboCop
189
189
  end
190
190
 
191
191
  def offense_location(node)
192
- if node.loc.respond_to?(:end) && node.loc.end
192
+ if node.loc?(:end)
193
193
  node.loc.end
194
194
  else
195
195
  node
@@ -22,8 +22,6 @@ module RuboCop
22
22
  # def b
23
23
  # end
24
24
  #
25
- # @example
26
- #
27
25
  # # good
28
26
  # def a
29
27
  # end
@@ -42,8 +40,6 @@ module RuboCop
42
40
  # def b
43
41
  # end
44
42
  #
45
- # @example
46
- #
47
43
  # # good
48
44
  # class A
49
45
  # end
@@ -65,8 +61,6 @@ module RuboCop
65
61
  # def b
66
62
  # end
67
63
  #
68
- # @example
69
- #
70
64
  # # good
71
65
  # module A
72
66
  # end
@@ -27,9 +27,14 @@ module RuboCop
27
27
  KIND = 'method'
28
28
 
29
29
  def on_def(node)
30
- first_line = node.arguments.source_range&.last_line
30
+ if node.endless?
31
+ return unless offending_endless_method?(node)
31
32
 
32
- check(node, node.body, adjusted_first_line: first_line)
33
+ register_offense_for_endless_method(node)
34
+ else
35
+ first_line = node.arguments.source_range&.last_line
36
+ check(node, node.body, adjusted_first_line: first_line)
37
+ end
33
38
  end
34
39
  alias on_defs on_def
35
40
 
@@ -38,6 +43,21 @@ module RuboCop
38
43
  def style
39
44
  :no_empty_lines
40
45
  end
46
+
47
+ def offending_endless_method?(node)
48
+ node.body.first_line > node.loc.assignment.line + 1 &&
49
+ processed_source.lines[node.loc.assignment.line].empty?
50
+ end
51
+
52
+ def register_offense_for_endless_method(node)
53
+ range = processed_source.buffer.line_range(node.loc.assignment.line + 1).resize(1)
54
+
55
+ msg = message(MSG_EXTRA, 'beginning')
56
+
57
+ add_offense(range, message: msg) do |corrector|
58
+ corrector.remove(range)
59
+ end
60
+ end
41
61
  end
42
62
  end
43
63
  end
@@ -162,7 +162,7 @@ module RuboCop
162
162
 
163
163
  def end_keyword_before_closing_parenthesis?(parenthesized_send_node)
164
164
  parenthesized_send_node.ancestors.any? do |ancestor|
165
- ancestor.loc.respond_to?(:end) && ancestor.loc.end&.source == 'end'
165
+ ancestor.loc_is?(:end, 'end')
166
166
  end
167
167
  end
168
168
 
@@ -216,7 +216,7 @@ module RuboCop
216
216
 
217
217
  def get_dot_right_above(node)
218
218
  node.each_ancestor.find do |a|
219
- dot = a.loc.respond_to?(:dot) && a.loc.dot
219
+ dot = a.loc.dot if a.loc?(:dot)
220
220
  next unless dot
221
221
 
222
222
  dot.line == node.loc.dot.line - 1 && dot.column == node.loc.dot.column
@@ -239,7 +239,7 @@ module RuboCop
239
239
  node = node.receiver while node.receiver
240
240
  # ascend to first call which has a dot
241
241
  node = node.parent
242
- node = node.parent until node.loc.respond_to?(:dot) && node.loc.dot
242
+ node = node.parent until node.loc?(:dot)
243
243
 
244
244
  node
245
245
  end
@@ -51,7 +51,7 @@ module RuboCop
51
51
  alias on_csend on_send
52
52
 
53
53
  def on_const(node)
54
- return unless node.loc.respond_to?(:double_colon) && node.loc.double_colon
54
+ return unless node.loc?(:double_colon)
55
55
 
56
56
  check_space_after_double_colon(node)
57
57
  end