ruby-lsp 0.14.6 → 0.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/VERSION +1 -1
- data/exe/ruby-lsp +1 -16
- data/exe/ruby-lsp-check +13 -22
- data/exe/ruby-lsp-doctor +9 -0
- data/lib/ruby_indexer/lib/ruby_indexer/collector.rb +14 -1
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +11 -23
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +32 -8
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +26 -0
- data/lib/ruby_indexer/ruby_indexer.rb +1 -0
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +46 -0
- data/lib/ruby_indexer/test/configuration_test.rb +2 -11
- data/lib/ruby_lsp/addon.rb +18 -9
- data/lib/ruby_lsp/base_server.rb +149 -0
- data/lib/ruby_lsp/document.rb +6 -11
- data/lib/ruby_lsp/global_state.rb +180 -0
- data/lib/ruby_lsp/internal.rb +4 -1
- data/lib/ruby_lsp/listeners/code_lens.rb +22 -13
- data/lib/ruby_lsp/listeners/completion.rb +13 -14
- data/lib/ruby_lsp/listeners/definition.rb +14 -6
- data/lib/ruby_lsp/listeners/document_symbol.rb +91 -3
- data/lib/ruby_lsp/listeners/hover.rb +6 -5
- data/lib/ruby_lsp/listeners/signature_help.rb +7 -4
- data/lib/ruby_lsp/load_sorbet.rb +62 -0
- data/lib/ruby_lsp/requests/code_lens.rb +3 -2
- data/lib/ruby_lsp/requests/completion.rb +15 -4
- data/lib/ruby_lsp/requests/completion_resolve.rb +56 -0
- data/lib/ruby_lsp/requests/definition.rb +11 -4
- data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
- data/lib/ruby_lsp/requests/document_symbol.rb +3 -3
- data/lib/ruby_lsp/requests/formatting.rb +7 -43
- data/lib/ruby_lsp/requests/hover.rb +4 -4
- data/lib/ruby_lsp/requests/request.rb +2 -0
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +7 -4
- data/lib/ruby_lsp/requests/signature_help.rb +4 -3
- data/lib/ruby_lsp/requests/support/common.rb +16 -5
- data/lib/ruby_lsp/requests/support/formatter.rb +26 -0
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +1 -1
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +47 -0
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +4 -0
- data/lib/ruby_lsp/requests/support/{syntax_tree_formatting_runner.rb → syntax_tree_formatter.rb} +13 -6
- data/lib/ruby_lsp/requests/workspace_symbol.rb +5 -4
- data/lib/ruby_lsp/requests.rb +3 -1
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +36 -13
- data/lib/ruby_lsp/server.rb +763 -142
- data/lib/ruby_lsp/setup_bundler.rb +13 -1
- data/lib/ruby_lsp/store.rb +3 -15
- data/lib/ruby_lsp/test_helper.rb +52 -0
- data/lib/ruby_lsp/utils.rb +68 -33
- metadata +16 -13
- data/lib/ruby_lsp/executor.rb +0 -614
- data/lib/ruby_lsp/requests/support/dependency_detector.rb +0 -93
- data/lib/ruby_lsp/requests/support/formatter_runner.rb +0 -18
- data/lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb +0 -34
- data/lib/ruby_lsp/requests/support/rubocop_formatting_runner.rb +0 -35
@@ -12,17 +12,20 @@ module RubyLsp
|
|
12
12
|
sig do
|
13
13
|
params(
|
14
14
|
response_builder: ResponseBuilders::DocumentSymbol,
|
15
|
+
uri: URI::Generic,
|
15
16
|
dispatcher: Prism::Dispatcher,
|
16
17
|
).void
|
17
18
|
end
|
18
|
-
def initialize(response_builder, dispatcher)
|
19
|
+
def initialize(response_builder, uri, dispatcher)
|
19
20
|
@response_builder = response_builder
|
21
|
+
@uri = uri
|
20
22
|
|
21
23
|
dispatcher.register(
|
22
24
|
self,
|
23
25
|
:on_class_node_enter,
|
24
26
|
:on_class_node_leave,
|
25
27
|
:on_call_node_enter,
|
28
|
+
:on_call_node_leave,
|
26
29
|
:on_constant_path_write_node_enter,
|
27
30
|
:on_constant_write_node_enter,
|
28
31
|
:on_constant_path_or_write_node_enter,
|
@@ -79,10 +82,24 @@ module RubyLsp
|
|
79
82
|
|
80
83
|
sig { params(node: Prism::CallNode).void }
|
81
84
|
def on_call_node_enter(node)
|
82
|
-
|
85
|
+
node_name = node.name
|
86
|
+
if ATTR_ACCESSORS.include?(node_name)
|
83
87
|
handle_attr_accessor(node)
|
84
|
-
elsif
|
88
|
+
elsif node_name == :alias_method
|
85
89
|
handle_alias_method(node)
|
90
|
+
elsif node_name == :namespace
|
91
|
+
handle_rake_namespace(node)
|
92
|
+
elsif node_name == :task
|
93
|
+
handle_rake_task(node)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
sig { params(node: Prism::CallNode).void }
|
98
|
+
def on_call_node_leave(node)
|
99
|
+
return unless rake?
|
100
|
+
|
101
|
+
if node.name == :namespace && !node.receiver
|
102
|
+
@response_builder.pop
|
86
103
|
end
|
87
104
|
end
|
88
105
|
|
@@ -279,6 +296,7 @@ module RubyLsp
|
|
279
296
|
).returns(Interface::DocumentSymbol)
|
280
297
|
end
|
281
298
|
def create_document_symbol(name:, kind:, range_location:, selection_range_location:)
|
299
|
+
name = "<blank>" if name.empty?
|
282
300
|
symbol = Interface::DocumentSymbol.new(
|
283
301
|
name: name,
|
284
302
|
kind: kind,
|
@@ -357,6 +375,76 @@ module RubyLsp
|
|
357
375
|
)
|
358
376
|
end
|
359
377
|
end
|
378
|
+
|
379
|
+
sig { params(node: Prism::CallNode).void }
|
380
|
+
def handle_rake_namespace(node)
|
381
|
+
return unless rake?
|
382
|
+
return if node.receiver
|
383
|
+
|
384
|
+
arguments = node.arguments
|
385
|
+
return unless arguments
|
386
|
+
|
387
|
+
name_argument = arguments.arguments.first
|
388
|
+
return unless name_argument
|
389
|
+
|
390
|
+
name = case name_argument
|
391
|
+
when Prism::StringNode then name_argument.content
|
392
|
+
when Prism::SymbolNode then name_argument.value
|
393
|
+
end
|
394
|
+
|
395
|
+
return if name.nil? || name.empty?
|
396
|
+
|
397
|
+
@response_builder << create_document_symbol(
|
398
|
+
name: name,
|
399
|
+
kind: Constant::SymbolKind::MODULE,
|
400
|
+
range_location: name_argument.location,
|
401
|
+
selection_range_location: name_argument.location,
|
402
|
+
)
|
403
|
+
end
|
404
|
+
|
405
|
+
sig { params(node: Prism::CallNode).void }
|
406
|
+
def handle_rake_task(node)
|
407
|
+
return unless rake?
|
408
|
+
return if node.receiver
|
409
|
+
|
410
|
+
arguments = node.arguments
|
411
|
+
return unless arguments
|
412
|
+
|
413
|
+
name_argument = arguments.arguments.first
|
414
|
+
return unless name_argument
|
415
|
+
|
416
|
+
name = case name_argument
|
417
|
+
when Prism::StringNode then name_argument.content
|
418
|
+
when Prism::SymbolNode then name_argument.value
|
419
|
+
when Prism::KeywordHashNode
|
420
|
+
first_element = name_argument.elements.first
|
421
|
+
if first_element.is_a?(Prism::AssocNode)
|
422
|
+
key = first_element.key
|
423
|
+
case key
|
424
|
+
when Prism::StringNode then key.content
|
425
|
+
when Prism::SymbolNode then key.value
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
return if name.nil? || name.empty?
|
431
|
+
|
432
|
+
create_document_symbol(
|
433
|
+
name: name,
|
434
|
+
kind: Constant::SymbolKind::METHOD,
|
435
|
+
range_location: name_argument.location,
|
436
|
+
selection_range_location: name_argument.location,
|
437
|
+
)
|
438
|
+
end
|
439
|
+
|
440
|
+
sig { returns(T::Boolean) }
|
441
|
+
def rake?
|
442
|
+
if (path = @uri.to_standardized_path)
|
443
|
+
path.match?(/(Rakefile|\.rake)$/)
|
444
|
+
else
|
445
|
+
false
|
446
|
+
end
|
447
|
+
end
|
360
448
|
end
|
361
449
|
end
|
362
450
|
end
|
@@ -28,18 +28,19 @@ module RubyLsp
|
|
28
28
|
sig do
|
29
29
|
params(
|
30
30
|
response_builder: ResponseBuilders::Hover,
|
31
|
+
global_state: GlobalState,
|
31
32
|
uri: URI::Generic,
|
32
33
|
nesting: T::Array[String],
|
33
|
-
index: RubyIndexer::Index,
|
34
34
|
dispatcher: Prism::Dispatcher,
|
35
35
|
typechecker_enabled: T::Boolean,
|
36
36
|
).void
|
37
37
|
end
|
38
|
-
def initialize(response_builder, uri, nesting,
|
38
|
+
def initialize(response_builder, global_state, uri, nesting, dispatcher, typechecker_enabled) # rubocop:disable Metrics/ParameterLists
|
39
39
|
@response_builder = response_builder
|
40
|
+
@global_state = global_state
|
41
|
+
@index = T.let(global_state.index, RubyIndexer::Index)
|
40
42
|
@path = T.let(uri.to_standardized_path, T.nilable(String))
|
41
43
|
@nesting = nesting
|
42
|
-
@index = index
|
43
44
|
@typechecker_enabled = typechecker_enabled
|
44
45
|
|
45
46
|
dispatcher.register(
|
@@ -63,14 +64,14 @@ module RubyLsp
|
|
63
64
|
|
64
65
|
sig { params(node: Prism::ConstantWriteNode).void }
|
65
66
|
def on_constant_write_node_enter(node)
|
66
|
-
return if
|
67
|
+
return if @global_state.typechecker
|
67
68
|
|
68
69
|
generate_hover(node.name.to_s, node.name_loc)
|
69
70
|
end
|
70
71
|
|
71
72
|
sig { params(node: Prism::ConstantPathNode).void }
|
72
73
|
def on_constant_path_node_enter(node)
|
73
|
-
return if
|
74
|
+
return if @global_state.typechecker
|
74
75
|
|
75
76
|
name = constant_name(node)
|
76
77
|
return if name.nil?
|
@@ -10,21 +10,24 @@ module RubyLsp
|
|
10
10
|
sig do
|
11
11
|
params(
|
12
12
|
response_builder: ResponseBuilders::SignatureHelp,
|
13
|
+
global_state: GlobalState,
|
13
14
|
nesting: T::Array[String],
|
14
|
-
index: RubyIndexer::Index,
|
15
15
|
dispatcher: Prism::Dispatcher,
|
16
|
+
typechecker_enabled: T::Boolean,
|
16
17
|
).void
|
17
18
|
end
|
18
|
-
def initialize(response_builder, nesting,
|
19
|
+
def initialize(response_builder, global_state, nesting, dispatcher, typechecker_enabled)
|
20
|
+
@typechecker_enabled = typechecker_enabled
|
19
21
|
@response_builder = response_builder
|
22
|
+
@global_state = global_state
|
23
|
+
@index = T.let(global_state.index, RubyIndexer::Index)
|
20
24
|
@nesting = nesting
|
21
|
-
@index = index
|
22
25
|
dispatcher.register(self, :on_call_node_enter)
|
23
26
|
end
|
24
27
|
|
25
28
|
sig { params(node: Prism::CallNode).void }
|
26
29
|
def on_call_node_enter(node)
|
27
|
-
return if
|
30
|
+
return if @typechecker_enabled
|
28
31
|
return unless self_receiver?(node)
|
29
32
|
|
30
33
|
message = node.message
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
6
|
+
begin
|
7
|
+
T::Configuration.default_checked_level = :never
|
8
|
+
# Suppresses call validation errors
|
9
|
+
T::Configuration.call_validation_error_handler = ->(*) {}
|
10
|
+
# Suppresses errors caused by T.cast, T.let, T.must, etc.
|
11
|
+
T::Configuration.inline_type_error_handler = ->(*) {}
|
12
|
+
# Suppresses errors caused by incorrect parameter ordering
|
13
|
+
T::Configuration.sig_validation_error_handler = ->(*) {}
|
14
|
+
rescue
|
15
|
+
# Need this rescue so that if another gem has
|
16
|
+
# already set the checked level by the time we
|
17
|
+
# get to it, we don't fail outright.
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
module RubyLsp
|
22
|
+
# No-op all inline type assertions defined in T
|
23
|
+
module InlineTypeAssertions
|
24
|
+
def absurd(value)
|
25
|
+
value
|
26
|
+
end
|
27
|
+
|
28
|
+
def any(type_a, type_b, *types)
|
29
|
+
T::Types::Union.new([type_a, type_b, *types])
|
30
|
+
end
|
31
|
+
|
32
|
+
def assert_type!(value, type, checked: true)
|
33
|
+
value
|
34
|
+
end
|
35
|
+
|
36
|
+
def bind(value, type, checked: true)
|
37
|
+
value
|
38
|
+
end
|
39
|
+
|
40
|
+
def cast(value, type, checked: true)
|
41
|
+
value
|
42
|
+
end
|
43
|
+
|
44
|
+
def let(value, type, checked: true)
|
45
|
+
value
|
46
|
+
end
|
47
|
+
|
48
|
+
def must(arg)
|
49
|
+
arg
|
50
|
+
end
|
51
|
+
|
52
|
+
def nilable(type)
|
53
|
+
T::Types::Union.new([type, T::Utils::Nilable::NIL_TYPE])
|
54
|
+
end
|
55
|
+
|
56
|
+
def unsafe(value)
|
57
|
+
value
|
58
|
+
end
|
59
|
+
|
60
|
+
T.singleton_class.prepend(self)
|
61
|
+
end
|
62
|
+
end
|
@@ -34,17 +34,18 @@ module RubyLsp
|
|
34
34
|
|
35
35
|
sig do
|
36
36
|
params(
|
37
|
+
global_state: GlobalState,
|
37
38
|
uri: URI::Generic,
|
38
39
|
dispatcher: Prism::Dispatcher,
|
39
40
|
).void
|
40
41
|
end
|
41
|
-
def initialize(uri, dispatcher)
|
42
|
+
def initialize(global_state, uri, dispatcher)
|
42
43
|
@response_builder = T.let(
|
43
44
|
ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens].new,
|
44
45
|
ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens],
|
45
46
|
)
|
46
47
|
super()
|
47
|
-
Listeners::CodeLens.new(@response_builder, uri, dispatcher)
|
48
|
+
Listeners::CodeLens.new(@response_builder, global_state, uri, dispatcher)
|
48
49
|
|
49
50
|
Addon.addons.each do |addon|
|
50
51
|
addon.create_code_lens_listener(@response_builder, uri, dispatcher)
|
@@ -33,7 +33,7 @@ module RubyLsp
|
|
33
33
|
sig { returns(Interface::CompletionOptions) }
|
34
34
|
def provider
|
35
35
|
Interface::CompletionOptions.new(
|
36
|
-
resolve_provider:
|
36
|
+
resolve_provider: true,
|
37
37
|
trigger_characters: ["/", "\"", "'"],
|
38
38
|
completion_item: {
|
39
39
|
labelDetailsSupport: true,
|
@@ -45,13 +45,13 @@ module RubyLsp
|
|
45
45
|
sig do
|
46
46
|
params(
|
47
47
|
document: Document,
|
48
|
-
|
48
|
+
global_state: GlobalState,
|
49
49
|
position: T::Hash[Symbol, T.untyped],
|
50
50
|
typechecker_enabled: T::Boolean,
|
51
51
|
dispatcher: Prism::Dispatcher,
|
52
52
|
).void
|
53
53
|
end
|
54
|
-
def initialize(document,
|
54
|
+
def initialize(document, global_state, position, typechecker_enabled, dispatcher)
|
55
55
|
super()
|
56
56
|
@target = T.let(nil, T.nilable(Prism::Node))
|
57
57
|
@dispatcher = dispatcher
|
@@ -68,7 +68,18 @@ module RubyLsp
|
|
68
68
|
ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem],
|
69
69
|
)
|
70
70
|
|
71
|
-
Listeners::Completion.new(
|
71
|
+
Listeners::Completion.new(
|
72
|
+
@response_builder,
|
73
|
+
global_state,
|
74
|
+
nesting,
|
75
|
+
typechecker_enabled,
|
76
|
+
dispatcher,
|
77
|
+
document.uri,
|
78
|
+
)
|
79
|
+
|
80
|
+
Addon.addons.each do |addon|
|
81
|
+
addon.create_completion_listener(@response_builder, nesting, dispatcher, document.uri)
|
82
|
+
end
|
72
83
|
|
73
84
|
return unless matched && parent
|
74
85
|
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RubyLsp
|
5
|
+
module Requests
|
6
|
+
# 
|
7
|
+
#
|
8
|
+
# The [completionItem/resolve](https://microsoft.github.io/language-server-protocol/specification#completionItem_resolve)
|
9
|
+
# request provides additional information about the currently selected completion. Specifically, the `labelDetails`
|
10
|
+
# and `documentation` fields are provided, which are omitted from the completion items returned by
|
11
|
+
# `textDocument/completion`.
|
12
|
+
#
|
13
|
+
# The `labelDetails` field lists the files where the completion item is defined, and the `documentation` field
|
14
|
+
# includes any available documentation for those definitions.
|
15
|
+
#
|
16
|
+
# At most 10 definitions are included, to ensure low latency during request processing and rendering the completion
|
17
|
+
# item.
|
18
|
+
#
|
19
|
+
# # Example
|
20
|
+
#
|
21
|
+
# ```ruby
|
22
|
+
# A # -> as the user cycles through completion items, the documentation will be resolved and displayed
|
23
|
+
# ```
|
24
|
+
class CompletionResolve < Request
|
25
|
+
extend T::Sig
|
26
|
+
include Requests::Support::Common
|
27
|
+
|
28
|
+
# set a limit on the number of documentation entries returned, to avoid rendering performance issues
|
29
|
+
# https://github.com/Shopify/ruby-lsp/pull/1798
|
30
|
+
MAX_DOCUMENTATION_ENTRIES = 10
|
31
|
+
|
32
|
+
sig { params(global_state: GlobalState, item: T::Hash[Symbol, T.untyped]).void }
|
33
|
+
def initialize(global_state, item)
|
34
|
+
super()
|
35
|
+
@index = T.let(global_state.index, RubyIndexer::Index)
|
36
|
+
@item = item
|
37
|
+
end
|
38
|
+
|
39
|
+
sig { override.returns(Interface::CompletionItem) }
|
40
|
+
def perform
|
41
|
+
label = @item[:label]
|
42
|
+
entries = @index[label] || []
|
43
|
+
Interface::CompletionItem.new(
|
44
|
+
label: label,
|
45
|
+
label_details: Interface::CompletionItemLabelDetails.new(
|
46
|
+
description: entries.take(MAX_DOCUMENTATION_ENTRIES).map(&:file_name).join(","),
|
47
|
+
),
|
48
|
+
documentation: Interface::MarkupContent.new(
|
49
|
+
kind: "markdown",
|
50
|
+
value: markdown_from_index_entries(label, entries, MAX_DOCUMENTATION_ENTRIES),
|
51
|
+
),
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -31,13 +31,13 @@ module RubyLsp
|
|
31
31
|
sig do
|
32
32
|
params(
|
33
33
|
document: Document,
|
34
|
-
|
34
|
+
global_state: GlobalState,
|
35
35
|
position: T::Hash[Symbol, T.untyped],
|
36
36
|
dispatcher: Prism::Dispatcher,
|
37
37
|
typechecker_enabled: T::Boolean,
|
38
38
|
).void
|
39
39
|
end
|
40
|
-
def initialize(document,
|
40
|
+
def initialize(document, global_state, position, dispatcher, typechecker_enabled)
|
41
41
|
super()
|
42
42
|
@response_builder = T.let(
|
43
43
|
ResponseBuilders::CollectionResponseBuilder[Interface::Location].new,
|
@@ -57,10 +57,17 @@ module RubyLsp
|
|
57
57
|
)
|
58
58
|
end
|
59
59
|
|
60
|
-
Listeners::Definition.new(
|
60
|
+
Listeners::Definition.new(
|
61
|
+
@response_builder,
|
62
|
+
global_state,
|
63
|
+
document.uri,
|
64
|
+
nesting,
|
65
|
+
dispatcher,
|
66
|
+
typechecker_enabled,
|
67
|
+
)
|
61
68
|
|
62
69
|
Addon.addons.each do |addon|
|
63
|
-
addon.create_definition_listener(@response_builder, document.uri, nesting,
|
70
|
+
addon.create_definition_listener(@response_builder, document.uri, nesting, dispatcher)
|
64
71
|
end
|
65
72
|
|
66
73
|
@target = T.let(target, T.nilable(Prism::Node))
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "ruby_lsp/requests/support/rubocop_diagnostics_runner"
|
5
|
-
|
6
4
|
module RubyLsp
|
7
5
|
module Requests
|
8
6
|
# 
|
@@ -33,9 +31,10 @@ module RubyLsp
|
|
33
31
|
end
|
34
32
|
end
|
35
33
|
|
36
|
-
sig { params(document: Document).void }
|
37
|
-
def initialize(document)
|
34
|
+
sig { params(global_state: GlobalState, document: Document).void }
|
35
|
+
def initialize(global_state, document)
|
38
36
|
super()
|
37
|
+
@active_linters = T.let(global_state.active_linters, T::Array[Support::Formatter])
|
39
38
|
@document = document
|
40
39
|
@uri = T.let(document.uri, URI::Generic)
|
41
40
|
end
|
@@ -46,14 +45,12 @@ module RubyLsp
|
|
46
45
|
diagnostics.concat(syntax_error_diagnostics, syntax_warning_diagnostics)
|
47
46
|
|
48
47
|
# Running RuboCop is slow, so to avoid excessive runs we only do so if the file is syntactically valid
|
49
|
-
return diagnostics if @document.syntax_error?
|
48
|
+
return diagnostics if @document.syntax_error? || @active_linters.empty?
|
50
49
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
).map!(&:to_lsp_diagnostic),
|
56
|
-
) if defined?(Support::RuboCopDiagnosticsRunner)
|
50
|
+
@active_linters.each do |linter|
|
51
|
+
linter_diagnostics = linter.run_diagnostic(@uri, @document)
|
52
|
+
diagnostics.concat(linter_diagnostics) if linter_diagnostics
|
53
|
+
end
|
57
54
|
|
58
55
|
diagnostics
|
59
56
|
end
|
@@ -45,11 +45,11 @@ module RubyLsp
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
sig { params(dispatcher: Prism::Dispatcher).void }
|
49
|
-
def initialize(dispatcher)
|
48
|
+
sig { params(uri: URI::Generic, dispatcher: Prism::Dispatcher).void }
|
49
|
+
def initialize(uri, dispatcher)
|
50
50
|
super()
|
51
51
|
@response_builder = T.let(ResponseBuilders::DocumentSymbol.new, ResponseBuilders::DocumentSymbol)
|
52
|
-
Listeners::DocumentSymbol.new(@response_builder, dispatcher)
|
52
|
+
Listeners::DocumentSymbol.new(@response_builder, uri, dispatcher)
|
53
53
|
|
54
54
|
Addon.addons.each do |addon|
|
55
55
|
addon.create_document_symbol_listener(@response_builder, dispatcher)
|
@@ -1,9 +1,6 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "ruby_lsp/requests/support/rubocop_formatting_runner"
|
5
|
-
require "ruby_lsp/requests/support/syntax_tree_formatting_runner"
|
6
|
-
|
7
4
|
module RubyLsp
|
8
5
|
module Requests
|
9
6
|
# 
|
@@ -26,47 +23,24 @@ module RubyLsp
|
|
26
23
|
# end
|
27
24
|
# ```
|
28
25
|
class Formatting < Request
|
29
|
-
class Error < StandardError; end
|
30
|
-
class InvalidFormatter < StandardError; end
|
31
|
-
|
32
|
-
@formatters = T.let({}, T::Hash[String, Support::FormatterRunner])
|
33
|
-
|
34
|
-
class << self
|
35
|
-
extend T::Sig
|
36
|
-
|
37
|
-
sig { returns(T::Hash[String, Support::FormatterRunner]) }
|
38
|
-
attr_reader :formatters
|
39
|
-
|
40
|
-
sig { params(identifier: String, instance: Support::FormatterRunner).void }
|
41
|
-
def register_formatter(identifier, instance)
|
42
|
-
@formatters[identifier] = instance
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
if defined?(Support::RuboCopFormattingRunner)
|
47
|
-
register_formatter("rubocop", Support::RuboCopFormattingRunner.instance)
|
48
|
-
end
|
49
|
-
|
50
|
-
if defined?(Support::SyntaxTreeFormattingRunner)
|
51
|
-
register_formatter("syntax_tree", Support::SyntaxTreeFormattingRunner.instance)
|
52
|
-
end
|
53
|
-
|
54
26
|
extend T::Sig
|
55
27
|
|
56
|
-
|
57
|
-
|
28
|
+
class Error < StandardError; end
|
29
|
+
|
30
|
+
sig { params(global_state: GlobalState, document: Document).void }
|
31
|
+
def initialize(global_state, document)
|
58
32
|
super()
|
59
33
|
@document = document
|
34
|
+
@active_formatter = T.let(global_state.active_formatter, T.nilable(Support::Formatter))
|
60
35
|
@uri = T.let(document.uri, URI::Generic)
|
61
|
-
@formatter = formatter
|
62
36
|
end
|
63
37
|
|
64
38
|
sig { override.returns(T.nilable(T.all(T::Array[Interface::TextEdit], Object))) }
|
65
39
|
def perform
|
66
|
-
return
|
40
|
+
return unless @active_formatter
|
67
41
|
return if @document.syntax_error?
|
68
42
|
|
69
|
-
formatted_text =
|
43
|
+
formatted_text = @active_formatter.run_formatting(@uri, @document)
|
70
44
|
return unless formatted_text
|
71
45
|
|
72
46
|
size = @document.source.size
|
@@ -82,16 +56,6 @@ module RubyLsp
|
|
82
56
|
),
|
83
57
|
]
|
84
58
|
end
|
85
|
-
|
86
|
-
private
|
87
|
-
|
88
|
-
sig { returns(T.nilable(String)) }
|
89
|
-
def formatted_file
|
90
|
-
formatter_runner = Formatting.formatters[@formatter]
|
91
|
-
raise InvalidFormatter, "Formatter is not available: #{@formatter}" unless formatter_runner
|
92
|
-
|
93
|
-
formatter_runner.run(@uri, @document)
|
94
|
-
end
|
95
59
|
end
|
96
60
|
end
|
97
61
|
end
|
@@ -33,13 +33,13 @@ module RubyLsp
|
|
33
33
|
sig do
|
34
34
|
params(
|
35
35
|
document: Document,
|
36
|
-
|
36
|
+
global_state: GlobalState,
|
37
37
|
position: T::Hash[Symbol, T.untyped],
|
38
38
|
dispatcher: Prism::Dispatcher,
|
39
39
|
typechecker_enabled: T::Boolean,
|
40
40
|
).void
|
41
41
|
end
|
42
|
-
def initialize(document,
|
42
|
+
def initialize(document, global_state, position, dispatcher, typechecker_enabled)
|
43
43
|
super()
|
44
44
|
@target = T.let(nil, T.nilable(Prism::Node))
|
45
45
|
@target, parent, nesting = document.locate_node(
|
@@ -62,9 +62,9 @@ module RubyLsp
|
|
62
62
|
|
63
63
|
uri = document.uri
|
64
64
|
@response_builder = T.let(ResponseBuilders::Hover.new, ResponseBuilders::Hover)
|
65
|
-
Listeners::Hover.new(@response_builder, uri, nesting,
|
65
|
+
Listeners::Hover.new(@response_builder, global_state, uri, nesting, dispatcher, typechecker_enabled)
|
66
66
|
Addon.addons.each do |addon|
|
67
|
-
addon.create_hover_listener(@response_builder, nesting,
|
67
|
+
addon.create_hover_listener(@response_builder, nesting, dispatcher)
|
68
68
|
end
|
69
69
|
|
70
70
|
@dispatcher = dispatcher
|
@@ -29,7 +29,7 @@ module RubyLsp
|
|
29
29
|
sig { returns(Interface::SemanticTokensRegistrationOptions) }
|
30
30
|
def provider
|
31
31
|
Interface::SemanticTokensRegistrationOptions.new(
|
32
|
-
document_selector: {
|
32
|
+
document_selector: [{ language: "ruby" }],
|
33
33
|
legend: Interface::SemanticTokensLegend.new(
|
34
34
|
token_types: ResponseBuilders::SemanticHighlighting::TOKEN_TYPES.keys,
|
35
35
|
token_modifiers: ResponseBuilders::SemanticHighlighting::TOKEN_MODIFIERS.keys,
|
@@ -40,10 +40,13 @@ module RubyLsp
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
sig { params(dispatcher: Prism::Dispatcher, range: T.nilable(T::Range[Integer])).void }
|
44
|
-
def initialize(dispatcher, range: nil)
|
43
|
+
sig { params(global_state: GlobalState, dispatcher: Prism::Dispatcher, range: T.nilable(T::Range[Integer])).void }
|
44
|
+
def initialize(global_state, dispatcher, range: nil)
|
45
45
|
super()
|
46
|
-
@response_builder = T.let(
|
46
|
+
@response_builder = T.let(
|
47
|
+
ResponseBuilders::SemanticHighlighting.new(global_state.encoding),
|
48
|
+
ResponseBuilders::SemanticHighlighting,
|
49
|
+
)
|
47
50
|
Listeners::SemanticHighlighting.new(dispatcher, @response_builder, range: range)
|
48
51
|
|
49
52
|
Addon.addons.each do |addon|
|
@@ -42,13 +42,14 @@ module RubyLsp
|
|
42
42
|
sig do
|
43
43
|
params(
|
44
44
|
document: Document,
|
45
|
-
|
45
|
+
global_state: GlobalState,
|
46
46
|
position: T::Hash[Symbol, T.untyped],
|
47
47
|
context: T.nilable(T::Hash[Symbol, T.untyped]),
|
48
48
|
dispatcher: Prism::Dispatcher,
|
49
|
+
typechecker_enabled: T::Boolean,
|
49
50
|
).void
|
50
51
|
end
|
51
|
-
def initialize(document,
|
52
|
+
def initialize(document, global_state, position, context, dispatcher, typechecker_enabled) # rubocop:disable Metrics/ParameterLists
|
52
53
|
super()
|
53
54
|
target, parent, nesting = document.locate_node(
|
54
55
|
{ line: position[:line], character: position[:character] },
|
@@ -60,7 +61,7 @@ module RubyLsp
|
|
60
61
|
@target = T.let(target, T.nilable(Prism::Node))
|
61
62
|
@dispatcher = dispatcher
|
62
63
|
@response_builder = T.let(ResponseBuilders::SignatureHelp.new, ResponseBuilders::SignatureHelp)
|
63
|
-
Listeners::SignatureHelp.new(@response_builder, nesting,
|
64
|
+
Listeners::SignatureHelp.new(@response_builder, global_state, nesting, dispatcher, typechecker_enabled)
|
64
65
|
end
|
65
66
|
|
66
67
|
sig { override.returns(T.nilable(Interface::SignatureHelp)) }
|