ruby-lsp 0.23.10 → 0.23.14
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 +12 -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 +81 -115
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +117 -166
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +9 -7
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +89 -201
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +63 -192
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +14 -16
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +22 -45
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +42 -60
- 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/classes_and_modules_test.rb +75 -0
- data/lib/ruby_indexer/test/configuration_test.rb +42 -3
- data/lib/ruby_indexer/test/index_test.rb +21 -0
- data/lib/ruby_indexer/test/method_test.rb +28 -2
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +1 -1
- 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 +31 -33
- data/lib/ruby_lsp/client_capabilities.rb +10 -12
- data/lib/ruby_lsp/document.rb +34 -45
- data/lib/ruby_lsp/erb_document.rb +24 -36
- data/lib/ruby_lsp/global_state.rb +51 -56
- data/lib/ruby_lsp/internal.rb +6 -0
- data/lib/ruby_lsp/listeners/code_lens.rb +81 -88
- data/lib/ruby_lsp/listeners/completion.rb +36 -55
- data/lib/ruby_lsp/listeners/definition.rb +37 -51
- data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
- data/lib/ruby_lsp/listeners/document_link.rb +43 -62
- data/lib/ruby_lsp/listeners/document_symbol.rb +35 -49
- data/lib/ruby_lsp/listeners/folding_ranges.rb +32 -39
- data/lib/ruby_lsp/listeners/hover.rb +81 -100
- data/lib/ruby_lsp/listeners/inlay_hints.rb +4 -11
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +42 -51
- data/lib/ruby_lsp/listeners/signature_help.rb +6 -25
- 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 +236 -0
- 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 +10 -10
- 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 +5 -5
- 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 +75 -0
- 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 +8 -18
- data/lib/ruby_lsp/requests/inlay_hints.rb +6 -17
- data/lib/ruby_lsp/requests/on_type_formatting.rb +28 -38
- data/lib/ruby_lsp/requests/prepare_rename.rb +4 -9
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +4 -13
- data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
- data/lib/ruby_lsp/requests/references.rb +6 -36
- data/lib/ruby_lsp/requests/rename.rb +11 -37
- data/lib/ruby_lsp/requests/request.rb +7 -19
- data/lib/ruby_lsp/requests/selection_ranges.rb +5 -5
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +12 -31
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +5 -6
- 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 +13 -48
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +9 -12
- 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 +16 -30
- data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
- data/lib/ruby_lsp/requests/support/test_item.rb +55 -0
- 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 +10 -16
- data/lib/ruby_lsp/response_builders/hover.rb +10 -13
- data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +59 -87
- data/lib/ruby_lsp/response_builders/signature_help.rb +5 -6
- data/lib/ruby_lsp/response_builders/test_collection.rb +34 -0
- data/lib/ruby_lsp/ruby_document.rb +22 -60
- data/lib/ruby_lsp/ruby_lsp_reporter_plugin.rb +109 -0
- data/lib/ruby_lsp/scope.rb +7 -11
- data/lib/ruby_lsp/server.rb +177 -72
- data/lib/ruby_lsp/setup_bundler.rb +61 -59
- data/lib/ruby_lsp/static_docs.rb +4 -7
- data/lib/ruby_lsp/store.rb +21 -40
- data/lib/ruby_lsp/test_helper.rb +2 -12
- data/lib/ruby_lsp/test_reporter.rb +207 -0
- data/lib/ruby_lsp/test_unit_test_runner.rb +98 -0
- data/lib/ruby_lsp/type_inferrer.rb +9 -13
- data/lib/ruby_lsp/utils.rb +37 -81
- metadata +13 -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]
|
|
@@ -90,7 +87,8 @@ module RubyLsp
|
|
|
90
87
|
# The following requests need to be executed in the main thread directly to avoid concurrency issues. Everything
|
|
91
88
|
# else is pushed into the incoming queue
|
|
92
89
|
case method
|
|
93
|
-
when "initialize", "initialized", "textDocument/didOpen", "textDocument/didClose", "textDocument/didChange"
|
|
90
|
+
when "initialize", "initialized", "textDocument/didOpen", "textDocument/didClose", "textDocument/didChange",
|
|
91
|
+
"rubyLsp/diagnoseState"
|
|
94
92
|
process_message(message)
|
|
95
93
|
when "shutdown"
|
|
96
94
|
@global_state.synchronize do
|
|
@@ -107,7 +105,7 @@ module RubyLsp
|
|
|
107
105
|
end
|
|
108
106
|
end
|
|
109
107
|
|
|
110
|
-
|
|
108
|
+
#: -> void
|
|
111
109
|
def run_shutdown
|
|
112
110
|
@incoming_queue.clear
|
|
113
111
|
@outgoing_queue.clear
|
|
@@ -121,13 +119,13 @@ module RubyLsp
|
|
|
121
119
|
end
|
|
122
120
|
|
|
123
121
|
# This method is only intended to be used in tests! Pops the latest response that would be sent to the client
|
|
124
|
-
|
|
122
|
+
#: -> untyped
|
|
125
123
|
def pop_response
|
|
126
124
|
@outgoing_queue.pop
|
|
127
125
|
end
|
|
128
126
|
|
|
129
127
|
# This method is only intended to be used in tests! Pushes a message to the incoming queue directly
|
|
130
|
-
|
|
128
|
+
#: (Hash[Symbol, untyped] message) -> void
|
|
131
129
|
def push_message(message)
|
|
132
130
|
@incoming_queue << message
|
|
133
131
|
end
|
|
@@ -138,16 +136,16 @@ module RubyLsp
|
|
|
138
136
|
sig { abstract.void }
|
|
139
137
|
def shutdown; end
|
|
140
138
|
|
|
141
|
-
|
|
139
|
+
#: (Integer id, String message, ?type: Integer) -> void
|
|
142
140
|
def fail_request_and_notify(id, message, type: Constant::MessageType::INFO)
|
|
143
141
|
send_message(Error.new(id: id, code: Constant::ErrorCodes::REQUEST_FAILED, message: message))
|
|
144
142
|
send_message(Notification.window_show_message(message, type: type))
|
|
145
143
|
end
|
|
146
144
|
|
|
147
|
-
|
|
145
|
+
#: -> Thread
|
|
148
146
|
def new_worker
|
|
149
147
|
Thread.new do
|
|
150
|
-
while (message =
|
|
148
|
+
while (message = @incoming_queue.pop)
|
|
151
149
|
id = message[:id]
|
|
152
150
|
|
|
153
151
|
# Check if the request was cancelled before trying to process it
|
|
@@ -164,7 +162,7 @@ module RubyLsp
|
|
|
164
162
|
end
|
|
165
163
|
end
|
|
166
164
|
|
|
167
|
-
|
|
165
|
+
#: ((Result | Error | Notification | Request) message) -> void
|
|
168
166
|
def send_message(message)
|
|
169
167
|
# When we're shutting down the server, there's a small race condition between closing the thread queues and
|
|
170
168
|
# finishing remaining requests. We may close the queue in the middle of processing a request, which will then fail
|
|
@@ -175,12 +173,12 @@ module RubyLsp
|
|
|
175
173
|
@current_request_id += 1 if message.is_a?(Request)
|
|
176
174
|
end
|
|
177
175
|
|
|
178
|
-
|
|
176
|
+
#: (Integer id) -> void
|
|
179
177
|
def send_empty_response(id)
|
|
180
178
|
send_message(Result.new(id: id, response: nil))
|
|
181
179
|
end
|
|
182
180
|
|
|
183
|
-
|
|
181
|
+
#: (String message, ?type: Integer) -> void
|
|
184
182
|
def send_log_message(message, type: Constant::MessageType::LOG)
|
|
185
183
|
send_message(Notification.window_log_message(message, type: Constant::MessageType::LOG))
|
|
186
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,47 @@ 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
|
-
@parse_result = T.
|
|
60
|
-
@last_edit =
|
|
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
|
+
@parse_result = T.unsafe(nil) #: ParseResultType
|
|
60
|
+
@last_edit = nil #: Edit?
|
|
61
61
|
parse!
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
#: (Document[untyped] other) -> bool
|
|
65
65
|
def ==(other)
|
|
66
66
|
self.class == other.class && uri == other.uri && @source == other.source
|
|
67
67
|
end
|
|
@@ -69,13 +69,7 @@ module RubyLsp
|
|
|
69
69
|
sig { abstract.returns(LanguageId) }
|
|
70
70
|
def language_id; end
|
|
71
71
|
|
|
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
|
|
72
|
+
#: [T] (String request_name) { (Document[ParseResultType] document) -> T } -> T
|
|
79
73
|
def cache_fetch(request_name, &block)
|
|
80
74
|
cached = @cache[request_name]
|
|
81
75
|
return cached if cached != EMPTY_CACHE
|
|
@@ -85,17 +79,17 @@ module RubyLsp
|
|
|
85
79
|
result
|
|
86
80
|
end
|
|
87
81
|
|
|
88
|
-
|
|
82
|
+
#: [T] (String request_name, T value) -> T
|
|
89
83
|
def cache_set(request_name, value)
|
|
90
84
|
@cache[request_name] = value
|
|
91
85
|
end
|
|
92
86
|
|
|
93
|
-
|
|
87
|
+
#: (String request_name) -> untyped
|
|
94
88
|
def cache_get(request_name)
|
|
95
89
|
@cache[request_name]
|
|
96
90
|
end
|
|
97
91
|
|
|
98
|
-
|
|
92
|
+
#: (Array[Hash[Symbol, untyped]] edits, version: Integer) -> void
|
|
99
93
|
def push_edits(edits, version:)
|
|
100
94
|
edits.each do |edit|
|
|
101
95
|
range = edit[:range]
|
|
@@ -132,17 +126,12 @@ module RubyLsp
|
|
|
132
126
|
sig { abstract.returns(T::Boolean) }
|
|
133
127
|
def syntax_error?; end
|
|
134
128
|
|
|
135
|
-
|
|
129
|
+
#: -> bool
|
|
136
130
|
def past_expensive_limit?
|
|
137
131
|
@source.length > MAXIMUM_CHARACTERS_FOR_EXPENSIVE_FEATURES
|
|
138
132
|
end
|
|
139
133
|
|
|
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
|
|
134
|
+
#: (Hash[Symbol, untyped] start_pos, ?Hash[Symbol, untyped]? end_pos) -> [Integer, Integer?]
|
|
146
135
|
def find_index_by_position(start_pos, end_pos = nil)
|
|
147
136
|
@global_state.synchronize do
|
|
148
137
|
scanner = create_scanner
|
|
@@ -154,7 +143,7 @@ module RubyLsp
|
|
|
154
143
|
|
|
155
144
|
private
|
|
156
145
|
|
|
157
|
-
|
|
146
|
+
#: -> Scanner
|
|
158
147
|
def create_scanner
|
|
159
148
|
Scanner.new(@source, @encoding)
|
|
160
149
|
end
|
|
@@ -165,10 +154,10 @@ module RubyLsp
|
|
|
165
154
|
|
|
166
155
|
abstract!
|
|
167
156
|
|
|
168
|
-
|
|
157
|
+
#: Hash[Symbol, untyped]
|
|
169
158
|
attr_reader :range
|
|
170
159
|
|
|
171
|
-
|
|
160
|
+
#: (Hash[Symbol, untyped] range) -> void
|
|
172
161
|
def initialize(range)
|
|
173
162
|
@range = range
|
|
174
163
|
end
|
|
@@ -181,20 +170,20 @@ module RubyLsp
|
|
|
181
170
|
class Scanner
|
|
182
171
|
extend T::Sig
|
|
183
172
|
|
|
184
|
-
LINE_BREAK =
|
|
173
|
+
LINE_BREAK = 0x0A #: Integer
|
|
185
174
|
# After character 0xFFFF, UTF-16 considers characters to have length 2 and we have to account for that
|
|
186
|
-
SURROGATE_PAIR_START =
|
|
175
|
+
SURROGATE_PAIR_START = 0xFFFF #: Integer
|
|
187
176
|
|
|
188
|
-
|
|
177
|
+
#: (String source, Encoding encoding) -> void
|
|
189
178
|
def initialize(source, encoding)
|
|
190
|
-
@current_line =
|
|
191
|
-
@pos =
|
|
192
|
-
@source =
|
|
179
|
+
@current_line = 0 #: Integer
|
|
180
|
+
@pos = 0 #: Integer
|
|
181
|
+
@source = source.codepoints #: Array[Integer]
|
|
193
182
|
@encoding = encoding
|
|
194
183
|
end
|
|
195
184
|
|
|
196
185
|
# Finds the character index inside the source string for a given line and column
|
|
197
|
-
|
|
186
|
+
#: (Hash[Symbol, untyped] position) -> Integer
|
|
198
187
|
def find_char_position(position)
|
|
199
188
|
# Find the character index for the beginning of the requested line
|
|
200
189
|
until @current_line == position[:line]
|
|
@@ -224,7 +213,7 @@ module RubyLsp
|
|
|
224
213
|
|
|
225
214
|
# Subtract 1 for each character after 0xFFFF in the current line from the column position, so that we hit the
|
|
226
215
|
# right character in the UTF-8 representation
|
|
227
|
-
|
|
216
|
+
#: (Integer current_position, Integer requested_position) -> Integer
|
|
228
217
|
def utf_16_character_position_correction(current_position, requested_position)
|
|
229
218
|
utf16_unicode_correction = 0
|
|
230
219
|
|
|
@@ -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
|
|
|
@@ -159,7 +147,7 @@ module RubyLsp
|
|
|
159
147
|
end
|
|
160
148
|
end
|
|
161
149
|
|
|
162
|
-
|
|
150
|
+
#: (String char) -> void
|
|
163
151
|
def push_char(char)
|
|
164
152
|
if @inside_ruby
|
|
165
153
|
@ruby << char
|
|
@@ -170,7 +158,7 @@ module RubyLsp
|
|
|
170
158
|
end
|
|
171
159
|
end
|
|
172
160
|
|
|
173
|
-
|
|
161
|
+
#: -> String
|
|
174
162
|
def next_char
|
|
175
163
|
@source[@current_pos + 1] || ""
|
|
176
164
|
end
|