ruby-lsp 0.23.11 → 0.23.16
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-launcher +20 -11
- data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -1
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -5
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +82 -116
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +123 -169
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +9 -7
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +92 -202
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +116 -222
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +18 -19
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +22 -45
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +47 -61
- data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +17 -19
- data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +5 -9
- 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 +48 -7
- 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 +139 -135
- data/lib/ruby_indexer/test/instance_variables_test.rb +37 -37
- data/lib/ruby_indexer/test/method_test.rb +143 -117
- data/lib/ruby_indexer/test/prefix_tree_test.rb +13 -13
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +65 -71
- data/lib/ruby_indexer/test/test_case.rb +2 -2
- data/lib/ruby_indexer/test/uri_test.rb +15 -2
- data/lib/ruby_lsp/addon.rb +44 -71
- data/lib/ruby_lsp/base_server.rb +29 -32
- data/lib/ruby_lsp/client_capabilities.rb +10 -12
- data/lib/ruby_lsp/document.rb +39 -45
- data/lib/ruby_lsp/erb_document.rb +36 -40
- data/lib/ruby_lsp/global_state.rb +52 -57
- data/lib/ruby_lsp/internal.rb +2 -0
- data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
- data/lib/ruby_lsp/listeners/completion.rb +60 -66
- data/lib/ruby_lsp/listeners/definition.rb +38 -52
- data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
- data/lib/ruby_lsp/listeners/document_link.rb +46 -63
- 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 +83 -102
- data/lib/ruby_lsp/listeners/inlay_hints.rb +4 -11
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -56
- data/lib/ruby_lsp/listeners/signature_help.rb +11 -26
- data/lib/ruby_lsp/listeners/spec_style.rb +155 -0
- data/lib/ruby_lsp/listeners/test_discovery.rb +89 -0
- data/lib/ruby_lsp/listeners/test_style.rb +160 -88
- data/lib/ruby_lsp/node_context.rb +12 -39
- data/lib/ruby_lsp/rbs_document.rb +8 -6
- data/lib/ruby_lsp/requests/code_action_resolve.rb +24 -25
- data/lib/ruby_lsp/requests/code_actions.rb +14 -26
- data/lib/ruby_lsp/requests/code_lens.rb +6 -17
- data/lib/ruby_lsp/requests/completion.rb +7 -20
- data/lib/ruby_lsp/requests/completion_resolve.rb +6 -6
- data/lib/ruby_lsp/requests/definition.rb +8 -17
- data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
- data/lib/ruby_lsp/requests/discover_tests.rb +18 -5
- data/lib/ruby_lsp/requests/document_highlight.rb +5 -15
- 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 +87 -0
- data/lib/ruby_lsp/requests/hover.rb +10 -20
- data/lib/ruby_lsp/requests/inlay_hints.rb +6 -17
- data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
- data/lib/ruby_lsp/requests/prepare_rename.rb +4 -9
- 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 +8 -37
- data/lib/ruby_lsp/requests/rename.rb +19 -42
- data/lib/ruby_lsp/requests/request.rb +7 -19
- data/lib/ruby_lsp/requests/selection_ranges.rb +6 -6
- 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 +8 -26
- data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
- data/lib/ruby_lsp/requests/support/common.rb +16 -51
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +11 -14
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +22 -34
- 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 +10 -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 +5 -5
- data/lib/ruby_lsp/response_builders/document_symbol.rb +13 -18
- data/lib/ruby_lsp/response_builders/hover.rb +11 -14
- data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +60 -88
- data/lib/ruby_lsp/response_builders/signature_help.rb +5 -6
- data/lib/ruby_lsp/response_builders/test_collection.rb +6 -10
- data/lib/ruby_lsp/ruby_document.rb +24 -62
- data/lib/ruby_lsp/scope.rb +7 -11
- data/lib/ruby_lsp/scripts/compose_bundle.rb +6 -4
- data/lib/ruby_lsp/server.rb +147 -79
- data/lib/ruby_lsp/setup_bundler.rb +65 -60
- data/lib/ruby_lsp/static_docs.rb +11 -7
- data/lib/ruby_lsp/store.rb +24 -42
- data/lib/ruby_lsp/test_helper.rb +2 -12
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +164 -0
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +105 -0
- data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +94 -0
- data/lib/ruby_lsp/type_inferrer.rb +13 -14
- data/lib/ruby_lsp/utils.rb +49 -83
- metadata +9 -3
data/lib/ruby_lsp/base_server.rb
CHANGED
@@ -8,30 +8,27 @@ module RubyLsp
|
|
8
8
|
|
9
9
|
abstract!
|
10
10
|
|
11
|
-
|
11
|
+
#: (**untyped options) -> void
|
12
12
|
def initialize(**options)
|
13
|
-
@test_mode =
|
14
|
-
@setup_error =
|
15
|
-
@install_error =
|
16
|
-
@writer =
|
17
|
-
@reader =
|
18
|
-
@incoming_queue =
|
19
|
-
@outgoing_queue =
|
20
|
-
@cancelled_requests =
|
21
|
-
@worker =
|
22
|
-
@current_request_id =
|
23
|
-
@global_state =
|
24
|
-
@store =
|
25
|
-
@outgoing_dispatcher =
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@global_state.synchronize { @writer.write(message.to_hash) }
|
30
|
-
end
|
13
|
+
@test_mode = options[:test_mode] #: bool?
|
14
|
+
@setup_error = options[:setup_error] #: StandardError?
|
15
|
+
@install_error = options[:install_error] #: StandardError?
|
16
|
+
@writer = Transport::Stdio::Writer.new #: Transport::Stdio::Writer
|
17
|
+
@reader = Transport::Stdio::Reader.new #: Transport::Stdio::Reader
|
18
|
+
@incoming_queue = Thread::Queue.new #: Thread::Queue
|
19
|
+
@outgoing_queue = Thread::Queue.new #: Thread::Queue
|
20
|
+
@cancelled_requests = [] #: Array[Integer]
|
21
|
+
@worker = new_worker #: Thread
|
22
|
+
@current_request_id = 1 #: Integer
|
23
|
+
@global_state = GlobalState.new #: GlobalState
|
24
|
+
@store = Store.new(@global_state) #: Store
|
25
|
+
@outgoing_dispatcher = Thread.new do
|
26
|
+
unless @test_mode
|
27
|
+
while (message = @outgoing_queue.pop)
|
28
|
+
@global_state.synchronize { @writer.write(message.to_hash) }
|
31
29
|
end
|
32
|
-
end
|
33
|
-
|
34
|
-
)
|
30
|
+
end
|
31
|
+
end #: Thread
|
35
32
|
|
36
33
|
Thread.main.priority = 1
|
37
34
|
|
@@ -41,7 +38,7 @@ module RubyLsp
|
|
41
38
|
process_message(initialize_request) if initialize_request
|
42
39
|
end
|
43
40
|
|
44
|
-
|
41
|
+
#: -> void
|
45
42
|
def start
|
46
43
|
@reader.read do |message|
|
47
44
|
method = message[:method]
|
@@ -108,7 +105,7 @@ module RubyLsp
|
|
108
105
|
end
|
109
106
|
end
|
110
107
|
|
111
|
-
|
108
|
+
#: -> void
|
112
109
|
def run_shutdown
|
113
110
|
@incoming_queue.clear
|
114
111
|
@outgoing_queue.clear
|
@@ -122,13 +119,13 @@ module RubyLsp
|
|
122
119
|
end
|
123
120
|
|
124
121
|
# This method is only intended to be used in tests! Pops the latest response that would be sent to the client
|
125
|
-
|
122
|
+
#: -> untyped
|
126
123
|
def pop_response
|
127
124
|
@outgoing_queue.pop
|
128
125
|
end
|
129
126
|
|
130
127
|
# This method is only intended to be used in tests! Pushes a message to the incoming queue directly
|
131
|
-
|
128
|
+
#: (Hash[Symbol, untyped] message) -> void
|
132
129
|
def push_message(message)
|
133
130
|
@incoming_queue << message
|
134
131
|
end
|
@@ -139,16 +136,16 @@ module RubyLsp
|
|
139
136
|
sig { abstract.void }
|
140
137
|
def shutdown; end
|
141
138
|
|
142
|
-
|
139
|
+
#: (Integer id, String message, ?type: Integer) -> void
|
143
140
|
def fail_request_and_notify(id, message, type: Constant::MessageType::INFO)
|
144
141
|
send_message(Error.new(id: id, code: Constant::ErrorCodes::REQUEST_FAILED, message: message))
|
145
142
|
send_message(Notification.window_show_message(message, type: type))
|
146
143
|
end
|
147
144
|
|
148
|
-
|
145
|
+
#: -> Thread
|
149
146
|
def new_worker
|
150
147
|
Thread.new do
|
151
|
-
while (message =
|
148
|
+
while (message = @incoming_queue.pop)
|
152
149
|
id = message[:id]
|
153
150
|
|
154
151
|
# Check if the request was cancelled before trying to process it
|
@@ -165,7 +162,7 @@ module RubyLsp
|
|
165
162
|
end
|
166
163
|
end
|
167
164
|
|
168
|
-
|
165
|
+
#: ((Result | Error | Notification | Request) message) -> void
|
169
166
|
def send_message(message)
|
170
167
|
# When we're shutting down the server, there's a small race condition between closing the thread queues and
|
171
168
|
# finishing remaining requests. We may close the queue in the middle of processing a request, which will then fail
|
@@ -176,12 +173,12 @@ module RubyLsp
|
|
176
173
|
@current_request_id += 1 if message.is_a?(Request)
|
177
174
|
end
|
178
175
|
|
179
|
-
|
176
|
+
#: (Integer id) -> void
|
180
177
|
def send_empty_response(id)
|
181
178
|
send_message(Result.new(id: id, response: nil))
|
182
179
|
end
|
183
180
|
|
184
|
-
|
181
|
+
#: (String message, ?type: Integer) -> void
|
185
182
|
def send_log_message(message, type: Constant::MessageType::LOG)
|
186
183
|
send_message(Notification.window_log_message(message, type: Constant::MessageType::LOG))
|
187
184
|
end
|
@@ -5,40 +5,38 @@ module RubyLsp
|
|
5
5
|
# This class stores all client capabilities that the Ruby LSP and its add-ons depend on to ensure that we're
|
6
6
|
# not enabling functionality unsupported by the editor connecting to the server
|
7
7
|
class ClientCapabilities
|
8
|
-
|
9
|
-
|
10
|
-
sig { returns(T::Boolean) }
|
8
|
+
#: bool
|
11
9
|
attr_reader :supports_watching_files,
|
12
10
|
:supports_request_delegation,
|
13
11
|
:window_show_message_supports_extra_properties,
|
14
12
|
:supports_progress,
|
15
13
|
:supports_diagnostic_refresh
|
16
14
|
|
17
|
-
|
15
|
+
#: -> void
|
18
16
|
def initialize
|
19
17
|
# The editor supports watching files. This requires two capabilities: dynamic registration and relative pattern
|
20
18
|
# support
|
21
|
-
@supports_watching_files =
|
19
|
+
@supports_watching_files = false #: bool
|
22
20
|
|
23
21
|
# The editor supports request delegation. This is an experimental capability since request delegation has not been
|
24
22
|
# standardized into the LSP spec yet
|
25
|
-
@supports_request_delegation =
|
23
|
+
@supports_request_delegation = false #: bool
|
26
24
|
|
27
25
|
# The editor supports extra arbitrary properties for `window/showMessageRequest`. Necessary for add-ons to show
|
28
26
|
# dialogs with user interactions
|
29
|
-
@window_show_message_supports_extra_properties =
|
27
|
+
@window_show_message_supports_extra_properties = false #: bool
|
30
28
|
|
31
29
|
# Which resource operations the editor supports, like renaming files
|
32
|
-
@supported_resource_operations =
|
30
|
+
@supported_resource_operations = [] #: Array[String]
|
33
31
|
|
34
32
|
# The editor supports displaying progress requests
|
35
|
-
@supports_progress =
|
33
|
+
@supports_progress = false #: bool
|
36
34
|
|
37
35
|
# The editor supports server initiated refresh for diagnostics
|
38
|
-
@supports_diagnostic_refresh =
|
36
|
+
@supports_diagnostic_refresh = false #: bool
|
39
37
|
end
|
40
38
|
|
41
|
-
|
39
|
+
#: (Hash[Symbol, untyped] capabilities) -> void
|
42
40
|
def apply_client_capabilities(capabilities)
|
43
41
|
workspace_capabilities = capabilities[:workspace] || {}
|
44
42
|
|
@@ -65,7 +63,7 @@ module RubyLsp
|
|
65
63
|
@supports_diagnostic_refresh = workspace_capabilities.dig(:diagnostics, :refreshSupport) || false
|
66
64
|
end
|
67
65
|
|
68
|
-
|
66
|
+
#: -> bool
|
69
67
|
def supports_rename?
|
70
68
|
@supported_resource_operations.include?("rename")
|
71
69
|
end
|
data/lib/ruby_lsp/document.rb
CHANGED
@@ -21,47 +21,52 @@ module RubyLsp
|
|
21
21
|
# This maximum number of characters for providing expensive features, like semantic highlighting and diagnostics.
|
22
22
|
# This is the same number used by the TypeScript extension in VS Code
|
23
23
|
MAXIMUM_CHARACTERS_FOR_EXPENSIVE_FEATURES = 100_000
|
24
|
-
EMPTY_CACHE =
|
24
|
+
EMPTY_CACHE = Object.new.freeze #: Object
|
25
25
|
|
26
26
|
abstract!
|
27
27
|
|
28
|
-
|
28
|
+
#: ParseResultType
|
29
29
|
attr_reader :parse_result
|
30
30
|
|
31
|
-
|
31
|
+
#: String
|
32
32
|
attr_reader :source
|
33
33
|
|
34
|
-
|
34
|
+
#: Integer
|
35
35
|
attr_reader :version
|
36
36
|
|
37
|
-
|
37
|
+
#: URI::Generic
|
38
38
|
attr_reader :uri
|
39
39
|
|
40
|
-
|
40
|
+
#: Encoding
|
41
41
|
attr_reader :encoding
|
42
42
|
|
43
|
-
|
43
|
+
#: Edit?
|
44
44
|
attr_reader :last_edit
|
45
45
|
|
46
|
-
|
46
|
+
#: (Interface::SemanticTokens | Object)
|
47
47
|
attr_accessor :semantic_tokens
|
48
48
|
|
49
|
-
|
49
|
+
#: (source: String, version: Integer, uri: URI::Generic, global_state: GlobalState) -> void
|
50
50
|
def initialize(source:, version:, uri:, global_state:)
|
51
51
|
@source = source
|
52
52
|
@version = version
|
53
53
|
@global_state = global_state
|
54
|
-
@cache =
|
55
|
-
@semantic_tokens =
|
56
|
-
@encoding =
|
57
|
-
@uri =
|
58
|
-
@needs_parsing =
|
59
|
-
@
|
60
|
-
|
54
|
+
@cache = Hash.new(EMPTY_CACHE) #: Hash[String, untyped]
|
55
|
+
@semantic_tokens = EMPTY_CACHE #: (Interface::SemanticTokens | Object)
|
56
|
+
@encoding = global_state.encoding #: Encoding
|
57
|
+
@uri = uri #: URI::Generic
|
58
|
+
@needs_parsing = true #: bool
|
59
|
+
@last_edit = nil #: Edit?
|
60
|
+
|
61
|
+
# Workaround to be able to type parse_result properly. It is immediately set when invoking parse!
|
62
|
+
@parse_result = ( # rubocop:disable Style/RedundantParentheses
|
63
|
+
nil #: as untyped
|
64
|
+
) #: ParseResultType
|
65
|
+
|
61
66
|
parse!
|
62
67
|
end
|
63
68
|
|
64
|
-
|
69
|
+
#: (Document[untyped] other) -> bool
|
65
70
|
def ==(other)
|
66
71
|
self.class == other.class && uri == other.uri && @source == other.source
|
67
72
|
end
|
@@ -69,13 +74,7 @@ module RubyLsp
|
|
69
74
|
sig { abstract.returns(LanguageId) }
|
70
75
|
def language_id; end
|
71
76
|
|
72
|
-
|
73
|
-
type_parameters(:T)
|
74
|
-
.params(
|
75
|
-
request_name: String,
|
76
|
-
block: T.proc.params(document: Document[ParseResultType]).returns(T.type_parameter(:T)),
|
77
|
-
).returns(T.type_parameter(:T))
|
78
|
-
end
|
77
|
+
#: [T] (String request_name) { (Document[ParseResultType] document) -> T } -> T
|
79
78
|
def cache_fetch(request_name, &block)
|
80
79
|
cached = @cache[request_name]
|
81
80
|
return cached if cached != EMPTY_CACHE
|
@@ -85,17 +84,17 @@ module RubyLsp
|
|
85
84
|
result
|
86
85
|
end
|
87
86
|
|
88
|
-
|
87
|
+
#: [T] (String request_name, T value) -> T
|
89
88
|
def cache_set(request_name, value)
|
90
89
|
@cache[request_name] = value
|
91
90
|
end
|
92
91
|
|
93
|
-
|
92
|
+
#: (String request_name) -> untyped
|
94
93
|
def cache_get(request_name)
|
95
94
|
@cache[request_name]
|
96
95
|
end
|
97
96
|
|
98
|
-
|
97
|
+
#: (Array[Hash[Symbol, untyped]] edits, version: Integer) -> void
|
99
98
|
def push_edits(edits, version:)
|
100
99
|
edits.each do |edit|
|
101
100
|
range = edit[:range]
|
@@ -132,17 +131,12 @@ module RubyLsp
|
|
132
131
|
sig { abstract.returns(T::Boolean) }
|
133
132
|
def syntax_error?; end
|
134
133
|
|
135
|
-
|
134
|
+
#: -> bool
|
136
135
|
def past_expensive_limit?
|
137
136
|
@source.length > MAXIMUM_CHARACTERS_FOR_EXPENSIVE_FEATURES
|
138
137
|
end
|
139
138
|
|
140
|
-
|
141
|
-
params(
|
142
|
-
start_pos: T::Hash[Symbol, T.untyped],
|
143
|
-
end_pos: T.nilable(T::Hash[Symbol, T.untyped]),
|
144
|
-
).returns([Integer, T.nilable(Integer)])
|
145
|
-
end
|
139
|
+
#: (Hash[Symbol, untyped] start_pos, ?Hash[Symbol, untyped]? end_pos) -> [Integer, Integer?]
|
146
140
|
def find_index_by_position(start_pos, end_pos = nil)
|
147
141
|
@global_state.synchronize do
|
148
142
|
scanner = create_scanner
|
@@ -154,7 +148,7 @@ module RubyLsp
|
|
154
148
|
|
155
149
|
private
|
156
150
|
|
157
|
-
|
151
|
+
#: -> Scanner
|
158
152
|
def create_scanner
|
159
153
|
Scanner.new(@source, @encoding)
|
160
154
|
end
|
@@ -165,10 +159,10 @@ module RubyLsp
|
|
165
159
|
|
166
160
|
abstract!
|
167
161
|
|
168
|
-
|
162
|
+
#: Hash[Symbol, untyped]
|
169
163
|
attr_reader :range
|
170
164
|
|
171
|
-
|
165
|
+
#: (Hash[Symbol, untyped] range) -> void
|
172
166
|
def initialize(range)
|
173
167
|
@range = range
|
174
168
|
end
|
@@ -181,20 +175,20 @@ module RubyLsp
|
|
181
175
|
class Scanner
|
182
176
|
extend T::Sig
|
183
177
|
|
184
|
-
LINE_BREAK =
|
178
|
+
LINE_BREAK = 0x0A #: Integer
|
185
179
|
# After character 0xFFFF, UTF-16 considers characters to have length 2 and we have to account for that
|
186
|
-
SURROGATE_PAIR_START =
|
180
|
+
SURROGATE_PAIR_START = 0xFFFF #: Integer
|
187
181
|
|
188
|
-
|
182
|
+
#: (String source, Encoding encoding) -> void
|
189
183
|
def initialize(source, encoding)
|
190
|
-
@current_line =
|
191
|
-
@pos =
|
192
|
-
@source =
|
184
|
+
@current_line = 0 #: Integer
|
185
|
+
@pos = 0 #: Integer
|
186
|
+
@source = source.codepoints #: Array[Integer]
|
193
187
|
@encoding = encoding
|
194
188
|
end
|
195
189
|
|
196
190
|
# Finds the character index inside the source string for a given line and column
|
197
|
-
|
191
|
+
#: (Hash[Symbol, untyped] position) -> Integer
|
198
192
|
def find_char_position(position)
|
199
193
|
# Find the character index for the beginning of the requested line
|
200
194
|
until @current_line == position[:line]
|
@@ -224,7 +218,7 @@ module RubyLsp
|
|
224
218
|
|
225
219
|
# Subtract 1 for each character after 0xFFFF in the current line from the column position, so that we hit the
|
226
220
|
# right character in the UTF-8 representation
|
227
|
-
|
221
|
+
#: (Integer current_position, Integer requested_position) -> Integer
|
228
222
|
def utf_16_character_position_correction(current_position, requested_position)
|
229
223
|
utf16_unicode_correction = 0
|
230
224
|
|
@@ -3,35 +3,28 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
class ERBDocument < Document
|
6
|
-
extend T::Sig
|
7
6
|
extend T::Generic
|
8
7
|
|
9
8
|
ParseResultType = type_member { { fixed: Prism::ParseResult } }
|
10
9
|
|
11
|
-
|
10
|
+
#: String
|
12
11
|
attr_reader :host_language_source
|
13
12
|
|
14
|
-
|
15
|
-
returns(T.any(
|
16
|
-
T.proc.params(arg0: Integer).returns(Integer),
|
17
|
-
Prism::CodeUnitsCache,
|
18
|
-
))
|
19
|
-
end
|
13
|
+
#: (^(Integer arg0) -> Integer | Prism::CodeUnitsCache)
|
20
14
|
attr_reader :code_units_cache
|
21
15
|
|
22
|
-
|
16
|
+
#: (source: String, version: Integer, uri: URI::Generic, global_state: GlobalState) -> void
|
23
17
|
def initialize(source:, version:, uri:, global_state:)
|
24
18
|
# This has to be initialized before calling super because we call `parse` in the parent constructor, which
|
25
19
|
# overrides this with the proper virtual host language source
|
26
|
-
@host_language_source =
|
20
|
+
@host_language_source = "" #: String
|
27
21
|
super
|
28
|
-
@code_units_cache =
|
29
|
-
|
30
|
-
Prism::CodeUnitsCache,
|
31
|
-
))
|
22
|
+
@code_units_cache =
|
23
|
+
@parse_result.code_units_cache(@encoding) #: (^(Integer arg0) -> Integer | Prism::CodeUnitsCache)
|
32
24
|
end
|
33
25
|
|
34
|
-
|
26
|
+
# @override
|
27
|
+
#: -> bool
|
35
28
|
def parse!
|
36
29
|
return false unless @needs_parsing
|
37
30
|
|
@@ -46,22 +39,19 @@ module RubyLsp
|
|
46
39
|
true
|
47
40
|
end
|
48
41
|
|
49
|
-
|
42
|
+
# @override
|
43
|
+
#: -> bool
|
50
44
|
def syntax_error?
|
51
45
|
@parse_result.failure?
|
52
46
|
end
|
53
47
|
|
54
|
-
|
48
|
+
# @override
|
49
|
+
#: -> LanguageId
|
55
50
|
def language_id
|
56
51
|
LanguageId::ERB
|
57
52
|
end
|
58
53
|
|
59
|
-
|
60
|
-
params(
|
61
|
-
position: T::Hash[Symbol, T.untyped],
|
62
|
-
node_types: T::Array[T.class_of(Prism::Node)],
|
63
|
-
).returns(NodeContext)
|
64
|
-
end
|
54
|
+
#: (Hash[Symbol, untyped] position, ?node_types: Array[singleton(Prism::Node)]) -> NodeContext
|
65
55
|
def locate_node(position, node_types: [])
|
66
56
|
char_position, _ = find_index_by_position(position)
|
67
57
|
|
@@ -73,28 +63,26 @@ module RubyLsp
|
|
73
63
|
)
|
74
64
|
end
|
75
65
|
|
76
|
-
|
66
|
+
#: (Integer char_position) -> bool?
|
77
67
|
def inside_host_language?(char_position)
|
78
68
|
char = @host_language_source[char_position]
|
79
69
|
char && char != " "
|
80
70
|
end
|
81
71
|
|
82
72
|
class ERBScanner
|
83
|
-
|
84
|
-
|
85
|
-
sig { returns(String) }
|
73
|
+
#: String
|
86
74
|
attr_reader :ruby, :host_language
|
87
75
|
|
88
|
-
|
76
|
+
#: (String source) -> void
|
89
77
|
def initialize(source)
|
90
78
|
@source = source
|
91
|
-
@host_language =
|
92
|
-
@ruby =
|
93
|
-
@current_pos =
|
94
|
-
@inside_ruby =
|
79
|
+
@host_language = +"" #: String
|
80
|
+
@ruby = +"" #: String
|
81
|
+
@current_pos = 0 #: Integer
|
82
|
+
@inside_ruby = false #: bool
|
95
83
|
end
|
96
84
|
|
97
|
-
|
85
|
+
#: -> void
|
98
86
|
def scan
|
99
87
|
while @current_pos < @source.length
|
100
88
|
scan_char
|
@@ -104,7 +92,7 @@ module RubyLsp
|
|
104
92
|
|
105
93
|
private
|
106
94
|
|
107
|
-
|
95
|
+
#: -> void
|
108
96
|
def scan_char
|
109
97
|
char = @source[@current_pos]
|
110
98
|
|
@@ -123,7 +111,9 @@ module RubyLsp
|
|
123
111
|
push_char(" ")
|
124
112
|
end
|
125
113
|
else
|
126
|
-
push_char(
|
114
|
+
push_char(
|
115
|
+
char, #: as !nil
|
116
|
+
)
|
127
117
|
end
|
128
118
|
when "-"
|
129
119
|
if @inside_ruby && next_char == "%" &&
|
@@ -132,7 +122,9 @@ module RubyLsp
|
|
132
122
|
push_char(" ")
|
133
123
|
@inside_ruby = false
|
134
124
|
else
|
135
|
-
push_char(
|
125
|
+
push_char(
|
126
|
+
char, #: as !nil
|
127
|
+
)
|
136
128
|
end
|
137
129
|
when "%"
|
138
130
|
if @inside_ruby && next_char == ">"
|
@@ -140,7 +132,9 @@ module RubyLsp
|
|
140
132
|
@current_pos += 1
|
141
133
|
push_char(" ")
|
142
134
|
else
|
143
|
-
push_char(
|
135
|
+
push_char(
|
136
|
+
char, #: as !nil
|
137
|
+
)
|
144
138
|
end
|
145
139
|
when "\r"
|
146
140
|
@ruby << char
|
@@ -155,11 +149,13 @@ module RubyLsp
|
|
155
149
|
@ruby << char
|
156
150
|
@host_language << char
|
157
151
|
else
|
158
|
-
push_char(
|
152
|
+
push_char(
|
153
|
+
char, #: as !nil
|
154
|
+
)
|
159
155
|
end
|
160
156
|
end
|
161
157
|
|
162
|
-
|
158
|
+
#: (String char) -> void
|
163
159
|
def push_char(char)
|
164
160
|
if @inside_ruby
|
165
161
|
@ruby << char
|
@@ -170,7 +166,7 @@ module RubyLsp
|
|
170
166
|
end
|
171
167
|
end
|
172
168
|
|
173
|
-
|
169
|
+
#: -> String
|
174
170
|
def next_char
|
175
171
|
@source[@current_pos + 1] || ""
|
176
172
|
end
|