ruby-lsp 0.19.1 → 0.20.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/VERSION +1 -1
- data/lib/core_ext/uri.rb +2 -2
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +85 -36
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +5 -1
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +39 -98
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +2 -3
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +22 -0
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +2 -7
- data/lib/ruby_indexer/test/enhancements_test.rb +5 -7
- data/lib/ruby_indexer/test/global_variable_test.rb +49 -0
- data/lib/ruby_lsp/erb_document.rb +15 -2
- data/lib/ruby_lsp/listeners/definition.rb +20 -0
- data/lib/ruby_lsp/listeners/folding_ranges.rb +3 -3
- data/lib/ruby_lsp/requests/code_action_resolve.rb +8 -2
- data/lib/ruby_lsp/requests/completion.rb +1 -1
- data/lib/ruby_lsp/requests/definition.rb +2 -1
- data/lib/ruby_lsp/requests/document_highlight.rb +5 -1
- data/lib/ruby_lsp/requests/hover.rb +1 -1
- data/lib/ruby_lsp/requests/range_formatting.rb +4 -2
- data/lib/ruby_lsp/requests/references.rb +1 -1
- data/lib/ruby_lsp/requests/rename.rb +1 -1
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +1 -1
- data/lib/ruby_lsp/requests/signature_help.rb +1 -1
- data/lib/ruby_lsp/requests/support/common.rb +1 -1
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +6 -6
- data/lib/ruby_lsp/response_builders/document_symbol.rb +2 -2
- data/lib/ruby_lsp/response_builders/hover.rb +2 -2
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +14 -8
- data/lib/ruby_lsp/response_builders/signature_help.rb +2 -2
- data/lib/ruby_lsp/ruby_document.rb +33 -12
- data/lib/ruby_lsp/type_inferrer.rb +1 -1
- metadata +6 -5
@@ -9,14 +9,14 @@ module RubyIndexer
|
|
9
9
|
enhancement_class = Class.new do
|
10
10
|
include Enhancement
|
11
11
|
|
12
|
-
def on_call_node(index, owner, node, file_path)
|
12
|
+
def on_call_node(index, owner, node, file_path, code_units_cache)
|
13
13
|
return unless owner
|
14
14
|
return unless node.name == :extend
|
15
15
|
|
16
16
|
arguments = node.arguments&.arguments
|
17
17
|
return unless arguments
|
18
18
|
|
19
|
-
location = node.location
|
19
|
+
location = Location.from_prism_location(node.location, code_units_cache)
|
20
20
|
|
21
21
|
arguments.each do |node|
|
22
22
|
next unless node.is_a?(Prism::ConstantReadNode) || node.is_a?(Prism::ConstantPathNode)
|
@@ -39,7 +39,6 @@ module RubyIndexer
|
|
39
39
|
location,
|
40
40
|
location,
|
41
41
|
nil,
|
42
|
-
index.configuration.encoding,
|
43
42
|
[Entry::Signature.new([Entry::RequiredParameter.new(name: :a)])],
|
44
43
|
Entry::Visibility::PUBLIC,
|
45
44
|
owner,
|
@@ -102,7 +101,7 @@ module RubyIndexer
|
|
102
101
|
enhancement_class = Class.new do
|
103
102
|
include Enhancement
|
104
103
|
|
105
|
-
def on_call_node(index, owner, node, file_path)
|
104
|
+
def on_call_node(index, owner, node, file_path, code_units_cache)
|
106
105
|
return unless owner
|
107
106
|
|
108
107
|
name = node.name
|
@@ -114,7 +113,7 @@ module RubyIndexer
|
|
114
113
|
association_name = arguments.first
|
115
114
|
return unless association_name.is_a?(Prism::SymbolNode)
|
116
115
|
|
117
|
-
location = association_name.location
|
116
|
+
location = Location.from_prism_location(association_name.location, code_units_cache)
|
118
117
|
|
119
118
|
index.add(Entry::Method.new(
|
120
119
|
T.must(association_name.value),
|
@@ -122,7 +121,6 @@ module RubyIndexer
|
|
122
121
|
location,
|
123
122
|
location,
|
124
123
|
nil,
|
125
|
-
index.configuration.encoding,
|
126
124
|
[],
|
127
125
|
Entry::Visibility::PUBLIC,
|
128
126
|
owner,
|
@@ -166,7 +164,7 @@ module RubyIndexer
|
|
166
164
|
enhancement_class = Class.new do
|
167
165
|
include Enhancement
|
168
166
|
|
169
|
-
def on_call_node(index, owner, node, file_path)
|
167
|
+
def on_call_node(index, owner, node, file_path, code_units_cache)
|
170
168
|
raise "Error"
|
171
169
|
end
|
172
170
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "test_case"
|
5
|
+
|
6
|
+
module RubyIndexer
|
7
|
+
class GlobalVariableTest < TestCase
|
8
|
+
def test_global_variable_and_write
|
9
|
+
index(<<~RUBY)
|
10
|
+
$foo &&= 1
|
11
|
+
RUBY
|
12
|
+
|
13
|
+
assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_global_variable_operator_write
|
17
|
+
index(<<~RUBY)
|
18
|
+
$foo += 1
|
19
|
+
RUBY
|
20
|
+
|
21
|
+
assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_global_variable_or_write
|
25
|
+
index(<<~RUBY)
|
26
|
+
$foo ||= 1
|
27
|
+
RUBY
|
28
|
+
|
29
|
+
assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_global_variable_target_node
|
33
|
+
index(<<~RUBY)
|
34
|
+
$foo, $bar = 1
|
35
|
+
RUBY
|
36
|
+
|
37
|
+
assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
|
38
|
+
assert_entry("$bar", Entry::GlobalVariable, "/fake/path/foo.rb:0-6:0-10")
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_global_variable_write
|
42
|
+
index(<<~RUBY)
|
43
|
+
$foo = 1
|
44
|
+
RUBY
|
45
|
+
|
46
|
+
assert_entry("$foo", Entry::GlobalVariable, "/fake/path/foo.rb:0-0:0-4")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -6,10 +6,18 @@ module RubyLsp
|
|
6
6
|
extend T::Sig
|
7
7
|
extend T::Generic
|
8
8
|
|
9
|
+
ParseResultType = type_member { { fixed: Prism::ParseResult } }
|
10
|
+
|
9
11
|
sig { returns(String) }
|
10
12
|
attr_reader :host_language_source
|
11
13
|
|
12
|
-
|
14
|
+
sig do
|
15
|
+
returns(T.any(
|
16
|
+
T.proc.params(arg0: Integer).returns(Integer),
|
17
|
+
Prism::CodeUnitsCache,
|
18
|
+
))
|
19
|
+
end
|
20
|
+
attr_reader :code_units_cache
|
13
21
|
|
14
22
|
sig { params(source: String, version: Integer, uri: URI::Generic, encoding: Encoding).void }
|
15
23
|
def initialize(source:, version:, uri:, encoding: Encoding::UTF_8)
|
@@ -17,6 +25,10 @@ module RubyLsp
|
|
17
25
|
# overrides this with the proper virtual host language source
|
18
26
|
@host_language_source = T.let("", String)
|
19
27
|
super
|
28
|
+
@code_units_cache = T.let(@parse_result.code_units_cache(@encoding), T.any(
|
29
|
+
T.proc.params(arg0: Integer).returns(Integer),
|
30
|
+
Prism::CodeUnitsCache,
|
31
|
+
))
|
20
32
|
end
|
21
33
|
|
22
34
|
sig { override.returns(T::Boolean) }
|
@@ -30,6 +42,7 @@ module RubyLsp
|
|
30
42
|
# Use partial script to avoid syntax errors in ERB files where keywords may be used without the full context in
|
31
43
|
# which they will be evaluated
|
32
44
|
@parse_result = Prism.parse(scanner.ruby, partial_script: true)
|
45
|
+
@code_units_cache = @parse_result.code_units_cache(@encoding)
|
33
46
|
true
|
34
47
|
end
|
35
48
|
|
@@ -53,8 +66,8 @@ module RubyLsp
|
|
53
66
|
RubyDocument.locate(
|
54
67
|
@parse_result.value,
|
55
68
|
create_scanner.find_char_position(position),
|
69
|
+
code_units_cache: @code_units_cache,
|
56
70
|
node_types: node_types,
|
57
|
-
encoding: @encoding,
|
58
71
|
)
|
59
72
|
end
|
60
73
|
|
@@ -39,6 +39,7 @@ module RubyLsp
|
|
39
39
|
:on_block_argument_node_enter,
|
40
40
|
:on_constant_read_node_enter,
|
41
41
|
:on_constant_path_node_enter,
|
42
|
+
:on_global_variable_read_node_enter,
|
42
43
|
:on_instance_variable_read_node_enter,
|
43
44
|
:on_instance_variable_write_node_enter,
|
44
45
|
:on_instance_variable_and_write_node_enter,
|
@@ -120,6 +121,25 @@ module RubyLsp
|
|
120
121
|
find_in_index(name)
|
121
122
|
end
|
122
123
|
|
124
|
+
sig { params(node: Prism::GlobalVariableReadNode).void }
|
125
|
+
def on_global_variable_read_node_enter(node)
|
126
|
+
entries = @index[node.name.to_s]
|
127
|
+
|
128
|
+
return unless entries
|
129
|
+
|
130
|
+
entries.each do |entry|
|
131
|
+
location = entry.location
|
132
|
+
|
133
|
+
@response_builder << Interface::Location.new(
|
134
|
+
uri: URI::Generic.from_path(path: entry.file_path).to_s,
|
135
|
+
range: Interface::Range.new(
|
136
|
+
start: Interface::Position.new(line: location.start_line - 1, character: location.start_column),
|
137
|
+
end: Interface::Position.new(line: location.end_line - 1, character: location.end_column),
|
138
|
+
),
|
139
|
+
)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
123
143
|
sig { params(node: Prism::InstanceVariableReadNode).void }
|
124
144
|
def on_instance_variable_read_node_enter(node)
|
125
145
|
handle_instance_variable_definition(node.name.to_s)
|
@@ -239,10 +239,10 @@ module RubyLsp
|
|
239
239
|
statements = node.statements
|
240
240
|
return unless statements
|
241
241
|
|
242
|
-
|
243
|
-
return
|
242
|
+
statement = statements.body.last
|
243
|
+
return unless statement
|
244
244
|
|
245
|
-
add_lines_range(node.location.start_line,
|
245
|
+
add_lines_range(node.location.start_line, statement.location.end_line)
|
246
246
|
end
|
247
247
|
|
248
248
|
sig { params(node: Prism::Node).void }
|
@@ -99,7 +99,13 @@ module RubyLsp
|
|
99
99
|
|
100
100
|
# Find the closest statements node, so that we place the refactor in a valid position
|
101
101
|
node_context = RubyDocument
|
102
|
-
.locate(@document.parse_result.value,
|
102
|
+
.locate(@document.parse_result.value,
|
103
|
+
start_index,
|
104
|
+
node_types: [
|
105
|
+
Prism::StatementsNode,
|
106
|
+
Prism::BlockNode,
|
107
|
+
],
|
108
|
+
code_units_cache: @document.code_units_cache)
|
103
109
|
|
104
110
|
closest_statements = node_context.node
|
105
111
|
parent_statements = node_context.parent
|
@@ -196,7 +202,7 @@ module RubyLsp
|
|
196
202
|
@document.parse_result.value,
|
197
203
|
start_index,
|
198
204
|
node_types: [Prism::DefNode],
|
199
|
-
|
205
|
+
code_units_cache: @document.code_units_cache,
|
200
206
|
)
|
201
207
|
closest_node = node_context.node
|
202
208
|
return Error::InvalidTargetRange unless closest_node
|
@@ -57,7 +57,7 @@ module RubyLsp
|
|
57
57
|
Prism::InstanceVariableTargetNode,
|
58
58
|
Prism::InstanceVariableWriteNode,
|
59
59
|
],
|
60
|
-
|
60
|
+
code_units_cache: document.code_units_cache,
|
61
61
|
)
|
62
62
|
@response_builder = T.let(
|
63
63
|
ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem].new,
|
@@ -46,6 +46,7 @@ module RubyLsp
|
|
46
46
|
Prism::ConstantReadNode,
|
47
47
|
Prism::ConstantPathNode,
|
48
48
|
Prism::BlockArgumentNode,
|
49
|
+
Prism::GlobalVariableReadNode,
|
49
50
|
Prism::InstanceVariableReadNode,
|
50
51
|
Prism::InstanceVariableAndWriteNode,
|
51
52
|
Prism::InstanceVariableOperatorWriteNode,
|
@@ -57,7 +58,7 @@ module RubyLsp
|
|
57
58
|
Prism::SuperNode,
|
58
59
|
Prism::ForwardingSuperNode,
|
59
60
|
],
|
60
|
-
|
61
|
+
code_units_cache: document.code_units_cache,
|
61
62
|
)
|
62
63
|
|
63
64
|
target = node_context.node
|
@@ -28,7 +28,11 @@ module RubyLsp
|
|
28
28
|
char_position = document.create_scanner.find_char_position(position)
|
29
29
|
delegate_request_if_needed!(global_state, document, char_position)
|
30
30
|
|
31
|
-
node_context = RubyDocument.locate(
|
31
|
+
node_context = RubyDocument.locate(
|
32
|
+
document.parse_result.value,
|
33
|
+
char_position,
|
34
|
+
code_units_cache: document.code_units_cache,
|
35
|
+
)
|
32
36
|
|
33
37
|
@response_builder = T.let(
|
34
38
|
ResponseBuilders::CollectionResponseBuilder[Interface::DocumentHighlight].new,
|
@@ -41,7 +41,7 @@ module RubyLsp
|
|
41
41
|
document.parse_result.value,
|
42
42
|
char_position,
|
43
43
|
node_types: Listeners::Hover::ALLOWED_TARGETS,
|
44
|
-
|
44
|
+
code_units_cache: document.code_units_cache,
|
45
45
|
)
|
46
46
|
target = node_context.node
|
47
47
|
parent = node_context.parent
|
@@ -34,16 +34,18 @@ module RubyLsp
|
|
34
34
|
)
|
35
35
|
return unless formatted_text
|
36
36
|
|
37
|
+
code_units_cache = @document.code_units_cache
|
38
|
+
|
37
39
|
[
|
38
40
|
Interface::TextEdit.new(
|
39
41
|
range: Interface::Range.new(
|
40
42
|
start: Interface::Position.new(
|
41
43
|
line: location.start_line - 1,
|
42
|
-
character: location.
|
44
|
+
character: location.cached_start_code_units_column(code_units_cache),
|
43
45
|
),
|
44
46
|
end: Interface::Position.new(
|
45
47
|
line: location.end_line - 1,
|
46
|
-
character: location.
|
48
|
+
character: location.cached_end_code_units_column(code_units_cache),
|
47
49
|
),
|
48
50
|
),
|
49
51
|
new_text: formatted_text.strip,
|
@@ -37,7 +37,7 @@ module RubyLsp
|
|
37
37
|
@document.parse_result.value,
|
38
38
|
char_position,
|
39
39
|
node_types: [Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::ConstantPathTargetNode],
|
40
|
-
|
40
|
+
code_units_cache: @document.code_units_cache,
|
41
41
|
)
|
42
42
|
target = node_context.node
|
43
43
|
parent = node_context.parent
|
@@ -101,7 +101,7 @@ module RubyLsp
|
|
101
101
|
@range = range
|
102
102
|
@result_id = T.let(SemanticHighlighting.next_result_id.to_s, String)
|
103
103
|
@response_builder = T.let(
|
104
|
-
ResponseBuilders::SemanticHighlighting.new(
|
104
|
+
ResponseBuilders::SemanticHighlighting.new(document.code_units_cache),
|
105
105
|
ResponseBuilders::SemanticHighlighting,
|
106
106
|
)
|
107
107
|
Listeners::SemanticHighlighting.new(dispatcher, @response_builder)
|
@@ -43,7 +43,7 @@ module RubyLsp
|
|
43
43
|
document.parse_result.value,
|
44
44
|
char_position,
|
45
45
|
node_types: [Prism::CallNode],
|
46
|
-
|
46
|
+
code_units_cache: document.code_units_cache,
|
47
47
|
)
|
48
48
|
|
49
49
|
target = adjust_for_nested_target(node_context.node, node_context.parent, position)
|
@@ -159,7 +159,7 @@ module RubyLsp
|
|
159
159
|
def namespace_constant_name(node)
|
160
160
|
path = node.constant_path
|
161
161
|
case path
|
162
|
-
when Prism::ConstantPathNode, Prism::ConstantReadNode
|
162
|
+
when Prism::ConstantPathNode, Prism::ConstantReadNode
|
163
163
|
constant_name(path)
|
164
164
|
end
|
165
165
|
end
|
@@ -47,12 +47,6 @@ module RubyLsp
|
|
47
47
|
|
48
48
|
class ConfigurationError < StandardError; end
|
49
49
|
|
50
|
-
sig { returns(T::Array[RuboCop::Cop::Offense]) }
|
51
|
-
attr_reader :offenses
|
52
|
-
|
53
|
-
sig { returns(::RuboCop::Config) }
|
54
|
-
attr_reader :config_for_working_directory
|
55
|
-
|
56
50
|
DEFAULT_ARGS = T.let(
|
57
51
|
[
|
58
52
|
"--stderr", # Print any output to stderr so that our stdout does not get polluted
|
@@ -63,6 +57,12 @@ module RubyLsp
|
|
63
57
|
T::Array[String],
|
64
58
|
)
|
65
59
|
|
60
|
+
sig { returns(T::Array[RuboCop::Cop::Offense]) }
|
61
|
+
attr_reader :offenses
|
62
|
+
|
63
|
+
sig { returns(::RuboCop::Config) }
|
64
|
+
attr_reader :config_for_working_directory
|
65
|
+
|
66
66
|
begin
|
67
67
|
RuboCop::Options.new.parse(["--raise-cop-error"])
|
68
68
|
DEFAULT_ARGS << "--raise-cop-error"
|
@@ -4,6 +4,8 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module ResponseBuilders
|
6
6
|
class DocumentSymbol < ResponseBuilder
|
7
|
+
extend T::Sig
|
8
|
+
|
7
9
|
ResponseType = type_member { { fixed: T::Array[Interface::DocumentSymbol] } }
|
8
10
|
|
9
11
|
class SymbolHierarchyRoot
|
@@ -18,8 +20,6 @@ module RubyLsp
|
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
21
|
-
extend T::Sig
|
22
|
-
|
23
23
|
sig { void }
|
24
24
|
def initialize
|
25
25
|
super
|
@@ -4,11 +4,11 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module ResponseBuilders
|
6
6
|
class Hover < ResponseBuilder
|
7
|
-
ResponseType = type_member { { fixed: String } }
|
8
|
-
|
9
7
|
extend T::Sig
|
10
8
|
extend T::Generic
|
11
9
|
|
10
|
+
ResponseType = type_member { { fixed: String } }
|
11
|
+
|
12
12
|
sig { void }
|
13
13
|
def initialize
|
14
14
|
super
|
@@ -6,6 +6,8 @@ module RubyLsp
|
|
6
6
|
class SemanticHighlighting < ResponseBuilder
|
7
7
|
class UndefinedTokenType < StandardError; end
|
8
8
|
|
9
|
+
extend T::Sig
|
10
|
+
|
9
11
|
TOKEN_TYPES = T.let(
|
10
12
|
{
|
11
13
|
namespace: 0,
|
@@ -51,25 +53,29 @@ module RubyLsp
|
|
51
53
|
T::Hash[Symbol, Integer],
|
52
54
|
)
|
53
55
|
|
54
|
-
extend T::Sig
|
55
|
-
|
56
56
|
ResponseType = type_member { { fixed: Interface::SemanticTokens } }
|
57
57
|
|
58
|
-
sig
|
59
|
-
|
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
|
64
|
+
def initialize(code_units_cache)
|
60
65
|
super()
|
61
|
-
@
|
66
|
+
@code_units_cache = code_units_cache
|
62
67
|
@stack = T.let([], T::Array[SemanticToken])
|
63
68
|
end
|
64
69
|
|
65
70
|
sig { params(location: Prism::Location, type: Symbol, modifiers: T::Array[Symbol]).void }
|
66
71
|
def add_token(location, type, modifiers = [])
|
67
|
-
|
72
|
+
end_code_unit = location.cached_end_code_units_offset(@code_units_cache)
|
73
|
+
length = end_code_unit - location.cached_start_code_units_offset(@code_units_cache)
|
68
74
|
modifiers_indices = modifiers.filter_map { |modifier| TOKEN_MODIFIERS[modifier] }
|
69
75
|
@stack.push(
|
70
76
|
SemanticToken.new(
|
71
77
|
start_line: location.start_line,
|
72
|
-
start_code_unit_column: location.
|
78
|
+
start_code_unit_column: location.cached_start_code_units_column(@code_units_cache),
|
73
79
|
length: length,
|
74
80
|
type: T.must(TOKEN_TYPES[type]),
|
75
81
|
modifier: modifiers_indices,
|
@@ -83,7 +89,7 @@ module RubyLsp
|
|
83
89
|
return false unless token
|
84
90
|
|
85
91
|
token.start_line == location.start_line &&
|
86
|
-
token.start_code_unit_column == location.
|
92
|
+
token.start_code_unit_column == location.cached_start_code_units_column(@code_units_cache)
|
87
93
|
end
|
88
94
|
|
89
95
|
sig { returns(T.nilable(SemanticToken)) }
|
@@ -4,10 +4,10 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module ResponseBuilders
|
6
6
|
class SignatureHelp < ResponseBuilder
|
7
|
-
ResponseType = type_member { { fixed: T.nilable(Interface::SignatureHelp) } }
|
8
|
-
|
9
7
|
extend T::Sig
|
10
8
|
|
9
|
+
ResponseType = type_member { { fixed: T.nilable(Interface::SignatureHelp) } }
|
10
|
+
|
11
11
|
sig { void }
|
12
12
|
def initialize
|
13
13
|
super
|
@@ -25,11 +25,14 @@ module RubyLsp
|
|
25
25
|
params(
|
26
26
|
node: Prism::Node,
|
27
27
|
char_position: Integer,
|
28
|
+
code_units_cache: T.any(
|
29
|
+
T.proc.params(arg0: Integer).returns(Integer),
|
30
|
+
Prism::CodeUnitsCache,
|
31
|
+
),
|
28
32
|
node_types: T::Array[T.class_of(Prism::Node)],
|
29
|
-
encoding: Encoding,
|
30
33
|
).returns(NodeContext)
|
31
34
|
end
|
32
|
-
def locate(node, char_position, node_types: []
|
35
|
+
def locate(node, char_position, code_units_cache:, node_types: [])
|
33
36
|
queue = T.let(node.child_nodes.compact, T::Array[T.nilable(Prism::Node)])
|
34
37
|
closest = node
|
35
38
|
parent = T.let(nil, T.nilable(Prism::Node))
|
@@ -62,8 +65,8 @@ module RubyLsp
|
|
62
65
|
|
63
66
|
# Skip if the current node doesn't cover the desired position
|
64
67
|
loc = candidate.location
|
65
|
-
loc_start_offset = loc.
|
66
|
-
loc_end_offset = loc.
|
68
|
+
loc_start_offset = loc.cached_start_code_units_offset(code_units_cache)
|
69
|
+
loc_end_offset = loc.cached_end_code_units_offset(code_units_cache)
|
67
70
|
next unless (loc_start_offset...loc_end_offset).cover?(char_position)
|
68
71
|
|
69
72
|
# If the node's start character is already past the position, then we should've found the closest node
|
@@ -74,7 +77,7 @@ module RubyLsp
|
|
74
77
|
# and need to pop the stack
|
75
78
|
previous_level = nesting_nodes.last
|
76
79
|
if previous_level &&
|
77
|
-
(loc_start_offset > previous_level.location.
|
80
|
+
(loc_start_offset > previous_level.location.cached_end_code_units_offset(code_units_cache))
|
78
81
|
nesting_nodes.pop
|
79
82
|
end
|
80
83
|
|
@@ -89,10 +92,10 @@ module RubyLsp
|
|
89
92
|
if candidate.is_a?(Prism::CallNode)
|
90
93
|
arg_loc = candidate.arguments&.location
|
91
94
|
blk_loc = candidate.block&.location
|
92
|
-
if (arg_loc && (arg_loc.
|
93
|
-
arg_loc.
|
94
|
-
(blk_loc && (blk_loc.
|
95
|
-
blk_loc.
|
95
|
+
if (arg_loc && (arg_loc.cached_start_code_units_offset(code_units_cache)...
|
96
|
+
arg_loc.cached_end_code_units_offset(code_units_cache)).cover?(char_position)) ||
|
97
|
+
(blk_loc && (blk_loc.cached_start_code_units_offset(code_units_cache)...
|
98
|
+
blk_loc.cached_end_code_units_offset(code_units_cache)).cover?(char_position))
|
96
99
|
call_node = candidate
|
97
100
|
end
|
98
101
|
end
|
@@ -102,8 +105,8 @@ module RubyLsp
|
|
102
105
|
|
103
106
|
# If the current node is narrower than or equal to the previous closest node, then it is more precise
|
104
107
|
closest_loc = closest.location
|
105
|
-
closest_node_start_offset = closest_loc.
|
106
|
-
closest_node_end_offset = closest_loc.
|
108
|
+
closest_node_start_offset = closest_loc.cached_start_code_units_offset(code_units_cache)
|
109
|
+
closest_node_end_offset = closest_loc.cached_end_code_units_offset(code_units_cache)
|
107
110
|
if loc_end_offset - loc_start_offset <= closest_node_end_offset - closest_node_start_offset
|
108
111
|
parent = closest
|
109
112
|
closest = candidate
|
@@ -131,12 +134,30 @@ module RubyLsp
|
|
131
134
|
end
|
132
135
|
end
|
133
136
|
|
137
|
+
sig do
|
138
|
+
returns(T.any(
|
139
|
+
T.proc.params(arg0: Integer).returns(Integer),
|
140
|
+
Prism::CodeUnitsCache,
|
141
|
+
))
|
142
|
+
end
|
143
|
+
attr_reader :code_units_cache
|
144
|
+
|
145
|
+
sig { params(source: String, version: Integer, uri: URI::Generic, encoding: Encoding).void }
|
146
|
+
def initialize(source:, version:, uri:, encoding: Encoding::UTF_8)
|
147
|
+
super
|
148
|
+
@code_units_cache = T.let(@parse_result.code_units_cache(@encoding), T.any(
|
149
|
+
T.proc.params(arg0: Integer).returns(Integer),
|
150
|
+
Prism::CodeUnitsCache,
|
151
|
+
))
|
152
|
+
end
|
153
|
+
|
134
154
|
sig { override.returns(T::Boolean) }
|
135
155
|
def parse!
|
136
156
|
return false unless @needs_parsing
|
137
157
|
|
138
158
|
@needs_parsing = false
|
139
159
|
@parse_result = Prism.parse(@source)
|
160
|
+
@code_units_cache = @parse_result.code_units_cache(@encoding)
|
140
161
|
true
|
141
162
|
end
|
142
163
|
|
@@ -214,8 +235,8 @@ module RubyLsp
|
|
214
235
|
RubyDocument.locate(
|
215
236
|
@parse_result.value,
|
216
237
|
create_scanner.find_char_position(position),
|
238
|
+
code_units_cache: @code_units_cache,
|
217
239
|
node_types: node_types,
|
218
|
-
encoding: @encoding,
|
219
240
|
)
|
220
241
|
end
|
221
242
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-lsp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-10-
|
11
|
+
date: 2024-10-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: language_server-protocol
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.2'
|
34
34
|
- - "<"
|
35
35
|
- !ruby/object:Gem::Version
|
36
36
|
version: '2.0'
|
@@ -40,7 +40,7 @@ dependencies:
|
|
40
40
|
requirements:
|
41
41
|
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: '1.
|
43
|
+
version: '1.2'
|
44
44
|
- - "<"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '2.0'
|
@@ -111,6 +111,7 @@ files:
|
|
111
111
|
- lib/ruby_indexer/test/configuration_test.rb
|
112
112
|
- lib/ruby_indexer/test/constant_test.rb
|
113
113
|
- lib/ruby_indexer/test/enhancements_test.rb
|
114
|
+
- lib/ruby_indexer/test/global_variable_test.rb
|
114
115
|
- lib/ruby_indexer/test/index_test.rb
|
115
116
|
- lib/ruby_indexer/test/instance_variables_test.rb
|
116
117
|
- lib/ruby_indexer/test/method_test.rb
|
@@ -211,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
211
212
|
- !ruby/object:Gem::Version
|
212
213
|
version: '0'
|
213
214
|
requirements: []
|
214
|
-
rubygems_version: 3.5.
|
215
|
+
rubygems_version: 3.5.21
|
215
216
|
signing_key:
|
216
217
|
specification_version: 4
|
217
218
|
summary: An opinionated language server for Ruby
|