ruby-lsp 0.3.8 → 0.4.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.
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.3.8
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-16 00:00:00.000000000 Z
11
+ date: 2023-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: language_server-protocol
@@ -44,20 +44,20 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 5.0.0
47
+ version: '6'
48
48
  - - "<"
49
49
  - !ruby/object:Gem::Version
50
- version: '6'
50
+ version: '7'
51
51
  type: :runtime
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
55
  - - ">="
56
56
  - !ruby/object:Gem::Version
57
- version: 5.0.0
57
+ version: '6'
58
58
  - - "<"
59
59
  - !ruby/object:Gem::Version
60
- version: '6'
60
+ version: '7'
61
61
  description: An opinionated language server for Ruby
62
62
  email:
63
63
  - ruby@shopify.com
@@ -72,11 +72,11 @@ files:
72
72
  - exe/ruby-lsp
73
73
  - lib/ruby-lsp.rb
74
74
  - lib/ruby_lsp/document.rb
75
- - lib/ruby_lsp/handler.rb
75
+ - lib/ruby_lsp/executor.rb
76
76
  - lib/ruby_lsp/internal.rb
77
- - lib/ruby_lsp/queue.rb
78
77
  - lib/ruby_lsp/requests.rb
79
78
  - lib/ruby_lsp/requests/base_request.rb
79
+ - lib/ruby_lsp/requests/code_action_resolve.rb
80
80
  - lib/ruby_lsp/requests/code_actions.rb
81
81
  - lib/ruby_lsp/requests/diagnostics.rb
82
82
  - lib/ruby_lsp/requests/document_highlight.rb
@@ -87,9 +87,12 @@ files:
87
87
  - lib/ruby_lsp/requests/hover.rb
88
88
  - lib/ruby_lsp/requests/inlay_hints.rb
89
89
  - lib/ruby_lsp/requests/on_type_formatting.rb
90
+ - lib/ruby_lsp/requests/path_completion.rb
90
91
  - lib/ruby_lsp/requests/selection_ranges.rb
91
92
  - lib/ruby_lsp/requests/semantic_highlighting.rb
93
+ - lib/ruby_lsp/requests/support/annotation.rb
92
94
  - lib/ruby_lsp/requests/support/highlight_target.rb
95
+ - lib/ruby_lsp/requests/support/prefix_tree.rb
93
96
  - lib/ruby_lsp/requests/support/rails_document_client.rb
94
97
  - lib/ruby_lsp/requests/support/rubocop_diagnostic.rb
95
98
  - lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb
@@ -97,10 +100,11 @@ files:
97
100
  - lib/ruby_lsp/requests/support/rubocop_runner.rb
98
101
  - lib/ruby_lsp/requests/support/selection_range.rb
99
102
  - lib/ruby_lsp/requests/support/semantic_token_encoder.rb
103
+ - lib/ruby_lsp/requests/support/sorbet.rb
100
104
  - lib/ruby_lsp/requests/support/source_uri.rb
101
- - lib/ruby_lsp/requests/support/syntax_error_diagnostic.rb
102
105
  - lib/ruby_lsp/server.rb
103
106
  - lib/ruby_lsp/store.rb
107
+ - lib/ruby_lsp/utils.rb
104
108
  homepage: https://github.com/Shopify/ruby-lsp
105
109
  licenses:
106
110
  - MIT
@@ -1,118 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "ruby_lsp/requests"
5
- require "ruby_lsp/store"
6
- require "ruby_lsp/queue"
7
-
8
- module RubyLsp
9
- Interface = LanguageServer::Protocol::Interface
10
- Constant = LanguageServer::Protocol::Constant
11
- Transport = LanguageServer::Protocol::Transport
12
-
13
- class Handler
14
- extend T::Sig
15
- VOID = T.let(Object.new.freeze, Object)
16
-
17
- class RequestHandler < T::Struct
18
- extend T::Sig
19
-
20
- const :action, T.proc.params(request: T::Hash[Symbol, T.untyped]).returns(T.untyped)
21
- const :parallel, T::Boolean
22
- prop :error_handler,
23
- T.nilable(T.proc.params(error: Exception, request: T::Hash[Symbol, T.untyped]).void)
24
-
25
- # A proc that runs in case a request has errored. Receives the error and the original request as arguments. Useful
26
- # for displaying window messages on errors
27
- sig do
28
- params(
29
- block: T.proc.bind(Handler).params(error: Exception, request: T::Hash[Symbol, T.untyped]).void,
30
- ).void
31
- end
32
- def on_error(&block)
33
- self.error_handler = block
34
- end
35
- end
36
-
37
- class << self
38
- extend T::Sig
39
-
40
- sig { params(blk: T.proc.bind(Handler).params(arg0: T.untyped).void).void }
41
- def start(&blk)
42
- handler = new
43
- handler.instance_exec(&blk)
44
- handler.start
45
- end
46
- end
47
-
48
- sig { returns(Store) }
49
- attr_reader :store
50
-
51
- sig { void }
52
- def initialize
53
- @writer = T.let(Transport::Stdio::Writer.new, Transport::Stdio::Writer)
54
- @reader = T.let(Transport::Stdio::Reader.new, Transport::Stdio::Reader)
55
- @handlers = T.let({}, T::Hash[String, RequestHandler])
56
- @store = T.let(Store.new, Store)
57
- @queue = T.let(Queue.new(@writer, @handlers), Queue)
58
- end
59
-
60
- sig { void }
61
- def start
62
- warn("Starting Ruby LSP...")
63
-
64
- @reader.read do |request|
65
- handler = @handlers[request[:method]]
66
- next if handler.nil?
67
-
68
- if handler.parallel
69
- @queue.push(request)
70
- else
71
- result = @queue.execute(request)
72
- @queue.finalize_request(result, request)
73
- end
74
- end
75
- end
76
-
77
- private
78
-
79
- sig { params(id: T.any(String, Integer)).void }
80
- def cancel_request(id)
81
- @queue.cancel(id)
82
- end
83
-
84
- sig do
85
- params(
86
- msg: String,
87
- parallel: T::Boolean,
88
- blk: T.proc.bind(Handler).params(request: T::Hash[Symbol, T.untyped]).returns(T.untyped),
89
- ).returns(RequestHandler)
90
- end
91
- def on(msg, parallel: false, &blk)
92
- @handlers[msg] = RequestHandler.new(action: blk, parallel: parallel)
93
- end
94
-
95
- sig { void }
96
- def shutdown
97
- warn("Shutting down Ruby LSP...")
98
- @queue.shutdown
99
- store.clear
100
- end
101
-
102
- sig { params(uri: String).void }
103
- def clear_diagnostics(uri)
104
- @writer.write(
105
- method: "textDocument/publishDiagnostics",
106
- params: Interface::PublishDiagnosticsParams.new(uri: uri, diagnostics: []),
107
- )
108
- end
109
-
110
- sig { params(type: Integer, message: String).void }
111
- def show_message(type, message)
112
- @writer.write(
113
- method: "window/showMessage",
114
- params: Interface::ShowMessageParams.new(type: type, message: message),
115
- )
116
- end
117
- end
118
- end
@@ -1,182 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "benchmark"
5
-
6
- module RubyLsp
7
- class Queue
8
- extend T::Sig
9
-
10
- class Result < T::Struct
11
- const :response, T.untyped # rubocop:disable Sorbet/ForbidUntypedStructProps
12
- const :error, T.nilable(Exception)
13
- const :request_time, T.nilable(Float)
14
- end
15
-
16
- class Job < T::Struct
17
- extend T::Sig
18
-
19
- const :request, T::Hash[Symbol, T.untyped]
20
- prop :cancelled, T::Boolean
21
-
22
- sig { void }
23
- def cancel
24
- self.cancelled = true
25
- end
26
- end
27
-
28
- sig do
29
- params(
30
- writer: LanguageServer::Protocol::Transport::Stdio::Writer,
31
- handlers: T::Hash[String, Handler::RequestHandler],
32
- ).void
33
- end
34
- def initialize(writer, handlers)
35
- @writer = writer
36
- @handlers = handlers
37
- # The job queue is the actual list of requests we have to process
38
- @job_queue = T.let(Thread::Queue.new, Thread::Queue)
39
- # The jobs hash is just a way of keeping a handle to jobs based on the request ID, so we can cancel them
40
- @jobs = T.let({}, T::Hash[T.any(String, Integer), Job])
41
- @mutex = T.let(Mutex.new, Mutex)
42
- @worker = T.let(new_worker, Thread)
43
-
44
- Thread.main.priority = 1
45
- end
46
-
47
- sig { params(request: T::Hash[Symbol, T.untyped]).void }
48
- def push(request)
49
- job = Job.new(request: request, cancelled: false)
50
-
51
- # Remember a handle to the job, so that we can cancel it
52
- @mutex.synchronize do
53
- @jobs[request[:id]] = job
54
- end
55
-
56
- @job_queue << job
57
- end
58
-
59
- sig { params(id: T.any(String, Integer)).void }
60
- def cancel(id)
61
- @mutex.synchronize do
62
- # Cancel the job if it's still in the queue
63
- @jobs[id]&.cancel
64
- end
65
- end
66
-
67
- sig { void }
68
- def shutdown
69
- # Close the queue so that we can no longer receive items
70
- @job_queue.close
71
- # Clear any remaining jobs so that the thread can terminate
72
- @job_queue.clear
73
- # Wait until the thread is finished
74
- @worker.join
75
- end
76
-
77
- # Executes a request and returns a Queue::Result. No IO should happen in this method, because it can be cancelled in
78
- # the middle with a raise
79
- sig { params(request: T::Hash[Symbol, T.untyped]).returns(Queue::Result) }
80
- def execute(request)
81
- response = T.let(nil, T.untyped)
82
- error = T.let(nil, T.nilable(Exception))
83
-
84
- request_time = Benchmark.realtime do
85
- response = T.must(@handlers[request[:method]]).action.call(request)
86
- rescue StandardError, LoadError => e
87
- error = e
88
- end
89
-
90
- Queue::Result.new(response: response, error: error, request_time: request_time)
91
- end
92
-
93
- # Finalize a Queue::Result. All IO operations should happen here to avoid any issues with cancelling requests
94
- sig do
95
- params(
96
- result: Result,
97
- request: T::Hash[Symbol, T.untyped],
98
- ).void
99
- end
100
- def finalize_request(result, request)
101
- @mutex.synchronize do
102
- error = result.error
103
- if error
104
- T.must(@handlers[request[:method]]).error_handler&.call(error, request)
105
-
106
- @writer.write(
107
- id: request[:id],
108
- error: {
109
- code: LanguageServer::Protocol::Constant::ErrorCodes::INTERNAL_ERROR,
110
- message: error.inspect,
111
- data: request.to_json,
112
- },
113
- )
114
- elsif result.response != Handler::VOID
115
- @writer.write(id: request[:id], result: result.response)
116
- end
117
-
118
- request_time = result.request_time
119
- if request_time
120
- @writer.write(method: "telemetry/event", params: telemetry_params(request, request_time, error))
121
- end
122
- end
123
- end
124
-
125
- private
126
-
127
- sig { returns(Thread) }
128
- def new_worker
129
- Thread.new do
130
- # Thread::Queue#pop is thread safe and will wait until an item is available
131
- loop do
132
- job = T.let(@job_queue.pop, T.nilable(Job))
133
- # The only time when the job is nil is when the queue is closed and we can then terminate the thread
134
- break if job.nil?
135
-
136
- request = job.request
137
- @mutex.synchronize { @jobs.delete(request[:id]) }
138
-
139
- result = if job.cancelled
140
- # We need to return nil to the client even if the request was cancelled
141
- Queue::Result.new(response: nil, error: nil, request_time: nil)
142
- else
143
- execute(request)
144
- end
145
-
146
- finalize_request(result, request)
147
- end
148
- end
149
- end
150
-
151
- sig do
152
- params(
153
- request: T::Hash[Symbol, T.untyped],
154
- request_time: Float,
155
- error: T.nilable(Exception),
156
- ).returns(T::Hash[Symbol, T.any(String, Float)])
157
- end
158
- def telemetry_params(request, request_time, error)
159
- uri = request.dig(:params, :textDocument, :uri)
160
-
161
- params = {
162
- request: request[:method],
163
- lspVersion: RubyLsp::VERSION,
164
- requestTime: request_time,
165
- }
166
-
167
- if error
168
- params[:errorClass] = error.class.name
169
- params[:errorMessage] = error.message
170
-
171
- log_params = request[:params]&.reject { |k, _| k == :textDocument }
172
- params[:params] = log_params.to_json if log_params&.any?
173
-
174
- backtrace = error.backtrace
175
- params[:backtrace] = backtrace.map { |bt| bt.sub(/^#{Dir.home}/, "~") }.join("\n") if backtrace
176
- end
177
-
178
- params[:uri] = uri.sub(%r{.*://#{Dir.home}}, "~") if uri
179
- params
180
- end
181
- end
182
- end
@@ -1,32 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module RubyLsp
5
- module Requests
6
- module Support
7
- class SyntaxErrorDiagnostic
8
- extend T::Sig
9
-
10
- sig { params(edit: Document::EditShape).void }
11
- def initialize(edit)
12
- @edit = edit
13
- end
14
-
15
- sig { returns(FalseClass) }
16
- def correctable?
17
- false
18
- end
19
-
20
- sig { returns(LanguageServer::Protocol::Interface::Diagnostic) }
21
- def to_lsp_diagnostic
22
- LanguageServer::Protocol::Interface::Diagnostic.new(
23
- message: "Syntax error",
24
- source: "SyntaxTree",
25
- severity: LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR,
26
- range: @edit[:range],
27
- )
28
- end
29
- end
30
- end
31
- end
32
- end