From e39e77aa0d89a1af8523a49d47e00993e738e510 Mon Sep 17 00:00:00 2001 From: Agent Smith <1769712655@qq.com> Date: Thu, 28 Sep 2023 15:33:00 +0800 Subject: [PATCH] fix: wrong semantic delta after file switch --- src/ast/ctx.rs | 19 +++++++++++-------- src/ast/ctx/references.rs | 6 ++++++ src/ast/node/statement.rs | 28 +++++++++++++++------------- src/ast/pltype.rs | 4 ++-- src/lsp/lspserver.rs | 17 +++++++++++++++++ 5 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/ast/ctx.rs b/src/ast/ctx.rs index f32518614..8ba7d84ba 100644 --- a/src/ast/ctx.rs +++ b/src/ast/ctx.rs @@ -80,7 +80,7 @@ pub type GenericCache = Arc>; /// Context for code generation pub struct Ctx<'a> { pub generic_types: FxHashMap>>, - pub need_highlight: usize, + pub need_highlight: Arc>, pub plmod: Mod, pub father: Option<&'a Ctx<'a>>, // father context, for symbol lookup pub root: Option<&'a Ctx<'a>>, // root context, for symbol lookup @@ -280,7 +280,7 @@ impl<'a, 'ctx> Ctx<'a> { ) -> Ctx<'a> { let generic_infer: GenericCache = Default::default(); Ctx { - need_highlight: 0, + need_highlight: Default::default(), generic_types: FxHashMap::default(), plmod: Mod::new(src_file_path.to_string(), generic_infer.clone()), father: None, @@ -321,7 +321,7 @@ impl<'a, 'ctx> Ctx<'a> { root = Some(self); } let mut ctx = Ctx { - need_highlight: self.need_highlight, + need_highlight: self.need_highlight.clone(), generic_types: FxHashMap::default(), plmod: self.plmod.new_child(), father: Some(self), @@ -1221,6 +1221,9 @@ impl<'a, 'ctx> Ctx<'a> { } pub fn send_if_go_to_def(&self, range: Range, destrange: Range, file: String) { + if self.need_highlight.borrow().ne(&0) { + return; + } if range == Default::default() { return; } @@ -1384,7 +1387,7 @@ impl<'a, 'ctx> Ctx<'a> { } pub fn push_semantic_token(&self, range: Range, tp: SemanticTokenType, modifiers: u32) { - if self.need_highlight != 0 || self.in_macro { + if self.need_highlight.borrow().ne(&0) || self.in_macro { return; } self.get_root_ctx() @@ -1394,7 +1397,7 @@ impl<'a, 'ctx> Ctx<'a> { .push(range.to_diag_range(), type_index(tp), modifiers) } pub fn push_type_hints(&self, range: Range, pltype: Arc>) { - if self.need_highlight != 0 || self.in_macro { + if self.need_highlight.borrow().ne(&0) || self.in_macro { return; } let hint = InlayHint { @@ -1412,7 +1415,7 @@ impl<'a, 'ctx> Ctx<'a> { self.plmod.hints.borrow_mut().push(hint); } pub fn push_param_hint(&self, range: Range, name: String) { - if self.need_highlight != 0 || self.in_macro { + if self.need_highlight.borrow().ne(&0) || self.in_macro { return; } let hint = InlayHint { @@ -1482,7 +1485,7 @@ impl<'a, 'ctx> Ctx<'a> { } pub fn save_if_comment_doc_hover(&self, range: Range, docs: Option>>) { - if self.need_highlight != 0 { + if self.need_highlight.borrow().ne(&0) { return; } let mut content = vec![]; @@ -1500,7 +1503,7 @@ impl<'a, 'ctx> Ctx<'a> { } pub fn save_if_hover(&self, range: Range, value: HoverContents) { - if self.need_highlight != 0 { + if self.need_highlight.borrow().ne(&0) { return; } self.plmod.hovers.borrow_mut().insert( diff --git a/src/ast/ctx/references.rs b/src/ast/ctx/references.rs index 35faa63fc..3c1d61c5a 100644 --- a/src/ast/ctx/references.rs +++ b/src/ast/ctx/references.rs @@ -73,6 +73,9 @@ impl<'a> Ctx<'a> { /// /// For details, see the module documentation. pub fn set_glob_refs(&self, name: &str, range: Range) { + if self.need_highlight.borrow().ne(&0) { + return; + } let root = self.get_root_ctx(); root.plmod .glob_refs @@ -118,6 +121,9 @@ impl<'a> Ctx<'a> { /// /// For details, see the module documentation. pub fn set_local_refs(&self, refs: Arc>, range: Range) { + if self.need_highlight.borrow().ne(&0) { + return; + } refs.borrow_mut().push(self.get_location(range)); self.plmod.local_refs.borrow_mut().insert(range, refs); } diff --git a/src/ast/node/statement.rs b/src/ast/node/statement.rs index 92fef9ca5..6ab0a8468 100644 --- a/src/ast/node/statement.rs +++ b/src/ast/node/statement.rs @@ -600,19 +600,21 @@ impl Node for StatementsNode { } terminator = re.unwrap().get_term(); } - for (v, symbol) in &ctx.table { - if let Some(refs) = &symbol.refs { - if refs.borrow().len() <= 1 && v != "self" && !v.starts_with('_') { - symbol - .range - .new_warn(WarnCode::UNUSED_VARIABLE) - .set_source(&ctx.get_file()) - .add_label( - symbol.range, - ctx.get_file(), - format_label!("Unused variable `{}`", v), - ) - .add_to_ctx(ctx); + if ctx.need_highlight.borrow().eq(&0) { + for (v, symbol) in &ctx.table { + if let Some(refs) = &symbol.refs { + if refs.borrow().len() <= 1 && v != "self" && !v.starts_with('_') { + symbol + .range + .new_warn(WarnCode::UNUSED_VARIABLE) + .set_source(&ctx.get_file()) + .add_label( + symbol.range, + ctx.get_file(), + format_label!("Unused variable `{}`", v), + ) + .add_to_ctx(ctx); + } } } } diff --git a/src/ast/pltype.rs b/src/ast/pltype.rs index 386f55692..c97d40a12 100644 --- a/src/ast/pltype.rs +++ b/src/ast/pltype.rs @@ -904,7 +904,7 @@ impl FNValue { .insert(name, Arc::new(RefCell::new(PLType::Fn(res.clone())))); let block = ctx.block; - ctx.need_highlight += 1; + *ctx.need_highlight.borrow_mut() += 1; let f = self.clone(); if let Some(n) = &mut self.node { builder.rm_curr_debug_location(); @@ -914,7 +914,7 @@ impl FNValue { } else { unreachable!() } - ctx.need_highlight -= 1; + *ctx.need_highlight.borrow_mut() -= 1; ctx.position_at_end(block.unwrap(), builder); res.fntype.ret_pltype = self diff --git a/src/lsp/lspserver.rs b/src/lsp/lspserver.rs index 4e23941d7..7fd856229 100644 --- a/src/lsp/lspserver.rs +++ b/src/lsp/lspserver.rs @@ -137,6 +137,7 @@ fn main_loop( ); let last_tokens = Cell::new(Default::default()); let mut completions: Vec> = vec![]; + let mut last_semantic_file = "".to_string(); log::info!("starting main loop"); for msg in &connection.receiver { @@ -233,6 +234,7 @@ fn main_loop( }) .on::(|id, params| { let uri = url_to_path(params.text_document.uri); + last_semantic_file = uri.clone(); docin.set_file(&mut db).to(uri); docin.set_action(&mut db).to(ActionType::SemanticTokensFull); docin @@ -251,6 +253,21 @@ fn main_loop( }) .on::(|id, params| { let uri = url_to_path(params.text_document.uri); + if last_semantic_file != uri { + let sender = connection.sender.clone(); + pool.execute(move || { + send_semantic_tokens_edit( + &sender, + id, + SemanticTokensDelta { + result_id: None, + edits: vec![], + }, + ); + }); + return; + } + last_semantic_file = uri.clone(); docin.set_file(&mut db).to(uri); docin.set_action(&mut db).to(ActionType::SemanticTokensFull); docin