ruby-lsp 0.27.0.beta2 → 0.27.0.beta3
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/VERSION +1 -1
- data/exe/ruby-lsp +0 -46
- data/exe/ruby-lsp-check +0 -15
- data/lib/ruby_lsp/global_state.rb +0 -5
- data/lib/ruby_lsp/internal.rb +2 -1
- data/lib/ruby_lsp/listeners/code_lens.rb +1 -1
- data/lib/ruby_lsp/listeners/completion.rb +246 -382
- data/lib/ruby_lsp/listeners/definition.rb +6 -9
- data/lib/ruby_lsp/listeners/hover.rb +11 -9
- data/lib/ruby_lsp/listeners/signature_help.rb +11 -12
- data/lib/ruby_lsp/listeners/test_discovery.rb +17 -1
- data/lib/ruby_lsp/listeners/test_style.rb +1 -1
- data/lib/ruby_lsp/requests/completion_resolve.rb +49 -29
- data/lib/ruby_lsp/requests/references.rb +21 -7
- data/lib/ruby_lsp/requests/rename.rb +1 -1
- data/lib/ruby_lsp/requests/support/common.rb +69 -68
- data/lib/ruby_lsp/ruby_document.rb +0 -73
- data/lib/ruby_lsp/rubydex/declaration.rb +128 -2
- data/lib/ruby_lsp/rubydex/definition.rb +16 -0
- data/lib/ruby_lsp/rubydex/signature.rb +107 -0
- data/lib/ruby_lsp/scripts/compose_bundle.rb +1 -1
- data/lib/ruby_lsp/server.rb +7 -162
- data/lib/ruby_lsp/test_helper.rb +0 -1
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +1 -1
- data/lib/ruby_lsp/type_inferrer.rb +2 -2
- metadata +11 -14
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +0 -276
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +0 -1101
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +0 -44
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +0 -605
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +0 -1077
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +0 -37
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +0 -149
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +0 -294
- data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +0 -32
- data/lib/ruby_indexer/ruby_indexer.rb +0 -19
- /data/lib/{ruby_indexer/lib/ruby_indexer → ruby_lsp}/uri.rb +0 -0
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Rubydex
|
|
5
|
+
# @abstract
|
|
5
6
|
class Declaration
|
|
6
7
|
# Detail text shown on a `TypeHierarchyItem` for this declaration. Hints at multiplicity
|
|
7
8
|
# when the declaration spans more than one re-open; otherwise falls back to the primary
|
|
8
9
|
# definition's file name so users can quickly see where the type comes from.
|
|
9
10
|
#
|
|
10
|
-
#:
|
|
11
|
+
#: -> String?
|
|
11
12
|
def lsp_type_hierarchy_detail
|
|
12
13
|
defs = definitions
|
|
13
14
|
count = defs.count
|
|
@@ -20,13 +21,20 @@ module Rubydex
|
|
|
20
21
|
path = uri.full_path
|
|
21
22
|
path ? File.basename(path) : uri.to_s
|
|
22
23
|
end
|
|
24
|
+
|
|
25
|
+
# @abstract
|
|
26
|
+
#: -> Integer
|
|
27
|
+
def to_lsp_completion_kind
|
|
28
|
+
raise RubyLsp::AbstractMethodInvokedError
|
|
29
|
+
end
|
|
23
30
|
end
|
|
24
31
|
|
|
32
|
+
# @abstract
|
|
25
33
|
class Namespace
|
|
26
34
|
# Resolved, deduplicated direct supertypes across every re-open of this declaration.
|
|
27
35
|
# Aggregates each definition's own `superclass`/`include`/`prepend` references and drops
|
|
28
36
|
# unresolved ones. Order is stable (first-seen across definitions).
|
|
29
|
-
#:
|
|
37
|
+
#: -> Array[Rubydex::Namespace]
|
|
30
38
|
def direct_supertypes
|
|
31
39
|
seen = {} #: Hash[String, Rubydex::Namespace]
|
|
32
40
|
|
|
@@ -45,4 +53,122 @@ module Rubydex
|
|
|
45
53
|
seen.values
|
|
46
54
|
end
|
|
47
55
|
end
|
|
56
|
+
|
|
57
|
+
class Class
|
|
58
|
+
# @override
|
|
59
|
+
#: -> Integer
|
|
60
|
+
def to_lsp_completion_kind
|
|
61
|
+
RubyLsp::Constant::CompletionItemKind::CLASS
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
class Module
|
|
66
|
+
# @override
|
|
67
|
+
#: -> Integer
|
|
68
|
+
def to_lsp_completion_kind
|
|
69
|
+
RubyLsp::Constant::CompletionItemKind::MODULE
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class SingletonClass
|
|
74
|
+
# @override
|
|
75
|
+
#: -> Integer
|
|
76
|
+
def to_lsp_completion_kind
|
|
77
|
+
RubyLsp::Constant::CompletionItemKind::CLASS
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
class Todo
|
|
82
|
+
# @override
|
|
83
|
+
#: -> Integer
|
|
84
|
+
def to_lsp_completion_kind
|
|
85
|
+
RubyLsp::Constant::CompletionItemKind::CLASS
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
class Constant
|
|
90
|
+
# @override
|
|
91
|
+
#: -> Integer
|
|
92
|
+
def to_lsp_completion_kind
|
|
93
|
+
RubyLsp::Constant::CompletionItemKind::CONSTANT
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
class ConstantAlias
|
|
98
|
+
# @override
|
|
99
|
+
#: -> Integer
|
|
100
|
+
def to_lsp_completion_kind
|
|
101
|
+
RubyLsp::Constant::CompletionItemKind::CONSTANT
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
class Method
|
|
106
|
+
# @override
|
|
107
|
+
#: -> Integer
|
|
108
|
+
def to_lsp_completion_kind
|
|
109
|
+
RubyLsp::Constant::CompletionItemKind::METHOD
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# All signatures collected across every definition (re-opens, RBS overloads, alias targets) of this method.
|
|
113
|
+
#: () -> Array[Rubydex::Signature]
|
|
114
|
+
def signatures
|
|
115
|
+
definitions.flat_map do |defn|
|
|
116
|
+
case defn
|
|
117
|
+
when Rubydex::MethodDefinition, Rubydex::MethodAliasDefinition
|
|
118
|
+
defn.signatures
|
|
119
|
+
else
|
|
120
|
+
[]
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Decorated parameter list of the first signature, e.g. `(a, b = <default>, &block)`. Returns `()` when there are
|
|
126
|
+
# no signatures (e.g. an unresolved alias).
|
|
127
|
+
#: () -> String
|
|
128
|
+
def decorated_parameters
|
|
129
|
+
first = signatures.first
|
|
130
|
+
return "()" unless first
|
|
131
|
+
|
|
132
|
+
"(#{first.format})"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Suffix line that hints at additional overloads beyond the first signature, matching the legacy index entry
|
|
136
|
+
# rendering used in hover.
|
|
137
|
+
#: () -> String
|
|
138
|
+
def formatted_signatures
|
|
139
|
+
count = signatures.size
|
|
140
|
+
case count
|
|
141
|
+
when 0, 1
|
|
142
|
+
""
|
|
143
|
+
when 2
|
|
144
|
+
"\n(+1 overload)"
|
|
145
|
+
else
|
|
146
|
+
"\n(+#{count - 1} overloads)"
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
class InstanceVariable
|
|
152
|
+
# @override
|
|
153
|
+
#: -> Integer
|
|
154
|
+
def to_lsp_completion_kind
|
|
155
|
+
RubyLsp::Constant::CompletionItemKind::FIELD
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
class ClassVariable
|
|
160
|
+
# @override
|
|
161
|
+
#: -> Integer
|
|
162
|
+
def to_lsp_completion_kind
|
|
163
|
+
RubyLsp::Constant::CompletionItemKind::FIELD
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
class GlobalVariable
|
|
168
|
+
# @override
|
|
169
|
+
#: -> Integer
|
|
170
|
+
def to_lsp_completion_kind
|
|
171
|
+
RubyLsp::Constant::CompletionItemKind::VARIABLE
|
|
172
|
+
end
|
|
173
|
+
end
|
|
48
174
|
end
|
|
@@ -183,6 +183,14 @@ module Rubydex
|
|
|
183
183
|
end
|
|
184
184
|
end
|
|
185
185
|
|
|
186
|
+
class ConstantVisibilityDefinition
|
|
187
|
+
# @override
|
|
188
|
+
#: () -> Integer
|
|
189
|
+
def to_lsp_kind
|
|
190
|
+
RubyLsp::Constant::SymbolKind::CONSTANT
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
186
194
|
class MethodDefinition
|
|
187
195
|
# @override
|
|
188
196
|
#: () -> Integer
|
|
@@ -199,6 +207,14 @@ module Rubydex
|
|
|
199
207
|
end
|
|
200
208
|
end
|
|
201
209
|
|
|
210
|
+
class MethodVisibilityDefinition
|
|
211
|
+
# @override
|
|
212
|
+
#: () -> Integer
|
|
213
|
+
def to_lsp_kind
|
|
214
|
+
RubyLsp::Constant::SymbolKind::METHOD
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
202
218
|
class AttrReaderDefinition
|
|
203
219
|
# @override
|
|
204
220
|
#: () -> Integer
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Rubydex
|
|
5
|
+
class Signature
|
|
6
|
+
# Returns a string with the decorated names of the parameters of this signature, e.g.
|
|
7
|
+
# `(a, b = <default>, *c, d, e:, f: <default>, **g, &h)`.
|
|
8
|
+
#: () -> String
|
|
9
|
+
def format
|
|
10
|
+
parameters.map { |param| decorated_name(param) }.join(", ")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Returns `true` if the given call node arguments array matches this signature. The matching is intentionally lenient
|
|
14
|
+
# because this method is used to detect which overload should be displayed in signature help while the user is still
|
|
15
|
+
# typing the call. We prefer returning `true` for situations that cannot be analyzed statically (e.g. presence of
|
|
16
|
+
# splats, keyword splats, forwarding) and accept missing arguments since the user may not be done typing yet.
|
|
17
|
+
#: (Array[Prism::Node] arguments) -> bool
|
|
18
|
+
def matches?(arguments)
|
|
19
|
+
min_pos = 0
|
|
20
|
+
max_pos = 0 #: (Integer | Float)
|
|
21
|
+
names = []
|
|
22
|
+
has_forward = false #: bool
|
|
23
|
+
has_keyword_rest = false #: bool
|
|
24
|
+
|
|
25
|
+
parameters.each do |param|
|
|
26
|
+
case param
|
|
27
|
+
when PositionalParameter, PostParameter
|
|
28
|
+
min_pos += 1
|
|
29
|
+
max_pos += 1
|
|
30
|
+
when OptionalPositionalParameter
|
|
31
|
+
max_pos += 1
|
|
32
|
+
when RestPositionalParameter
|
|
33
|
+
max_pos = Float::INFINITY
|
|
34
|
+
when ForwardParameter
|
|
35
|
+
max_pos = Float::INFINITY
|
|
36
|
+
has_forward = true
|
|
37
|
+
when KeywordParameter, OptionalKeywordParameter
|
|
38
|
+
names << param.name
|
|
39
|
+
when RestKeywordParameter
|
|
40
|
+
has_keyword_rest = true
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
keyword_hash_nodes, positional_args = arguments.partition { |arg| arg.is_a?(Prism::KeywordHashNode) }
|
|
45
|
+
keyword_args = keyword_hash_nodes.first #: as Prism::KeywordHashNode?
|
|
46
|
+
&.elements
|
|
47
|
+
forwarding_arguments, positionals = positional_args.partition do |arg|
|
|
48
|
+
arg.is_a?(Prism::ForwardingArgumentsNode)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
return true if has_forward && min_pos == 0
|
|
52
|
+
|
|
53
|
+
# If the only argument passed is a forwarding argument, then anything will match
|
|
54
|
+
(positionals.empty? && forwarding_arguments.any?) ||
|
|
55
|
+
(
|
|
56
|
+
positional_arguments_match?(positionals, forwarding_arguments, keyword_args, min_pos, max_pos) &&
|
|
57
|
+
(has_forward || has_keyword_rest || keyword_arguments_match?(keyword_args, names))
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
#: (Parameter) -> String
|
|
64
|
+
def decorated_name(param)
|
|
65
|
+
case param
|
|
66
|
+
when OptionalPositionalParameter
|
|
67
|
+
"#{param.name} = <default>"
|
|
68
|
+
when RestPositionalParameter
|
|
69
|
+
"*#{param.name}"
|
|
70
|
+
when KeywordParameter
|
|
71
|
+
"#{param.name}:"
|
|
72
|
+
when OptionalKeywordParameter
|
|
73
|
+
"#{param.name}: <default>"
|
|
74
|
+
when RestKeywordParameter
|
|
75
|
+
"**#{param.name}"
|
|
76
|
+
when BlockParameter
|
|
77
|
+
"&#{param.name}"
|
|
78
|
+
else
|
|
79
|
+
param.name.to_s
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#: (Array[Prism::Node] positional_args, Array[Prism::Node] forwarding_arguments, Array[Prism::Node]? keyword_args, Integer min_pos, (Integer | Float) max_pos) -> bool
|
|
84
|
+
def positional_arguments_match?(positional_args, forwarding_arguments, keyword_args, min_pos, max_pos)
|
|
85
|
+
(min_pos > 0 && positional_args.any? { |arg| arg.is_a?(Prism::SplatNode) }) ||
|
|
86
|
+
(min_pos - positional_args.length > 0 && keyword_args&.any? { |arg| arg.is_a?(Prism::AssocSplatNode) }) ||
|
|
87
|
+
(min_pos - positional_args.length > 0 && forwarding_arguments.any?) ||
|
|
88
|
+
(min_pos > 0 && positional_args.length <= max_pos) ||
|
|
89
|
+
(min_pos == 0 && positional_args.empty?)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
#: (Array[Prism::Node]? args, Array[Symbol] names) -> bool
|
|
93
|
+
def keyword_arguments_match?(args, names)
|
|
94
|
+
return true unless args
|
|
95
|
+
return true if args.any? { |arg| arg.is_a?(Prism::AssocSplatNode) }
|
|
96
|
+
|
|
97
|
+
arg_names = args.filter_map do |arg|
|
|
98
|
+
next unless arg.is_a?(Prism::AssocNode)
|
|
99
|
+
|
|
100
|
+
key = arg.key
|
|
101
|
+
key.value&.to_sym if key.is_a?(Prism::SymbolNode)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
(arg_names - names).empty?
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -5,7 +5,7 @@ def compose(raw_initialize, **options)
|
|
|
5
5
|
require_relative "../setup_bundler"
|
|
6
6
|
require "json"
|
|
7
7
|
require "uri"
|
|
8
|
-
require_relative "
|
|
8
|
+
require_relative "../uri"
|
|
9
9
|
|
|
10
10
|
initialize_request = JSON.parse(raw_initialize, symbolize_names: true)
|
|
11
11
|
workspace_uri = initialize_request.dig(:params, :workspaceFolders, 0, :uri)
|
data/lib/ruby_lsp/server.rb
CHANGED
|
@@ -325,8 +325,6 @@ module RubyLsp
|
|
|
325
325
|
))
|
|
326
326
|
end
|
|
327
327
|
|
|
328
|
-
process_indexing_configuration(options.dig(:initializationOptions, :indexing))
|
|
329
|
-
|
|
330
328
|
begin_progress("indexing-progress", "Ruby LSP: indexing files")
|
|
331
329
|
|
|
332
330
|
global_state_notifications.each { |notification| send_message(notification) }
|
|
@@ -499,39 +497,15 @@ module RubyLsp
|
|
|
499
497
|
document,
|
|
500
498
|
dispatcher,
|
|
501
499
|
)
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
# the dispatcher's state
|
|
505
|
-
code_lens = nil #: Requests::CodeLens?
|
|
506
|
-
|
|
507
|
-
if document.is_a?(RubyDocument) && document.should_index?
|
|
508
|
-
# Re-index the file as it is modified. This mode of indexing updates entries only. Require path trees are only
|
|
509
|
-
# updated on save
|
|
510
|
-
@global_state.synchronize do
|
|
511
|
-
send_log_message("Determined that document should be indexed: #{uri}")
|
|
512
|
-
|
|
513
|
-
@global_state.index.handle_change(uri) do |index|
|
|
514
|
-
index.delete(uri, skip_require_paths_tree: true)
|
|
515
|
-
RubyIndexer::DeclarationListener.new(index, dispatcher, parse_result, uri, collect_comments: true)
|
|
516
|
-
code_lens = Requests::CodeLens.new(@global_state, document, dispatcher)
|
|
517
|
-
dispatcher.dispatch(document.ast)
|
|
518
|
-
end
|
|
519
|
-
end
|
|
520
|
-
else
|
|
521
|
-
code_lens = Requests::CodeLens.new(@global_state, document, dispatcher)
|
|
522
|
-
dispatcher.dispatch(document.ast)
|
|
523
|
-
end
|
|
500
|
+
code_lens = Requests::CodeLens.new(@global_state, document, dispatcher)
|
|
501
|
+
dispatcher.dispatch(document.ast)
|
|
524
502
|
|
|
525
503
|
# Store all responses retrieve in this round of visits in the cache and then return the response for the request
|
|
526
504
|
# we actually received
|
|
527
505
|
document.cache_set("textDocument/foldingRange", folding_range.perform)
|
|
528
506
|
document.cache_set("textDocument/documentSymbol", document_symbol.perform)
|
|
529
507
|
document.cache_set("textDocument/documentLink", document_link.perform)
|
|
530
|
-
document.cache_set(
|
|
531
|
-
"textDocument/codeLens",
|
|
532
|
-
code_lens #: as !nil
|
|
533
|
-
.perform,
|
|
534
|
-
)
|
|
508
|
+
document.cache_set("textDocument/codeLens", code_lens.perform)
|
|
535
509
|
document.cache_set("textDocument/inlayHint", inlay_hint.perform)
|
|
536
510
|
|
|
537
511
|
send_message(Result.new(id: message[:id], response: document.cache_get(message[:method])))
|
|
@@ -1038,21 +1012,6 @@ module RubyLsp
|
|
|
1038
1012
|
|
|
1039
1013
|
#: (Hash[Symbol, untyped] message) -> void
|
|
1040
1014
|
def workspace_did_change_watched_files(message)
|
|
1041
|
-
# If indexing is not complete yet, delay processing did change watched file notifications. We need initial
|
|
1042
|
-
# indexing to be in place so that we can handle file changes appropriately without risking duplicates. We also
|
|
1043
|
-
# have to sleep before re-inserting the notification in the queue otherwise the worker can get stuck in its own
|
|
1044
|
-
# loop of pushing and popping the same notification
|
|
1045
|
-
unless @global_state.index.initial_indexing_completed
|
|
1046
|
-
Thread.new do
|
|
1047
|
-
sleep(2)
|
|
1048
|
-
# We have to ensure that the queue is not closed yet, since nothing stops the user from saving a file and then
|
|
1049
|
-
# immediately telling the LSP to shutdown
|
|
1050
|
-
@incoming_queue << message unless @incoming_queue.closed?
|
|
1051
|
-
end
|
|
1052
|
-
|
|
1053
|
-
return
|
|
1054
|
-
end
|
|
1055
|
-
|
|
1056
1015
|
changes = message.dig(:params, :changes)
|
|
1057
1016
|
# We allow add-ons to register for watching files and we have no restrictions for what they register for. If the
|
|
1058
1017
|
# same pattern is registered more than once, the LSP will receive duplicate change notifications. Receiving them
|
|
@@ -1076,18 +1035,12 @@ module RubyLsp
|
|
|
1076
1035
|
benchmark("index_all") { graph.index_all(additions_and_changes) }
|
|
1077
1036
|
benchmark("incremental_resolve") { graph.resolve }
|
|
1078
1037
|
|
|
1079
|
-
index = @global_state.index
|
|
1080
1038
|
changes.each do |change|
|
|
1081
1039
|
# File change events include folders, but we're only interested in files
|
|
1082
1040
|
uri = URI(change[:uri])
|
|
1083
1041
|
file_path = uri.to_standardized_path
|
|
1084
1042
|
next if file_path.nil? || File.directory?(file_path)
|
|
1085
1043
|
|
|
1086
|
-
if file_path.end_with?(".rb")
|
|
1087
|
-
handle_ruby_file_change(index, file_path, change[:type])
|
|
1088
|
-
next
|
|
1089
|
-
end
|
|
1090
|
-
|
|
1091
1044
|
file_name = File.basename(file_path)
|
|
1092
1045
|
|
|
1093
1046
|
if file_name == ".rubocop.yml" || file_name == ".rubocop" || file_name == ".rubocop_todo.yml"
|
|
@@ -1106,33 +1059,6 @@ module RubyLsp
|
|
|
1106
1059
|
end
|
|
1107
1060
|
end
|
|
1108
1061
|
|
|
1109
|
-
#: (RubyIndexer::Index index, String file_path, Integer change_type) -> void
|
|
1110
|
-
def handle_ruby_file_change(index, file_path, change_type)
|
|
1111
|
-
@global_state.synchronize do
|
|
1112
|
-
load_path_entry = $LOAD_PATH.find { |load_path| file_path.start_with?(load_path) }
|
|
1113
|
-
uri = URI::Generic.from_path(load_path_entry: load_path_entry, path: file_path)
|
|
1114
|
-
|
|
1115
|
-
case change_type
|
|
1116
|
-
when Constant::FileChangeType::CREATED
|
|
1117
|
-
content = File.read(file_path)
|
|
1118
|
-
# If we receive a late created notification for a file that has already been claimed by the client, we want to
|
|
1119
|
-
# handle change for that URI so that the require path tree is updated
|
|
1120
|
-
@store.key?(uri) ? index.handle_change(uri, content) : index.index_single(uri, content)
|
|
1121
|
-
when Constant::FileChangeType::CHANGED
|
|
1122
|
-
content = File.read(file_path)
|
|
1123
|
-
# We only handle changes on file watched notifications if the client is not the one managing this URI.
|
|
1124
|
-
# Otherwise, these changes are handled when running the combined requests
|
|
1125
|
-
index.handle_change(uri, content) unless @store.key?(uri)
|
|
1126
|
-
when Constant::FileChangeType::DELETED
|
|
1127
|
-
index.delete(uri)
|
|
1128
|
-
end
|
|
1129
|
-
rescue Errno::ENOENT
|
|
1130
|
-
# If a file is created and then delete immediately afterwards, we will process the created notification before
|
|
1131
|
-
# we receive the deleted one, but the file no longer exists. This may happen when running a test suite that
|
|
1132
|
-
# creates and deletes files automatically.
|
|
1133
|
-
end
|
|
1134
|
-
end
|
|
1135
|
-
|
|
1136
1062
|
#: (URI::Generic uri) -> void
|
|
1137
1063
|
def handle_rubocop_config_change(uri)
|
|
1138
1064
|
return unless defined?(Requests::Support::RuboCopFormatter)
|
|
@@ -1271,56 +1197,16 @@ module RubyLsp
|
|
|
1271
1197
|
|
|
1272
1198
|
#: -> void
|
|
1273
1199
|
def perform_initial_indexing
|
|
1200
|
+
# Index
|
|
1274
1201
|
progress("indexing-progress", message: "Indexing workspace...")
|
|
1275
1202
|
benchmark("index_workspace") { @global_state.graph.index_workspace }
|
|
1276
1203
|
|
|
1204
|
+
# Resolve
|
|
1277
1205
|
progress("indexing-progress", message: "Resolving graph...")
|
|
1278
1206
|
benchmark("full_resolve") { @global_state.graph.resolve }
|
|
1279
1207
|
|
|
1280
|
-
#
|
|
1281
|
-
|
|
1282
|
-
Thread.new do
|
|
1283
|
-
begin
|
|
1284
|
-
@global_state.index.index_all do |percentage|
|
|
1285
|
-
progress("indexing-progress", percentage: percentage)
|
|
1286
|
-
true
|
|
1287
|
-
rescue ClosedQueueError
|
|
1288
|
-
# Since we run indexing on a separate thread, it's possible to kill the server before indexing is complete.
|
|
1289
|
-
# In those cases, the message queue will be closed and raise a ClosedQueueError. By returning `false`, we
|
|
1290
|
-
# tell the index to stop working immediately
|
|
1291
|
-
false
|
|
1292
|
-
end
|
|
1293
|
-
rescue StandardError => error
|
|
1294
|
-
message = "Error while indexing (see [troubleshooting steps]" \
|
|
1295
|
-
"(https://shopify.github.io/ruby-lsp/troubleshooting#indexing)): #{error.message}"
|
|
1296
|
-
send_message(Notification.window_show_message(message, type: Constant::MessageType::ERROR))
|
|
1297
|
-
end
|
|
1298
|
-
|
|
1299
|
-
# Indexing produces a high number of short lived object allocations. That might lead to some fragmentation and
|
|
1300
|
-
# an unnecessarily expanded heap. Compacting ensures that the heap is as small as possible and that future
|
|
1301
|
-
# allocations and garbage collections are faster
|
|
1302
|
-
GC.compact unless @test_mode
|
|
1303
|
-
|
|
1304
|
-
@global_state.synchronize do
|
|
1305
|
-
# If we linearize ancestors while the index is not fully populated, we may end up caching incorrect results
|
|
1306
|
-
# that were missing namespaces. After indexing is complete, we need to clear the ancestors cache and start
|
|
1307
|
-
# again
|
|
1308
|
-
@global_state.index.clear_ancestors
|
|
1309
|
-
|
|
1310
|
-
# The results for code lens depend on ancestor linearization, so we need to clear any previously computed
|
|
1311
|
-
# responses
|
|
1312
|
-
@store.each { |_uri, document| document.clear_cache("textDocument/codeLens") }
|
|
1313
|
-
end
|
|
1314
|
-
|
|
1315
|
-
# Always end the progress notification even if indexing failed or else it never goes away and the user has no
|
|
1316
|
-
# way of dismissing it
|
|
1317
|
-
end_progress("indexing-progress")
|
|
1318
|
-
|
|
1319
|
-
# Request a code lens refresh if we populated them before all test parent classes were indexed
|
|
1320
|
-
if @global_state.client_capabilities.supports_code_lens_refresh
|
|
1321
|
-
send_message(Request.new(id: @current_request_id, method: "workspace/codeLens/refresh", params: nil))
|
|
1322
|
-
end
|
|
1323
|
-
end
|
|
1208
|
+
# End
|
|
1209
|
+
end_progress("indexing-progress")
|
|
1324
1210
|
end
|
|
1325
1211
|
|
|
1326
1212
|
#: (String id, String title, ?percentage: Integer) -> void
|
|
@@ -1373,47 +1259,6 @@ module RubyLsp
|
|
|
1373
1259
|
end
|
|
1374
1260
|
end
|
|
1375
1261
|
|
|
1376
|
-
#: (Hash[Symbol, untyped]? indexing_options) -> void
|
|
1377
|
-
def process_indexing_configuration(indexing_options)
|
|
1378
|
-
# Need to use the workspace URI, otherwise, this will fail for people working on a project that is a symlink.
|
|
1379
|
-
index_path = File.join(@global_state.workspace_path, ".index.yml")
|
|
1380
|
-
|
|
1381
|
-
if File.exist?(index_path)
|
|
1382
|
-
begin
|
|
1383
|
-
@global_state.index.configuration.apply_config(YAML.parse_file(index_path).to_ruby)
|
|
1384
|
-
send_message(
|
|
1385
|
-
Notification.new(
|
|
1386
|
-
method: "window/showMessage",
|
|
1387
|
-
params: Interface::ShowMessageParams.new(
|
|
1388
|
-
type: Constant::MessageType::WARNING,
|
|
1389
|
-
message: "The .index.yml configuration file is deprecated. " \
|
|
1390
|
-
"Please use editor settings to configure the index",
|
|
1391
|
-
),
|
|
1392
|
-
),
|
|
1393
|
-
)
|
|
1394
|
-
rescue Psych::SyntaxError => e
|
|
1395
|
-
message = "Syntax error while loading configuration: #{e.message}"
|
|
1396
|
-
send_message(
|
|
1397
|
-
Notification.new(
|
|
1398
|
-
method: "window/showMessage",
|
|
1399
|
-
params: Interface::ShowMessageParams.new(
|
|
1400
|
-
type: Constant::MessageType::WARNING,
|
|
1401
|
-
message: message,
|
|
1402
|
-
),
|
|
1403
|
-
),
|
|
1404
|
-
)
|
|
1405
|
-
end
|
|
1406
|
-
return
|
|
1407
|
-
end
|
|
1408
|
-
|
|
1409
|
-
configuration = @global_state.index.configuration
|
|
1410
|
-
configuration.workspace_path = @global_state.workspace_path
|
|
1411
|
-
return unless indexing_options
|
|
1412
|
-
|
|
1413
|
-
# The index expects snake case configurations, but VS Code standardizes on camel case settings
|
|
1414
|
-
configuration.apply_config(indexing_options.transform_keys { |key| key.to_s.gsub(/([A-Z])/, "_\\1").downcase })
|
|
1415
|
-
end
|
|
1416
|
-
|
|
1417
1262
|
#: (Hash[Symbol, untyped] message) -> void
|
|
1418
1263
|
def window_show_message_request(message)
|
|
1419
1264
|
result = message[:result]
|
data/lib/ruby_lsp/test_helper.rb
CHANGED
|
@@ -78,7 +78,7 @@ module RubyLsp
|
|
|
78
78
|
# When the receiver is a constant reference, we have to try to resolve it to figure out the right
|
|
79
79
|
# receiver. But since the invocation is directly on the constant, that's the singleton context of that
|
|
80
80
|
# class/module
|
|
81
|
-
receiver_name =
|
|
81
|
+
receiver_name = Requests::Support::Common.constant_name(receiver)
|
|
82
82
|
return unless receiver_name
|
|
83
83
|
|
|
84
84
|
resolved_receiver = @graph.resolve_constant(receiver_name, node_context.nesting)
|
|
@@ -124,7 +124,7 @@ module RubyLsp
|
|
|
124
124
|
|
|
125
125
|
declaration = @graph.resolve_constant(guessed_name, nesting)
|
|
126
126
|
declaration ||= @graph.search(guessed_name).first
|
|
127
|
-
return unless declaration
|
|
127
|
+
return unless declaration.is_a?(Rubydex::Namespace)
|
|
128
128
|
|
|
129
129
|
GuessedType.new(declaration.name)
|
|
130
130
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-lsp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.27.0.
|
|
4
|
+
version: 0.27.0.beta3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shopify
|
|
@@ -69,14 +69,20 @@ dependencies:
|
|
|
69
69
|
requirements:
|
|
70
70
|
- - "~>"
|
|
71
71
|
- !ruby/object:Gem::Version
|
|
72
|
-
version: 0.
|
|
72
|
+
version: 0.2.0
|
|
73
|
+
- - "<"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 0.3.0
|
|
73
76
|
type: :runtime
|
|
74
77
|
prerelease: false
|
|
75
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
76
79
|
requirements:
|
|
77
80
|
- - "~>"
|
|
78
81
|
- !ruby/object:Gem::Version
|
|
79
|
-
version: 0.
|
|
82
|
+
version: 0.2.0
|
|
83
|
+
- - "<"
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: 0.3.0
|
|
80
86
|
description: An opinionated language server for Ruby
|
|
81
87
|
email:
|
|
82
88
|
- ruby@shopify.com
|
|
@@ -98,17 +104,6 @@ files:
|
|
|
98
104
|
- lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb
|
|
99
105
|
- lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb
|
|
100
106
|
- lib/ruby-lsp.rb
|
|
101
|
-
- lib/ruby_indexer/lib/ruby_indexer/configuration.rb
|
|
102
|
-
- lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb
|
|
103
|
-
- lib/ruby_indexer/lib/ruby_indexer/enhancement.rb
|
|
104
|
-
- lib/ruby_indexer/lib/ruby_indexer/entry.rb
|
|
105
|
-
- lib/ruby_indexer/lib/ruby_indexer/index.rb
|
|
106
|
-
- lib/ruby_indexer/lib/ruby_indexer/location.rb
|
|
107
|
-
- lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb
|
|
108
|
-
- lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb
|
|
109
|
-
- lib/ruby_indexer/lib/ruby_indexer/uri.rb
|
|
110
|
-
- lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb
|
|
111
|
-
- lib/ruby_indexer/ruby_indexer.rb
|
|
112
107
|
- lib/ruby_lsp/addon.rb
|
|
113
108
|
- lib/ruby_lsp/base_server.rb
|
|
114
109
|
- lib/ruby_lsp/client_capabilities.rb
|
|
@@ -184,6 +179,7 @@ files:
|
|
|
184
179
|
- lib/ruby_lsp/rubydex/declaration.rb
|
|
185
180
|
- lib/ruby_lsp/rubydex/definition.rb
|
|
186
181
|
- lib/ruby_lsp/rubydex/reference.rb
|
|
182
|
+
- lib/ruby_lsp/rubydex/signature.rb
|
|
187
183
|
- lib/ruby_lsp/scope.rb
|
|
188
184
|
- lib/ruby_lsp/scripts/compose_bundle.rb
|
|
189
185
|
- lib/ruby_lsp/scripts/compose_bundle_windows.rb
|
|
@@ -195,6 +191,7 @@ files:
|
|
|
195
191
|
- lib/ruby_lsp/test_reporters/minitest_reporter.rb
|
|
196
192
|
- lib/ruby_lsp/test_reporters/test_unit_reporter.rb
|
|
197
193
|
- lib/ruby_lsp/type_inferrer.rb
|
|
194
|
+
- lib/ruby_lsp/uri.rb
|
|
198
195
|
- lib/ruby_lsp/utils.rb
|
|
199
196
|
homepage: https://github.com/Shopify/ruby-lsp
|
|
200
197
|
licenses:
|