Class: TypeProf::LSP::Server
| Relationships & Source Files | |
| Inherits: | Object |
| Defined in: | lib/typeprof/lsp/server.rb |
Class Method Summary
Instance Attribute Summary
- #open_texts readonly
- #signature_enabled rw
Instance Method Summary
-
#add_workspaces(folders)
: (Array) -> void.
- #aggregate_each_core(path)
- #cancel_request(id)
- #code_lens(path, &blk)
- #completion(path, trigger, pos, &blk)
- #definitions(path, pos)
- #each_core(path)
- #exit
- #hover(path, pos)
-
#path_to_uri(path)
: (String) -> String.
- #publish_updated_diagnostics
- #references(path, pos)
- #rename(path, pos)
- #run
- #send_notification(method, **params)
- #send_request(method, **params, &blk)
- #send_response(**msg)
-
#target_path?(path) ⇒ Boolean
: (String) -> bool.
- #type_definitions(path, pos)
- #update_file(path, text)
- #uri_to_path(uri)
Constructor Details
.new(core_options, reader, writer, url_schema: nil) ⇒ Server
# File 'lib/typeprof/lsp/server.rb', line 50
def initialize(, reader, writer, url_schema: nil) @core_options = @cores = {} @reader = reader @writer = writer @request_id = 0 @running_requests_from_client = {} @running_requests_from_server = {} @open_texts = {} @exit = false @signature_enabled = true @url_schema = url_schema || (File::ALT_SEPARATOR != "\\" ? "file://" : "file:///") @diagnostic_severity = :error end
Class Method Details
.start_socket(core_options)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 24
def self.start_socket() Socket.tcp_server_sockets("localhost", nil) do |servs| serv = servs[0].local_address $stdout << JSON.generate({ host: serv.ip_address, port: serv.ip_port, pid: $$, }) $stdout.flush $stdout = $stderr Socket.accept_loop(servs) do |sock| sock.set_encoding("UTF-8") begin reader = Reader.new(sock) writer = Writer.new(sock) new(, reader, writer).run ensure sock.close end exit end end end
.start_stdio(core_options)
[ GitHub ]Instance Attribute Details
#open_texts (readonly)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 65
attr_reader :open_texts
#signature_enabled (rw)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 66
attr_accessor :signature_enabled
Instance Method Details
#add_workspaces(folders)
: (Array) -> void
# File 'lib/typeprof/lsp/server.rb', line 78
def add_workspaces(folders) folders.each do |path| conf_path = [".json", ".jsonc"].map do |ext| File.join(path, "typeprof.conf" + ext) end.find do |path| File.readable?(path) end unless conf_path puts "typeprof.conf.json is not found in #{ path }" next end conf = TypeProf::LSP.load_json_with_comments(conf_path, symbolize_names: true) if conf if conf[:rbs_dir] rbs_dir = File.(conf[:rbs_dir]) else rbs_dir = File.(File.("sig", path)) end @rbs_dir = rbs_dir if conf[:typeprof_version] == "experimental" if conf[:diagnostic_severity] severity = conf[:diagnostic_severity].to_sym case severity when :error, :warning, :info, :hint @diagnostic_severity = severity else puts "unknown severity: #{ severity }" end end conf[:analysis_unit_dirs].each do |dir| dir = File.(dir, path) core = @cores[dir] = TypeProf::Core::Service.new(@core_options) core.add_workspace(dir, @rbs_dir) end else puts "Unknown typeprof_version: #{ conf[:typeprof_version] }" end end end end
#aggregate_each_core(path)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 136
def aggregate_each_core(path) ret = [] each_core(path) do |core| r = yield(core) ret.concat(r) if r end ret end
#cancel_request(id)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 231
def cancel_request(id) req = @running_requests_from_client[id] req.cancel if req.respond_to?(:cancel) end
#code_lens(path, &blk)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 177
def code_lens(path, &blk) each_core(path) do |core| core.code_lens(path, &blk) end end
#completion(path, trigger, pos, &blk)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 183
def completion(path, trigger, pos, &blk) each_core(path) do |core| core.completion(path, trigger, pos, &blk) end end
#definitions(path, pos)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 151
def definitions(path, pos) aggregate_each_core(path) do |core| core.definitions(path, pos) end end
#each_core(path)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 128
def each_core(path) @cores.each do |folder, core| if path.start_with?(folder) || @rbs_dir && path.start_with?(@rbs_dir) yield core end end end
#exit
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 236
def exit @exit = true end
#hover(path, pos)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 169
def hover(path, pos) ret = [] each_core(path) do |core| ret << core.hover(path, pos) end ret.compact.first # TODO end
#path_to_uri(path)
: (String) -> String
# File 'lib/typeprof/lsp/server.rb', line 69
def path_to_uri(path) @url_schema + File.(path).split("/").map {|s| CGI.escapeURIComponent(s) }.join("/") end
#publish_updated_diagnostics
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 240
def publish_updated_diagnostics @cores.each do |_, core| diags = [] core.process_diagnostic_paths do |path| uri = path_to_uri(path) next false unless @open_texts[uri] core.diagnostics(path) do |diag| diags << diag.to_lsp(severity: @diagnostic_severity) end send_notification( "textDocument/publishDiagnostics", uri: uri, diagnostics: diags ) true end end end
#references(path, pos)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 163
def references(path, pos) aggregate_each_core(path) do |core| core.references(path, pos) end end
#rename(path, pos)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 189
def rename(path, pos) aggregate_each_core(path) do |core| core.rename(path, pos) end end
#run
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 195
def run @reader.read do |json| if json[:method] # request or notification msg_class = Message.find(json[:method]) if msg_class msg = msg_class.new(self, json) @running_requests_from_client[json[:id]] = msg if json[:id] msg.run else end else # response callback = @running_requests_from_server.delete(json[:id]) callback&.call(json[:params], json[:error]) end break if @exit end end
#send_notification(method, **params)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 221
def send_notification(method, **params) @writer.write(method: method, params: params) end
#send_request(method, **params, &blk)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 225
def send_request(method, **params, &blk) id = @request_id += 1 @running_requests_from_server[id] = blk @writer.write(id: id, method: method, params: params) end
#send_response(**msg)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 216
def send_response(**msg) @running_requests_from_client.delete(msg[:id]) @writer.write(**msg) end
#target_path?(path) ⇒ Boolean
: (String) -> bool
# File 'lib/typeprof/lsp/server.rb', line 120
def target_path?(path) return true if @rbs_dir && path.start_with?(@rbs_dir) @cores.each do |folder, _| return true if path.start_with?(folder) end return false end
#type_definitions(path, pos)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 157
def type_definitions(path, pos) aggregate_each_core(path) do |core| core.type_definitions(path, pos) end end
#update_file(path, text)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 145
def update_file(path, text) each_core(path) do |core| core.update_file(path, text) end end
#uri_to_path(uri)
[ GitHub ]# File 'lib/typeprof/lsp/server.rb', line 73
def uri_to_path(uri) uri.delete_prefix(@url_schema).split("/").map {|s| CGI.unescapeURIComponent(s) }.join("/") end