class TypeProf::LSP::Server

Attributes

core[R]
open_texts[R]
signature_enabled[RW]

Public Class Methods

new(core, reader, writer, url_schema: nil, publish_all_diagnostics: false) click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 47
def initialize(core, reader, writer, url_schema: nil, publish_all_diagnostics: false)
  @core = core
  @workspaces = {}
  @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:///")
  @publish_all_diagnostics = publish_all_diagnostics # TODO: implement more dedicated publish feature
end
start_socket(core) click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 21
def self.start_socket(core)
  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(core, reader, writer).run
      ensure
        sock.close
      end
      exit
    end
  end
end
start_stdio(core) click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 11
def self.start_stdio(core)
  $stdin.binmode
  $stdout.binmode
  reader = Reader.new($stdin)
  writer = Writer.new($stdout)
  # pipe all builtin print output to stderr to avoid conflicting with lsp
  $stdout = $stderr
  new(core, reader, writer).run
end

Public Instance Methods

add_workspaces(folders) click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 73
def add_workspaces(folders)
  folders.each do |path|
    conf_path = File.join(path, "typeprof.conf.json")
    if File.readable?(conf_path)
      conf = TypeProf::LSP.load_json_with_comments(conf_path, symbolize_names: true)
      if conf
        if conf[:typeprof_version] == "experimental"
          if conf[:analysis_unit_dirs].size >= 2
             puts "currently analysis_unit_dirs can have only one directory"
          end
          conf[:analysis_unit_dirs].each do |dir|
            dir = File.expand_path(dir, path)
            @workspaces[dir] = true
            @core.add_workspace(dir, conf[:rbs_dir])
          end
        else
          puts "Unknown typeprof_version: #{ conf[:typeprof_version] }"
        end
      end
    else
      puts "typeprof.conf.json is not found"
    end
  end
end
cancel_request(id) click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 141
def cancel_request(id)
  req = @running_requests_from_client[id]
  req.cancel if req.respond_to?(:cancel)
end
exit() click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 146
def exit
  @exit = true
end
path_to_uri(path) click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 65
def path_to_uri(path)
  @url_schema + File.expand_path(path)
end
publish_diagnostics(uri) click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 150
def publish_diagnostics(uri)
  (@publish_all_diagnostics ? @open_texts : [[uri, @open_texts[uri]]]).each do |uri, text|
    diags = []
    if text
      @core.diagnostics(text.path) do |diag|
        diags << diag.to_lsp
      end
    end
    send_notification(
      "textDocument/publishDiagnostics",
      uri: uri,
      diagnostics: diags
    )
  end
end
run() click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 105
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) click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 131
def send_notification(method, **params)
  @writer.write(method: method, params: params)
end
send_request(method, **params, &blk) click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 135
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) click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 126
def send_response(**msg)
  @running_requests_from_client.delete(msg[:id])
  @writer.write(**msg)
end
target_path?(path) click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 98
def target_path?(path)
  @workspaces.each do |folder, _|
    return true if path.start_with?(folder)
  end
  return false
end
uri_to_path(url) click to toggle source
# File typeprof-0.30.1/lib/typeprof/lsp/server.rb, line 69
def uri_to_path(url)
  url.delete_prefix(@url_schema)
end