ruby-lsp 0.1.0 → 0.2.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.
- 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
|
+
# 
|
|
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
|
+
# 
|
|
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
|
+
# 
|
|
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
|
+
# 
|
|
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
|
+
# 
|
|
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
|
+
# 
|
|
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
|
+
# 
|
|
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
|
+
# 
|
|
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
|
+

|
|
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
|