ruby-lsp 0.23.11 → 0.26.1
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 +2 -2
- data/VERSION +1 -1
- data/exe/ruby-lsp +10 -4
- data/exe/ruby-lsp-check +0 -4
- data/exe/ruby-lsp-launcher +45 -22
- data/exe/ruby-lsp-test-exec +6 -0
- data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -2
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -6
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +82 -116
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +140 -183
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +10 -14
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +107 -236
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +166 -281
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +23 -27
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +25 -57
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +58 -68
- data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +17 -19
- data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +7 -11
- data/lib/ruby_indexer/test/class_variables_test.rb +14 -14
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +65 -40
- data/lib/ruby_indexer/test/configuration_test.rb +49 -9
- data/lib/ruby_indexer/test/constant_test.rb +34 -34
- data/lib/ruby_indexer/test/enhancements_test.rb +1 -1
- data/lib/ruby_indexer/test/index_test.rb +185 -135
- data/lib/ruby_indexer/test/instance_variables_test.rb +61 -37
- data/lib/ruby_indexer/test/method_test.rb +166 -123
- data/lib/ruby_indexer/test/prefix_tree_test.rb +21 -21
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +70 -75
- data/lib/ruby_indexer/test/reference_finder_test.rb +79 -14
- data/lib/ruby_indexer/test/test_case.rb +9 -3
- data/lib/ruby_indexer/test/uri_test.rb +15 -2
- data/lib/ruby_lsp/addon.rb +88 -86
- data/lib/ruby_lsp/base_server.rb +59 -54
- data/lib/ruby_lsp/client_capabilities.rb +16 -13
- data/lib/ruby_lsp/document.rb +205 -104
- data/lib/ruby_lsp/erb_document.rb +45 -47
- data/lib/ruby_lsp/global_state.rb +73 -57
- data/lib/ruby_lsp/internal.rb +8 -3
- data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
- data/lib/ruby_lsp/listeners/completion.rb +81 -76
- data/lib/ruby_lsp/listeners/definition.rb +44 -58
- data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
- data/lib/ruby_lsp/listeners/document_link.rb +50 -70
- data/lib/ruby_lsp/listeners/document_symbol.rb +38 -52
- data/lib/ruby_lsp/listeners/folding_ranges.rb +40 -43
- data/lib/ruby_lsp/listeners/hover.rb +107 -115
- data/lib/ruby_lsp/listeners/inlay_hints.rb +8 -13
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -56
- data/lib/ruby_lsp/listeners/signature_help.rb +12 -27
- data/lib/ruby_lsp/listeners/spec_style.rb +214 -0
- data/lib/ruby_lsp/listeners/test_discovery.rb +92 -0
- data/lib/ruby_lsp/listeners/test_style.rb +205 -95
- data/lib/ruby_lsp/node_context.rb +12 -39
- data/lib/ruby_lsp/rbs_document.rb +10 -11
- data/lib/ruby_lsp/requests/code_action_resolve.rb +65 -61
- data/lib/ruby_lsp/requests/code_actions.rb +14 -26
- data/lib/ruby_lsp/requests/code_lens.rb +31 -21
- data/lib/ruby_lsp/requests/completion.rb +8 -21
- data/lib/ruby_lsp/requests/completion_resolve.rb +6 -6
- data/lib/ruby_lsp/requests/definition.rb +8 -20
- data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
- data/lib/ruby_lsp/requests/discover_tests.rb +20 -7
- data/lib/ruby_lsp/requests/document_highlight.rb +6 -16
- data/lib/ruby_lsp/requests/document_link.rb +6 -17
- data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
- data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
- data/lib/ruby_lsp/requests/formatting.rb +6 -9
- data/lib/ruby_lsp/requests/go_to_relevant_file.rb +85 -0
- data/lib/ruby_lsp/requests/hover.rb +12 -25
- data/lib/ruby_lsp/requests/inlay_hints.rb +8 -19
- data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
- data/lib/ruby_lsp/requests/prepare_rename.rb +5 -10
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +5 -15
- data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
- data/lib/ruby_lsp/requests/references.rb +17 -57
- data/lib/ruby_lsp/requests/rename.rb +27 -51
- data/lib/ruby_lsp/requests/request.rb +13 -25
- data/lib/ruby_lsp/requests/selection_ranges.rb +7 -7
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +16 -35
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +7 -8
- data/lib/ruby_lsp/requests/signature_help.rb +9 -27
- data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
- data/lib/ruby_lsp/requests/support/common.rb +16 -58
- data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +13 -16
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +34 -36
- data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
- data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
- data/lib/ruby_lsp/requests/support/source_uri.rb +20 -32
- data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
- data/lib/ruby_lsp/requests/support/test_item.rb +16 -14
- data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
- data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
- data/lib/ruby_lsp/response_builders/collection_response_builder.rb +6 -9
- data/lib/ruby_lsp/response_builders/document_symbol.rb +15 -21
- data/lib/ruby_lsp/response_builders/hover.rb +12 -18
- data/lib/ruby_lsp/response_builders/response_builder.rb +6 -7
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +62 -91
- data/lib/ruby_lsp/response_builders/signature_help.rb +6 -8
- data/lib/ruby_lsp/response_builders/test_collection.rb +35 -13
- data/lib/ruby_lsp/ruby_document.rb +32 -98
- data/lib/ruby_lsp/scope.rb +7 -11
- data/lib/ruby_lsp/scripts/compose_bundle.rb +6 -4
- data/lib/ruby_lsp/server.rb +303 -196
- data/lib/ruby_lsp/setup_bundler.rb +121 -82
- data/lib/ruby_lsp/static_docs.rb +12 -7
- data/lib/ruby_lsp/store.rb +21 -49
- data/lib/ruby_lsp/test_helper.rb +3 -16
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +233 -0
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +145 -0
- data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +92 -0
- data/lib/ruby_lsp/type_inferrer.rb +13 -14
- data/lib/ruby_lsp/utils.rb +138 -93
- data/static_docs/break.md +103 -0
- metadata +14 -20
- data/lib/ruby_lsp/load_sorbet.rb +0 -62
@@ -3,14 +3,13 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module ResponseBuilders
|
6
|
+
# @abstract
|
6
7
|
class ResponseBuilder
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
sig { abstract.returns(T.anything) }
|
13
|
-
def response; end
|
8
|
+
# @abstract
|
9
|
+
#: -> top
|
10
|
+
def response
|
11
|
+
raise AbstractMethodInvokedError
|
12
|
+
end
|
14
13
|
end
|
15
14
|
end
|
16
15
|
end
|
@@ -3,71 +3,57 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module ResponseBuilders
|
6
|
+
#: [ResponseType = Interface::SemanticTokens]
|
6
7
|
class SemanticHighlighting < ResponseBuilder
|
7
8
|
class UndefinedTokenType < StandardError; end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
modification: 7,
|
50
|
-
documentation: 8,
|
51
|
-
default_library: 9,
|
52
|
-
}.freeze,
|
53
|
-
T::Hash[Symbol, Integer],
|
54
|
-
)
|
55
|
-
|
56
|
-
ResponseType = type_member { { fixed: Interface::SemanticTokens } }
|
57
|
-
|
58
|
-
sig do
|
59
|
-
params(code_units_cache: T.any(
|
60
|
-
T.proc.params(arg0: Integer).returns(Integer),
|
61
|
-
Prism::CodeUnitsCache,
|
62
|
-
)).void
|
63
|
-
end
|
10
|
+
TOKEN_TYPES = {
|
11
|
+
namespace: 0,
|
12
|
+
type: 1,
|
13
|
+
class: 2,
|
14
|
+
enum: 3,
|
15
|
+
interface: 4,
|
16
|
+
struct: 5,
|
17
|
+
typeParameter: 6,
|
18
|
+
parameter: 7,
|
19
|
+
variable: 8,
|
20
|
+
property: 9,
|
21
|
+
enumMember: 10,
|
22
|
+
event: 11,
|
23
|
+
function: 12,
|
24
|
+
method: 13,
|
25
|
+
macro: 14,
|
26
|
+
keyword: 15,
|
27
|
+
modifier: 16,
|
28
|
+
comment: 17,
|
29
|
+
string: 18,
|
30
|
+
number: 19,
|
31
|
+
regexp: 20,
|
32
|
+
operator: 21,
|
33
|
+
decorator: 22,
|
34
|
+
}.freeze #: Hash[Symbol, Integer]
|
35
|
+
|
36
|
+
TOKEN_MODIFIERS = {
|
37
|
+
declaration: 0,
|
38
|
+
definition: 1,
|
39
|
+
readonly: 2,
|
40
|
+
static: 3,
|
41
|
+
deprecated: 4,
|
42
|
+
abstract: 5,
|
43
|
+
async: 6,
|
44
|
+
modification: 7,
|
45
|
+
documentation: 8,
|
46
|
+
default_library: 9,
|
47
|
+
}.freeze #: Hash[Symbol, Integer]
|
48
|
+
|
49
|
+
#: ((^(Integer arg0) -> Integer | Prism::CodeUnitsCache) code_units_cache) -> void
|
64
50
|
def initialize(code_units_cache)
|
65
51
|
super()
|
66
52
|
@code_units_cache = code_units_cache
|
67
|
-
@stack =
|
53
|
+
@stack = [] #: Array[SemanticToken]
|
68
54
|
end
|
69
55
|
|
70
|
-
|
56
|
+
#: (Prism::Location location, Symbol type, ?Array[Symbol] modifiers) -> void
|
71
57
|
def add_token(location, type, modifiers = [])
|
72
58
|
end_code_unit = location.cached_end_code_units_offset(@code_units_cache)
|
73
59
|
length = end_code_unit - location.cached_start_code_units_offset(@code_units_cache)
|
@@ -77,13 +63,13 @@ module RubyLsp
|
|
77
63
|
start_line: location.start_line,
|
78
64
|
start_code_unit_column: location.cached_start_code_units_column(@code_units_cache),
|
79
65
|
length: length,
|
80
|
-
type:
|
66
|
+
type: TOKEN_TYPES[type], #: as !nil
|
81
67
|
modifier: modifiers_indices,
|
82
68
|
),
|
83
69
|
)
|
84
70
|
end
|
85
71
|
|
86
|
-
|
72
|
+
#: (Prism::Location location) -> bool
|
87
73
|
def last_token_matches?(location)
|
88
74
|
token = @stack.last
|
89
75
|
return false unless token
|
@@ -92,43 +78,34 @@ module RubyLsp
|
|
92
78
|
token.start_code_unit_column == location.cached_start_code_units_column(@code_units_cache)
|
93
79
|
end
|
94
80
|
|
95
|
-
|
81
|
+
#: -> SemanticToken?
|
96
82
|
def last
|
97
83
|
@stack.last
|
98
84
|
end
|
99
85
|
|
100
|
-
|
86
|
+
# @override
|
87
|
+
#: -> Array[SemanticToken]
|
101
88
|
def response
|
102
89
|
@stack
|
103
90
|
end
|
104
91
|
|
105
92
|
class SemanticToken
|
106
|
-
|
107
|
-
|
108
|
-
sig { returns(Integer) }
|
93
|
+
#: Integer
|
109
94
|
attr_reader :start_line
|
110
95
|
|
111
|
-
|
96
|
+
#: Integer
|
112
97
|
attr_reader :start_code_unit_column
|
113
98
|
|
114
|
-
|
99
|
+
#: Integer
|
115
100
|
attr_reader :length
|
116
101
|
|
117
|
-
|
102
|
+
#: Integer
|
118
103
|
attr_reader :type
|
119
104
|
|
120
|
-
|
105
|
+
#: Array[Integer]
|
121
106
|
attr_reader :modifier
|
122
107
|
|
123
|
-
|
124
|
-
params(
|
125
|
-
start_line: Integer,
|
126
|
-
start_code_unit_column: Integer,
|
127
|
-
length: Integer,
|
128
|
-
type: Integer,
|
129
|
-
modifier: T::Array[Integer],
|
130
|
-
).void
|
131
|
-
end
|
108
|
+
#: (start_line: Integer, start_code_unit_column: Integer, length: Integer, type: Integer, modifier: Array[Integer]) -> void
|
132
109
|
def initialize(start_line:, start_code_unit_column:, length:, type:, modifier:)
|
133
110
|
@start_line = start_line
|
134
111
|
@start_code_unit_column = start_code_unit_column
|
@@ -137,7 +114,7 @@ module RubyLsp
|
|
137
114
|
@modifier = modifier
|
138
115
|
end
|
139
116
|
|
140
|
-
|
117
|
+
#: (Symbol type_symbol) -> void
|
141
118
|
def replace_type(type_symbol)
|
142
119
|
type_int = TOKEN_TYPES[type_symbol]
|
143
120
|
raise UndefinedTokenType, "Undefined token type: #{type_symbol}" unless type_int
|
@@ -145,7 +122,7 @@ module RubyLsp
|
|
145
122
|
@type = type_int
|
146
123
|
end
|
147
124
|
|
148
|
-
|
125
|
+
#: (Array[Symbol] modifier_symbols) -> void
|
149
126
|
def replace_modifier(modifier_symbols)
|
150
127
|
@modifier = modifier_symbols.filter_map do |modifier_symbol|
|
151
128
|
modifier_index = TOKEN_MODIFIERS[modifier_symbol]
|
@@ -157,19 +134,13 @@ module RubyLsp
|
|
157
134
|
end
|
158
135
|
|
159
136
|
class SemanticTokenEncoder
|
160
|
-
|
161
|
-
|
162
|
-
sig { void }
|
137
|
+
#: -> void
|
163
138
|
def initialize
|
164
|
-
@current_row =
|
165
|
-
@current_column =
|
139
|
+
@current_row = 0 #: Integer
|
140
|
+
@current_column = 0 #: Integer
|
166
141
|
end
|
167
142
|
|
168
|
-
|
169
|
-
params(
|
170
|
-
tokens: T::Array[SemanticToken],
|
171
|
-
).returns(T::Array[Integer])
|
172
|
-
end
|
143
|
+
#: (Array[SemanticToken] tokens) -> Array[Integer]
|
173
144
|
def encode(tokens)
|
174
145
|
sorted_tokens = tokens.sort_by.with_index do |token, index|
|
175
146
|
# Enumerable#sort_by is not deterministic when the compared values are equal.
|
@@ -194,7 +165,7 @@ module RubyLsp
|
|
194
165
|
|
195
166
|
# For more information on how each number is calculated, read:
|
196
167
|
# https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens
|
197
|
-
|
168
|
+
#: (SemanticToken token) -> Array[Integer]
|
198
169
|
def compute_delta(token)
|
199
170
|
row = token.start_line - 1
|
200
171
|
column = token.start_code_unit_column
|
@@ -216,7 +187,7 @@ module RubyLsp
|
|
216
187
|
# For example, [:default_library] will be encoded as
|
217
188
|
# 0b1000000000, as :default_library is the 10th bit according
|
218
189
|
# to the token modifiers index map.
|
219
|
-
|
190
|
+
#: (Array[Integer] modifiers) -> Integer
|
220
191
|
def encode_modifiers(modifiers)
|
221
192
|
modifiers.inject(0) do |encoded_modifiers, modifier|
|
222
193
|
encoded_modifiers | (1 << modifier)
|
@@ -3,23 +3,21 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module ResponseBuilders
|
6
|
+
#: [ResponseType = Interface::SignatureHelp?]
|
6
7
|
class SignatureHelp < ResponseBuilder
|
7
|
-
|
8
|
-
|
9
|
-
ResponseType = type_member { { fixed: T.nilable(Interface::SignatureHelp) } }
|
10
|
-
|
11
|
-
sig { void }
|
8
|
+
#: -> void
|
12
9
|
def initialize
|
13
10
|
super
|
14
|
-
@signature_help =
|
11
|
+
@signature_help = nil #: ResponseType
|
15
12
|
end
|
16
13
|
|
17
|
-
|
14
|
+
#: (ResponseType signature_help) -> void
|
18
15
|
def replace(signature_help)
|
19
16
|
@signature_help = signature_help
|
20
17
|
end
|
21
18
|
|
22
|
-
|
19
|
+
# @override
|
20
|
+
#: -> ResponseType
|
23
21
|
def response
|
24
22
|
@signature_help
|
25
23
|
end
|
@@ -3,33 +3,55 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module ResponseBuilders
|
6
|
+
#: [ResponseType = Requests::Support::TestItem]
|
6
7
|
class TestCollection < ResponseBuilder
|
7
|
-
|
8
|
+
#: Array[Interface::CodeLens]
|
9
|
+
attr_reader :code_lens
|
8
10
|
|
9
|
-
|
10
|
-
extend T::Generic
|
11
|
-
|
12
|
-
ResponseType = type_member { { fixed: Requests::Support::TestItem } }
|
13
|
-
|
14
|
-
sig { void }
|
11
|
+
#: -> void
|
15
12
|
def initialize
|
16
13
|
super
|
17
|
-
@items =
|
14
|
+
@items = {} #: Hash[String, ResponseType]
|
15
|
+
@code_lens = [] #: Array[Interface::CodeLens]
|
18
16
|
end
|
19
17
|
|
20
|
-
|
18
|
+
#: (ResponseType item) -> void
|
21
19
|
def add(item)
|
22
|
-
raise DuplicateIdError, "TestItem ID is already in use" if @items.key?(item.id)
|
23
|
-
|
24
20
|
@items[item.id] = item
|
25
21
|
end
|
26
22
|
|
27
|
-
|
23
|
+
#: (ResponseType item) -> void
|
24
|
+
def add_code_lens(item)
|
25
|
+
arguments = [item.uri.to_standardized_path, item.id]
|
26
|
+
start = item.range.start
|
27
|
+
range = Interface::Range.new(
|
28
|
+
start: start,
|
29
|
+
end: Interface::Position.new(line: start.line, character: start.character + 1),
|
30
|
+
)
|
31
|
+
|
32
|
+
@code_lens << Interface::CodeLens.new(
|
33
|
+
range: range,
|
34
|
+
data: { arguments: arguments, kind: "run_test" },
|
35
|
+
)
|
36
|
+
|
37
|
+
@code_lens << Interface::CodeLens.new(
|
38
|
+
range: range,
|
39
|
+
data: { arguments: arguments, kind: "run_test_in_terminal" },
|
40
|
+
)
|
41
|
+
|
42
|
+
@code_lens << Interface::CodeLens.new(
|
43
|
+
range: range,
|
44
|
+
data: { arguments: arguments, kind: "debug_test" },
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
#: (String id) -> ResponseType?
|
28
49
|
def [](id)
|
29
50
|
@items[id]
|
30
51
|
end
|
31
52
|
|
32
|
-
|
53
|
+
# @override
|
54
|
+
#: -> Array[ResponseType]
|
33
55
|
def response
|
34
56
|
@items.values
|
35
57
|
end
|
@@ -2,12 +2,8 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
5
|
+
#: [ParseResultType = Prism::ParseLexResult]
|
5
6
|
class RubyDocument < Document
|
6
|
-
extend T::Sig
|
7
|
-
extend T::Generic
|
8
|
-
|
9
|
-
ParseResultType = type_member { { fixed: Prism::ParseResult } }
|
10
|
-
|
11
7
|
METHODS_THAT_CHANGE_DECLARATIONS = [
|
12
8
|
:private_constant,
|
13
9
|
:attr_reader,
|
@@ -24,49 +20,16 @@ module RubyLsp
|
|
24
20
|
:private_class_method,
|
25
21
|
].freeze
|
26
22
|
|
27
|
-
class SorbetLevel < T::Enum
|
28
|
-
enums do
|
29
|
-
None = new("none")
|
30
|
-
Ignore = new("ignore")
|
31
|
-
False = new("false")
|
32
|
-
True = new("true")
|
33
|
-
Strict = new("strict")
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
23
|
class << self
|
38
|
-
|
39
|
-
|
40
|
-
sig do
|
41
|
-
params(
|
42
|
-
node: Prism::Node,
|
43
|
-
char_position: Integer,
|
44
|
-
code_units_cache: T.any(
|
45
|
-
T.proc.params(arg0: Integer).returns(Integer),
|
46
|
-
Prism::CodeUnitsCache,
|
47
|
-
),
|
48
|
-
node_types: T::Array[T.class_of(Prism::Node)],
|
49
|
-
).returns(NodeContext)
|
50
|
-
end
|
24
|
+
#: (Prism::Node node, Integer char_position, code_units_cache: (^(Integer arg0) -> Integer | Prism::CodeUnitsCache), ?node_types: Array[singleton(Prism::Node)]) -> NodeContext
|
51
25
|
def locate(node, char_position, code_units_cache:, node_types: [])
|
52
|
-
queue =
|
26
|
+
queue = node.child_nodes.compact #: Array[Prism::Node?]
|
53
27
|
closest = node
|
54
|
-
parent =
|
55
|
-
nesting_nodes =
|
56
|
-
[],
|
57
|
-
T::Array[T.any(
|
58
|
-
Prism::ClassNode,
|
59
|
-
Prism::ModuleNode,
|
60
|
-
Prism::SingletonClassNode,
|
61
|
-
Prism::DefNode,
|
62
|
-
Prism::BlockNode,
|
63
|
-
Prism::LambdaNode,
|
64
|
-
Prism::ProgramNode,
|
65
|
-
)],
|
66
|
-
)
|
28
|
+
parent = nil #: Prism::Node?
|
29
|
+
nesting_nodes = [] #: Array[(Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode | Prism::DefNode | Prism::BlockNode | Prism::LambdaNode | Prism::ProgramNode)]
|
67
30
|
|
68
31
|
nesting_nodes << node if node.is_a?(Prism::ProgramNode)
|
69
|
-
call_node =
|
32
|
+
call_node = nil #: Prism::CallNode?
|
70
33
|
|
71
34
|
until queue.empty?
|
72
35
|
candidate = queue.shift
|
@@ -77,7 +40,7 @@ module RubyLsp
|
|
77
40
|
# Add the next child_nodes to the queue to be processed. The order here is important! We want to move in the
|
78
41
|
# same order as the visiting mechanism, which means searching the child nodes before moving on to the next
|
79
42
|
# sibling
|
80
|
-
|
43
|
+
queue.unshift(*candidate.child_nodes)
|
81
44
|
|
82
45
|
# Skip if the current node doesn't cover the desired position
|
83
46
|
loc = candidate.location
|
@@ -150,74 +113,50 @@ module RubyLsp
|
|
150
113
|
end
|
151
114
|
end
|
152
115
|
|
153
|
-
|
154
|
-
returns(T.any(
|
155
|
-
T.proc.params(arg0: Integer).returns(Integer),
|
156
|
-
Prism::CodeUnitsCache,
|
157
|
-
))
|
158
|
-
end
|
116
|
+
#: (^(Integer arg0) -> Integer | Prism::CodeUnitsCache)
|
159
117
|
attr_reader :code_units_cache
|
160
118
|
|
161
|
-
|
119
|
+
#: (source: String, version: Integer, uri: URI::Generic, global_state: GlobalState) -> void
|
162
120
|
def initialize(source:, version:, uri:, global_state:)
|
163
121
|
super
|
164
|
-
@code_units_cache =
|
165
|
-
|
166
|
-
Prism::CodeUnitsCache,
|
167
|
-
))
|
122
|
+
@code_units_cache = @parse_result
|
123
|
+
.code_units_cache(@encoding) #: (^(Integer arg0) -> Integer | Prism::CodeUnitsCache)
|
168
124
|
end
|
169
125
|
|
170
|
-
|
126
|
+
# @override
|
127
|
+
#: -> bool
|
171
128
|
def parse!
|
172
129
|
return false unless @needs_parsing
|
173
130
|
|
174
131
|
@needs_parsing = false
|
175
|
-
@parse_result = Prism.
|
132
|
+
@parse_result = Prism.parse_lex(@source)
|
176
133
|
@code_units_cache = @parse_result.code_units_cache(@encoding)
|
177
134
|
true
|
178
135
|
end
|
179
136
|
|
180
|
-
|
137
|
+
#: -> Prism::ProgramNode
|
138
|
+
def ast
|
139
|
+
@parse_result.value.first
|
140
|
+
end
|
141
|
+
|
142
|
+
# @override
|
143
|
+
#: -> bool
|
181
144
|
def syntax_error?
|
182
145
|
@parse_result.failure?
|
183
146
|
end
|
184
147
|
|
185
|
-
|
148
|
+
# @override
|
149
|
+
#: -> Symbol
|
186
150
|
def language_id
|
187
|
-
|
151
|
+
:ruby
|
188
152
|
end
|
189
153
|
|
190
|
-
|
191
|
-
def sorbet_level
|
192
|
-
sigil = parse_result.magic_comments.find do |comment|
|
193
|
-
comment.key == "typed"
|
194
|
-
end&.value
|
195
|
-
|
196
|
-
case sigil
|
197
|
-
when "ignore"
|
198
|
-
SorbetLevel::Ignore
|
199
|
-
when "false"
|
200
|
-
SorbetLevel::False
|
201
|
-
when "true"
|
202
|
-
SorbetLevel::True
|
203
|
-
when "strict", "strong"
|
204
|
-
SorbetLevel::Strict
|
205
|
-
else
|
206
|
-
SorbetLevel::None
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
sig do
|
211
|
-
params(
|
212
|
-
range: T::Hash[Symbol, T.untyped],
|
213
|
-
node_types: T::Array[T.class_of(Prism::Node)],
|
214
|
-
).returns(T.nilable(Prism::Node))
|
215
|
-
end
|
154
|
+
#: (Hash[Symbol, untyped] range, ?node_types: Array[singleton(Prism::Node)]) -> Prism::Node?
|
216
155
|
def locate_first_within_range(range, node_types: [])
|
217
156
|
start_position, end_position = find_index_by_position(range[:start], range[:end])
|
218
157
|
|
219
158
|
desired_range = (start_position...end_position)
|
220
|
-
queue =
|
159
|
+
queue = ast.child_nodes.compact #: Array[Prism::Node?]
|
221
160
|
|
222
161
|
until queue.empty?
|
223
162
|
candidate = queue.shift
|
@@ -228,7 +167,7 @@ module RubyLsp
|
|
228
167
|
# Add the next child_nodes to the queue to be processed. The order here is important! We want to move in the
|
229
168
|
# same order as the visiting mechanism, which means searching the child nodes before moving on to the next
|
230
169
|
# sibling
|
231
|
-
|
170
|
+
queue.unshift(*candidate.child_nodes)
|
232
171
|
|
233
172
|
# Skip if the current node doesn't cover the desired position
|
234
173
|
loc = candidate.location
|
@@ -240,24 +179,19 @@ module RubyLsp
|
|
240
179
|
end
|
241
180
|
end
|
242
181
|
|
243
|
-
|
244
|
-
params(
|
245
|
-
position: T::Hash[Symbol, T.untyped],
|
246
|
-
node_types: T::Array[T.class_of(Prism::Node)],
|
247
|
-
).returns(NodeContext)
|
248
|
-
end
|
182
|
+
#: (Hash[Symbol, untyped] position, ?node_types: Array[singleton(Prism::Node)]) -> NodeContext
|
249
183
|
def locate_node(position, node_types: [])
|
250
184
|
char_position, _ = find_index_by_position(position)
|
251
185
|
|
252
186
|
RubyDocument.locate(
|
253
|
-
|
187
|
+
ast,
|
254
188
|
char_position,
|
255
189
|
code_units_cache: @code_units_cache,
|
256
190
|
node_types: node_types,
|
257
191
|
)
|
258
192
|
end
|
259
193
|
|
260
|
-
|
194
|
+
#: -> bool
|
261
195
|
def should_index?
|
262
196
|
# This method controls when we should index documents. If there's no recent edit and the document has just been
|
263
197
|
# opened, we need to index it
|
@@ -268,7 +202,7 @@ module RubyLsp
|
|
268
202
|
|
269
203
|
private
|
270
204
|
|
271
|
-
|
205
|
+
#: -> bool
|
272
206
|
def last_edit_may_change_declarations?
|
273
207
|
case @last_edit
|
274
208
|
when Delete
|
@@ -282,7 +216,7 @@ module RubyLsp
|
|
282
216
|
end
|
283
217
|
end
|
284
218
|
|
285
|
-
|
219
|
+
#: (Hash[Symbol, Integer] position) -> bool
|
286
220
|
def position_may_impact_declarations?(position)
|
287
221
|
node_context = locate_node(position)
|
288
222
|
node_at_edit = node_context.node
|
data/lib/ruby_lsp/scope.rb
CHANGED
@@ -3,26 +3,24 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
class Scope
|
6
|
-
|
7
|
-
|
8
|
-
sig { returns(T.nilable(Scope)) }
|
6
|
+
#: Scope?
|
9
7
|
attr_reader :parent
|
10
8
|
|
11
|
-
|
9
|
+
#: (?Scope? parent) -> void
|
12
10
|
def initialize(parent = nil)
|
13
11
|
@parent = parent
|
14
12
|
|
15
13
|
# A hash of name => type
|
16
|
-
@locals =
|
14
|
+
@locals = {} #: Hash[Symbol, Local]
|
17
15
|
end
|
18
16
|
|
19
17
|
# Add a new local to this scope. The types should only be `:parameter` or `:variable`
|
20
|
-
|
18
|
+
#: ((String | Symbol) name, Symbol type) -> void
|
21
19
|
def add(name, type)
|
22
20
|
@locals[name.to_sym] = Local.new(type)
|
23
21
|
end
|
24
22
|
|
25
|
-
|
23
|
+
#: ((String | Symbol) name) -> Local?
|
26
24
|
def lookup(name)
|
27
25
|
sym = name.to_sym
|
28
26
|
entry = @locals[sym]
|
@@ -33,12 +31,10 @@ module RubyLsp
|
|
33
31
|
end
|
34
32
|
|
35
33
|
class Local
|
36
|
-
|
37
|
-
|
38
|
-
sig { returns(Symbol) }
|
34
|
+
#: Symbol
|
39
35
|
attr_reader :type
|
40
36
|
|
41
|
-
|
37
|
+
#: (Symbol type) -> void
|
42
38
|
def initialize(type)
|
43
39
|
@type = type
|
44
40
|
end
|
@@ -13,8 +13,10 @@ def compose(raw_initialize)
|
|
13
13
|
workspace_path ||= Dir.pwd
|
14
14
|
|
15
15
|
env = RubyLsp::SetupBundler.new(workspace_path, launcher: true).setup!
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
|
17
|
+
File.open(File.join(".ruby-lsp", "bundle_env"), "w") do |f|
|
18
|
+
f.flock(File::LOCK_EX)
|
19
|
+
f.write(env.map { |k, v| "#{k}=#{v}" }.join("\n"))
|
20
|
+
f.flush
|
21
|
+
end
|
20
22
|
end
|