Skip to content

Commit

Permalink
fix(els): eliminate unwraps
Browse files Browse the repository at this point in the history
  • Loading branch information
mtshiba committed Feb 5, 2024
1 parent 2a24941 commit 30f615f
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 59 deletions.
61 changes: 31 additions & 30 deletions crates/els/channels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,33 +136,27 @@ impl SendChannels {
}

pub(crate) fn close(&self) {
self.completion.send(WorkerMessage::Kill).unwrap();
self.resolve_completion.send(WorkerMessage::Kill).unwrap();
self.goto_definition.send(WorkerMessage::Kill).unwrap();
self.semantic_tokens_full.send(WorkerMessage::Kill).unwrap();
self.inlay_hint.send(WorkerMessage::Kill).unwrap();
self.inlay_hint_resolve.send(WorkerMessage::Kill).unwrap();
self.hover.send(WorkerMessage::Kill).unwrap();
self.references.send(WorkerMessage::Kill).unwrap();
self.code_lens.send(WorkerMessage::Kill).unwrap();
self.code_action.send(WorkerMessage::Kill).unwrap();
self.code_action_resolve.send(WorkerMessage::Kill).unwrap();
self.signature_help.send(WorkerMessage::Kill).unwrap();
self.will_rename_files.send(WorkerMessage::Kill).unwrap();
self.execute_command.send(WorkerMessage::Kill).unwrap();
self.workspace_symbol.send(WorkerMessage::Kill).unwrap();
self.document_symbol.send(WorkerMessage::Kill).unwrap();
self.call_hierarchy_prepare
.send(WorkerMessage::Kill)
.unwrap();
self.call_hierarchy_incoming
.send(WorkerMessage::Kill)
.unwrap();
self.call_hierarchy_outgoing
.send(WorkerMessage::Kill)
.unwrap();
self.folding_range.send(WorkerMessage::Kill).unwrap();
self.health_check.send(WorkerMessage::Kill).unwrap();
let _ = self.completion.send(WorkerMessage::Kill);
let _ = self.resolve_completion.send(WorkerMessage::Kill);
let _ = self.goto_definition.send(WorkerMessage::Kill);
let _ = self.semantic_tokens_full.send(WorkerMessage::Kill);
let _ = self.inlay_hint.send(WorkerMessage::Kill);
let _ = self.inlay_hint_resolve.send(WorkerMessage::Kill);
let _ = self.hover.send(WorkerMessage::Kill);
let _ = self.references.send(WorkerMessage::Kill);
let _ = self.code_lens.send(WorkerMessage::Kill);
let _ = self.code_action.send(WorkerMessage::Kill);
let _ = self.code_action_resolve.send(WorkerMessage::Kill);
let _ = self.signature_help.send(WorkerMessage::Kill);
let _ = self.will_rename_files.send(WorkerMessage::Kill);
let _ = self.execute_command.send(WorkerMessage::Kill);
let _ = self.workspace_symbol.send(WorkerMessage::Kill);
let _ = self.document_symbol.send(WorkerMessage::Kill);
let _ = self.call_hierarchy_prepare.send(WorkerMessage::Kill);
let _ = self.call_hierarchy_incoming.send(WorkerMessage::Kill);
let _ = self.call_hierarchy_outgoing.send(WorkerMessage::Kill);
let _ = self.folding_range.send(WorkerMessage::Kill);
let _ = self.health_check.send(WorkerMessage::Kill);
}
}

Expand Down Expand Up @@ -195,21 +189,28 @@ pub struct ReceiveChannels {
}

pub trait Sendable<R: lsp_types::request::Request + 'static> {
fn send(&self, id: i64, params: R::Params);
fn send(
&self,
id: i64,
params: R::Params,
) -> Result<(), mpsc::SendError<WorkerMessage<R::Params>>>;
}

macro_rules! impl_sendable {
($Request: ident, $Params: ident, $receiver: ident) => {
impl<Checker: BuildRunnable, Parser: Parsable> Sendable<$Request>
for Server<Checker, Parser>
{
fn send(&self, id: i64, params: $Params) {
fn send(
&self,
id: i64,
params: $Params,
) -> Result<(), mpsc::SendError<WorkerMessage<$Params>>> {
self.channels
.as_ref()
.unwrap()
.$receiver
.send($crate::channels::WorkerMessage::Request(id, params))
.unwrap();
}
}
};
Expand Down
42 changes: 24 additions & 18 deletions crates/els/rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use crate::util::{self, NormalizedUrl};
impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
pub(crate) fn rename(&mut self, msg: &Value) -> ELSResult<()> {
let params = RenameParams::deserialize(&msg["params"])?;
let id = msg["id"].as_i64().unwrap();
self.send_log(format!("rename request: {params:?}"))?;
let uri = NormalizedUrl::new(params.text_document_position.text_document.uri);
let pos = params.text_document_position.position;
Expand Down Expand Up @@ -66,9 +67,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
_ => format!("this {kind} cannot be renamed"),
};
let edit = WorkspaceEdit::new(changes);
self.send_stdout(
&json!({ "jsonrpc": "2.0", "id": msg["id"].as_i64().unwrap(), "result": edit }),
)?;
self.send_stdout(&json!({ "jsonrpc": "2.0", "id": id, "result": edit }))?;
return self.send_error_info(error_reason);
}
Self::commit_change(&mut changes, &vi.def_loc, params.new_name.clone());
Expand All @@ -88,9 +87,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
}
let timestamps = self.get_timestamps(changes.keys());
let edit = WorkspaceEdit::new(changes);
self.send_stdout(
&json!({ "jsonrpc": "2.0", "id": msg["id"].as_i64().unwrap(), "result": edit }),
)?;
self.send_stdout(&json!({ "jsonrpc": "2.0", "id": id, "result": edit }))?;
for _ in 0..20 {
self.send_log("waiting for file to be modified...")?;
if self.all_changed(&timestamps) {
Expand All @@ -108,9 +105,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
return Ok(());
}
}
self.send_stdout(
&json!({ "jsonrpc": "2.0", "id": msg["id"].as_i64().unwrap(), "result": Value::Null }),
)
self.send_stdout(&json!({ "jsonrpc": "2.0", "id": id, "result": Value::Null }))
}

fn commit_change(
Expand Down Expand Up @@ -169,7 +164,11 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
.ref_inner()
.iter()
.filter(|node| node.id == path || self_node.depends_on(&node.id))
.map(|node| NormalizedUrl::new(Url::from_file_path(node.id.to_path_buf()).unwrap()))
.filter_map(|node| {
Some(NormalizedUrl::new(
Url::from_file_path(node.id.to_path_buf()).ok()?,
))
})
.collect()
}

Expand All @@ -181,7 +180,11 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
.ref_inner()
.iter()
.filter(|node| node.depends_on(&path))
.map(|node| NormalizedUrl::new(Url::from_file_path(node.id.to_path_buf()).unwrap()))
.filter_map(|node| {
Some(NormalizedUrl::new(
Url::from_file_path(node.id.to_path_buf()).ok()?,
))
})
.collect()
}
}
Expand All @@ -192,26 +195,29 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
old_uri: &NormalizedUrl,
new_uri: &NormalizedUrl,
) -> HashMap<Url, Vec<TextEdit>> {
let mut changes = HashMap::new();
let old_path = util::uri_to_path(old_uri)
.file_stem()
.unwrap()
.unwrap_or_default()
.to_string_lossy()
.to_string();
let old_path = old_path.trim_end_matches(".d");
let new_path = util::uri_to_path(new_uri)
.file_stem()
.unwrap()
.unwrap_or_default()
.to_string_lossy()
.to_string();
if old_path.is_empty() || new_path.is_empty() {
return changes;
}
let new_path = new_path.trim_end_matches(".d");
let mut changes = HashMap::new();
for dep in self.dependents_of(old_uri) {
let imports = self.search_imports(&dep, old_path);
let edits = imports.iter().map(|lit| {
TextEdit::new(
util::loc_to_range(lit.loc()).unwrap(),
let edits = imports.iter().filter_map(|lit| {
Some(TextEdit::new(
util::loc_to_range(lit.loc())?,
lit.token.content.replace(old_path, new_path),
)
))
});
changes.insert(dep.raw(), edits.collect());
}
Expand Down
28 changes: 18 additions & 10 deletions crates/els/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ use lsp_types::request::{
use lsp_types::{
CallHierarchyServerCapability, CodeActionKind, CodeActionOptions, CodeActionProviderCapability,
CodeLensOptions, CompletionOptions, ConfigurationItem, ConfigurationParams,
DidChangeTextDocumentParams, DidOpenTextDocumentParams, ExecuteCommandOptions,
FoldingRangeProviderCapability, HoverProviderCapability, ImplementationProviderCapability,
InitializeParams, InitializeResult, InlayHintOptions, InlayHintServerCapabilities, OneOf,
Position, SemanticTokenType, SemanticTokensFullOptions, SemanticTokensLegend,
SemanticTokensOptions, SemanticTokensServerCapabilities, ServerCapabilities,
SignatureHelpOptions, WorkDoneProgressOptions,
DidChangeTextDocumentParams, DidOpenTextDocumentParams, DidSaveTextDocumentParams,
ExecuteCommandOptions, FoldingRangeProviderCapability, HoverProviderCapability,
ImplementationProviderCapability, InitializeParams, InitializeResult, InlayHintOptions,
InlayHintServerCapabilities, OneOf, Position, SemanticTokenType, SemanticTokensFullOptions,
SemanticTokensLegend, SemanticTokensOptions, SemanticTokensServerCapabilities,
ServerCapabilities, SignatureHelpOptions, WorkDoneProgressOptions,
};

use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -325,6 +325,9 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
let msg = _self.read_message().unwrap();
if let Err(err) = _self.dispatch(msg) {
lsp_log!("error: {err}");
if err.to_string().contains("sending on a closed channel") {
_self.restart();
};
}
},
fn_name!(),
Expand All @@ -333,14 +336,17 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
// recover from crash
if handle.is_finished() {
self.send_error_info("The compiler has crashed. Restarting...")
.unwrap();
.expect("failed to send error info to client");
self.restart();
let mut _self = self.clone();
handle = spawn_new_thread(
move || loop {
let msg = _self.read_message().unwrap();
if let Err(err) = _self.dispatch(msg) {
lsp_log!("error: {err}");
if err.to_string().contains("sending on a closed channel") {
_self.restart();
};
}
},
fn_name!(),
Expand Down Expand Up @@ -600,8 +606,10 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
}))
}

/// Restart the server. Clear caches and close & reopen channels.
#[allow(unused)]
pub(crate) fn restart(&mut self) {
lsp_log!("restarting ELS");
self.file_cache.clear();
self.comp_cache.clear();
self.channels.as_ref().unwrap().close();
Expand Down Expand Up @@ -696,7 +704,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
Server<Checker, Parser>: Sendable<R>,
{
let params = R::Params::deserialize(&msg["params"])?;
self.send(id, params);
self.send(id, params)?;
Ok(())
}

Expand Down Expand Up @@ -801,8 +809,8 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
self.check_file(uri, code)
}
"textDocument/didSave" => {
let uri =
NormalizedUrl::parse(msg["params"]["textDocument"]["uri"].as_str().unwrap())?;
let params = DidSaveTextDocumentParams::deserialize(msg["params"].clone())?;
let uri = NormalizedUrl::new(params.text_document.uri);
self.send_log(format!("{method}: {uri}"))?;
let code = self.file_cache.get_entire_code(&uri)?;
self.recheck_file(uri, code)
Expand Down
4 changes: 3 additions & 1 deletion crates/els/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ pub(crate) fn get_token_from_stream(
}

pub(crate) fn get_metadata_from_uri(uri: &Url) -> ELSResult<Metadata> {
let path = uri.to_file_path().unwrap();
let path = uri
.to_file_path()
.map_err(|_| "failed to convert uri to path")?;
Ok(metadata(path)?)
}

Expand Down

0 comments on commit 30f615f

Please sign in to comment.