ruby-lsp 0.0.4 → 0.1.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/.rubocop.yml +10 -1
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +13 -13
- data/README.md +1 -1
- data/VERSION +1 -1
- data/exe/ruby-lsp +1 -1
- data/lib/ruby-lsp.rb +2 -2
- data/lib/ruby_lsp/document.rb +7 -1
- data/lib/ruby_lsp/handler.rb +30 -32
- data/lib/{internal.rb → ruby_lsp/internal.rb} +1 -1
- data/lib/ruby_lsp/requests/base_request.rb +9 -7
- data/lib/ruby_lsp/requests/code_actions.rb +18 -9
- data/lib/ruby_lsp/requests/diagnostics.rb +13 -1
- data/lib/ruby_lsp/requests/document_highlight.rb +21 -6
- data/lib/ruby_lsp/requests/document_symbol.rb +57 -10
- data/lib/ruby_lsp/requests/folding_ranges.rb +52 -18
- data/lib/ruby_lsp/requests/formatting.rb +8 -3
- data/lib/ruby_lsp/requests/rubocop_request.rb +19 -9
- data/lib/ruby_lsp/requests/selection_ranges.rb +16 -5
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +104 -29
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +16 -4
- data/lib/ruby_lsp/requests/support/selection_range.rb +4 -1
- data/lib/ruby_lsp/requests/support/semantic_token_encoder.rb +13 -3
- data/lib/ruby_lsp/requests/support/syntax_error_diagnostic.rb +6 -1
- data/lib/ruby_lsp/requests.rb +1 -1
- data/lib/ruby_lsp/store.rb +6 -5
- data/rakelib/check_docs.rake +1 -0
- data/ruby-lsp.gemspec +1 -1
- data/sorbet/tapioca/require.rb +1 -1
- metadata +6 -7
- data/shipit.production.yml +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b072ffa3ea73a83aba6d6c32b931c4de30b0de06fd70655d620c3ed95bd8aa4
|
4
|
+
data.tar.gz: 24568688b20ffed38defcbc0b00708eb22a7dad20a9b5f397348242a64359bfd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea1830f0be08cb291e67d80bbe21dbe17f3e4b4d285b1d9112e004ca2feff32eaca85af755bc2635e3341ab4e64491710c3ba13c5bed617e34495534e1d7a5f8
|
7
|
+
data.tar.gz: f84b1b27c5c17455d1e8423f1e52f98a754ed123e1722bd536ee7bfdc754952e5d6619c0f4402664a33dc278bdc2422a3e7a37c8de5f172e4456e7a6c08b7a67
|
data/.rubocop.yml
CHANGED
@@ -25,6 +25,15 @@ Sorbet/FalseSigil:
|
|
25
25
|
Sorbet/TrueSigil:
|
26
26
|
Enabled: true
|
27
27
|
Include:
|
28
|
-
- "
|
28
|
+
- "test/**/*.rb"
|
29
29
|
Exclude:
|
30
30
|
- "**/*.rake"
|
31
|
+
- "lib/**/*.rb"
|
32
|
+
|
33
|
+
Sorbet/StrictSigil:
|
34
|
+
Enabled: true
|
35
|
+
Include:
|
36
|
+
- "lib/**/*.rb"
|
37
|
+
Exclude:
|
38
|
+
- "**/*.rake"
|
39
|
+
- "test/**/*.rb"
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,16 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.1.0]
|
10
|
+
|
11
|
+
- Implement token modifiers in SemanticTokenEncoder ([#112](https://github.com/Shopify/ruby-lsp/pull/112))
|
12
|
+
- Add semantic token for name in a method definition ([#133](https://github.com/Shopify/ruby-lsp/pull/133))
|
13
|
+
- Add semantic highighting for def endless and singleton method names ([#134](https://github.com/Shopify/ruby-lsp/pull/134))
|
14
|
+
- Add semantic token for keyword self ([#137](https://github.com/Shopify/ruby-lsp/pull/137))
|
15
|
+
- Add semantic token for constants ([#138](https://github.com/Shopify/ruby-lsp/pull/138))
|
16
|
+
- Improve error handling + fix formatting hanging issue ([#149](https://github.com/Shopify/ruby-lsp/pull/149))
|
17
|
+
- Set the minimum syntax_tree version to 2.4 ([#151](https://github.com/Shopify/ruby-lsp/pull/151))
|
18
|
+
|
9
19
|
## [0.0.4]
|
10
20
|
|
11
21
|
- Add basic document highlight (https://github.com/Shopify/ruby-lsp/pull/91)
|
data/Gemfile
CHANGED
@@ -9,7 +9,7 @@ gem "minitest", "~> 5.15"
|
|
9
9
|
gem "minitest-reporters", "~> 1.5"
|
10
10
|
gem "rake", "~> 13.0"
|
11
11
|
gem "rubocop-shopify", "~> 2.7", require: false
|
12
|
-
gem "rubocop-minitest", "~> 0.20.
|
12
|
+
gem "rubocop-minitest", "~> 0.20.1", require: false
|
13
13
|
gem "rubocop-rake", "~> 0.6.0", require: false
|
14
14
|
gem "rubocop-sorbet", "~> 0.6", require: false
|
15
15
|
gem "sorbet-static-and-runtime"
|
data/Gemfile.lock
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruby-lsp (0.0
|
4
|
+
ruby-lsp (0.1.0)
|
5
5
|
language_server-protocol
|
6
6
|
rubocop (>= 1.0)
|
7
7
|
sorbet-runtime
|
8
|
-
syntax_tree (>= 2.
|
8
|
+
syntax_tree (>= 2.4)
|
9
9
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
@@ -47,7 +47,7 @@ GEM
|
|
47
47
|
reline (0.3.1)
|
48
48
|
io-console (~> 0.5)
|
49
49
|
rexml (3.2.5)
|
50
|
-
rubocop (1.30.
|
50
|
+
rubocop (1.30.1)
|
51
51
|
parallel (~> 1.10)
|
52
52
|
parser (>= 3.1.0.0)
|
53
53
|
rainbow (>= 2.2.2, < 4.0)
|
@@ -58,7 +58,7 @@ GEM
|
|
58
58
|
unicode-display_width (>= 1.4.0, < 3.0)
|
59
59
|
rubocop-ast (1.18.0)
|
60
60
|
parser (>= 3.1.1.0)
|
61
|
-
rubocop-minitest (0.20.
|
61
|
+
rubocop-minitest (0.20.1)
|
62
62
|
rubocop (>= 0.90, < 2.0)
|
63
63
|
rubocop-rake (0.6.0)
|
64
64
|
rubocop (~> 1.0)
|
@@ -67,14 +67,14 @@ GEM
|
|
67
67
|
rubocop-sorbet (0.6.8)
|
68
68
|
rubocop (>= 0.90.0)
|
69
69
|
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.
|
70
|
+
sorbet (0.5.10092)
|
71
|
+
sorbet-static (= 0.5.10092)
|
72
|
+
sorbet-runtime (0.5.10092)
|
73
|
+
sorbet-static (0.5.10092-universal-darwin-21)
|
74
|
+
sorbet-static (0.5.10092-x86_64-linux)
|
75
|
+
sorbet-static-and-runtime (0.5.10092)
|
76
|
+
sorbet (= 0.5.10092)
|
77
|
+
sorbet-runtime (= 0.5.10092)
|
78
78
|
spoom (1.1.11)
|
79
79
|
sorbet (>= 0.5.9204)
|
80
80
|
sorbet-runtime (>= 0.5.9204)
|
@@ -111,7 +111,7 @@ DEPENDENCIES
|
|
111
111
|
minitest (~> 5.15)
|
112
112
|
minitest-reporters (~> 1.5)
|
113
113
|
rake (~> 13.0)
|
114
|
-
rubocop-minitest (~> 0.20.
|
114
|
+
rubocop-minitest (~> 0.20.1)
|
115
115
|
rubocop-rake (~> 0.6.0)
|
116
116
|
rubocop-shopify (~> 2.7)
|
117
117
|
rubocop-sorbet (~> 0.6)
|
data/README.md
CHANGED
@@ -50,7 +50,7 @@ To add a new expectations test runner for a new request handler:
|
|
50
50
|
require "expectations/expectations_test_runner"
|
51
51
|
|
52
52
|
class $HANDLERExpectationsTest < ExpectationsTestRunner
|
53
|
-
|
53
|
+
expectations_tests RubyLsp::Requests::$HANDLER, "$EXPECTATIONS_DIR"
|
54
54
|
end
|
55
55
|
```
|
56
56
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/exe/ruby-lsp
CHANGED
data/lib/ruby-lsp.rb
CHANGED
data/lib/ruby_lsp/document.rb
CHANGED
@@ -32,7 +32,13 @@ module RubyLsp
|
|
32
32
|
@source == other.source
|
33
33
|
end
|
34
34
|
|
35
|
-
sig
|
35
|
+
sig do
|
36
|
+
type_parameters(:T)
|
37
|
+
.params(
|
38
|
+
request_name: Symbol,
|
39
|
+
block: T.proc.params(document: Document).returns(T.type_parameter(:T))
|
40
|
+
).returns(T.type_parameter(:T))
|
41
|
+
end
|
36
42
|
def cache_fetch(request_name, &block)
|
37
43
|
cached = @cache[request_name]
|
38
44
|
return cached if cached
|
data/lib/ruby_lsp/handler.rb
CHANGED
@@ -28,9 +28,7 @@ module RubyLsp
|
|
28
28
|
sig { void }
|
29
29
|
def start
|
30
30
|
$stderr.puts "Starting Ruby LSP..."
|
31
|
-
@reader.read
|
32
|
-
with_telemetry(request) { handle(request) }
|
33
|
-
end
|
31
|
+
@reader.read { |request| handle(request) }
|
34
32
|
end
|
35
33
|
|
36
34
|
sig { params(blk: T.proc.bind(Handler).params(arg0: T.untyped).void).void }
|
@@ -52,11 +50,23 @@ module RubyLsp
|
|
52
50
|
|
53
51
|
sig { params(request: T::Hash[Symbol, T.untyped]).void }
|
54
52
|
def handle(request)
|
53
|
+
result = T.let(nil, T.untyped)
|
54
|
+
error = T.let(nil, T.nilable(StandardError))
|
55
55
|
handler = @handlers[request[:method]]
|
56
|
-
return unless handler
|
57
56
|
|
58
|
-
|
59
|
-
|
57
|
+
request_time = Benchmark.realtime do
|
58
|
+
if handler
|
59
|
+
begin
|
60
|
+
result = handler.call(request)
|
61
|
+
rescue StandardError => e
|
62
|
+
error = e
|
63
|
+
end
|
64
|
+
|
65
|
+
@writer.write(id: request[:id], result: result) unless result == VOID
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
@writer.write(method: "telemetry/event", params: telemetry_params(request, request_time, error))
|
60
70
|
end
|
61
71
|
|
62
72
|
sig { void }
|
@@ -114,14 +124,14 @@ module RubyLsp
|
|
114
124
|
sig { params(uri: String).returns(T::Array[LanguageServer::Protocol::Interface::DocumentSymbol]) }
|
115
125
|
def respond_with_document_symbol(uri)
|
116
126
|
store.cache_fetch(uri, :document_symbol) do |document|
|
117
|
-
RubyLsp::Requests::DocumentSymbol.
|
127
|
+
RubyLsp::Requests::DocumentSymbol.new(document).run
|
118
128
|
end
|
119
129
|
end
|
120
130
|
|
121
131
|
sig { params(uri: String).returns(T::Array[LanguageServer::Protocol::Interface::FoldingRange]) }
|
122
132
|
def respond_with_folding_ranges(uri)
|
123
133
|
store.cache_fetch(uri, :folding_ranges) do |document|
|
124
|
-
Requests::FoldingRanges.
|
134
|
+
Requests::FoldingRanges.new(document).run
|
125
135
|
end
|
126
136
|
end
|
127
137
|
|
@@ -129,11 +139,11 @@ module RubyLsp
|
|
129
139
|
params(
|
130
140
|
uri: String,
|
131
141
|
positions: T::Array[Document::PositionShape]
|
132
|
-
).returns(T::Array[RubyLsp::Requests::Support::SelectionRange])
|
142
|
+
).returns(T::Array[T.nilable(RubyLsp::Requests::Support::SelectionRange)])
|
133
143
|
end
|
134
144
|
def respond_with_selection_ranges(uri, positions)
|
135
145
|
ranges = store.cache_fetch(uri, :selection_ranges) do |document|
|
136
|
-
Requests::SelectionRanges.
|
146
|
+
Requests::SelectionRanges.new(document).run
|
137
147
|
end
|
138
148
|
|
139
149
|
# Per the selection range request spec (https://microsoft.github.io/language-server-protocol/specification#textDocument_selectionRange),
|
@@ -150,19 +160,22 @@ module RubyLsp
|
|
150
160
|
sig { params(uri: String).returns(LanguageServer::Protocol::Interface::SemanticTokens) }
|
151
161
|
def respond_with_semantic_highlighting(uri)
|
152
162
|
store.cache_fetch(uri, :semantic_highlighting) do |document|
|
153
|
-
|
163
|
+
T.cast(
|
164
|
+
Requests::SemanticHighlighting.new(document, encoder: Requests::Support::SemanticTokenEncoder.new).run,
|
165
|
+
LanguageServer::Protocol::Interface::SemanticTokens
|
166
|
+
)
|
154
167
|
end
|
155
168
|
end
|
156
169
|
|
157
|
-
sig { params(uri: String).returns(T::Array[LanguageServer::Protocol::Interface::TextEdit]) }
|
170
|
+
sig { params(uri: String).returns(T.nilable(T::Array[LanguageServer::Protocol::Interface::TextEdit])) }
|
158
171
|
def respond_with_formatting(uri)
|
159
|
-
Requests::Formatting.
|
172
|
+
Requests::Formatting.new(uri, store.get(uri)).run
|
160
173
|
end
|
161
174
|
|
162
175
|
sig { params(uri: String).void }
|
163
176
|
def send_diagnostics(uri)
|
164
177
|
response = store.cache_fetch(uri, :diagnostics) do |document|
|
165
|
-
Requests::Diagnostics.
|
178
|
+
Requests::Diagnostics.new(uri, document).run
|
166
179
|
end
|
167
180
|
|
168
181
|
@writer.write(
|
@@ -175,11 +188,11 @@ module RubyLsp
|
|
175
188
|
end
|
176
189
|
|
177
190
|
sig do
|
178
|
-
params(uri: String, range: T::Range[Integer]).returns(T::Array[LanguageServer::Protocol::Interface::
|
191
|
+
params(uri: String, range: T::Range[Integer]).returns(T::Array[LanguageServer::Protocol::Interface::CodeAction])
|
179
192
|
end
|
180
193
|
def respond_with_code_actions(uri, range)
|
181
194
|
store.cache_fetch(uri, :code_actions) do |document|
|
182
|
-
Requests::CodeActions.
|
195
|
+
Requests::CodeActions.new(uri, document, range).run
|
183
196
|
end
|
184
197
|
end
|
185
198
|
|
@@ -190,22 +203,7 @@ module RubyLsp
|
|
190
203
|
).returns(T::Array[LanguageServer::Protocol::Interface::DocumentHighlight])
|
191
204
|
end
|
192
205
|
def respond_with_document_highlight(uri, position)
|
193
|
-
Requests::DocumentHighlight.
|
194
|
-
end
|
195
|
-
|
196
|
-
sig { params(request: T::Hash[Symbol, T.untyped], block: T.proc.void).returns(T.untyped) }
|
197
|
-
def with_telemetry(request, &block)
|
198
|
-
result = T.let(nil, T.untyped)
|
199
|
-
error = T.let(nil, T.nilable(StandardError))
|
200
|
-
|
201
|
-
request_time = Benchmark.realtime do
|
202
|
-
result = block.call
|
203
|
-
rescue StandardError => e
|
204
|
-
error = e
|
205
|
-
end
|
206
|
-
|
207
|
-
@writer.write(method: "telemetry/event", params: telemetry_params(request, request_time, error))
|
208
|
-
result
|
206
|
+
Requests::DocumentHighlight.new(store.get(uri), position).run
|
209
207
|
end
|
210
208
|
|
211
209
|
sig do
|
@@ -1,24 +1,26 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
6
|
# :nodoc:
|
7
7
|
class BaseRequest < SyntaxTree::Visitor
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
extend T::Sig
|
9
|
+
extend T::Helpers
|
10
|
+
|
11
|
+
abstract!
|
11
12
|
|
13
|
+
sig { params(document: Document).void }
|
12
14
|
def initialize(document)
|
13
15
|
@document = document
|
14
16
|
|
15
17
|
super()
|
16
18
|
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
end
|
20
|
+
sig { abstract.returns(Object) }
|
21
|
+
def run; end
|
21
22
|
|
23
|
+
sig { params(node: SyntaxTree::Node).returns(LanguageServer::Protocol::Interface::Range) }
|
22
24
|
def range_from_syntax_tree_node(node)
|
23
25
|
loc = node.location
|
24
26
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
@@ -14,23 +14,32 @@ module RubyLsp
|
|
14
14
|
# puts "Hello" # --> code action: quick fix indentation
|
15
15
|
# end
|
16
16
|
# ```
|
17
|
-
class CodeActions
|
18
|
-
|
19
|
-
new(uri, document, range).run
|
20
|
-
end
|
17
|
+
class CodeActions < BaseRequest
|
18
|
+
extend T::Sig
|
21
19
|
|
20
|
+
sig do
|
21
|
+
params(
|
22
|
+
uri: String,
|
23
|
+
document: Document,
|
24
|
+
range: T::Range[Integer]
|
25
|
+
).void
|
26
|
+
end
|
22
27
|
def initialize(uri, document, range)
|
23
|
-
|
28
|
+
super(document)
|
29
|
+
|
24
30
|
@uri = uri
|
25
31
|
@range = range
|
26
32
|
end
|
27
33
|
|
34
|
+
sig { override.returns(T.all(T::Array[LanguageServer::Protocol::Interface::CodeAction], Object)) }
|
28
35
|
def run
|
29
|
-
diagnostics = Diagnostics.
|
30
|
-
corrections = diagnostics.select
|
36
|
+
diagnostics = Diagnostics.new(@uri, @document).run
|
37
|
+
corrections = diagnostics.select do |diagnostic|
|
38
|
+
diagnostic.correctable? && T.cast(diagnostic, Support::RuboCopDiagnostic).in_range?(@range)
|
39
|
+
end
|
31
40
|
return [] if corrections.empty?
|
32
41
|
|
33
|
-
corrections.map!(&:to_lsp_code_action)
|
42
|
+
T.cast(corrections, T::Array[Support::RuboCopDiagnostic]).map!(&:to_lsp_code_action)
|
34
43
|
end
|
35
44
|
end
|
36
45
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
@@ -15,6 +15,16 @@ module RubyLsp
|
|
15
15
|
# end
|
16
16
|
# ```
|
17
17
|
class Diagnostics < RuboCopRequest
|
18
|
+
extend T::Sig
|
19
|
+
|
20
|
+
sig do
|
21
|
+
override.returns(
|
22
|
+
T.any(
|
23
|
+
T.all(T::Array[Support::RuboCopDiagnostic], Object),
|
24
|
+
T.all(T::Array[Support::SyntaxErrorDiagnostic], Object),
|
25
|
+
)
|
26
|
+
)
|
27
|
+
end
|
18
28
|
def run
|
19
29
|
return syntax_error_diagnostics if @document.syntax_errors?
|
20
30
|
|
@@ -23,12 +33,14 @@ module RubyLsp
|
|
23
33
|
@diagnostics
|
24
34
|
end
|
25
35
|
|
36
|
+
sig { params(_file: String, offenses: T::Array[RuboCop::Cop::Offense]).void }
|
26
37
|
def file_finished(_file, offenses)
|
27
38
|
@diagnostics = offenses.map { |offense| Support::RuboCopDiagnostic.new(offense, @uri) }
|
28
39
|
end
|
29
40
|
|
30
41
|
private
|
31
42
|
|
43
|
+
sig { returns(T::Array[Support::SyntaxErrorDiagnostic]) }
|
32
44
|
def syntax_error_diagnostics
|
33
45
|
@document.syntax_error_edits.map { |e| Support::SyntaxErrorDiagnostic.new(e) }
|
34
46
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
@@ -21,18 +21,28 @@ module RubyLsp
|
|
21
21
|
# end
|
22
22
|
# ```
|
23
23
|
class DocumentHighlight < BaseRequest
|
24
|
-
|
25
|
-
|
24
|
+
extend T::Sig
|
25
|
+
|
26
|
+
VarNodes = T.type_alias do
|
27
|
+
T.any(
|
28
|
+
SyntaxTree::GVar,
|
29
|
+
SyntaxTree::Ident,
|
30
|
+
SyntaxTree::IVar,
|
31
|
+
SyntaxTree::Const,
|
32
|
+
SyntaxTree::CVar
|
33
|
+
)
|
26
34
|
end
|
27
35
|
|
36
|
+
sig { params(document: Document, position: Document::PositionShape).void }
|
28
37
|
def initialize(document, position)
|
29
|
-
@highlights = []
|
38
|
+
@highlights = T.let([], T::Array[LanguageServer::Protocol::Interface::DocumentHighlight])
|
30
39
|
position = Document::Scanner.new(document.source).find_position(position)
|
31
|
-
@target = find(document.tree, position)
|
40
|
+
@target = T.let(find(document.tree, position), T.nilable(VarNodes))
|
32
41
|
|
33
42
|
super(document)
|
34
43
|
end
|
35
44
|
|
45
|
+
sig { override.returns(T.all(T::Array[LanguageServer::Protocol::Interface::DocumentHighlight], Object)) }
|
36
46
|
def run
|
37
47
|
# no @target means the target is not highlightable
|
38
48
|
return [] unless @target
|
@@ -41,6 +51,7 @@ module RubyLsp
|
|
41
51
|
@highlights
|
42
52
|
end
|
43
53
|
|
54
|
+
sig { params(node: SyntaxTree::VarField).void }
|
44
55
|
def visit_var_field(node)
|
45
56
|
if matches_target?(node.value)
|
46
57
|
add_highlight(
|
@@ -52,6 +63,7 @@ module RubyLsp
|
|
52
63
|
super
|
53
64
|
end
|
54
65
|
|
66
|
+
sig { params(node: SyntaxTree::VarRef).void }
|
55
67
|
def visit_var_ref(node)
|
56
68
|
if matches_target?(node.value)
|
57
69
|
add_highlight(
|
@@ -65,6 +77,7 @@ module RubyLsp
|
|
65
77
|
|
66
78
|
private
|
67
79
|
|
80
|
+
sig { params(node: SyntaxTree::Node, position: Integer).returns(T.nilable(VarNodes)) }
|
68
81
|
def find(node, position)
|
69
82
|
matched =
|
70
83
|
node.child_nodes.compact.bsearch do |child|
|
@@ -83,10 +96,12 @@ module RubyLsp
|
|
83
96
|
end
|
84
97
|
end
|
85
98
|
|
99
|
+
sig { params(node: SyntaxTree::Node).returns(T::Boolean) }
|
86
100
|
def matches_target?(node)
|
87
|
-
node.is_a?(@target.class) && node.value == @target.value
|
101
|
+
node.is_a?(@target.class) && T.cast(node, VarNodes).value == T.must(@target).value
|
88
102
|
end
|
89
103
|
|
104
|
+
sig { params(node: SyntaxTree::Node, kind: Integer).void }
|
90
105
|
def add_highlight(node, kind)
|
91
106
|
range = range_from_syntax_tree_node(node)
|
92
107
|
@highlights << LanguageServer::Protocol::Interface::DocumentHighlight.new(range: range, kind: kind)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
@@ -25,7 +25,9 @@ module RubyLsp
|
|
25
25
|
# end
|
26
26
|
# ```
|
27
27
|
class DocumentSymbol < BaseRequest
|
28
|
-
|
28
|
+
extend T::Sig
|
29
|
+
|
30
|
+
SYMBOL_KIND = T.let({
|
29
31
|
file: 1,
|
30
32
|
module: 2,
|
31
33
|
namespace: 3,
|
@@ -52,33 +54,43 @@ module RubyLsp
|
|
52
54
|
event: 24,
|
53
55
|
operator: 25,
|
54
56
|
typeparameter: 26,
|
55
|
-
}.freeze
|
57
|
+
}.freeze, T::Hash[Symbol, Integer])
|
56
58
|
|
57
|
-
ATTR_ACCESSORS = ["attr_reader", "attr_writer", "attr_accessor"].freeze
|
59
|
+
ATTR_ACCESSORS = T.let(["attr_reader", "attr_writer", "attr_accessor"].freeze, T::Array[String])
|
58
60
|
|
59
61
|
class SymbolHierarchyRoot
|
62
|
+
extend T::Sig
|
63
|
+
|
64
|
+
sig { returns(T::Array[LanguageServer::Protocol::Interface::DocumentSymbol]) }
|
60
65
|
attr_reader :children
|
61
66
|
|
67
|
+
sig { void }
|
62
68
|
def initialize
|
63
|
-
@children = []
|
69
|
+
@children = T.let([], T::Array[LanguageServer::Protocol::Interface::DocumentSymbol])
|
64
70
|
end
|
65
71
|
end
|
66
72
|
|
73
|
+
sig { params(document: Document).void }
|
67
74
|
def initialize(document)
|
68
75
|
super
|
69
76
|
|
70
|
-
@root = SymbolHierarchyRoot.new
|
71
|
-
@stack =
|
77
|
+
@root = T.let(SymbolHierarchyRoot.new, SymbolHierarchyRoot)
|
78
|
+
@stack = T.let(
|
79
|
+
[@root],
|
80
|
+
T::Array[T.any(SymbolHierarchyRoot, LanguageServer::Protocol::Interface::DocumentSymbol)]
|
81
|
+
)
|
72
82
|
end
|
73
83
|
|
84
|
+
sig { override.returns(T.all(T::Array[LanguageServer::Protocol::Interface::DocumentSymbol], Object)) }
|
74
85
|
def run
|
75
86
|
visit(@document.tree)
|
76
87
|
@root.children
|
77
88
|
end
|
78
89
|
|
90
|
+
sig { params(node: SyntaxTree::ClassDeclaration).void }
|
79
91
|
def visit_class(node)
|
80
92
|
symbol = create_document_symbol(
|
81
|
-
name: node
|
93
|
+
name: fully_qualified_name(node),
|
82
94
|
kind: :class,
|
83
95
|
range_node: node,
|
84
96
|
selection_range_node: node.constant
|
@@ -89,6 +101,7 @@ module RubyLsp
|
|
89
101
|
@stack.pop
|
90
102
|
end
|
91
103
|
|
104
|
+
sig { params(node: SyntaxTree::Command).void }
|
92
105
|
def visit_command(node)
|
93
106
|
return unless ATTR_ACCESSORS.include?(node.message.value)
|
94
107
|
|
@@ -104,6 +117,7 @@ module RubyLsp
|
|
104
117
|
end
|
105
118
|
end
|
106
119
|
|
120
|
+
sig { params(node: SyntaxTree::ConstPathField).void }
|
107
121
|
def visit_const_path_field(node)
|
108
122
|
create_document_symbol(
|
109
123
|
name: node.constant.value,
|
@@ -113,6 +127,7 @@ module RubyLsp
|
|
113
127
|
)
|
114
128
|
end
|
115
129
|
|
130
|
+
sig { params(node: SyntaxTree::Def).void }
|
116
131
|
def visit_def(node)
|
117
132
|
name = node.name.value
|
118
133
|
|
@@ -128,6 +143,7 @@ module RubyLsp
|
|
128
143
|
@stack.pop
|
129
144
|
end
|
130
145
|
|
146
|
+
sig { params(node: SyntaxTree::DefEndless).void }
|
131
147
|
def visit_def_endless(node)
|
132
148
|
name = node.name.value
|
133
149
|
|
@@ -143,6 +159,7 @@ module RubyLsp
|
|
143
159
|
@stack.pop
|
144
160
|
end
|
145
161
|
|
162
|
+
sig { params(node: SyntaxTree::Defs).void }
|
146
163
|
def visit_defs(node)
|
147
164
|
symbol = create_document_symbol(
|
148
165
|
name: "self.#{node.name.value}",
|
@@ -156,9 +173,10 @@ module RubyLsp
|
|
156
173
|
@stack.pop
|
157
174
|
end
|
158
175
|
|
176
|
+
sig { params(node: SyntaxTree::ModuleDeclaration).void }
|
159
177
|
def visit_module(node)
|
160
178
|
symbol = create_document_symbol(
|
161
|
-
name: node
|
179
|
+
name: fully_qualified_name(node),
|
162
180
|
kind: :module,
|
163
181
|
range_node: node,
|
164
182
|
selection_range_node: node.constant
|
@@ -169,6 +187,7 @@ module RubyLsp
|
|
169
187
|
@stack.pop
|
170
188
|
end
|
171
189
|
|
190
|
+
sig { params(node: SyntaxTree::TopConstField).void }
|
172
191
|
def visit_top_const_field(node)
|
173
192
|
create_document_symbol(
|
174
193
|
name: node.constant.value,
|
@@ -178,6 +197,7 @@ module RubyLsp
|
|
178
197
|
)
|
179
198
|
end
|
180
199
|
|
200
|
+
sig { params(node: SyntaxTree::VarField).void }
|
181
201
|
def visit_var_field(node)
|
182
202
|
kind = case node.value
|
183
203
|
when SyntaxTree::Const
|
@@ -198,6 +218,14 @@ module RubyLsp
|
|
198
218
|
|
199
219
|
private
|
200
220
|
|
221
|
+
sig do
|
222
|
+
params(
|
223
|
+
name: String,
|
224
|
+
kind: Symbol,
|
225
|
+
range_node: SyntaxTree::Node,
|
226
|
+
selection_range_node: SyntaxTree::Node
|
227
|
+
).returns(LanguageServer::Protocol::Interface::DocumentSymbol)
|
228
|
+
end
|
201
229
|
def create_document_symbol(name:, kind:, range_node:, selection_range_node:)
|
202
230
|
symbol = LanguageServer::Protocol::Interface::DocumentSymbol.new(
|
203
231
|
name: name,
|
@@ -207,10 +235,29 @@ module RubyLsp
|
|
207
235
|
children: [],
|
208
236
|
)
|
209
237
|
|
210
|
-
@stack.last.children << symbol
|
238
|
+
T.must(@stack.last).children << symbol
|
211
239
|
|
212
240
|
symbol
|
213
241
|
end
|
242
|
+
|
243
|
+
sig { params(node: T.any(SyntaxTree::ClassDeclaration, SyntaxTree::ModuleDeclaration)).returns(String) }
|
244
|
+
def fully_qualified_name(node)
|
245
|
+
constant = T.let(node.constant, SyntaxTree::Node)
|
246
|
+
name = +node.constant.constant.value
|
247
|
+
|
248
|
+
while constant.is_a?(SyntaxTree::ConstPathRef)
|
249
|
+
constant = constant.parent
|
250
|
+
|
251
|
+
case constant
|
252
|
+
when SyntaxTree::ConstPathRef
|
253
|
+
name.prepend("#{constant.constant.value}::")
|
254
|
+
when SyntaxTree::VarRef
|
255
|
+
name.prepend("#{constant.value.value}::")
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
name
|
260
|
+
end
|
214
261
|
end
|
215
262
|
end
|
216
263
|
end
|