ruby-lsp 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/Gemfile +3 -2
- data/Gemfile.lock +23 -21
- data/README.md +2 -1
- data/Rakefile +8 -1
- data/VERSION +1 -1
- data/bin/console +19 -0
- data/lib/ruby_lsp/cli.rb +1 -0
- data/lib/ruby_lsp/handler.rb +20 -3
- data/lib/ruby_lsp/requests/code_actions.rb +2 -0
- data/lib/ruby_lsp/requests/diagnostics.rb +14 -9
- data/lib/ruby_lsp/requests/document_highlight.rb +2 -0
- data/lib/ruby_lsp/requests/document_symbol.rb +2 -0
- data/lib/ruby_lsp/requests/folding_ranges.rb +21 -20
- data/lib/ruby_lsp/requests/formatting.rb +20 -16
- data/lib/ruby_lsp/requests/selection_ranges.rb +2 -0
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +73 -9
- data/lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb +61 -0
- data/lib/ruby_lsp/requests/support/rubocop_formatting_runner.rb +50 -0
- data/lib/ruby_lsp/requests.rb +11 -1
- data/rakelib/check_docs.rake +29 -5
- data/ruby-lsp.gemspec +5 -4
- metadata +8 -20
- data/lib/ruby_lsp/requests/rubocop_request.rb +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f81baa8f09011e5130c955c4c5d2a33583379b0b073caee556719b874efc320e
|
4
|
+
data.tar.gz: 55a664f923d93bda9ddb06624303f889123496c672c46b31ea71c629cfa96a81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a872f34699bfaa4f955c714c4e49eed52e87b009afc0a642d0ad434956f6a14690188ad9c359cc7aadd53e96fbd0d5d320e00aa263265e1ce3d3e369e8bd124
|
7
|
+
data.tar.gz: 06444ea3e08b961445db6cb1a9093fc322b40ddf47daa00deb09a77f3b114014be8f525d7d391430b578b7916042bf345759d113c74e41a8ea51d65791abe69c
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,18 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.2.0]
|
10
|
+
|
11
|
+
- Add semantic token for keyword and keyword rest params (https://github.com/Shopify/ruby-lsp/pull/142)
|
12
|
+
- Return error responses on exceptions (https://github.com/Shopify/ruby-lsp/pull/160)
|
13
|
+
- Sanitize home directory for telemetry (https://github.com/Shopify/ruby-lsp/pull/171)
|
14
|
+
- Avoid adding semantic tokens for special methods (https://github.com/Shopify/ruby-lsp/pull/162)
|
15
|
+
- Properly respect excluded files in RuboCop requests (https://github.com/Shopify/ruby-lsp/pull/173)
|
16
|
+
- Clear diagnostics when closing files (https://github.com/Shopify/ruby-lsp/pull/174)
|
17
|
+
- Avoid pushing ranges for single line partial ranges (https://github.com/Shopify/ruby-lsp/pull/185)
|
18
|
+
- Change folding ranges to include closing tokens (https://github.com/Shopify/ruby-lsp/pull/181)
|
19
|
+
- Remove RuboCop dependency and fallback to SyntaxTree formatting (https://github.com/Shopify/ruby-lsp/pull/184)
|
20
|
+
|
9
21
|
## [0.1.0]
|
10
22
|
|
11
23
|
- Implement token modifiers in SemanticTokenEncoder ([#112](https://github.com/Shopify/ruby-lsp/pull/112))
|
data/Gemfile
CHANGED
@@ -5,10 +5,11 @@ source "https://rubygems.org"
|
|
5
5
|
gemspec
|
6
6
|
|
7
7
|
gem "debug", "~> 1.5", require: false
|
8
|
-
gem "minitest", "~> 5.
|
8
|
+
gem "minitest", "~> 5.16"
|
9
9
|
gem "minitest-reporters", "~> 1.5"
|
10
10
|
gem "rake", "~> 13.0"
|
11
|
-
gem "rubocop
|
11
|
+
gem "rubocop", ">= 1.0.0"
|
12
|
+
gem "rubocop-shopify", "~> 2.8", require: false
|
12
13
|
gem "rubocop-minitest", "~> 0.20.1", require: false
|
13
14
|
gem "rubocop-rake", "~> 0.6.0", require: false
|
14
15
|
gem "rubocop-sorbet", "~> 0.6", require: false
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruby-lsp (0.
|
4
|
+
ruby-lsp (0.2.0)
|
5
5
|
language_server-protocol
|
6
|
-
rubocop (>= 1.0)
|
7
6
|
sorbet-runtime
|
8
7
|
syntax_tree (>= 2.4)
|
9
8
|
|
@@ -21,9 +20,10 @@ GEM
|
|
21
20
|
io-console (0.5.11)
|
22
21
|
irb (1.4.1)
|
23
22
|
reline (>= 0.3.0)
|
23
|
+
json (2.6.2)
|
24
24
|
language_server-protocol (3.16.0.3)
|
25
25
|
method_source (1.0.0)
|
26
|
-
minitest (5.
|
26
|
+
minitest (5.16.2)
|
27
27
|
minitest-reporters (1.5.0)
|
28
28
|
ansi
|
29
29
|
builder
|
@@ -38,7 +38,7 @@ GEM
|
|
38
38
|
method_source (~> 1.0)
|
39
39
|
rainbow (3.1.1)
|
40
40
|
rake (13.0.6)
|
41
|
-
rbi (0.0.
|
41
|
+
rbi (0.0.15)
|
42
42
|
ast
|
43
43
|
parser (>= 2.6.4.0)
|
44
44
|
sorbet-runtime (>= 0.5.9204)
|
@@ -47,7 +47,8 @@ GEM
|
|
47
47
|
reline (0.3.1)
|
48
48
|
io-console (~> 0.5)
|
49
49
|
rexml (3.2.5)
|
50
|
-
rubocop (1.
|
50
|
+
rubocop (1.31.1)
|
51
|
+
json (~> 2.3)
|
51
52
|
parallel (~> 1.10)
|
52
53
|
parser (>= 3.1.0.0)
|
53
54
|
rainbow (>= 2.2.2, < 4.0)
|
@@ -62,26 +63,26 @@ GEM
|
|
62
63
|
rubocop (>= 0.90, < 2.0)
|
63
64
|
rubocop-rake (0.6.0)
|
64
65
|
rubocop (~> 1.0)
|
65
|
-
rubocop-shopify (2.
|
66
|
-
rubocop (~> 1.
|
67
|
-
rubocop-sorbet (0.6.
|
66
|
+
rubocop-shopify (2.8.0)
|
67
|
+
rubocop (~> 1.31)
|
68
|
+
rubocop-sorbet (0.6.11)
|
68
69
|
rubocop (>= 0.90.0)
|
69
70
|
ruby-progressbar (1.11.0)
|
70
|
-
sorbet (0.5.
|
71
|
-
sorbet-static (= 0.5.
|
72
|
-
sorbet-runtime (0.5.
|
73
|
-
sorbet-static (0.5.
|
74
|
-
sorbet-static (0.5.
|
75
|
-
sorbet-static-and-runtime (0.5.
|
76
|
-
sorbet (= 0.5.
|
77
|
-
sorbet-runtime (= 0.5.
|
71
|
+
sorbet (0.5.10139)
|
72
|
+
sorbet-static (= 0.5.10139)
|
73
|
+
sorbet-runtime (0.5.10139)
|
74
|
+
sorbet-static (0.5.10139-universal-darwin-21)
|
75
|
+
sorbet-static (0.5.10139-x86_64-linux)
|
76
|
+
sorbet-static-and-runtime (0.5.10139)
|
77
|
+
sorbet (= 0.5.10139)
|
78
|
+
sorbet-runtime (= 0.5.10139)
|
78
79
|
spoom (1.1.11)
|
79
80
|
sorbet (>= 0.5.9204)
|
80
81
|
sorbet-runtime (>= 0.5.9204)
|
81
82
|
thor (>= 0.19.2)
|
82
|
-
syntax_tree (2.
|
83
|
+
syntax_tree (2.8.0)
|
83
84
|
prettier_print
|
84
|
-
tapioca (0.8.
|
85
|
+
tapioca (0.8.3)
|
85
86
|
bundler (>= 1.17.3)
|
86
87
|
parallel (>= 1.21.0)
|
87
88
|
pry (>= 0.12.2)
|
@@ -91,7 +92,7 @@ GEM
|
|
91
92
|
thor (>= 1.2.0)
|
92
93
|
yard-sorbet
|
93
94
|
thor (1.2.1)
|
94
|
-
unicode-display_width (2.
|
95
|
+
unicode-display_width (2.2.0)
|
95
96
|
unparser (0.6.5)
|
96
97
|
diff-lcs (~> 1.3)
|
97
98
|
parser (>= 3.1.0)
|
@@ -108,12 +109,13 @@ PLATFORMS
|
|
108
109
|
|
109
110
|
DEPENDENCIES
|
110
111
|
debug (~> 1.5)
|
111
|
-
minitest (~> 5.
|
112
|
+
minitest (~> 5.16)
|
112
113
|
minitest-reporters (~> 1.5)
|
113
114
|
rake (~> 13.0)
|
115
|
+
rubocop (>= 1.0.0)
|
114
116
|
rubocop-minitest (~> 0.20.1)
|
115
117
|
rubocop-rake (~> 0.6.0)
|
116
|
-
rubocop-shopify (~> 2.
|
118
|
+
rubocop-shopify (~> 2.8)
|
117
119
|
rubocop-sorbet (~> 0.6)
|
118
120
|
ruby-lsp!
|
119
121
|
sorbet-static-and-runtime
|
data/README.md
CHANGED
@@ -17,7 +17,8 @@ end
|
|
17
17
|
If using VS Code, install the [Ruby LSP plugin](https://github.com/Shopify/vscode-ruby-lsp) to get the extra features in
|
18
18
|
the editor.
|
19
19
|
|
20
|
-
See the [documentation](https://shopify.github.io/ruby-lsp) for
|
20
|
+
See the [documentation](https://shopify.github.io/ruby-lsp) for
|
21
|
+
[supported features](https://shopify.github.io/ruby-lsp/RubyLsp/Requests.html).
|
21
22
|
|
22
23
|
## Contributing
|
23
24
|
|
data/Rakefile
CHANGED
@@ -11,7 +11,14 @@ Rake::TestTask.new(:test) do |t|
|
|
11
11
|
end
|
12
12
|
|
13
13
|
YARD::Rake::YardocTask.new do |t|
|
14
|
-
t.options = [
|
14
|
+
t.options = [
|
15
|
+
"--markup",
|
16
|
+
"markdown",
|
17
|
+
"--output-dir",
|
18
|
+
"docs",
|
19
|
+
"--asset",
|
20
|
+
"misc",
|
21
|
+
]
|
15
22
|
end
|
16
23
|
|
17
24
|
require "rubocop/rake_task"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/bin/console
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# typed: strict
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
require "bundler/setup"
|
6
|
+
require_relative "../lib/ruby_lsp/internal"
|
7
|
+
require "irb"
|
8
|
+
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig { params(source: String).returns(RubyLsp::Document) }
|
12
|
+
def new_doc(source)
|
13
|
+
RubyLsp::Document.new(source)
|
14
|
+
end
|
15
|
+
|
16
|
+
@source = T.let(File.read(File.expand_path("../lib/ruby_lsp/handler.rb", __dir__)), String)
|
17
|
+
@document = T.let(new_doc(@source), RubyLsp::Document)
|
18
|
+
|
19
|
+
IRB.start(__FILE__)
|
data/lib/ruby_lsp/cli.rb
CHANGED
data/lib/ruby_lsp/handler.rb
CHANGED
@@ -62,7 +62,16 @@ module RubyLsp
|
|
62
62
|
error = e
|
63
63
|
end
|
64
64
|
|
65
|
-
|
65
|
+
if error
|
66
|
+
@writer.write(
|
67
|
+
{
|
68
|
+
id: request[:id],
|
69
|
+
error: { code: Constant::ErrorCodes::INTERNAL_ERROR, message: error.inspect, data: request.to_json },
|
70
|
+
}
|
71
|
+
)
|
72
|
+
elsif result != VOID
|
73
|
+
@writer.write(id: request[:id], result: result)
|
74
|
+
end
|
66
75
|
end
|
67
76
|
end
|
68
77
|
|
@@ -94,7 +103,7 @@ module RubyLsp
|
|
94
103
|
Interface::SemanticTokensRegistrationOptions.new(
|
95
104
|
document_selector: { scheme: "file", language: "ruby" },
|
96
105
|
legend: Interface::SemanticTokensLegend.new(
|
97
|
-
token_types: Requests::SemanticHighlighting::TOKEN_TYPES,
|
106
|
+
token_types: Requests::SemanticHighlighting::TOKEN_TYPES.keys,
|
98
107
|
token_modifiers: Requests::SemanticHighlighting::TOKEN_MODIFIERS.keys
|
99
108
|
),
|
100
109
|
range: false,
|
@@ -187,6 +196,14 @@ module RubyLsp
|
|
187
196
|
)
|
188
197
|
end
|
189
198
|
|
199
|
+
sig { params(uri: String).void }
|
200
|
+
def clear_diagnostics(uri)
|
201
|
+
@writer.write(
|
202
|
+
method: "textDocument/publishDiagnostics",
|
203
|
+
params: Interface::PublishDiagnosticsParams.new(uri: uri, diagnostics: [])
|
204
|
+
)
|
205
|
+
end
|
206
|
+
|
190
207
|
sig do
|
191
208
|
params(uri: String, range: T::Range[Integer]).returns(T::Array[LanguageServer::Protocol::Interface::CodeAction])
|
192
209
|
end
|
@@ -227,7 +244,7 @@ module RubyLsp
|
|
227
244
|
params[:errorMessage] = error.message
|
228
245
|
end
|
229
246
|
|
230
|
-
params[:uri] = uri if uri
|
247
|
+
params[:uri] = uri.sub(%r{.*://#{Dir.home}}, "~") if uri
|
231
248
|
params
|
232
249
|
end
|
233
250
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
|
+
# ![Code actions demo](../../misc/code_actions.gif)
|
7
|
+
#
|
6
8
|
# The [code actions](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeAction)
|
7
9
|
# request informs the editor of RuboCop quick fixes that can be applied. These are accesible by hovering over a
|
8
10
|
# specific diagnostic.
|
@@ -1,8 +1,12 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "ruby_lsp/requests/support/rubocop_diagnostics_runner"
|
5
|
+
|
4
6
|
module RubyLsp
|
5
7
|
module Requests
|
8
|
+
# ![Diagnostics demo](../../misc/diagnostics.gif)
|
9
|
+
#
|
6
10
|
# The
|
7
11
|
# [diagnostics](https://microsoft.github.io/language-server-protocol/specification#textDocument_publishDiagnostics)
|
8
12
|
# request informs the editor of RuboCop offenses for a given file.
|
@@ -14,9 +18,16 @@ module RubyLsp
|
|
14
18
|
# puts "Hello" # --> diagnostics: incorrect indentantion
|
15
19
|
# end
|
16
20
|
# ```
|
17
|
-
class Diagnostics <
|
21
|
+
class Diagnostics < BaseRequest
|
18
22
|
extend T::Sig
|
19
23
|
|
24
|
+
sig { params(uri: String, document: Document).void }
|
25
|
+
def initialize(uri, document)
|
26
|
+
super(document)
|
27
|
+
|
28
|
+
@uri = uri
|
29
|
+
end
|
30
|
+
|
20
31
|
sig do
|
21
32
|
override.returns(
|
22
33
|
T.any(
|
@@ -27,15 +38,9 @@ module RubyLsp
|
|
27
38
|
end
|
28
39
|
def run
|
29
40
|
return syntax_error_diagnostics if @document.syntax_errors?
|
41
|
+
return [] unless defined?(Support::RuboCopDiagnosticsRunner)
|
30
42
|
|
31
|
-
|
32
|
-
|
33
|
-
@diagnostics
|
34
|
-
end
|
35
|
-
|
36
|
-
sig { params(_file: String, offenses: T::Array[RuboCop::Cop::Offense]).void }
|
37
|
-
def file_finished(_file, offenses)
|
38
|
-
@diagnostics = offenses.map { |offense| Support::RuboCopDiagnostic.new(offense, @uri) }
|
43
|
+
Support::RuboCopDiagnosticsRunner.instance.run(@uri, @document)
|
39
44
|
end
|
40
45
|
|
41
46
|
private
|
@@ -3,6 +3,8 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
|
+
# ![Document highlight demo](../../misc/document_highlight.gif)
|
7
|
+
#
|
6
8
|
# The [document highlight](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentHighlight)
|
7
9
|
# informs the editor all relevant elements of the currently pointed item for highlighting. For example, when
|
8
10
|
# the cursor is on the `F` of the constant `FOO`, the editor should identify other occurences of `FOO`
|
@@ -3,6 +3,8 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
|
+
# ![Document symbol demo](../../misc/document_symbol.gif)
|
7
|
+
#
|
6
8
|
# The [document
|
7
9
|
# symbol](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentSymbol) request
|
8
10
|
# informs the editor of all the important symbols, such as classes, variables, and methods, defined in a file. With
|
@@ -3,10 +3,13 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
|
+
# ![Folding ranges demo](../../misc/folding_ranges.gif)
|
7
|
+
#
|
6
8
|
# The [folding ranges](https://microsoft.github.io/language-server-protocol/specification#textDocument_foldingRange)
|
7
|
-
# request informs the editor of the ranges where code can be folded.
|
9
|
+
# request informs the editor of the ranges where and how code can be folded.
|
8
10
|
#
|
9
11
|
# # Example
|
12
|
+
#
|
10
13
|
# ```ruby
|
11
14
|
# def say_hello # <-- folding range start
|
12
15
|
# puts "Hello"
|
@@ -32,12 +35,13 @@ module RubyLsp
|
|
32
35
|
SyntaxTree::Unless,
|
33
36
|
SyntaxTree::Until,
|
34
37
|
SyntaxTree::While,
|
38
|
+
SyntaxTree::Else,
|
39
|
+
SyntaxTree::Ensure,
|
40
|
+
SyntaxTree::Begin,
|
35
41
|
].freeze, T::Array[T.class_of(SyntaxTree::Node)])
|
36
42
|
|
37
43
|
NODES_WITH_STATEMENTS = T.let([
|
38
|
-
SyntaxTree::Else,
|
39
44
|
SyntaxTree::Elsif,
|
40
|
-
SyntaxTree::Ensure,
|
41
45
|
SyntaxTree::In,
|
42
46
|
SyntaxTree::Rescue,
|
43
47
|
SyntaxTree::When,
|
@@ -45,9 +49,7 @@ module RubyLsp
|
|
45
49
|
|
46
50
|
StatementNode = T.type_alias do
|
47
51
|
T.any(
|
48
|
-
SyntaxTree::Else,
|
49
52
|
SyntaxTree::Elsif,
|
50
|
-
SyntaxTree::Ensure,
|
51
53
|
SyntaxTree::In,
|
52
54
|
SyntaxTree::Rescue,
|
53
55
|
SyntaxTree::When,
|
@@ -77,11 +79,10 @@ module RubyLsp
|
|
77
79
|
|
78
80
|
case node
|
79
81
|
when *SIMPLE_FOLDABLES
|
80
|
-
|
82
|
+
location = T.must(node).location
|
83
|
+
add_lines_range(location.start_line, location.end_line - 1)
|
81
84
|
when *NODES_WITH_STATEMENTS
|
82
85
|
add_statements_range(T.must(node), T.cast(node, StatementNode).statements)
|
83
|
-
when SyntaxTree::Begin
|
84
|
-
add_statements_range(node, node.bodystmt.statements)
|
85
86
|
when SyntaxTree::Call, SyntaxTree::CommandCall
|
86
87
|
add_call_range(node)
|
87
88
|
return
|
@@ -135,6 +136,11 @@ module RubyLsp
|
|
135
136
|
kind: @kind
|
136
137
|
)
|
137
138
|
end
|
139
|
+
|
140
|
+
sig { returns(T::Boolean) }
|
141
|
+
def multiline?
|
142
|
+
@end_line > @start_line
|
143
|
+
end
|
138
144
|
end
|
139
145
|
|
140
146
|
sig { params(node: T.nilable(SyntaxTree::Node)).returns(T::Boolean) }
|
@@ -175,7 +181,7 @@ module RubyLsp
|
|
175
181
|
def emit_partial_range
|
176
182
|
return if @partial_range.nil?
|
177
183
|
|
178
|
-
@ranges << @partial_range.to_range
|
184
|
+
@ranges << @partial_range.to_range if @partial_range.multiline?
|
179
185
|
@partial_range = nil
|
180
186
|
end
|
181
187
|
|
@@ -195,7 +201,7 @@ module RubyLsp
|
|
195
201
|
end
|
196
202
|
end
|
197
203
|
|
198
|
-
add_lines_range(receiver.location.start_line, node.location.end_line)
|
204
|
+
add_lines_range(receiver.location.start_line, node.location.end_line - 1)
|
199
205
|
|
200
206
|
visit(node.arguments)
|
201
207
|
end
|
@@ -205,9 +211,10 @@ module RubyLsp
|
|
205
211
|
params_location = node.params.location
|
206
212
|
|
207
213
|
if params_location.start_line < params_location.end_line
|
208
|
-
add_lines_range(params_location.end_line, node.location.end_line)
|
214
|
+
add_lines_range(params_location.end_line, node.location.end_line - 1)
|
209
215
|
else
|
210
|
-
|
216
|
+
location = node.location
|
217
|
+
add_lines_range(location.start_line, location.end_line - 1)
|
211
218
|
end
|
212
219
|
|
213
220
|
visit(node.bodystmt.statements)
|
@@ -215,7 +222,7 @@ module RubyLsp
|
|
215
222
|
|
216
223
|
sig { params(node: SyntaxTree::Node, statements: SyntaxTree::Statements).void }
|
217
224
|
def add_statements_range(node, statements)
|
218
|
-
add_lines_range(node.location.start_line, statements.location.end_line) unless statements.empty?
|
225
|
+
add_lines_range(node.location.start_line, statements.body.last.location.end_line) unless statements.empty?
|
219
226
|
end
|
220
227
|
|
221
228
|
sig { params(node: SyntaxTree::StringConcat).void }
|
@@ -223,13 +230,7 @@ module RubyLsp
|
|
223
230
|
left = T.let(node.left, SyntaxTree::Node)
|
224
231
|
left = left.left while left.is_a?(SyntaxTree::StringConcat)
|
225
232
|
|
226
|
-
add_lines_range(left.location.start_line, node.right.location.end_line)
|
227
|
-
end
|
228
|
-
|
229
|
-
sig { params(node: SyntaxTree::Node).void }
|
230
|
-
def add_node_range(node)
|
231
|
-
location = node.location
|
232
|
-
add_lines_range(location.start_line, location.end_line)
|
233
|
+
add_lines_range(left.location.start_line, node.right.location.end_line - 1)
|
233
234
|
end
|
234
235
|
|
235
236
|
sig { params(start_line: Integer, end_line: Integer).void }
|
@@ -1,8 +1,12 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "ruby_lsp/requests/support/rubocop_formatting_runner"
|
5
|
+
|
4
6
|
module RubyLsp
|
5
7
|
module Requests
|
8
|
+
# ![Formatting symbol demo](../../misc/formatting.gif)
|
9
|
+
#
|
6
10
|
# The [formatting](https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting)
|
7
11
|
# request uses RuboCop to fix auto-correctable offenses in the document. This requires enabling format on save and
|
8
12
|
# registering the ruby-lsp as the Ruby formatter.
|
@@ -14,43 +18,43 @@ module RubyLsp
|
|
14
18
|
# puts "Hello" # --> formatting: fixes the indentation on save
|
15
19
|
# end
|
16
20
|
# ```
|
17
|
-
class Formatting <
|
21
|
+
class Formatting < BaseRequest
|
18
22
|
extend T::Sig
|
19
23
|
|
20
|
-
RUBOCOP_FLAGS = T.let((COMMON_RUBOCOP_FLAGS + ["--auto-correct"]).freeze, T::Array[String])
|
21
|
-
|
22
24
|
sig { params(uri: String, document: Document).void }
|
23
25
|
def initialize(uri, document)
|
24
|
-
super
|
25
|
-
|
26
|
+
super(document)
|
27
|
+
|
28
|
+
@uri = uri
|
26
29
|
end
|
27
30
|
|
28
31
|
sig { override.returns(T.nilable(T.all(T::Array[LanguageServer::Protocol::Interface::TextEdit], Object))) }
|
29
32
|
def run
|
30
|
-
|
33
|
+
formatted_text = formatted_file
|
34
|
+
return unless formatted_text
|
31
35
|
|
32
|
-
|
33
|
-
return unless @formatted_text
|
36
|
+
size = @document.source.size
|
34
37
|
|
35
38
|
[
|
36
39
|
LanguageServer::Protocol::Interface::TextEdit.new(
|
37
40
|
range: LanguageServer::Protocol::Interface::Range.new(
|
38
41
|
start: LanguageServer::Protocol::Interface::Position.new(line: 0, character: 0),
|
39
|
-
end: LanguageServer::Protocol::Interface::Position.new(
|
40
|
-
line: text.size,
|
41
|
-
character: text.size
|
42
|
-
)
|
42
|
+
end: LanguageServer::Protocol::Interface::Position.new(line: size, character: size)
|
43
43
|
),
|
44
|
-
new_text:
|
44
|
+
new_text: formatted_text
|
45
45
|
),
|
46
46
|
]
|
47
47
|
end
|
48
48
|
|
49
49
|
private
|
50
50
|
|
51
|
-
sig { returns(T
|
52
|
-
def
|
53
|
-
|
51
|
+
sig { returns(T.nilable(String)) }
|
52
|
+
def formatted_file
|
53
|
+
if defined?(Support::RuboCopFormattingRunner)
|
54
|
+
Support::RuboCopFormattingRunner.instance.run(@uri, @document)
|
55
|
+
else
|
56
|
+
SyntaxTree.format(@document.source)
|
57
|
+
end
|
54
58
|
end
|
55
59
|
end
|
56
60
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
|
+
# ![Selection ranges demo](../../misc/selection_ranges.gif)
|
7
|
+
#
|
6
8
|
# The [selection ranges](https://microsoft.github.io/language-server-protocol/specification#textDocument_selectionRange)
|
7
9
|
# request informs the editor of ranges that the user may want to select based on the location(s)
|
8
10
|
# of their cursor(s).
|
@@ -3,6 +3,8 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
|
+
# ![Semantic highlighting demo](../../misc/semantic_highlighting.gif)
|
7
|
+
#
|
6
8
|
# The [semantic
|
7
9
|
# highlighting](https://microsoft.github.io/language-server-protocol/specification#textDocument_semanticTokens)
|
8
10
|
# request informs the editor of the correct token types to provide consistent and accurate highlighting for themes.
|
@@ -19,11 +21,31 @@ module RubyLsp
|
|
19
21
|
class SemanticHighlighting < BaseRequest
|
20
22
|
extend T::Sig
|
21
23
|
|
22
|
-
TOKEN_TYPES = T.let(
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
|
24
|
+
TOKEN_TYPES = T.let({
|
25
|
+
namespace: 0,
|
26
|
+
type: 1,
|
27
|
+
class: 2,
|
28
|
+
enum: 3,
|
29
|
+
interface: 4,
|
30
|
+
struct: 5,
|
31
|
+
typeParameter: 6,
|
32
|
+
parameter: 7,
|
33
|
+
variable: 8,
|
34
|
+
property: 9,
|
35
|
+
enumMember: 10,
|
36
|
+
event: 11,
|
37
|
+
function: 12,
|
38
|
+
method: 13,
|
39
|
+
macro: 14,
|
40
|
+
keyword: 15,
|
41
|
+
modifier: 16,
|
42
|
+
comment: 17,
|
43
|
+
string: 18,
|
44
|
+
number: 19,
|
45
|
+
regexp: 20,
|
46
|
+
operator: 21,
|
47
|
+
decorator: 22,
|
48
|
+
}.freeze, T::Hash[Symbol, Integer])
|
27
49
|
|
28
50
|
TOKEN_MODIFIERS = T.let({
|
29
51
|
declaration: 0,
|
@@ -38,6 +60,11 @@ module RubyLsp
|
|
38
60
|
default_library: 9,
|
39
61
|
}.freeze, T::Hash[Symbol, Integer])
|
40
62
|
|
63
|
+
SPECIAL_RUBY_METHODS = T.let((Module.instance_methods(false) +
|
64
|
+
Kernel.methods(false) + Bundler::Dsl.instance_methods(false) +
|
65
|
+
Module.private_instance_methods(false))
|
66
|
+
.map(&:to_s), T::Array[String])
|
67
|
+
|
41
68
|
class SemanticToken < T::Struct
|
42
69
|
const :location, SyntaxTree::Location
|
43
70
|
const :length, Integer
|
@@ -52,6 +79,7 @@ module RubyLsp
|
|
52
79
|
@encoder = encoder
|
53
80
|
@tokens = T.let([], T::Array[SemanticToken])
|
54
81
|
@tree = T.let(document.tree, SyntaxTree::Node)
|
82
|
+
@special_methods = T.let(nil, T.nilable(T::Array[String]))
|
55
83
|
end
|
56
84
|
|
57
85
|
sig do
|
@@ -83,7 +111,7 @@ module RubyLsp
|
|
83
111
|
|
84
112
|
sig { params(node: SyntaxTree::Command).void }
|
85
113
|
def visit_command(node)
|
86
|
-
add_token(node.message.location, :method)
|
114
|
+
add_token(node.message.location, :method) unless special_method?(node.message.value)
|
87
115
|
visit(node.arguments)
|
88
116
|
end
|
89
117
|
|
@@ -125,7 +153,7 @@ module RubyLsp
|
|
125
153
|
|
126
154
|
sig { params(node: SyntaxTree::FCall).void }
|
127
155
|
def visit_fcall(node)
|
128
|
-
add_token(node.value.location, :method)
|
156
|
+
add_token(node.value.location, :method) unless special_method?(node.value.value)
|
129
157
|
visit(node.arguments)
|
130
158
|
end
|
131
159
|
|
@@ -144,6 +172,16 @@ module RubyLsp
|
|
144
172
|
end
|
145
173
|
end
|
146
174
|
|
175
|
+
sig { params(node: SyntaxTree::Params).void }
|
176
|
+
def visit_params(node)
|
177
|
+
node.keywords.each do |keyword,|
|
178
|
+
location = keyword.location
|
179
|
+
add_token(location_without_colon(location), :variable)
|
180
|
+
end
|
181
|
+
|
182
|
+
add_token(node.keyword_rest.name.location, :variable) if node.keyword_rest
|
183
|
+
end
|
184
|
+
|
147
185
|
sig { params(node: SyntaxTree::VarField).void }
|
148
186
|
def visit_var_field(node)
|
149
187
|
case node.value
|
@@ -166,7 +204,7 @@ module RubyLsp
|
|
166
204
|
|
167
205
|
sig { params(node: SyntaxTree::VCall).void }
|
168
206
|
def visit_vcall(node)
|
169
|
-
add_token(node.value.location, :method)
|
207
|
+
add_token(node.value.location, :method) unless special_method?(node.value.value)
|
170
208
|
end
|
171
209
|
|
172
210
|
sig { params(location: SyntaxTree::Location, type: Symbol, modifiers: T::Array[Symbol]).void }
|
@@ -177,11 +215,37 @@ module RubyLsp
|
|
177
215
|
SemanticToken.new(
|
178
216
|
location: location,
|
179
217
|
length: length,
|
180
|
-
type: T.must(TOKEN_TYPES
|
218
|
+
type: T.must(TOKEN_TYPES[type]),
|
181
219
|
modifier: modifiers_indices
|
182
220
|
)
|
183
221
|
)
|
184
222
|
end
|
223
|
+
|
224
|
+
private
|
225
|
+
|
226
|
+
# Exclude the ":" symbol at the end of a location
|
227
|
+
# We use it on keyword parameters to be consistent
|
228
|
+
# with the rest of the parameters
|
229
|
+
sig { params(location: T.untyped).returns(SyntaxTree::Location) }
|
230
|
+
def location_without_colon(location)
|
231
|
+
SyntaxTree::Location.new(
|
232
|
+
start_line: location.start_line,
|
233
|
+
start_column: location.start_column,
|
234
|
+
start_char: location.start_char,
|
235
|
+
end_char: location.end_char - 1,
|
236
|
+
end_column: location.end_column - 1,
|
237
|
+
end_line: location.end_line,
|
238
|
+
)
|
239
|
+
end
|
240
|
+
|
241
|
+
# Textmate provides highlighting for a subset
|
242
|
+
# of these special Ruby-specific methods.
|
243
|
+
# We want to utilize that highlighting, so we
|
244
|
+
# avoid making a semantic token for it.
|
245
|
+
sig { params(method_name: String).returns(T::Boolean) }
|
246
|
+
def special_method?(method_name)
|
247
|
+
SPECIAL_RUBY_METHODS.include?(method_name)
|
248
|
+
end
|
185
249
|
end
|
186
250
|
end
|
187
251
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
begin
|
5
|
+
require "rubocop"
|
6
|
+
rescue LoadError
|
7
|
+
return
|
8
|
+
end
|
9
|
+
|
10
|
+
require "cgi"
|
11
|
+
require "singleton"
|
12
|
+
|
13
|
+
module RubyLsp
|
14
|
+
module Requests
|
15
|
+
module Support
|
16
|
+
# :nodoc:
|
17
|
+
class RuboCopDiagnosticsRunner < RuboCop::Runner
|
18
|
+
extend T::Sig
|
19
|
+
include Singleton
|
20
|
+
|
21
|
+
sig { void }
|
22
|
+
def initialize
|
23
|
+
@options = T.let({}, T::Hash[Symbol, T.untyped])
|
24
|
+
@uri = T.let(nil, T.nilable(String))
|
25
|
+
@diagnostics = T.let([], T::Array[Support::RuboCopDiagnostic])
|
26
|
+
|
27
|
+
super(
|
28
|
+
::RuboCop::Options.new.parse([
|
29
|
+
"--stderr", # Print any output to stderr so that our stdout does not get polluted
|
30
|
+
"--force-exclusion",
|
31
|
+
"--format",
|
32
|
+
"RuboCop::Formatter::BaseFormatter", # Suppress any output by using the base formatter
|
33
|
+
]).first,
|
34
|
+
::RuboCop::ConfigStore.new
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
sig { params(uri: String, document: Document).returns(T::Array[Support::RuboCopDiagnostic]) }
|
39
|
+
def run(uri, document)
|
40
|
+
@diagnostics.clear
|
41
|
+
@uri = uri
|
42
|
+
|
43
|
+
file = CGI.unescape(URI.parse(uri).path)
|
44
|
+
# We communicate with Rubocop via stdin
|
45
|
+
@options[:stdin] = document.source
|
46
|
+
|
47
|
+
# Invoke RuboCop with just this file in `paths`
|
48
|
+
super([file])
|
49
|
+
@diagnostics
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
sig { params(_file: String, offenses: T::Array[RuboCop::Cop::Offense]).void }
|
55
|
+
def file_finished(_file, offenses)
|
56
|
+
@diagnostics = offenses.map { |offense| Support::RuboCopDiagnostic.new(offense, T.must(@uri)) }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
begin
|
5
|
+
require "rubocop"
|
6
|
+
rescue LoadError
|
7
|
+
return
|
8
|
+
end
|
9
|
+
|
10
|
+
require "cgi"
|
11
|
+
require "singleton"
|
12
|
+
|
13
|
+
module RubyLsp
|
14
|
+
module Requests
|
15
|
+
module Support
|
16
|
+
# :nodoc:
|
17
|
+
class RuboCopFormattingRunner < RuboCop::Runner
|
18
|
+
extend T::Sig
|
19
|
+
include Singleton
|
20
|
+
|
21
|
+
sig { void }
|
22
|
+
def initialize
|
23
|
+
@options = T.let({}, T::Hash[Symbol, T.untyped])
|
24
|
+
|
25
|
+
super(
|
26
|
+
::RuboCop::Options.new.parse([
|
27
|
+
"--stderr", # Print any output to stderr so that our stdout does not get polluted
|
28
|
+
"--force-exclusion",
|
29
|
+
"--format",
|
30
|
+
"RuboCop::Formatter::BaseFormatter", # Suppress any output by using the base formatter
|
31
|
+
"-a", # --auto-correct
|
32
|
+
]).first,
|
33
|
+
::RuboCop::ConfigStore.new
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
sig { params(uri: String, document: Document).returns(T.nilable(String)) }
|
38
|
+
def run(uri, document)
|
39
|
+
file = CGI.unescape(URI.parse(uri).path)
|
40
|
+
# We communicate with Rubocop via stdin
|
41
|
+
@options[:stdin] = document.source
|
42
|
+
|
43
|
+
# Invoke RuboCop with just this file in `paths`
|
44
|
+
super([file])
|
45
|
+
@options[:stdin]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/ruby_lsp/requests.rb
CHANGED
@@ -2,18 +2,28 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
5
|
+
# Supported features
|
6
|
+
#
|
7
|
+
# - {RubyLsp::Requests::DocumentSymbol}
|
8
|
+
# - {RubyLsp::Requests::FoldingRanges}
|
9
|
+
# - {RubyLsp::Requests::SelectionRanges}
|
10
|
+
# - {RubyLsp::Requests::SemanticHighlighting}
|
11
|
+
# - {RubyLsp::Requests::Formatting}
|
12
|
+
# - {RubyLsp::Requests::Diagnostics}
|
13
|
+
# - {RubyLsp::Requests::CodeActions}
|
14
|
+
# - {RubyLsp::Requests::DocumentHighlight}
|
5
15
|
module Requests
|
6
16
|
autoload :BaseRequest, "ruby_lsp/requests/base_request"
|
7
17
|
autoload :DocumentSymbol, "ruby_lsp/requests/document_symbol"
|
8
18
|
autoload :FoldingRanges, "ruby_lsp/requests/folding_ranges"
|
9
19
|
autoload :SelectionRanges, "ruby_lsp/requests/selection_ranges"
|
10
20
|
autoload :SemanticHighlighting, "ruby_lsp/requests/semantic_highlighting"
|
11
|
-
autoload :RuboCopRequest, "ruby_lsp/requests/rubocop_request"
|
12
21
|
autoload :Formatting, "ruby_lsp/requests/formatting"
|
13
22
|
autoload :Diagnostics, "ruby_lsp/requests/diagnostics"
|
14
23
|
autoload :CodeActions, "ruby_lsp/requests/code_actions"
|
15
24
|
autoload :DocumentHighlight, "ruby_lsp/requests/document_highlight"
|
16
25
|
|
26
|
+
# :nodoc:
|
17
27
|
module Support
|
18
28
|
autoload :RuboCopDiagnostic, "ruby_lsp/requests/support/rubocop_diagnostic"
|
19
29
|
autoload :SelectionRange, "ruby_lsp/requests/support/selection_range"
|
data/rakelib/check_docs.rake
CHANGED
@@ -8,9 +8,13 @@ task :check_docs do
|
|
8
8
|
require "syntax_tree"
|
9
9
|
require "logger"
|
10
10
|
require "ruby_lsp/requests/base_request"
|
11
|
-
require "ruby_lsp/requests/
|
11
|
+
require "ruby_lsp/requests/support/rubocop_diagnostics_runner"
|
12
|
+
require "ruby_lsp/requests/support/rubocop_formatting_runner"
|
12
13
|
|
13
|
-
Dir["#{Dir.pwd}/lib/ruby_lsp/requests/*.rb"]
|
14
|
+
request_doc_files = Dir["#{Dir.pwd}/lib/ruby_lsp/requests/*.rb"]
|
15
|
+
request_doc_files << "#{Dir.pwd}/lib/ruby_lsp/requests.rb"
|
16
|
+
|
17
|
+
request_doc_files.each do |file|
|
14
18
|
require(file)
|
15
19
|
YARD.parse(file, [], Logger::Severity::FATAL)
|
16
20
|
end
|
@@ -19,6 +23,8 @@ task :check_docs do
|
|
19
23
|
error_messages = RubyLsp::Requests
|
20
24
|
.constants # rubocop:disable Sorbet/ConstantsFromStrings
|
21
25
|
.each_with_object(Hash.new { |h, k| h[k] = [] }) do |request, errors|
|
26
|
+
next if request == :Support
|
27
|
+
|
22
28
|
full_name = "RubyLsp::Requests::#{request}"
|
23
29
|
docs = YARD::Registry.at(full_name).docstring
|
24
30
|
next if /:nodoc:/.match?(docs)
|
@@ -32,15 +38,33 @@ task :check_docs do
|
|
32
38
|
For example, if your request handles text document hover, you should add a link to
|
33
39
|
https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover.
|
34
40
|
MESSAGE
|
41
|
+
elsif !%r{!\[.* demo\]\(\.\./\.\./misc/.*\.gif\)}.match?(docs)
|
42
|
+
errors[full_name] << <<~MESSAGE
|
43
|
+
Documentation for request handler class must contain a demonstration GIF, in the following format:
|
44
|
+
|
45
|
+
![Request name demo](../../misc/request_name.gif)
|
46
|
+
|
47
|
+
See the misc/ folder for examples.
|
48
|
+
MESSAGE
|
35
49
|
elsif !/# Example/.match?(docs)
|
36
50
|
errors[full_name] << <<~MESSAGE
|
37
51
|
Documentation for request handler class must contain an example.
|
38
52
|
|
39
|
-
|
40
|
-
|
41
|
-
|
53
|
+
# # Example
|
54
|
+
#
|
55
|
+
# ```ruby
|
56
|
+
# def my_method # <-- something happens here
|
57
|
+
# end
|
58
|
+
# ```
|
42
59
|
MESSAGE
|
43
60
|
end
|
61
|
+
|
62
|
+
supported_features = YARD::Registry.at("RubyLsp::Requests").docstring
|
63
|
+
next if /- {#{full_name}}/.match?(supported_features)
|
64
|
+
|
65
|
+
errors[full_name] << <<~MESSAGE
|
66
|
+
Documentation for request handler class must be listed in the RubyLsp::Requests module documentation.
|
67
|
+
MESSAGE
|
44
68
|
end
|
45
69
|
|
46
70
|
formatted_errors = error_messages.map { |name, errors| "#{name}: #{errors.join(", ")}" }
|
data/ruby-lsp.gemspec
CHANGED
@@ -7,20 +7,21 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.email = ["ruby@shopify.com"]
|
8
8
|
s.metadata["allowed_push_host"] = "https://rubygems.org"
|
9
9
|
|
10
|
-
s.summary = "
|
11
|
-
s.description = "
|
10
|
+
s.summary = "An opinionated language server for Ruby"
|
11
|
+
s.description = "An opinionated language server for Ruby"
|
12
12
|
s.homepage = "https://github.com/Shopify/ruby-lsp"
|
13
13
|
s.license = "MIT"
|
14
14
|
|
15
15
|
s.files = Dir.chdir(File.expand_path(__dir__)) do
|
16
|
-
%x(git ls-files -z).split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
16
|
+
%x(git ls-files -z).split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features|misc)/}) }
|
17
17
|
end
|
18
18
|
s.bindir = "exe"
|
19
19
|
s.executables = s.files.grep(/\Aexe/) { |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
22
|
s.add_dependency("language_server-protocol")
|
23
|
-
s.add_dependency("rubocop", ">= 1.0")
|
24
23
|
s.add_dependency("sorbet-runtime")
|
25
24
|
s.add_dependency("syntax_tree", ">= 2.4")
|
25
|
+
|
26
|
+
s.required_ruby_version = ">= 2.7.3"
|
26
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-lsp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: language_server-protocol
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rubocop
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '1.0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '1.0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: sorbet-runtime
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +52,7 @@ dependencies:
|
|
66
52
|
- - ">="
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: '2.4'
|
69
|
-
description:
|
55
|
+
description: An opinionated language server for Ruby
|
70
56
|
email:
|
71
57
|
- ruby@shopify.com
|
72
58
|
executables:
|
@@ -92,6 +78,7 @@ files:
|
|
92
78
|
- README.md
|
93
79
|
- Rakefile
|
94
80
|
- VERSION
|
81
|
+
- bin/console
|
95
82
|
- bin/rubocop
|
96
83
|
- bin/tapioca
|
97
84
|
- bin/test
|
@@ -110,10 +97,11 @@ files:
|
|
110
97
|
- lib/ruby_lsp/requests/document_symbol.rb
|
111
98
|
- lib/ruby_lsp/requests/folding_ranges.rb
|
112
99
|
- lib/ruby_lsp/requests/formatting.rb
|
113
|
-
- lib/ruby_lsp/requests/rubocop_request.rb
|
114
100
|
- lib/ruby_lsp/requests/selection_ranges.rb
|
115
101
|
- lib/ruby_lsp/requests/semantic_highlighting.rb
|
116
102
|
- lib/ruby_lsp/requests/support/rubocop_diagnostic.rb
|
103
|
+
- lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb
|
104
|
+
- lib/ruby_lsp/requests/support/rubocop_formatting_runner.rb
|
117
105
|
- lib/ruby_lsp/requests/support/selection_range.rb
|
118
106
|
- lib/ruby_lsp/requests/support/semantic_token_encoder.rb
|
119
107
|
- lib/ruby_lsp/requests/support/syntax_error_diagnostic.rb
|
@@ -179,7 +167,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
179
167
|
requirements:
|
180
168
|
- - ">="
|
181
169
|
- !ruby/object:Gem::Version
|
182
|
-
version:
|
170
|
+
version: 2.7.3
|
183
171
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
172
|
requirements:
|
185
173
|
- - ">="
|
@@ -189,5 +177,5 @@ requirements: []
|
|
189
177
|
rubygems_version: 3.3.3
|
190
178
|
signing_key:
|
191
179
|
specification_version: 4
|
192
|
-
summary:
|
180
|
+
summary: An opinionated language server for Ruby
|
193
181
|
test_files: []
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "rubocop"
|
5
|
-
require "cgi"
|
6
|
-
|
7
|
-
module RubyLsp
|
8
|
-
module Requests
|
9
|
-
# :nodoc:
|
10
|
-
class RuboCopRequest < RuboCop::Runner
|
11
|
-
extend T::Sig
|
12
|
-
extend T::Helpers
|
13
|
-
|
14
|
-
abstract!
|
15
|
-
|
16
|
-
COMMON_RUBOCOP_FLAGS = T.let([
|
17
|
-
"--stderr", # Print any output to stderr so that our stdout does not get polluted
|
18
|
-
"--format",
|
19
|
-
"RuboCop::Formatter::BaseFormatter", # Suppress any output by using the base formatter
|
20
|
-
].freeze, T::Array[String])
|
21
|
-
|
22
|
-
sig { returns(String) }
|
23
|
-
attr_reader :file
|
24
|
-
|
25
|
-
sig { returns(String) }
|
26
|
-
attr_reader :text
|
27
|
-
|
28
|
-
sig { params(uri: String, document: Document).void }
|
29
|
-
def initialize(uri, document)
|
30
|
-
@file = T.let(CGI.unescape(URI.parse(uri).path), String)
|
31
|
-
@document = document
|
32
|
-
@text = T.let(document.source, String)
|
33
|
-
@uri = uri
|
34
|
-
@options = T.let({}, T::Hash[Symbol, T.untyped])
|
35
|
-
@diagnostics = T.let([], T::Array[Support::RuboCopDiagnostic])
|
36
|
-
|
37
|
-
super(
|
38
|
-
::RuboCop::Options.new.parse(rubocop_flags).first,
|
39
|
-
::RuboCop::ConfigStore.new
|
40
|
-
)
|
41
|
-
end
|
42
|
-
|
43
|
-
sig { overridable.returns(Object) }
|
44
|
-
def run
|
45
|
-
# We communicate with Rubocop via stdin
|
46
|
-
@options[:stdin] = text
|
47
|
-
|
48
|
-
# Invoke the actual run method with just this file in `paths`
|
49
|
-
super([file])
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
sig { returns(T::Array[String]) }
|
55
|
-
def rubocop_flags
|
56
|
-
COMMON_RUBOCOP_FLAGS
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|