rubocop 1.51.0 → 1.54.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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +62 -3
- data/lib/rubocop/cli/command/lsp.rb +19 -0
- data/lib/rubocop/cli.rb +3 -0
- data/lib/rubocop/config_loader_resolver.rb +4 -3
- data/lib/rubocop/cop/base.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_version.rb +2 -2
- data/lib/rubocop/cop/gemspec/dependency_version.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +32 -8
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +3 -3
- data/lib/rubocop/cop/layout/class_structure.rb +7 -0
- data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +27 -4
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +3 -1
- data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -1
- data/lib/rubocop/cop/lint/debugger.rb +9 -5
- data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +46 -19
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -2
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +1 -1
- data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +1 -2
- data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
- data/lib/rubocop/cop/lint/missing_super.rb +34 -5
- data/lib/rubocop/cop/lint/mixed_case_range.rb +111 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +5 -0
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +8 -3
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
- data/lib/rubocop/cop/lint/shadowed_exception.rb +5 -11
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/useless_assignment.rb +4 -1
- data/lib/rubocop/cop/lint/void.rb +12 -18
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +30 -2
- data/lib/rubocop/cop/migration/department_name.rb +2 -2
- data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +3 -3
- data/lib/rubocop/cop/naming/variable_name.rb +6 -1
- data/lib/rubocop/cop/style/accessor_grouping.rb +5 -1
- data/lib/rubocop/cop/style/begin_block.rb +1 -2
- data/lib/rubocop/cop/style/block_comments.rb +1 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +3 -3
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
- data/lib/rubocop/cop/style/class_equality_comparison.rb +17 -39
- data/lib/rubocop/cop/style/collection_compact.rb +6 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +3 -1
- data/lib/rubocop/cop/style/dir.rb +1 -1
- data/lib/rubocop/cop/style/dir_empty.rb +8 -14
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
- data/lib/rubocop/cop/style/exact_regexp_match.rb +8 -2
- data/lib/rubocop/cop/style/file_read.rb +2 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -22
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +6 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +1 -1
- data/lib/rubocop/cop/style/lambda.rb +3 -3
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +3 -4
- data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/redundant_conditional.rb +1 -1
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +38 -0
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +101 -0
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +2 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +100 -0
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +2 -1
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +3 -1
- data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -0
- data/lib/rubocop/cop/style/require_order.rb +2 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +81 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +15 -5
- data/lib/rubocop/cop/style/signal_exception.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +3 -1
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
- data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +4 -2
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/utils/regexp_ranges.rb +100 -0
- data/lib/rubocop/cop/variable_force/assignment.rb +43 -4
- data/lib/rubocop/cop/variable_force.rb +1 -0
- data/lib/rubocop/cops_documentation_generator.rb +1 -1
- data/lib/rubocop/ext/regexp_parser.rb +4 -1
- data/lib/rubocop/lsp/logger.rb +22 -0
- data/lib/rubocop/lsp/routes.rb +231 -0
- data/lib/rubocop/lsp/runtime.rb +82 -0
- data/lib/rubocop/lsp/server.rb +66 -0
- data/lib/rubocop/lsp/severity.rb +27 -0
- data/lib/rubocop/options.rb +11 -1
- data/lib/rubocop/server/client_command/exec.rb +2 -1
- data/lib/rubocop/version.rb +8 -4
- data/lib/rubocop.rb +12 -0
- metadata +36 -5
@@ -0,0 +1,231 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'severity'
|
4
|
+
|
5
|
+
#
|
6
|
+
# This code is based on https://github.com/standardrb/standard.
|
7
|
+
#
|
8
|
+
# Copyright (c) 2023 Test Double, Inc.
|
9
|
+
#
|
10
|
+
# The MIT License (MIT)
|
11
|
+
#
|
12
|
+
# https://github.com/standardrb/standard/blob/main/LICENSE.txt
|
13
|
+
#
|
14
|
+
module RuboCop
|
15
|
+
module Lsp
|
16
|
+
# Routes for Language Server Protocol of RuboCop.
|
17
|
+
# @api private
|
18
|
+
class Routes
|
19
|
+
def self.handle(name, &block)
|
20
|
+
define_method("handle_#{name}", &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
private_class_method :handle
|
24
|
+
|
25
|
+
def initialize(server)
|
26
|
+
@server = server
|
27
|
+
|
28
|
+
@text_cache = {}
|
29
|
+
end
|
30
|
+
|
31
|
+
def for(name)
|
32
|
+
name = "handle_#{name}"
|
33
|
+
return unless respond_to?(name)
|
34
|
+
|
35
|
+
method(name)
|
36
|
+
end
|
37
|
+
|
38
|
+
handle 'initialize' do |request|
|
39
|
+
@server.configure(safe_autocorrect: safe_autocorrect?(request))
|
40
|
+
|
41
|
+
@server.write(
|
42
|
+
id: request[:id],
|
43
|
+
result: LanguageServer::Protocol::Interface::InitializeResult.new(
|
44
|
+
capabilities: LanguageServer::Protocol::Interface::ServerCapabilities.new(
|
45
|
+
document_formatting_provider: true,
|
46
|
+
diagnostic_provider: true,
|
47
|
+
text_document_sync: LanguageServer::Protocol::Interface::TextDocumentSyncOptions.new(
|
48
|
+
change: LanguageServer::Protocol::Constant::TextDocumentSyncKind::FULL,
|
49
|
+
open_close: true
|
50
|
+
)
|
51
|
+
)
|
52
|
+
)
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
handle 'initialized' do |_request|
|
57
|
+
version = RuboCop::Version::STRING
|
58
|
+
|
59
|
+
Logger.log("RuboCop #{version} language server initialized, PID #{Process.pid}")
|
60
|
+
end
|
61
|
+
|
62
|
+
handle 'shutdown' do |request|
|
63
|
+
Logger.log('Client asked to shutdown RuboCop language server.')
|
64
|
+
@server.stop do
|
65
|
+
@server.write(id: request[:id], result: nil)
|
66
|
+
Logger.log('Exiting...')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
handle 'textDocument/diagnostic' do |request|
|
71
|
+
doc = request[:params][:textDocument]
|
72
|
+
result = diagnostic(doc[:uri], doc[:text])
|
73
|
+
@server.write(result)
|
74
|
+
end
|
75
|
+
|
76
|
+
handle 'textDocument/didChange' do |request|
|
77
|
+
params = request[:params]
|
78
|
+
result = diagnostic(params[:textDocument][:uri], params[:contentChanges][0][:text])
|
79
|
+
@server.write(result)
|
80
|
+
end
|
81
|
+
|
82
|
+
handle 'textDocument/didOpen' do |request|
|
83
|
+
doc = request[:params][:textDocument]
|
84
|
+
result = diagnostic(doc[:uri], doc[:text])
|
85
|
+
@server.write(result)
|
86
|
+
end
|
87
|
+
|
88
|
+
handle 'textDocument/didClose' do |request|
|
89
|
+
@text_cache.delete(request.dig(:params, :textDocument, :uri))
|
90
|
+
end
|
91
|
+
|
92
|
+
handle 'textDocument/formatting' do |request|
|
93
|
+
uri = request[:params][:textDocument][:uri]
|
94
|
+
@server.write(id: request[:id], result: format_file(uri))
|
95
|
+
end
|
96
|
+
|
97
|
+
handle 'workspace/didChangeConfiguration' do |_request|
|
98
|
+
Logger.log('Ignoring workspace/didChangeConfiguration')
|
99
|
+
end
|
100
|
+
|
101
|
+
handle 'workspace/didChangeWatchedFiles' do |request|
|
102
|
+
changed = request[:params][:changes].any? do |change|
|
103
|
+
change[:uri].end_with?(RuboCop::ConfigFinder::DOTFILE)
|
104
|
+
end
|
105
|
+
|
106
|
+
if changed
|
107
|
+
Logger.log('Configuration file changed; restart required')
|
108
|
+
@server.stop
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
handle 'workspace/executeCommand' do |request|
|
113
|
+
if request[:params][:command] == 'rubocop.formatAutocorrects'
|
114
|
+
uri = request[:params][:arguments][0][:uri]
|
115
|
+
@server.write(
|
116
|
+
id: request[:id],
|
117
|
+
method: 'workspace/applyEdit',
|
118
|
+
params: {
|
119
|
+
label: 'Format with RuboCop autocorrects',
|
120
|
+
edit: {
|
121
|
+
changes: {
|
122
|
+
uri => format_file(uri)
|
123
|
+
}
|
124
|
+
}
|
125
|
+
}
|
126
|
+
)
|
127
|
+
else
|
128
|
+
handle_unsupported_method(request, request[:params][:command])
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
handle 'textDocument/willSave' do |_request|
|
133
|
+
# Nothing to do
|
134
|
+
end
|
135
|
+
|
136
|
+
handle 'textDocument/didSave' do |_request|
|
137
|
+
# Nothing to do
|
138
|
+
end
|
139
|
+
|
140
|
+
handle '$/cancelRequest' do |_request|
|
141
|
+
# Can't cancel anything because single-threaded
|
142
|
+
end
|
143
|
+
|
144
|
+
handle '$/setTrace' do |_request|
|
145
|
+
# No-op, we log everything
|
146
|
+
end
|
147
|
+
|
148
|
+
def handle_unsupported_method(request, method = request[:method])
|
149
|
+
@server.write(
|
150
|
+
id: request[:id],
|
151
|
+
error: LanguageServer::Protocol::Interface::ResponseError.new(
|
152
|
+
code: LanguageServer::Protocol::Constant::ErrorCodes::METHOD_NOT_FOUND,
|
153
|
+
message: "Unsupported Method: #{method}"
|
154
|
+
)
|
155
|
+
)
|
156
|
+
Logger.log("Unsupported Method: #{method}")
|
157
|
+
end
|
158
|
+
|
159
|
+
def handle_method_missing(request)
|
160
|
+
return unless request.key?(:id)
|
161
|
+
|
162
|
+
@server.write(id: request[:id], result: nil)
|
163
|
+
end
|
164
|
+
|
165
|
+
private
|
166
|
+
|
167
|
+
def safe_autocorrect?(request)
|
168
|
+
safe_autocorrect = request.dig(:params, :initializationOptions, :safeAutocorrect)
|
169
|
+
|
170
|
+
safe_autocorrect.nil? || safe_autocorrect == true
|
171
|
+
end
|
172
|
+
|
173
|
+
def format_file(file_uri)
|
174
|
+
unless (text = @text_cache[file_uri])
|
175
|
+
Logger.log("Format request arrived before text synchronized; skipping: `#{file_uri}'")
|
176
|
+
|
177
|
+
return []
|
178
|
+
end
|
179
|
+
|
180
|
+
new_text = @server.format(remove_file_protocol_from(file_uri), text)
|
181
|
+
|
182
|
+
return [] if new_text == text
|
183
|
+
|
184
|
+
[
|
185
|
+
newText: new_text,
|
186
|
+
range: {
|
187
|
+
start: { line: 0, character: 0 },
|
188
|
+
end: { line: text.count("\n") + 1, character: 0 }
|
189
|
+
}
|
190
|
+
]
|
191
|
+
end
|
192
|
+
|
193
|
+
def diagnostic(file_uri, text)
|
194
|
+
@text_cache[file_uri] = text
|
195
|
+
offenses = @server.offenses(remove_file_protocol_from(file_uri), text)
|
196
|
+
diagnostics = offenses.map { |offense| to_diagnostic(offense) }
|
197
|
+
|
198
|
+
{
|
199
|
+
method: 'textDocument/publishDiagnostics',
|
200
|
+
params: {
|
201
|
+
uri: file_uri,
|
202
|
+
diagnostics: diagnostics
|
203
|
+
}
|
204
|
+
}
|
205
|
+
end
|
206
|
+
|
207
|
+
def remove_file_protocol_from(uri)
|
208
|
+
uri.delete_prefix('file://')
|
209
|
+
end
|
210
|
+
|
211
|
+
def to_diagnostic(offense)
|
212
|
+
code = offense[:cop_name]
|
213
|
+
message = offense[:message]
|
214
|
+
loc = offense[:location]
|
215
|
+
rubocop_severity = offense[:severity]
|
216
|
+
severity = Severity.find_by(rubocop_severity)
|
217
|
+
|
218
|
+
{
|
219
|
+
code: code, message: message, range: to_range(loc), severity: severity, source: 'rubocop'
|
220
|
+
}
|
221
|
+
end
|
222
|
+
|
223
|
+
def to_range(location)
|
224
|
+
{
|
225
|
+
start: { character: location[:start_column] - 1, line: location[:start_line] - 1 },
|
226
|
+
end: { character: location[:last_column] - 1, line: location[:last_line] - 1 }
|
227
|
+
}
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
@@ -0,0 +1,82 @@
|
|
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
|
+
# Runtime for Language Server Protocol of RuboCop.
|
15
|
+
# @api private
|
16
|
+
class Runtime
|
17
|
+
attr_writer :safe_autocorrect
|
18
|
+
|
19
|
+
def initialize(config_store)
|
20
|
+
@config_store = config_store
|
21
|
+
@logged_paths = []
|
22
|
+
@safe_autocorrect = true
|
23
|
+
end
|
24
|
+
|
25
|
+
# This abuses the `--stdin` option of rubocop and reads the formatted text
|
26
|
+
# from the `options[:stdin]` that rubocop mutates. This depends on
|
27
|
+
# `parallel: false` as well as the fact that RuboCop doesn't otherwise dup
|
28
|
+
# or reassign that options object. Risky business!
|
29
|
+
#
|
30
|
+
# Reassigning `options[:stdin]` is done here:
|
31
|
+
# https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/cop/team.rb#L131
|
32
|
+
# Printing `options[:stdin]`
|
33
|
+
# https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/cli/command/execute_runner.rb#L95
|
34
|
+
# Setting `parallel: true` would break this here:
|
35
|
+
# https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/runner.rb#L72
|
36
|
+
def format(path, text)
|
37
|
+
formatting_options = {
|
38
|
+
stdin: text, force_exclusion: true, autocorrect: true, safe_autocorrect: @safe_autocorrect
|
39
|
+
}
|
40
|
+
|
41
|
+
redirect_stdout { run_rubocop(formatting_options, path) }
|
42
|
+
|
43
|
+
formatting_options[:stdin]
|
44
|
+
end
|
45
|
+
|
46
|
+
def offenses(path, text)
|
47
|
+
diagnostic_options = {
|
48
|
+
stdin: text, force_exclusion: true, formatters: ['json'], format: 'json'
|
49
|
+
}
|
50
|
+
|
51
|
+
json = redirect_stdout { run_rubocop(diagnostic_options, path) }
|
52
|
+
results = JSON.parse(json, symbolize_names: true)
|
53
|
+
|
54
|
+
if results[:files].empty?
|
55
|
+
unless @logged_paths.include?(path)
|
56
|
+
Logger.log "Ignoring file, per configuration: #{path}"
|
57
|
+
@logged_paths << path
|
58
|
+
end
|
59
|
+
return []
|
60
|
+
end
|
61
|
+
|
62
|
+
results.dig(:files, 0, :offenses)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def redirect_stdout(&block)
|
68
|
+
stdout = StringIO.new
|
69
|
+
|
70
|
+
RuboCop::Server::Helper.redirect(stdout: stdout, &block)
|
71
|
+
|
72
|
+
stdout.string
|
73
|
+
end
|
74
|
+
|
75
|
+
def run_rubocop(options, path)
|
76
|
+
runner = RuboCop::Runner.new(options, @config_store)
|
77
|
+
|
78
|
+
runner.run([path])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'language_server-protocol'
|
4
|
+
require_relative 'logger'
|
5
|
+
require_relative 'routes'
|
6
|
+
require_relative 'runtime'
|
7
|
+
|
8
|
+
#
|
9
|
+
# This code is based on https://github.com/standardrb/standard.
|
10
|
+
#
|
11
|
+
# Copyright (c) 2023 Test Double, Inc.
|
12
|
+
#
|
13
|
+
# The MIT License (MIT)
|
14
|
+
#
|
15
|
+
# https://github.com/standardrb/standard/blob/main/LICENSE.txt
|
16
|
+
#
|
17
|
+
module RuboCop
|
18
|
+
module Lsp
|
19
|
+
# Language Server Protocol of RuboCop.
|
20
|
+
# @api private
|
21
|
+
class Server
|
22
|
+
def initialize(config_store)
|
23
|
+
@reader = LanguageServer::Protocol::Transport::Io::Reader.new($stdin)
|
24
|
+
@writer = LanguageServer::Protocol::Transport::Io::Writer.new($stdout)
|
25
|
+
@runtime = RuboCop::Lsp::Runtime.new(config_store)
|
26
|
+
@routes = Routes.new(self)
|
27
|
+
end
|
28
|
+
|
29
|
+
def start
|
30
|
+
@reader.read do |request|
|
31
|
+
if !request.key?(:method)
|
32
|
+
@routes.handle_method_missing(request)
|
33
|
+
elsif (route = @routes.for(request[:method]))
|
34
|
+
route.call(request)
|
35
|
+
else
|
36
|
+
@routes.handle_unsupported_method(request)
|
37
|
+
end
|
38
|
+
rescue StandardError => e
|
39
|
+
Logger.log("Error #{e.class} #{e.message[0..100]}")
|
40
|
+
Logger.log(e.backtrace.inspect)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def write(response)
|
45
|
+
@writer.write(response)
|
46
|
+
end
|
47
|
+
|
48
|
+
def format(path, text)
|
49
|
+
@runtime.format(path, text)
|
50
|
+
end
|
51
|
+
|
52
|
+
def offenses(path, text)
|
53
|
+
@runtime.offenses(path, text)
|
54
|
+
end
|
55
|
+
|
56
|
+
def configure(safe_autocorrect: true)
|
57
|
+
@runtime.safe_autocorrect = safe_autocorrect
|
58
|
+
end
|
59
|
+
|
60
|
+
def stop(&block)
|
61
|
+
at_exit(&block) if block
|
62
|
+
exit
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Lsp
|
5
|
+
# Severity for Language Server Protocol of RuboCop.
|
6
|
+
# @api private
|
7
|
+
class Severity
|
8
|
+
SEVERITIES = {
|
9
|
+
fatal: LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR,
|
10
|
+
error: LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR,
|
11
|
+
warning: LanguageServer::Protocol::Constant::DiagnosticSeverity::WARNING,
|
12
|
+
convention: LanguageServer::Protocol::Constant::DiagnosticSeverity::INFORMATION,
|
13
|
+
refactor: LanguageServer::Protocol::Constant::DiagnosticSeverity::HINT,
|
14
|
+
info: LanguageServer::Protocol::Constant::DiagnosticSeverity::HINT
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
def self.find_by(rubocop_severity)
|
18
|
+
if (severity = SEVERITIES[rubocop_severity.to_sym])
|
19
|
+
return severity
|
20
|
+
end
|
21
|
+
|
22
|
+
Logger.log("Unknown severity: #{rubocop_severity}")
|
23
|
+
LanguageServer::Protocol::Constant::DiagnosticSeverity::HINT
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/rubocop/options.rb
CHANGED
@@ -16,7 +16,7 @@ module RuboCop
|
|
16
16
|
'root of the project. RuboCop will use this path to determine which ' \
|
17
17
|
'cops are enabled (via eg. Include/Exclude), and so that certain cops ' \
|
18
18
|
'like Naming/FileName can be checked.'
|
19
|
-
EXITING_OPTIONS = %i[version verbose_version show_cops show_docs_url].freeze
|
19
|
+
EXITING_OPTIONS = %i[version verbose_version show_cops show_docs_url lsp].freeze
|
20
20
|
DEFAULT_MAXIMUM_EXCLUSION_ITEMS = 15
|
21
21
|
|
22
22
|
def initialize
|
@@ -49,12 +49,14 @@ module RuboCop
|
|
49
49
|
|
50
50
|
private
|
51
51
|
|
52
|
+
# rubocop:disable Metrics/AbcSize
|
52
53
|
def define_options
|
53
54
|
OptionParser.new do |opts|
|
54
55
|
opts.banner = rainbow.wrap('Usage: rubocop [options] [file1, file2, ...]').bright
|
55
56
|
|
56
57
|
add_check_options(opts)
|
57
58
|
add_cache_options(opts)
|
59
|
+
add_lsp_option(opts)
|
58
60
|
add_server_options(opts)
|
59
61
|
add_output_options(opts)
|
60
62
|
add_autocorrection_options(opts)
|
@@ -66,6 +68,7 @@ module RuboCop
|
|
66
68
|
add_profile_options(opts) if RUBY_ENGINE == 'ruby' && !Platform.windows?
|
67
69
|
end
|
68
70
|
end
|
71
|
+
# rubocop:enable Metrics/AbcSize
|
69
72
|
|
70
73
|
def add_check_options(opts) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
71
74
|
section(opts, 'Basic Options') do # rubocop:disable Metrics/BlockLength
|
@@ -205,6 +208,12 @@ module RuboCop
|
|
205
208
|
end
|
206
209
|
end
|
207
210
|
|
211
|
+
def add_lsp_option(opts)
|
212
|
+
section(opts, 'LSP Option') do
|
213
|
+
option(opts, '--lsp')
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
208
217
|
def add_server_options(opts)
|
209
218
|
section(opts, 'Server Options') do
|
210
219
|
option(opts, '--[no-]server')
|
@@ -620,6 +629,7 @@ module RuboCop
|
|
620
629
|
stop_server: 'Stop server process.',
|
621
630
|
server_status: 'Show server status.',
|
622
631
|
no_detach: 'Run the server process in the foreground.',
|
632
|
+
lsp: 'Start a language server listening on STDIN.',
|
623
633
|
raise_cop_error: ['Raise cop-related errors with cause and location.',
|
624
634
|
'This is used to prevent cops from failing silently.',
|
625
635
|
'Default is false.'],
|
@@ -18,10 +18,11 @@ module RuboCop
|
|
18
18
|
def run
|
19
19
|
ensure_server!
|
20
20
|
Cache.status_path.delete if Cache.status_path.file?
|
21
|
+
read_stdin = ARGV.include?('-s') || ARGV.include?('--stdin')
|
21
22
|
send_request(
|
22
23
|
command: 'exec',
|
23
24
|
args: ARGV.dup,
|
24
|
-
body: $stdin.
|
25
|
+
body: read_stdin ? $stdin.read : ''
|
25
26
|
)
|
26
27
|
warn stderr unless stderr.empty?
|
27
28
|
status
|
data/lib/rubocop/version.rb
CHANGED
@@ -3,15 +3,19 @@
|
|
3
3
|
module RuboCop
|
4
4
|
# This module holds the RuboCop version information.
|
5
5
|
module Version
|
6
|
-
STRING = '1.
|
6
|
+
STRING = '1.54.1'
|
7
7
|
|
8
8
|
MSG = '%<version>s (using Parser %<parser_version>s, ' \
|
9
9
|
'rubocop-ast %<rubocop_ast_version>s, ' \
|
10
10
|
'running on %<ruby_engine>s %<ruby_version>s)%<server_mode>s [%<ruby_platform>s]'
|
11
11
|
|
12
|
-
CANONICAL_FEATURE_NAMES = {
|
13
|
-
|
14
|
-
|
12
|
+
CANONICAL_FEATURE_NAMES = {
|
13
|
+
'Rspec' => 'RSpec', 'Graphql' => 'GraphQL', 'Md' => 'Markdown', 'Factory_bot' => 'FactoryBot',
|
14
|
+
'Thread_safety' => 'ThreadSafety'
|
15
|
+
}.freeze
|
16
|
+
EXTENSION_PATH_NAMES = {
|
17
|
+
'rubocop-md' => 'markdown', 'rubocop-factory_bot' => 'factory_bot'
|
18
|
+
}.freeze
|
15
19
|
|
16
20
|
# @api private
|
17
21
|
def self.version(debug: false, env: nil)
|
data/lib/rubocop.rb
CHANGED
@@ -69,6 +69,7 @@ require_relative 'rubocop/cop/mixin/alignment'
|
|
69
69
|
require_relative 'rubocop/cop/mixin/allowed_identifiers'
|
70
70
|
require_relative 'rubocop/cop/mixin/allowed_methods'
|
71
71
|
require_relative 'rubocop/cop/mixin/allowed_pattern'
|
72
|
+
require_relative 'rubocop/cop/mixin/allowed_receivers'
|
72
73
|
require_relative 'rubocop/cop/mixin/auto_corrector' # rubocop:todo Naming/InclusiveLanguage
|
73
74
|
require_relative 'rubocop/cop/mixin/check_assignment'
|
74
75
|
require_relative 'rubocop/cop/mixin/check_line_breakable'
|
@@ -138,6 +139,7 @@ require_relative 'rubocop/cop/mixin/comments_help' # relies on visibility_help
|
|
138
139
|
require_relative 'rubocop/cop/mixin/def_node' # relies on visibility_help
|
139
140
|
|
140
141
|
require_relative 'rubocop/cop/utils/format_string'
|
142
|
+
require_relative 'rubocop/cop/utils/regexp_ranges'
|
141
143
|
|
142
144
|
require_relative 'rubocop/cop/migration/department_name'
|
143
145
|
|
@@ -335,6 +337,7 @@ require_relative 'rubocop/cop/lint/literal_in_interpolation'
|
|
335
337
|
require_relative 'rubocop/cop/lint/loop'
|
336
338
|
require_relative 'rubocop/cop/lint/missing_cop_enable_directive'
|
337
339
|
require_relative 'rubocop/cop/lint/missing_super'
|
340
|
+
require_relative 'rubocop/cop/lint/mixed_case_range'
|
338
341
|
require_relative 'rubocop/cop/lint/mixed_regexp_capture_types'
|
339
342
|
require_relative 'rubocop/cop/lint/multiple_comparison'
|
340
343
|
require_relative 'rubocop/cop/lint/nested_method_definition'
|
@@ -357,6 +360,7 @@ require_relative 'rubocop/cop/lint/rand_one'
|
|
357
360
|
require_relative 'rubocop/cop/lint/redundant_cop_disable_directive'
|
358
361
|
require_relative 'rubocop/cop/lint/redundant_cop_enable_directive'
|
359
362
|
require_relative 'rubocop/cop/lint/redundant_dir_glob_sort'
|
363
|
+
require_relative 'rubocop/cop/lint/redundant_regexp_quantifiers'
|
360
364
|
require_relative 'rubocop/cop/lint/redundant_require_statement'
|
361
365
|
require_relative 'rubocop/cop/lint/redundant_safe_navigation'
|
362
366
|
require_relative 'rubocop/cop/lint/redundant_splat_expansion'
|
@@ -558,15 +562,20 @@ require_relative 'rubocop/cop/style/multiline_in_pattern_then'
|
|
558
562
|
require_relative 'rubocop/cop/style/numbered_parameters'
|
559
563
|
require_relative 'rubocop/cop/style/open_struct_use'
|
560
564
|
require_relative 'rubocop/cop/style/operator_method_call'
|
565
|
+
require_relative 'rubocop/cop/style/redundant_array_constructor'
|
561
566
|
require_relative 'rubocop/cop/style/redundant_assignment'
|
562
567
|
require_relative 'rubocop/cop/style/redundant_constant_base'
|
568
|
+
require_relative 'rubocop/cop/style/redundant_current_directory_in_path'
|
563
569
|
require_relative 'rubocop/cop/style/redundant_double_splat_hash_braces'
|
564
570
|
require_relative 'rubocop/cop/style/redundant_each'
|
565
571
|
require_relative 'rubocop/cop/style/redundant_fetch_block'
|
566
572
|
require_relative 'rubocop/cop/style/redundant_file_extension_in_require'
|
573
|
+
require_relative 'rubocop/cop/style/redundant_filter_chain'
|
567
574
|
require_relative 'rubocop/cop/style/redundant_heredoc_delimiter_quotes'
|
568
575
|
require_relative 'rubocop/cop/style/redundant_initialize'
|
569
576
|
require_relative 'rubocop/cop/style/redundant_line_continuation'
|
577
|
+
require_relative 'rubocop/cop/style/redundant_regexp_argument'
|
578
|
+
require_relative 'rubocop/cop/style/redundant_regexp_constructor'
|
570
579
|
require_relative 'rubocop/cop/style/redundant_self_assignment'
|
571
580
|
require_relative 'rubocop/cop/style/redundant_self_assignment_branch'
|
572
581
|
require_relative 'rubocop/cop/style/require_order'
|
@@ -644,6 +653,7 @@ require_relative 'rubocop/cop/style/regexp_literal'
|
|
644
653
|
require_relative 'rubocop/cop/style/rescue_modifier'
|
645
654
|
require_relative 'rubocop/cop/style/rescue_standard_error'
|
646
655
|
require_relative 'rubocop/cop/style/return_nil'
|
656
|
+
require_relative 'rubocop/cop/style/return_nil_in_predicate_method_definition'
|
647
657
|
require_relative 'rubocop/cop/style/safe_navigation'
|
648
658
|
require_relative 'rubocop/cop/style/sample'
|
649
659
|
require_relative 'rubocop/cop/style/select_by_regexp'
|
@@ -690,6 +700,7 @@ require_relative 'rubocop/cop/style/when_then'
|
|
690
700
|
require_relative 'rubocop/cop/style/while_until_do'
|
691
701
|
require_relative 'rubocop/cop/style/while_until_modifier'
|
692
702
|
require_relative 'rubocop/cop/style/word_array'
|
703
|
+
require_relative 'rubocop/cop/style/yaml_file_read'
|
693
704
|
require_relative 'rubocop/cop/style/yoda_condition'
|
694
705
|
require_relative 'rubocop/cop/style/yoda_expression'
|
695
706
|
require_relative 'rubocop/cop/style/zero_length_predicate'
|
@@ -735,6 +746,7 @@ require_relative 'rubocop/cli/command/base'
|
|
735
746
|
require_relative 'rubocop/cli/command/auto_generate_config'
|
736
747
|
require_relative 'rubocop/cli/command/execute_runner'
|
737
748
|
require_relative 'rubocop/cli/command/init_dotfile'
|
749
|
+
require_relative 'rubocop/cli/command/lsp'
|
738
750
|
require_relative 'rubocop/cli/command/show_cops'
|
739
751
|
require_relative 'rubocop/cli/command/show_docs_url'
|
740
752
|
require_relative 'rubocop/cli/command/suggest_extensions'
|