rubocop 1.69.1 → 1.70.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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +19 -2
  5. data/lib/rubocop/cli/command/execute_runner.rb +3 -3
  6. data/lib/rubocop/config.rb +13 -4
  7. data/lib/rubocop/config_loader.rb +4 -0
  8. data/lib/rubocop/config_loader_resolver.rb +14 -3
  9. data/lib/rubocop/config_validator.rb +18 -8
  10. data/lib/rubocop/cop/autocorrect_logic.rb +31 -34
  11. data/lib/rubocop/cop/base.rb +6 -0
  12. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -1
  13. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  14. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  15. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  16. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +4 -2
  17. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  18. data/lib/rubocop/cop/layout/argument_alignment.rb +1 -7
  19. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
  20. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  21. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  22. data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -7
  23. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  24. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +1 -6
  25. data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
  26. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +1 -0
  27. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  28. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  29. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +1 -1
  30. data/lib/rubocop/cop/layout/line_length.rb +1 -0
  31. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +24 -0
  32. data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
  33. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  34. data/lib/rubocop/cop/layout/space_around_operators.rb +3 -3
  35. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  36. data/lib/rubocop/cop/lint/constant_reassignment.rb +152 -0
  37. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  38. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +11 -3
  39. data/lib/rubocop/cop/lint/nested_method_definition.rb +5 -1
  40. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +4 -2
  41. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +6 -14
  42. data/lib/rubocop/cop/lint/shared_mutable_default.rb +65 -0
  43. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  44. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -4
  45. data/lib/rubocop/cop/lint/void.rb +3 -2
  46. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  47. data/lib/rubocop/cop/metrics/method_length.rb +8 -1
  48. data/lib/rubocop/cop/mixin/check_line_breakable.rb +7 -7
  49. data/lib/rubocop/cop/mixin/comments_help.rb +6 -1
  50. data/lib/rubocop/cop/mixin/dig_help.rb +1 -1
  51. data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
  52. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +46 -22
  53. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  54. data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -1
  55. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  56. data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
  57. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
  58. data/lib/rubocop/cop/style/access_modifier_declarations.rb +32 -1
  59. data/lib/rubocop/cop/style/and_or.rb +1 -1
  60. data/lib/rubocop/cop/style/arguments_forwarding.rb +1 -4
  61. data/lib/rubocop/cop/style/block_delimiters.rb +8 -1
  62. data/lib/rubocop/cop/style/class_and_module_children.rb +5 -2
  63. data/lib/rubocop/cop/style/each_for_simple_loop.rb +3 -6
  64. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  65. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  66. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  67. data/lib/rubocop/cop/style/exact_regexp_match.rb +1 -2
  68. data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
  69. data/lib/rubocop/cop/style/file_null.rb +20 -4
  70. data/lib/rubocop/cop/style/float_division.rb +8 -4
  71. data/lib/rubocop/cop/style/hash_except.rb +54 -67
  72. data/lib/rubocop/cop/style/hash_syntax.rb +5 -2
  73. data/lib/rubocop/cop/style/if_with_semicolon.rb +6 -4
  74. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  75. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +11 -1
  76. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  77. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -1
  78. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  79. data/lib/rubocop/cop/style/multiple_comparison.rb +34 -22
  80. data/lib/rubocop/cop/style/mutable_constant.rb +1 -1
  81. data/lib/rubocop/cop/style/object_then.rb +13 -15
  82. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  83. data/lib/rubocop/cop/style/raise_args.rb +5 -3
  84. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  85. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
  86. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  87. data/lib/rubocop/cop/style/redundant_line_continuation.rb +12 -9
  88. data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -4
  89. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +3 -0
  90. data/lib/rubocop/cop/style/redundant_self_assignment.rb +6 -5
  91. data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
  92. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  93. data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -2
  94. data/lib/rubocop/cop/style/single_line_methods.rb +2 -3
  95. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  96. data/lib/rubocop/cop/style/super_arguments.rb +63 -15
  97. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  98. data/lib/rubocop/cop/style/yoda_expression.rb +1 -0
  99. data/lib/rubocop/cop/util.rb +9 -2
  100. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  101. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  102. data/lib/rubocop/lsp/logger.rb +2 -2
  103. data/lib/rubocop/lsp/routes.rb +7 -23
  104. data/lib/rubocop/lsp/runtime.rb +15 -49
  105. data/lib/rubocop/lsp/stdin_runner.rb +83 -0
  106. data/lib/rubocop/magic_comment.rb +3 -3
  107. data/lib/rubocop/path_util.rb +11 -8
  108. data/lib/rubocop/rspec/shared_contexts.rb +4 -1
  109. data/lib/rubocop/runner.rb +5 -6
  110. data/lib/rubocop/target_ruby.rb +15 -0
  111. data/lib/rubocop/version.rb +1 -1
  112. data/lib/rubocop.rb +3 -0
  113. data/lib/ruby_lsp/rubocop/addon.rb +78 -0
  114. data/lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb +50 -0
  115. metadata +16 -8
@@ -16,6 +16,11 @@ module RuboCop
16
16
  # Routes for Language Server Protocol of RuboCop.
17
17
  # @api private
18
18
  class Routes
19
+ CONFIGURATION_FILE_PATTERNS = [
20
+ RuboCop::ConfigFinder::DOTFILE,
21
+ RuboCop::CLI::Command::AutoGenerateConfig::AUTO_GENERATED_FILE
22
+ ].freeze
23
+
19
24
  def self.handle(name, &block)
20
25
  define_method(:"handle_#{name}", &block)
21
26
  end
@@ -96,7 +101,7 @@ module RuboCop
96
101
 
97
102
  handle 'workspace/didChangeWatchedFiles' do |request|
98
103
  changed = request[:params][:changes].any? do |change|
99
- change[:uri].end_with?(RuboCop::ConfigFinder::DOTFILE)
104
+ CONFIGURATION_FILE_PATTERNS.any? { |path| change[:uri].end_with?(path) }
100
105
  end
101
106
 
102
107
  if changed
@@ -204,14 +209,12 @@ module RuboCop
204
209
 
205
210
  def diagnostic(file_uri, text)
206
211
  @text_cache[file_uri] = text
207
- offenses = @server.offenses(remove_file_protocol_from(file_uri), text)
208
- diagnostics = offenses.map { |offense| to_diagnostic(offense) }
209
212
 
210
213
  {
211
214
  method: 'textDocument/publishDiagnostics',
212
215
  params: {
213
216
  uri: file_uri,
214
- diagnostics: diagnostics
217
+ diagnostics: @server.offenses(remove_file_protocol_from(file_uri), text)
215
218
  }
216
219
  }
217
220
  end
@@ -219,25 +222,6 @@ module RuboCop
219
222
  def remove_file_protocol_from(uri)
220
223
  uri.delete_prefix('file://')
221
224
  end
222
-
223
- def to_diagnostic(offense)
224
- code = offense[:cop_name]
225
- message = offense[:message]
226
- loc = offense[:location]
227
- rubocop_severity = offense[:severity]
228
- severity = Severity.find_by(rubocop_severity)
229
-
230
- {
231
- code: code, message: message, range: to_range(loc), severity: severity, source: 'rubocop'
232
- }
233
- end
234
-
235
- def to_range(location)
236
- {
237
- start: { character: location[:start_column] - 1, line: location[:start_line] - 1 },
238
- end: { character: location[:last_column], line: location[:last_line] - 1 }
239
- }
240
- end
241
225
  end
242
226
  end
243
227
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'stringio'
3
+ require_relative 'diagnostic'
4
+ require_relative 'stdin_runner'
4
5
 
5
6
  #
6
7
  # This code is based on https://github.com/standardrb/standard.
@@ -19,24 +20,14 @@ module RuboCop
19
20
  attr_writer :safe_autocorrect, :lint_mode, :layout_mode
20
21
 
21
22
  def initialize(config_store)
22
- @config_store = config_store
23
- @logged_paths = []
23
+ @runner = RuboCop::Lsp::StdinRunner.new(config_store)
24
+ @cop_registry = RuboCop::Cop::Registry.global.to_h
25
+
24
26
  @safe_autocorrect = true
25
27
  @lint_mode = false
26
28
  @layout_mode = false
27
29
  end
28
30
 
29
- # This abuses the `--stdin` option of rubocop and reads the formatted text
30
- # from the `options[:stdin]` that rubocop mutates. This depends on
31
- # `parallel: false` as well as the fact that RuboCop doesn't otherwise dup
32
- # or reassign that options object. Risky business!
33
- #
34
- # Reassigning `options[:stdin]` is done here:
35
- # https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/cop/team.rb#L131
36
- # Printing `options[:stdin]`
37
- # https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/cli/command/execute_runner.rb#L95
38
- # Setting `parallel: true` would break this here:
39
- # https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/runner.rb#L72
40
31
  def format(path, text, command:)
41
32
  safe_autocorrect = if command
42
33
  command == 'rubocop.formatAutocorrects'
@@ -44,34 +35,23 @@ module RuboCop
44
35
  @safe_autocorrect
45
36
  end
46
37
 
47
- formatting_options = {
48
- stdin: text, force_exclusion: true, autocorrect: true, safe_autocorrect: safe_autocorrect
49
- }
38
+ formatting_options = { autocorrect: true, safe_autocorrect: safe_autocorrect }
50
39
  formatting_options[:only] = config_only_options if @lint_mode || @layout_mode
51
40
 
52
- redirect_stdout { run_rubocop(formatting_options, path) }
53
-
54
- formatting_options[:stdin]
41
+ @runner.run(path, text, formatting_options)
42
+ @runner.formatted_source
55
43
  end
56
44
 
57
- def offenses(path, text)
58
- diagnostic_options = {
59
- stdin: text, force_exclusion: true, formatters: ['json'], format: 'json'
60
- }
45
+ def offenses(path, text, document_encoding = nil)
46
+ diagnostic_options = {}
61
47
  diagnostic_options[:only] = config_only_options if @lint_mode || @layout_mode
62
48
 
63
- json = redirect_stdout { run_rubocop(diagnostic_options, path) }
64
- results = JSON.parse(json, symbolize_names: true)
65
-
66
- if results[:files].empty?
67
- unless @logged_paths.include?(path)
68
- Logger.log "Ignoring file, per configuration: #{path}"
69
- @logged_paths << path
70
- end
71
- return []
49
+ @runner.run(path, text, diagnostic_options)
50
+ @runner.offenses.map do |offense|
51
+ Diagnostic.new(
52
+ document_encoding, offense, path, @cop_registry[offense.cop_name]&.first
53
+ ).to_lsp_diagnostic(@runner.config_for_working_directory)
72
54
  end
73
-
74
- results.dig(:files, 0, :offenses)
75
55
  end
76
56
 
77
57
  private
@@ -82,20 +62,6 @@ module RuboCop
82
62
  only_options << 'Layout' if @layout_mode
83
63
  only_options
84
64
  end
85
-
86
- def redirect_stdout(&block)
87
- stdout = StringIO.new
88
-
89
- RuboCop::Server::Helper.redirect(stdout: stdout, &block)
90
-
91
- stdout.string
92
- end
93
-
94
- def run_rubocop(options, path)
95
- runner = RuboCop::Runner.new(options, @config_store)
96
-
97
- runner.run([path])
98
- end
99
65
  end
100
66
  end
101
67
  end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # This code is based on https://github.com/standardrb/standard.
5
+ #
6
+ # Copyright (c) 2023 Test Double, Inc.
7
+ #
8
+ # The MIT License (MIT)
9
+ #
10
+ # https://github.com/standardrb/standard/blob/main/LICENSE.txt
11
+ #
12
+ module RuboCop
13
+ module Lsp
14
+ # Originally lifted from:
15
+ # https://github.com/Shopify/ruby-lsp/blob/8d4c17efce4e8ecc8e7c557ab2981db6b22c0b6d/lib/ruby_lsp/requests/support/rubocop_runner.rb#L20
16
+ # @api private
17
+ class StdinRunner < RuboCop::Runner
18
+ class ConfigurationError < StandardError; end
19
+
20
+ attr_reader :offenses, :config_for_working_directory
21
+
22
+ DEFAULT_RUBOCOP_OPTIONS = {
23
+ stderr: true,
24
+ force_exclusion: true,
25
+ formatters: ['RuboCop::Formatter::BaseFormatter'],
26
+ raise_cop_error: true,
27
+ todo_file: nil,
28
+ todo_ignore_files: []
29
+ }.freeze
30
+
31
+ def initialize(config_store)
32
+ @options = {}
33
+
34
+ @offenses = []
35
+ @warnings = []
36
+ @errors = []
37
+
38
+ @config_for_working_directory = config_store.for_pwd
39
+
40
+ super(@options, config_store)
41
+ end
42
+
43
+ # rubocop:disable Metrics/MethodLength
44
+ def run(path, contents, options)
45
+ @options = options.merge(DEFAULT_RUBOCOP_OPTIONS)
46
+ @options[:stdin] = contents
47
+
48
+ @offenses = []
49
+ @warnings = []
50
+ @errors = []
51
+
52
+ super([path])
53
+
54
+ raise Interrupt if aborting?
55
+ rescue RuboCop::Runner::InfiniteCorrectionLoop => e
56
+ if defined?(::RubyLsp::Requests::Formatting::Error)
57
+ raise ::RubyLsp::Requests::Formatting::Error, e.message
58
+ end
59
+
60
+ raise e
61
+ rescue RuboCop::ValidationError => e
62
+ raise ConfigurationError, e.message
63
+ rescue StandardError => e
64
+ if defined?(::RubyLsp::Requests::Formatting::Error)
65
+ raise ::RubyLsp::Requests::Support::InternalRuboCopError, e
66
+ end
67
+
68
+ raise e
69
+ end
70
+ # rubocop:enable Metrics/MethodLength
71
+
72
+ def formatted_source
73
+ @options[:stdin]
74
+ end
75
+
76
+ private
77
+
78
+ def file_finished(_file, offenses)
79
+ @offenses = offenses
80
+ end
81
+ end
82
+ end
83
+ end
@@ -80,13 +80,13 @@ module RuboCop
80
80
 
81
81
  # Expose the `frozen_string_literal` value coerced to a boolean if possible.
82
82
  #
83
- # @return [Boolean] if value is `true` or `false`
83
+ # @return [Boolean] if value is `true` or `false` in any case
84
84
  # @return [nil] if frozen_string_literal comment isn't found
85
85
  # @return [String] if comment is found but isn't true or false
86
86
  def frozen_string_literal
87
87
  return unless (setting = extract_frozen_string_literal)
88
88
 
89
- case setting
89
+ case setting.downcase
90
90
  when 'true' then true
91
91
  when 'false' then false
92
92
  else
@@ -283,7 +283,7 @@ module RuboCop
283
283
  # is the only text in the comment.
284
284
  #
285
285
  # Case-insensitive and dashes/underscores are acceptable.
286
- # @see https://github.com/ruby/ruby/blob/78b95b4/parse.y#L7134-L7138
286
+ # @see https://github.com/ruby/ruby/blob/78b95b49f8/parse.y#L7134-L7138
287
287
  def extract_frozen_string_literal
288
288
  extract(/\A\s*#\s*#{KEYWORDS[:frozen_string_literal]}:\s*#{TOKEN}\s*\z/io)
289
289
  end
@@ -32,16 +32,19 @@ module RuboCop
32
32
  private_constant :SMART_PATH_CACHE
33
33
 
34
34
  def smart_path(path)
35
- SMART_PATH_CACHE[path] ||= begin
36
- # Ideally, we calculate this relative to the project root.
37
- base_dir = Dir.pwd
38
-
39
- if path.start_with? base_dir
40
- relative_path(path, base_dir)
35
+ SMART_PATH_CACHE[path] ||=
36
+ if path.is_a?(RemoteConfig)
37
+ path.uri.to_s
41
38
  else
42
- path
39
+ # Ideally, we calculate this relative to the project root.
40
+ base_dir = Dir.pwd
41
+
42
+ if path.start_with? base_dir
43
+ relative_path(path, base_dir)
44
+ else
45
+ path
46
+ end
43
47
  end
44
- end
45
48
  end
46
49
 
47
50
  # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
@@ -98,6 +98,8 @@ RSpec.shared_context 'config' do # rubocop:disable Metrics/BlockLength
98
98
 
99
99
  let(:cop_options) { {} }
100
100
 
101
+ let(:gem_versions) { {} }
102
+
101
103
  ### Utilities
102
104
 
103
105
  def source_range(range, buffer: source_buffer)
@@ -138,7 +140,8 @@ RSpec.shared_context 'config' do # rubocop:disable Metrics/BlockLength
138
140
 
139
141
  allow(config).to receive(:gem_versions_in_target).and_return(
140
142
  {
141
- 'railties' => rails_version_in_gemfile
143
+ 'railties' => rails_version_in_gemfile,
144
+ **gem_versions.transform_values { |value| Gem::Version.new(value) }
142
145
  }
143
146
  )
144
147
 
@@ -20,11 +20,7 @@ module RuboCop
20
20
  message = 'Infinite loop detected'
21
21
  message += " in #{path}" if path
22
22
  message += " and caused by #{root_cause}" if root_cause
23
- message += "\n"
24
- hint = 'Hint: Please update to the latest RuboCop version if not already in use, ' \
25
- "and report a bug if the issue still occurs on this version.\n" \
26
- 'Please check the latest version at https://rubygems.org/gems/rubocop.'
27
- super(Rainbow(message).red + Rainbow(hint).yellow)
23
+ super(message)
28
24
  end
29
25
  end
30
26
 
@@ -157,8 +153,11 @@ module RuboCop
157
153
  file_started(file)
158
154
  offenses = file_offenses(file)
159
155
  rescue InfiniteCorrectionLoop => e
156
+ raise e if @options[:raise_cop_error]
157
+
158
+ errors << e
159
+ warn Rainbow(e.message).red
160
160
  offenses = e.offenses.compact.sort.freeze
161
- raise
162
161
  ensure
163
162
  file_finished(file, offenses || [])
164
163
  end
@@ -34,6 +34,20 @@ module RuboCop
34
34
  end
35
35
  end
36
36
 
37
+ # The target ruby version may be configured by setting the
38
+ # `RUBOCOP_TARGET_RUBY_VERSION` environment variable.
39
+ class RuboCopEnvVar < Source
40
+ def name
41
+ '`RUBOCOP_TARGET_RUBY_VERSION` environment variable'
42
+ end
43
+
44
+ private
45
+
46
+ def find_version
47
+ ENV.fetch('RUBOCOP_TARGET_RUBY_VERSION', nil)&.to_f
48
+ end
49
+ end
50
+
37
51
  # The target ruby version may be configured in RuboCop's config.
38
52
  # @api private
39
53
  class RuboCopConfig < Source
@@ -246,6 +260,7 @@ module RuboCop
246
260
  end
247
261
 
248
262
  SOURCES = [
263
+ RuboCopEnvVar,
249
264
  RuboCopConfig,
250
265
  GemspecFile,
251
266
  RubyVersionFile,
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.69.1'
6
+ STRING = '1.70.0'
7
7
 
8
8
  MSG = '%<version>s (using %<parser_version>s, ' \
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
data/lib/rubocop.rb CHANGED
@@ -300,6 +300,7 @@ require_relative 'rubocop/cop/lint/boolean_symbol'
300
300
  require_relative 'rubocop/cop/lint/circular_argument_reference'
301
301
  require_relative 'rubocop/cop/lint/constant_definition_in_block'
302
302
  require_relative 'rubocop/cop/lint/constant_overwritten_in_rescue'
303
+ require_relative 'rubocop/cop/lint/constant_reassignment'
303
304
  require_relative 'rubocop/cop/lint/constant_resolution'
304
305
  require_relative 'rubocop/cop/lint/debugger'
305
306
  require_relative 'rubocop/cop/lint/deprecated_class_methods'
@@ -329,6 +330,7 @@ require_relative 'rubocop/cop/lint/empty_in_pattern'
329
330
  require_relative 'rubocop/cop/lint/empty_interpolation'
330
331
  require_relative 'rubocop/cop/lint/empty_when'
331
332
  require_relative 'rubocop/cop/lint/ensure_return'
333
+ require_relative 'rubocop/cop/lint/shared_mutable_default'
332
334
  require_relative 'rubocop/cop/lint/erb_new_arguments'
333
335
  require_relative 'rubocop/cop/lint/flip_flop'
334
336
  require_relative 'rubocop/cop/lint/float_comparison'
@@ -573,6 +575,7 @@ require_relative 'rubocop/cop/style/inverse_methods'
573
575
  require_relative 'rubocop/cop/style/inline_comment'
574
576
  require_relative 'rubocop/cop/style/invertible_unless_condition'
575
577
  require_relative 'rubocop/cop/style/ip_addresses'
578
+ require_relative 'rubocop/cop/style/it_assignment'
576
579
  require_relative 'rubocop/cop/style/keyword_arguments_merging'
577
580
  require_relative 'rubocop/cop/style/keyword_parameters_order'
578
581
  require_relative 'rubocop/cop/style/lambda'
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../rubocop'
4
+ require_relative '../../rubocop/lsp/logger'
5
+ require_relative 'wraps_built_in_lsp_runtime'
6
+
7
+ module RubyLsp
8
+ module RuboCop
9
+ # A Ruby LSP add-on for RuboCop.
10
+ class Addon < RubyLsp::Addon
11
+ def initializer
12
+ @wraps_built_in_lsp_runtime = nil
13
+ end
14
+
15
+ def name
16
+ 'RuboCop'
17
+ end
18
+
19
+ def activate(global_state, message_queue)
20
+ ::RuboCop::LSP::Logger.log(
21
+ "Activating RuboCop LSP addon #{::RuboCop::Version::STRING}.", prefix: '[RuboCop]'
22
+ )
23
+
24
+ ::RuboCop::LSP.enable
25
+ @wraps_built_in_lsp_runtime = WrapsBuiltinLspRuntime.new
26
+
27
+ global_state.register_formatter('rubocop', @wraps_built_in_lsp_runtime)
28
+
29
+ register_additional_file_watchers(global_state, message_queue)
30
+
31
+ ::RuboCop::LSP::Logger.log(
32
+ "Initialized RuboCop LSP addon #{::RuboCop::Version::STRING}.", prefix: '[RuboCop]'
33
+ )
34
+ end
35
+
36
+ def deactivate
37
+ @wraps_built_in_lsp_runtime = nil
38
+ end
39
+
40
+ # rubocop:disable Layout/LineLength, Metrics/MethodLength
41
+ def register_additional_file_watchers(global_state, message_queue)
42
+ return unless global_state.supports_watching_files
43
+
44
+ message_queue << Request.new(
45
+ id: 'rubocop-file-watcher',
46
+ method: 'client/registerCapability',
47
+ params: Interface::RegistrationParams.new(
48
+ registrations: [
49
+ Interface::Registration.new(
50
+ id: 'workspace/didChangeWatchedFilesRuboCop',
51
+ method: 'workspace/didChangeWatchedFiles',
52
+ register_options: Interface::DidChangeWatchedFilesRegistrationOptions.new(
53
+ watchers: [
54
+ Interface::FileSystemWatcher.new(
55
+ glob_pattern: '**/.rubocop{,_todo}.yml',
56
+ kind: Constant::WatchKind::CREATE | Constant::WatchKind::CHANGE | Constant::WatchKind::DELETE
57
+ )
58
+ ]
59
+ )
60
+ )
61
+ ]
62
+ )
63
+ )
64
+ end
65
+ # rubocop:enable Layout/LineLength, Metrics/MethodLength
66
+
67
+ def workspace_did_change_watched_files(changes)
68
+ return unless changes.any? { |change| change[:uri].end_with?('.rubocop.yml') }
69
+
70
+ @wraps_built_in_lsp_runtime.init!
71
+
72
+ ::RuboCop::LSP::Logger(<<~MESSAGE, prefix: '[RuboCop]')
73
+ Re-initialized RuboCop LSP addon #{::RuboCop::Version::STRING} due to .rubocop.yml file change.
74
+ MESSAGE
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../rubocop/lsp/runtime'
4
+
5
+ module RubyLsp
6
+ module RuboCop
7
+ # Wrap RuboCop's built-in runtime for Ruby LSP's add-on.
8
+ class WrapsBuiltinLspRuntime
9
+ include RubyLsp::Requests::Support::Formatter
10
+
11
+ def initialize
12
+ init!
13
+ end
14
+
15
+ def init!
16
+ config = ::RuboCop::ConfigStore.new
17
+
18
+ @runtime = ::RuboCop::LSP::Runtime.new(config)
19
+ end
20
+
21
+ def run_diagnostic(uri, document)
22
+ @runtime.offenses(uri_to_path(uri), document.source, document.encoding)
23
+ end
24
+
25
+ def run_formatting(uri, document)
26
+ @runtime.format(uri_to_path(uri), document.source, command: 'rubocop.formatAutocorrects')
27
+ end
28
+
29
+ def run_range_formatting(_uri, _partial_source, _base_indentation)
30
+ # Not yet supported. Should return the formatted version of `partial_source` which is
31
+ # a partial selection of the entire document. For example, it should not try to add
32
+ # a frozen_string_literal magic comment and all style corrections should start from
33
+ # the `base_indentation`.
34
+ nil
35
+ end
36
+
37
+ private
38
+
39
+ # duplicated from: lib/standard/lsp/routes.rb
40
+ # modified to incorporate Ruby LSP's to_standardized_path method
41
+ def uri_to_path(uri)
42
+ if uri.respond_to?(:to_standardized_path) && (standardized_path = uri.to_standardized_path)
43
+ standardized_path
44
+ else
45
+ uri.to_s.delete_prefix('file://')
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.69.1
4
+ version: 1.70.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
8
8
  - Jonas Arvidsson
9
9
  - Yuji Nakayama
10
- autorequire:
10
+ autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2024-12-03 00:00:00.000000000 Z
13
+ date: 2025-01-10 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json
@@ -266,6 +266,7 @@ files:
266
266
  - lib/rubocop/cop/ignored_node.rb
267
267
  - lib/rubocop/cop/internal_affairs.rb
268
268
  - lib/rubocop/cop/internal_affairs/cop_description.rb
269
+ - lib/rubocop/cop/internal_affairs/cop_enabled.rb
269
270
  - lib/rubocop/cop/internal_affairs/create_empty_file.rb
270
271
  - lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb
271
272
  - lib/rubocop/cop/internal_affairs/example_description.rb
@@ -411,6 +412,7 @@ files:
411
412
  - lib/rubocop/cop/lint/circular_argument_reference.rb
412
413
  - lib/rubocop/cop/lint/constant_definition_in_block.rb
413
414
  - lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb
415
+ - lib/rubocop/cop/lint/constant_reassignment.rb
414
416
  - lib/rubocop/cop/lint/constant_resolution.rb
415
417
  - lib/rubocop/cop/lint/debugger.rb
416
418
  - lib/rubocop/cop/lint/deprecated_class_methods.rb
@@ -510,6 +512,7 @@ files:
510
512
  - lib/rubocop/cop/lint/shadowed_argument.rb
511
513
  - lib/rubocop/cop/lint/shadowed_exception.rb
512
514
  - lib/rubocop/cop/lint/shadowing_outer_local_variable.rb
515
+ - lib/rubocop/cop/lint/shared_mutable_default.rb
513
516
  - lib/rubocop/cop/lint/struct_new_override.rb
514
517
  - lib/rubocop/cop/lint/suppressed_exception.rb
515
518
  - lib/rubocop/cop/lint/symbol_conversion.rb
@@ -770,6 +773,7 @@ files:
770
773
  - lib/rubocop/cop/style/inverse_methods.rb
771
774
  - lib/rubocop/cop/style/invertible_unless_condition.rb
772
775
  - lib/rubocop/cop/style/ip_addresses.rb
776
+ - lib/rubocop/cop/style/it_assignment.rb
773
777
  - lib/rubocop/cop/style/keyword_arguments_merging.rb
774
778
  - lib/rubocop/cop/style/keyword_parameters_order.rb
775
779
  - lib/rubocop/cop/style/lambda.rb
@@ -985,11 +989,13 @@ files:
985
989
  - lib/rubocop/formatter/worst_offenders_formatter.rb
986
990
  - lib/rubocop/lockfile.rb
987
991
  - lib/rubocop/lsp.rb
992
+ - lib/rubocop/lsp/diagnostic.rb
988
993
  - lib/rubocop/lsp/logger.rb
989
994
  - lib/rubocop/lsp/routes.rb
990
995
  - lib/rubocop/lsp/runtime.rb
991
996
  - lib/rubocop/lsp/server.rb
992
997
  - lib/rubocop/lsp/severity.rb
998
+ - lib/rubocop/lsp/stdin_runner.rb
993
999
  - lib/rubocop/magic_comment.rb
994
1000
  - lib/rubocop/name_similarity.rb
995
1001
  - lib/rubocop/options.rb
@@ -1030,17 +1036,19 @@ files:
1030
1036
  - lib/rubocop/version.rb
1031
1037
  - lib/rubocop/warning.rb
1032
1038
  - lib/rubocop/yaml_duplication_checker.rb
1039
+ - lib/ruby_lsp/rubocop/addon.rb
1040
+ - lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb
1033
1041
  homepage: https://github.com/rubocop/rubocop
1034
1042
  licenses:
1035
1043
  - MIT
1036
1044
  metadata:
1037
1045
  homepage_uri: https://rubocop.org/
1038
- changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.69.1
1046
+ changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.70.0
1039
1047
  source_code_uri: https://github.com/rubocop/rubocop/
1040
- documentation_uri: https://docs.rubocop.org/rubocop/1.69/
1048
+ documentation_uri: https://docs.rubocop.org/rubocop/1.70/
1041
1049
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues
1042
1050
  rubygems_mfa_required: 'true'
1043
- post_install_message:
1051
+ post_install_message:
1044
1052
  rdoc_options: []
1045
1053
  require_paths:
1046
1054
  - lib
@@ -1055,8 +1063,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1055
1063
  - !ruby/object:Gem::Version
1056
1064
  version: '0'
1057
1065
  requirements: []
1058
- rubygems_version: 3.3.7
1059
- signing_key:
1066
+ rubygems_version: 3.4.22
1067
+ signing_key:
1060
1068
  specification_version: 4
1061
1069
  summary: Automatic Ruby code style checking tool.
1062
1070
  test_files: []