Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(language server): removed async code and switched to lsp_server #295

Merged
merged 2 commits into from Jan 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 5 additions & 5 deletions crates/mun_language_server/Cargo.toml
Expand Up @@ -16,26 +16,26 @@ categories = ["game-development", "mun"]

[dependencies]
rustc-hash="1.1.0"
lsp-types = "0.74"
lsp-types = "0.86.0"
lsp-server = "0.5.0"
log = "0.4"
serde = "1.0"
serde_json = "1.0"
serde_derive = "1.0"
async-std = "1.6"
futures = "0.3"
anyhow = "1.0"
thiserror = "1.0"
salsa = "0.15.0"
hir = { version = "=0.2.0", path="../mun_hir", package="mun_hir" }
rayon = "1.3"
num_cpus = "1.13.0"
threadpool="1.8.1"
vfs = { path = "../mun_vfs", package="mun_vfs" }
project = { path = "../mun_project", package="mun_project" }
mun_target = { version = "=0.2.0", path = "../mun_target" }
mun_syntax = { version = "=0.2.0", path = "../mun_syntax" }
mun_diagnostics = { version = "=0.1.0", path = "../mun_diagnostics" }
crossbeam-channel = "0.5.0"
parking_lot="0.11.1"
paths = {path="../mun_paths", package="mun_paths"}

[dev-dependencies]
tempdir = "0.3.7"
mun_test = { path = "../mun_test"}
5 changes: 5 additions & 0 deletions crates/mun_language_server/src/analysis.rs
Expand Up @@ -37,6 +37,11 @@ impl Analysis {
db: self.db.snapshot(),
}
}

/// Requests any outstanding snapshot to cancel computations.
pub fn request_cancelation(&mut self) {
self.db.request_cancelation();
}
}

/// The `AnalysisSnapshot` is a snapshot of the state of the source, it enables querying for
Expand Down
7 changes: 7 additions & 0 deletions crates/mun_language_server/src/cancelation.rs
@@ -1,3 +1,5 @@
use std::error::Error;

/// An error signifying a cancelled operation.
pub struct Canceled {
// This is here so that you cannot construct a Canceled
Expand Down Expand Up @@ -29,3 +31,8 @@ impl std::fmt::Debug for Canceled {
}

impl std::error::Error for Canceled {}

/// Returns true if the specified error is of type [`Canceled`]
pub(crate) fn is_canceled(e: &(dyn Error + 'static)) -> bool {
e.downcast_ref::<Canceled>().is_some()
}
2 changes: 1 addition & 1 deletion crates/mun_language_server/src/config.rs
@@ -1,5 +1,5 @@
use crate::project_manifest::ProjectManifest;
use paths::AbsPathBuf;
use project::ProjectManifest;

/// The configuration used by the language server.
#[derive(Debug, Clone)]
Expand Down
4 changes: 2 additions & 2 deletions crates/mun_language_server/src/conversion.rs
Expand Up @@ -63,8 +63,8 @@ pub fn convert_unit(
) -> lsp_types::Position {
let line_col = line_index.line_col(range);
lsp_types::Position {
line: line_col.line.into(),
character: line_col.col.into(),
line: line_col.line,
character: line_col.col,
}
}

Expand Down
7 changes: 6 additions & 1 deletion crates/mun_language_server/src/db.rs
Expand Up @@ -3,7 +3,7 @@
use crate::cancelation::Canceled;
use hir::{HirDatabase, Upcast};
use mun_target::spec::Target;
use salsa::{Database, Snapshot};
use salsa::{Database, Durability, Snapshot};
use std::panic;

/// The `AnalysisDatabase` provides the database for all analyses. A database is given input and
Expand Down Expand Up @@ -38,6 +38,11 @@ impl AnalysisDatabase {

db
}

/// Triggers a simple write on the database which will cancell all outstanding snapshots.
pub fn request_cancelation(&mut self) {
self.salsa_runtime_mut().synthetic_write(Durability::LOW);
}
}

impl salsa::Database for AnalysisDatabase {
Expand Down
49 changes: 22 additions & 27 deletions crates/mun_language_server/src/lib.rs
@@ -1,3 +1,13 @@
use std::convert::TryFrom;

use serde::{de::DeserializeOwned, Serialize};

pub use config::{Config, FilesWatcher};
pub use main_loop::main_loop;
use paths::AbsPathBuf;
use project::ProjectManifest;
pub(crate) use state::LanguageServerState;

mod analysis;
mod cancelation;
mod capabilities;
Expand All @@ -7,40 +17,31 @@ mod conversion;
mod db;
mod diagnostics;
mod main_loop;
mod project_manifest;
pub mod protocol;
mod workspace;

pub use config::Config;
pub use main_loop::main_loop;

use crate::{config::FilesWatcher, project_manifest::ProjectManifest};
use paths::AbsPathBuf;
use serde::{de::DeserializeOwned, Serialize};
use std::convert::TryFrom;

pub type Result<T> = anyhow::Result<T>;
mod state;

/// Deserializes a `T` from a json value.
pub fn from_json<T: DeserializeOwned>(what: &'static str, json: serde_json::Value) -> Result<T> {
pub fn from_json<T: DeserializeOwned>(
what: &'static str,
json: serde_json::Value,
) -> anyhow::Result<T> {
T::deserialize(&json)
.map_err(|e| anyhow::anyhow!("could not deserialize {}: {}: {}", what, e, json))
}

/// Converts the `T` to a json value
pub fn to_json<T: Serialize>(value: T) -> Result<serde_json::Value> {
pub fn to_json<T: Serialize>(value: T) -> anyhow::Result<serde_json::Value> {
serde_json::to_value(value).map_err(|e| anyhow::anyhow!("could not serialize to json: {}", e))
}

/// Main entry point for the language server
pub async fn run_server_async() -> Result<()> {
pub fn run_server() -> anyhow::Result<()> {
log::info!("language server started");

// Setup IO connections
let mut connection = protocol::Connection::stdio();
let (connection, io_threads) = lsp_server::Connection::stdio();

// Wait for a client to connect
let (initialize_id, initialize_params) = connection.initialize_start().await?;
let (initialize_id, initialize_params) = connection.initialize_start()?;

let initialize_params =
from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?;
Expand All @@ -57,9 +58,7 @@ pub async fn run_server_async() -> Result<()> {

let initialize_result = serde_json::to_value(initialize_result).unwrap();

connection
.initialize_finish(initialize_id, initialize_result)
.await?;
connection.initialize_finish(initialize_id, initialize_result)?;

if let Some(client_info) = initialize_params.client_info {
log::info!(
Expand Down Expand Up @@ -122,12 +121,8 @@ pub async fn run_server_async() -> Result<()> {
config
};

main_loop(connection, config).await?;
main_loop(connection, config)?;

io_threads.join()?;
Ok(())
}

/// Main entry point for the language server
pub fn run_server() -> Result<()> {
async_std::task::block_on(run_server_async())
}