From 72a3722470e5297c72dcaccaf2f113e7b758606d Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Fri, 30 Aug 2019 17:24:11 +0300
Subject: move lsp-server to a separate repository

---
 crates/gen_lsp_server/Cargo.toml                   |  18 --
 .../gen_lsp_server/examples/01_gen_lsp_server.rs   |  47 -----
 .../examples/02_gen_lsp_server_with_logging.rs     | 120 ------------
 crates/gen_lsp_server/src/lib.rs                   | 136 --------------
 crates/gen_lsp_server/src/msg.rs                   | 205 ---------------------
 crates/gen_lsp_server/src/stdio.rs                 |  57 ------
 6 files changed, 583 deletions(-)
 delete mode 100644 crates/gen_lsp_server/Cargo.toml
 delete mode 100644 crates/gen_lsp_server/examples/01_gen_lsp_server.rs
 delete mode 100644 crates/gen_lsp_server/examples/02_gen_lsp_server_with_logging.rs
 delete mode 100644 crates/gen_lsp_server/src/lib.rs
 delete mode 100644 crates/gen_lsp_server/src/msg.rs
 delete mode 100644 crates/gen_lsp_server/src/stdio.rs

(limited to 'crates/gen_lsp_server')

diff --git a/crates/gen_lsp_server/Cargo.toml b/crates/gen_lsp_server/Cargo.toml
deleted file mode 100644
index 7011aa1bf..000000000
--- a/crates/gen_lsp_server/Cargo.toml
+++ /dev/null
@@ -1,18 +0,0 @@
-[package]
-edition = "2018"
-name = "gen_lsp_server"
-version = "0.2.0"
-authors = ["rust-analyzer developers"]
-repository = "https://github.com/rust-analyzer/rust-analyzer"
-license = "MIT OR Apache-2.0"
-description = "Generic LSP server scaffold."
-
-[dependencies]
-lsp-types = "0.60.0"
-log = "0.4.3"
-serde_json = "1.0.34"
-serde = { version = "1.0.83", features = ["derive"] }
-crossbeam-channel = "0.3.5"
-
-[dev-dependencies]
-flexi_logger = "0.14.0"
diff --git a/crates/gen_lsp_server/examples/01_gen_lsp_server.rs b/crates/gen_lsp_server/examples/01_gen_lsp_server.rs
deleted file mode 100644
index f49965064..000000000
--- a/crates/gen_lsp_server/examples/01_gen_lsp_server.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-use std::error::Error;
-
-use crossbeam_channel::{Receiver, Sender};
-use gen_lsp_server::{handle_shutdown, run_server, stdio_transport, RawMessage, RawResponse};
-use lsp_types::{
-    request::{GotoDefinition, GotoDefinitionResponse},
-    InitializeParams, ServerCapabilities,
-};
-
-fn main() -> Result<(), Box<dyn Error + Sync + Send>> {
-    let (receiver, sender, io_threads) = stdio_transport();
-    run_server(ServerCapabilities::default(), receiver, sender, main_loop)?;
-    io_threads.join()?;
-    Ok(())
-}
-
-fn main_loop(
-    _params: InitializeParams,
-    receiver: &Receiver<RawMessage>,
-    sender: &Sender<RawMessage>,
-) -> Result<(), Box<dyn Error + Sync + Send>> {
-    for msg in receiver {
-        match msg {
-            RawMessage::Request(req) => {
-                let req = match handle_shutdown(req, sender) {
-                    None => return Ok(()),
-                    Some(req) => req,
-                };
-                match req.cast::<GotoDefinition>() {
-                    Ok((id, _params)) => {
-                        let resp = RawResponse::ok::<GotoDefinition>(
-                            id,
-                            &Some(GotoDefinitionResponse::Array(Vec::new())),
-                        );
-                        sender.send(RawMessage::Response(resp))?;
-                        continue;
-                    }
-                    Err(req) => req,
-                };
-                // ...
-            }
-            RawMessage::Response(_resp) => (),
-            RawMessage::Notification(_not) => (),
-        }
-    }
-    Ok(())
-}
diff --git a/crates/gen_lsp_server/examples/02_gen_lsp_server_with_logging.rs b/crates/gen_lsp_server/examples/02_gen_lsp_server_with_logging.rs
deleted file mode 100644
index 3c48106c5..000000000
--- a/crates/gen_lsp_server/examples/02_gen_lsp_server_with_logging.rs
+++ /dev/null
@@ -1,120 +0,0 @@
-//! A minimal example LSP server that can only respond to the `gotoDefinition` request. To use
-//! this example, execute it and then send an `initialize` request.
-//!
-//! ```no_run
-//! Content-Length: 85
-//!
-//! {"jsonrpc": "2.0", "method": "initialize", "id": 1, "params": {"capabilities": {}}}
-//! ```
-//!
-//! This will respond with a server respose. Then send it a `initialized` notification which will
-//! have no response.
-//!
-//! ```no_run
-//! Content-Length: 59
-//!
-//! {"jsonrpc": "2.0", "method": "initialized", "params": {}}
-//! ```
-//!
-//! Once these two are sent, then we enter the main loop of the server. The only request this
-//! example can handle is `gotoDefinition`:
-//!
-//! ```no_run
-//! Content-Length: 159
-//!
-//! {"jsonrpc": "2.0", "method": "textDocument/definition", "id": 2, "params": {"textDocument": {"uri": "file://temp"}, "position": {"line": 1, "character": 1}}}
-//! ```
-//!
-//! To finish up without errors, send a shutdown request:
-//!
-//! ```no_run
-//! Content-Length: 67
-//!
-//! {"jsonrpc": "2.0", "method": "shutdown", "id": 3, "params": null}
-//! ```
-//!
-//! The server will exit the main loop and finally we send a `shutdown` notification to stop
-//! the server.
-//!
-//! ```
-//! Content-Length: 54
-//!
-//! {"jsonrpc": "2.0", "method": "exit", "params": null}
-//! ```
-
-use std::error::Error;
-
-use crossbeam_channel::{Receiver, Sender};
-use gen_lsp_server::{
-    handle_shutdown, run_server, stdio_transport, RawMessage, RawRequest, RawResponse,
-};
-use log::info;
-use lsp_types::{
-    request::{GotoDefinition, GotoDefinitionResponse},
-    InitializeParams, ServerCapabilities,
-};
-
-fn main() -> Result<(), Box<dyn Error + Sync + Send>> {
-    // Set up logging. Because `stdio_transport` gets a lock on stdout and stdin, we must have
-    // our logging only write out to stderr.
-    flexi_logger::Logger::with_str("info").start().unwrap();
-    info!("starting generic LSP server");
-
-    // Create the transport. Includes the stdio (stdin and stdout) versions but this could
-    // also be implemented to use sockets or HTTP.
-    let (receiver, sender, io_threads) = stdio_transport();
-
-    // Run the server and wait for the two threads to end (typically by trigger LSP Exit event).
-    run_server(ServerCapabilities::default(), receiver, sender, main_loop)?;
-    io_threads.join()?;
-
-    // Shut down gracefully.
-    info!("shutting down server");
-    Ok(())
-}
-
-fn main_loop(
-    _params: InitializeParams,
-    receiver: &Receiver<RawMessage>,
-    sender: &Sender<RawMessage>,
-) -> Result<(), Box<dyn Error + Sync + Send>> {
-    info!("starting example main loop");
-    for msg in receiver {
-        info!("got msg: {:?}", msg);
-        match msg {
-            RawMessage::Request(req) => {
-                let req = match log_handle_shutdown(req, sender) {
-                    None => return Ok(()),
-                    Some(req) => req,
-                };
-                info!("got request: {:?}", req);
-                match req.cast::<GotoDefinition>() {
-                    Ok((id, params)) => {
-                        info!("got gotoDefinition request #{}: {:?}", id, params);
-                        let resp = RawResponse::ok::<GotoDefinition>(
-                            id,
-                            &Some(GotoDefinitionResponse::Array(Vec::new())),
-                        );
-                        info!("sending gotoDefinition response: {:?}", resp);
-                        sender.send(RawMessage::Response(resp))?;
-                        continue;
-                    }
-                    Err(req) => req,
-                };
-                // ...
-            }
-            RawMessage::Response(resp) => {
-                info!("got response: {:?}", resp);
-            }
-            RawMessage::Notification(not) => {
-                info!("got notification: {:?}", not);
-            }
-        }
-    }
-    Ok(())
-}
-
-pub fn log_handle_shutdown(req: RawRequest, sender: &Sender<RawMessage>) -> Option<RawRequest> {
-    info!("handle_shutdown: {:?}", req);
-    handle_shutdown(req, sender)
-}
diff --git a/crates/gen_lsp_server/src/lib.rs b/crates/gen_lsp_server/src/lib.rs
deleted file mode 100644
index 0984e3e25..000000000
--- a/crates/gen_lsp_server/src/lib.rs
+++ /dev/null
@@ -1,136 +0,0 @@
-//! A language server scaffold, exposing a synchronous crossbeam-channel based API.
-//! This crate handles protocol handshaking and parsing messages, while you
-//! control the message dispatch loop yourself.
-//!
-//! Run with `RUST_LOG=gen_lsp_server=debug` to see all the messages.
-//!
-//! ```no_run
-//! use std::error::Error;
-//! use crossbeam_channel::{Sender, Receiver};
-//! use lsp_types::{ServerCapabilities, InitializeParams, request::{GotoDefinition, GotoDefinitionResponse}};
-//! use gen_lsp_server::{run_server, stdio_transport, handle_shutdown, RawMessage, RawResponse};
-//!
-//! fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
-//!     let (receiver, sender, io_threads) = stdio_transport();
-//!     run_server(
-//!         ServerCapabilities::default(),
-//!         receiver,
-//!         sender,
-//!         main_loop,
-//!     )?;
-//!     io_threads.join()?;
-//!     Ok(())
-//! }
-//!
-//! fn main_loop(
-//!     _params: InitializeParams,
-//!     receiver: &Receiver<RawMessage>,
-//!     sender: &Sender<RawMessage>,
-//! ) -> Result<(), Box<dyn Error + Send + Sync>> {
-//!     for msg in receiver {
-//!         match msg {
-//!             RawMessage::Request(req) => {
-//!                 let req = match handle_shutdown(req, sender) {
-//!                     None => return Ok(()),
-//!                     Some(req) => req,
-//!                 };
-//!                 match req.cast::<GotoDefinition>() {
-//!                     Ok((id, _params)) => {
-//!                         let resp = RawResponse::ok::<GotoDefinition>(
-//!                             id,
-//!                             &Some(GotoDefinitionResponse::Array(Vec::new())),
-//!                         );
-//!                         sender.send(RawMessage::Response(resp))?;
-//!                         continue;
-//!                     },
-//!                     Err(req) => req,
-//!                 };
-//!                 // ...
-//!             }
-//!             RawMessage::Response(_resp) => (),
-//!             RawMessage::Notification(_not) => (),
-//!         }
-//!     }
-//!     Ok(())
-//! }
-//! ```
-
-use std::error::Error;
-
-mod msg;
-mod stdio;
-
-use crossbeam_channel::{Receiver, Sender};
-use lsp_types::{
-    notification::{Exit, Initialized},
-    request::{Initialize, Shutdown},
-    InitializeParams, InitializeResult, ServerCapabilities,
-};
-
-pub type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
-pub use crate::{
-    msg::{ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, RawResponseError},
-    stdio::{stdio_transport, Threads},
-};
-
-/// Main entry point: runs the server from initialization to shutdown.
-/// To attach server to standard input/output streams, use the `stdio_transport`
-/// function to create corresponding `sender` and `receiver` pair.
-///
-/// `server` should use the `handle_shutdown` function to handle the `Shutdown`
-/// request.
-pub fn run_server(
-    caps: ServerCapabilities,
-    receiver: Receiver<RawMessage>,
-    sender: Sender<RawMessage>,
-    server: impl FnOnce(InitializeParams, &Receiver<RawMessage>, &Sender<RawMessage>) -> Result<()>,
-) -> Result<()> {
-    log::info!("lsp server initializes");
-    let params = initialize(&receiver, &sender, caps)?;
-    log::info!("lsp server initialized, serving requests");
-    server(params, &receiver, &sender)?;
-    log::info!("lsp server waiting for exit notification");
-    match receiver.recv() {
-        Ok(RawMessage::Notification(n)) => n
-            .cast::<Exit>()
-            .map_err(|n| format!("unexpected notification during shutdown: {:?}", n))?,
-        m => Err(format!("unexpected message during shutdown: {:?}", m))?,
-    }
-    log::info!("lsp server shutdown complete");
-    Ok(())
-}
-
-/// If `req` is `Shutdown`, respond to it and return `None`, otherwise return `Some(req)`
-pub fn handle_shutdown(req: RawRequest, sender: &Sender<RawMessage>) -> Option<RawRequest> {
-    match req.cast::<Shutdown>() {
-        Ok((id, ())) => {
-            let resp = RawResponse::ok::<Shutdown>(id, &());
-            let _ = sender.send(RawMessage::Response(resp));
-            None
-        }
-        Err(req) => Some(req),
-    }
-}
-
-fn initialize(
-    receiver: &Receiver<RawMessage>,
-    sender: &Sender<RawMessage>,
-    caps: ServerCapabilities,
-) -> Result<InitializeParams> {
-    let (id, params) = match receiver.recv() {
-        Ok(RawMessage::Request(req)) => match req.cast::<Initialize>() {
-            Err(req) => Err(format!("expected initialize request, got {:?}", req))?,
-            Ok(req) => req,
-        },
-        msg => Err(format!("expected initialize request, got {:?}", msg))?,
-    };
-    let resp = RawResponse::ok::<Initialize>(id, &InitializeResult { capabilities: caps });
-    sender.send(RawMessage::Response(resp)).unwrap();
-    match receiver.recv() {
-        Ok(RawMessage::Notification(n)) => {
-            n.cast::<Initialized>().map_err(|_| "expected initialized notification")?;
-        }
-        _ => Err("expected initialized notification".to_string())?,
-    }
-    Ok(params)
-}
diff --git a/crates/gen_lsp_server/src/msg.rs b/crates/gen_lsp_server/src/msg.rs
deleted file mode 100644
index 2928e4f8b..000000000
--- a/crates/gen_lsp_server/src/msg.rs
+++ /dev/null
@@ -1,205 +0,0 @@
-use std::io::{BufRead, Write};
-
-use lsp_types::{notification::Notification, request::Request};
-use serde::{Deserialize, Serialize};
-use serde_json::{from_str, from_value, to_string, to_value, Value};
-
-use crate::Result;
-
-#[derive(Serialize, Deserialize, Debug, Clone)]
-#[serde(untagged)]
-pub enum RawMessage {
-    Request(RawRequest),
-    Notification(RawNotification),
-    Response(RawResponse),
-}
-
-impl From<RawRequest> for RawMessage {
-    fn from(raw: RawRequest) -> RawMessage {
-        RawMessage::Request(raw)
-    }
-}
-
-impl From<RawNotification> for RawMessage {
-    fn from(raw: RawNotification) -> RawMessage {
-        RawMessage::Notification(raw)
-    }
-}
-
-impl From<RawResponse> for RawMessage {
-    fn from(raw: RawResponse) -> RawMessage {
-        RawMessage::Response(raw)
-    }
-}
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct RawRequest {
-    pub id: u64,
-    pub method: String,
-    pub params: Value,
-}
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct RawResponse {
-    // JSON RPC allows this to be null if it was impossible
-    // to decode the request's id. Ignore this special case
-    // and just die horribly.
-    pub id: u64,
-    #[serde(skip_serializing_if = "Option::is_none")]
-    pub result: Option<Value>,
-    #[serde(skip_serializing_if = "Option::is_none")]
-    pub error: Option<RawResponseError>,
-}
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct RawResponseError {
-    pub code: i32,
-    pub message: String,
-    #[serde(skip_serializing_if = "Option::is_none")]
-    pub data: Option<Value>,
-}
-
-#[derive(Clone, Copy, Debug)]
-#[allow(unused)]
-pub enum ErrorCode {
-    ParseError = -32700,
-    InvalidRequest = -32600,
-    MethodNotFound = -32601,
-    InvalidParams = -32602,
-    InternalError = -32603,
-    ServerErrorStart = -32099,
-    ServerErrorEnd = -32000,
-    ServerNotInitialized = -32002,
-    UnknownErrorCode = -32001,
-    RequestCanceled = -32800,
-    ContentModified = -32801,
-}
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct RawNotification {
-    pub method: String,
-    pub params: Value,
-}
-
-impl RawMessage {
-    pub fn read(r: &mut impl BufRead) -> Result<Option<RawMessage>> {
-        let text = match read_msg_text(r)? {
-            None => return Ok(None),
-            Some(text) => text,
-        };
-        let msg = from_str(&text)?;
-        Ok(Some(msg))
-    }
-    pub fn write(self, w: &mut impl Write) -> Result<()> {
-        #[derive(Serialize)]
-        struct JsonRpc {
-            jsonrpc: &'static str,
-            #[serde(flatten)]
-            msg: RawMessage,
-        }
-        let text = to_string(&JsonRpc { jsonrpc: "2.0", msg: self })?;
-        write_msg_text(w, &text)?;
-        Ok(())
-    }
-}
-
-impl RawRequest {
-    pub fn new<R>(id: u64, params: &R::Params) -> RawRequest
-    where
-        R: Request,
-        R::Params: serde::Serialize,
-    {
-        RawRequest { id, method: R::METHOD.to_string(), params: to_value(params).unwrap() }
-    }
-    pub fn cast<R>(self) -> ::std::result::Result<(u64, R::Params), RawRequest>
-    where
-        R: Request,
-        R::Params: serde::de::DeserializeOwned,
-    {
-        if self.method != R::METHOD {
-            return Err(self);
-        }
-        let id = self.id;
-        let params: R::Params = from_value(self.params).unwrap();
-        Ok((id, params))
-    }
-}
-
-impl RawResponse {
-    pub fn ok<R>(id: u64, result: &R::Result) -> RawResponse
-    where
-        R: Request,
-        R::Result: serde::Serialize,
-    {
-        RawResponse { id, result: Some(to_value(&result).unwrap()), error: None }
-    }
-    pub fn err(id: u64, code: i32, message: String) -> RawResponse {
-        let error = RawResponseError { code, message, data: None };
-        RawResponse { id, result: None, error: Some(error) }
-    }
-}
-
-impl RawNotification {
-    pub fn new<N>(params: &N::Params) -> RawNotification
-    where
-        N: Notification,
-        N::Params: serde::Serialize,
-    {
-        RawNotification { method: N::METHOD.to_string(), params: to_value(params).unwrap() }
-    }
-    pub fn is<N>(&self) -> bool
-    where
-        N: Notification,
-    {
-        self.method == N::METHOD
-    }
-    pub fn cast<N>(self) -> ::std::result::Result<N::Params, RawNotification>
-    where
-        N: Notification,
-        N::Params: serde::de::DeserializeOwned,
-    {
-        if !self.is::<N>() {
-            return Err(self);
-        }
-        Ok(from_value(self.params).unwrap())
-    }
-}
-
-fn read_msg_text(inp: &mut impl BufRead) -> Result<Option<String>> {
-    let mut size = None;
-    let mut buf = String::new();
-    loop {
-        buf.clear();
-        if inp.read_line(&mut buf)? == 0 {
-            return Ok(None);
-        }
-        if !buf.ends_with("\r\n") {
-            Err(format!("malformed header: {:?}", buf))?;
-        }
-        let buf = &buf[..buf.len() - 2];
-        if buf.is_empty() {
-            break;
-        }
-        let mut parts = buf.splitn(2, ": ");
-        let header_name = parts.next().unwrap();
-        let header_value = parts.next().ok_or_else(|| format!("malformed header: {:?}", buf))?;
-        if header_name == "Content-Length" {
-            size = Some(header_value.parse::<usize>()?);
-        }
-    }
-    let size = size.ok_or("no Content-Length")?;
-    let mut buf = buf.into_bytes();
-    buf.resize(size, 0);
-    inp.read_exact(&mut buf)?;
-    let buf = String::from_utf8(buf)?;
-    log::debug!("< {}", buf);
-    Ok(Some(buf))
-}
-
-fn write_msg_text(out: &mut impl Write, msg: &str) -> Result<()> {
-    log::debug!("> {}", msg);
-    write!(out, "Content-Length: {}\r\n\r\n", msg.len())?;
-    out.write_all(msg.as_bytes())?;
-    out.flush()?;
-    Ok(())
-}
diff --git a/crates/gen_lsp_server/src/stdio.rs b/crates/gen_lsp_server/src/stdio.rs
deleted file mode 100644
index f8931f2dc..000000000
--- a/crates/gen_lsp_server/src/stdio.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-use std::{
-    io::{stdin, stdout},
-    thread,
-};
-
-use crossbeam_channel::{bounded, Receiver, Sender};
-use lsp_types::notification::Exit;
-
-use crate::{RawMessage, Result};
-
-pub fn stdio_transport() -> (Receiver<RawMessage>, Sender<RawMessage>, Threads) {
-    let (writer_sender, writer_receiver) = bounded::<RawMessage>(16);
-    let writer = thread::spawn(move || {
-        let stdout = stdout();
-        let mut stdout = stdout.lock();
-        writer_receiver.into_iter().try_for_each(|it| it.write(&mut stdout))?;
-        Ok(())
-    });
-    let (reader_sender, reader_receiver) = bounded::<RawMessage>(16);
-    let reader = thread::spawn(move || {
-        let stdin = stdin();
-        let mut stdin = stdin.lock();
-        while let Some(msg) = RawMessage::read(&mut stdin)? {
-            let is_exit = match &msg {
-                RawMessage::Notification(n) => n.is::<Exit>(),
-                _ => false,
-            };
-
-            reader_sender.send(msg).unwrap();
-
-            if is_exit {
-                break;
-            }
-        }
-        Ok(())
-    });
-    let threads = Threads { reader, writer };
-    (reader_receiver, writer_sender, threads)
-}
-
-pub struct Threads {
-    reader: thread::JoinHandle<Result<()>>,
-    writer: thread::JoinHandle<Result<()>>,
-}
-
-impl Threads {
-    pub fn join(self) -> Result<()> {
-        match self.reader.join() {
-            Ok(r) => r?,
-            Err(_) => Err("reader panicked")?,
-        }
-        match self.writer.join() {
-            Ok(r) => r,
-            Err(_) => Err("writer panicked")?,
-        }
-    }
-}
-- 
cgit v1.2.3