From 29bfa67513198210aec5271ffd85979ffa6c39a3 Mon Sep 17 00:00:00 2001 From: he1pa <18012015693@163.com> Date: Fri, 12 Apr 2024 14:22:19 +0800 Subject: [PATCH] feat: clear globalstate cache Signed-off-by: he1pa <18012015693@163.com> --- kclvm/api/src/service/service_impl.rs | 2 +- kclvm/loader/src/lib.rs | 10 +- kclvm/sema/src/advanced_resolver/mod.rs | 41 ++++--- kclvm/sema/src/advanced_resolver/node.rs | 94 +++++++++++---- kclvm/sema/src/core/global_state.rs | 147 +++++++++++++++++------ kclvm/sema/src/core/package.rs | 8 ++ kclvm/sema/src/core/scope.rs | 31 ++++- kclvm/sema/src/core/symbol.rs | 105 +++++++++++++++- kclvm/sema/src/namer/mod.rs | 81 +++++++------ kclvm/sema/src/namer/node.rs | 30 +++++ kclvm/sema/src/resolver/arg.rs | 1 + kclvm/sema/src/resolver/mod.rs | 14 +-- kclvm/sema/src/resolver/node.rs | 15 ++- kclvm/sema/src/resolver/schema.rs | 3 + kclvm/sema/src/resolver/scope.rs | 18 +-- kclvm/sema/src/resolver/ty.rs | 3 + kclvm/tools/src/LSP/src/find_refs.rs | 32 +---- kclvm/tools/src/LSP/src/quick_fix.rs | 1 + kclvm/tools/src/LSP/src/rename.rs | 10 +- kclvm/tools/src/LSP/src/request.rs | 9 -- kclvm/tools/src/LSP/src/state.rs | 8 ++ kclvm/tools/src/LSP/src/tests.rs | 10 ++ kclvm/tools/src/LSP/src/util.rs | 46 ++++--- 23 files changed, 513 insertions(+), 206 deletions(-) diff --git a/kclvm/api/src/service/service_impl.rs b/kclvm/api/src/service/service_impl.rs index 1b7b778f9..8add7dff5 100644 --- a/kclvm/api/src/service/service_impl.rs +++ b/kclvm/api/src/service/service_impl.rs @@ -212,7 +212,7 @@ impl KclvmServiceImpl { }, module_cache, scope_cache, - GlobalState::default(), + &mut GlobalState::default(), )?; if args.with_ast_index { // Thread local options diff --git a/kclvm/loader/src/lib.rs b/kclvm/loader/src/lib.rs index 079e31380..841e9481e 100644 --- a/kclvm/loader/src/lib.rs +++ b/kclvm/loader/src/lib.rs @@ -116,7 +116,7 @@ pub fn load_packages(opts: &LoadPackageOptions) -> Result { opts, KCLModuleCache::default(), KCLScopeCache::default(), - GlobalState::default(), + &mut GlobalState::default(), ) } @@ -126,7 +126,7 @@ pub fn load_packages_with_cache( opts: &LoadPackageOptions, module_cache: KCLModuleCache, scope_cache: KCLScopeCache, - gs: GlobalState, + gs: &mut GlobalState, ) -> Result { let sess = ParseSessionRef::default(); let paths: Vec<&str> = opts.paths.iter().map(|s| s.as_str()).collect(); @@ -149,8 +149,10 @@ pub fn load_packages_with_cache( Some(scope_cache), ); let node_ty_map = prog_scope.node_ty_map; - let gs = Namer::find_symbols(&program, gs); - let gs = AdvancedResolver::resolve_program(&program, gs, node_ty_map.clone()); + // let gs = Namer::find_symbols(&program, gs); + Namer::find_symbols(&program, gs); + // let gs = AdvancedResolver::resolve_program(&program, gs, node_ty_map.clone()); + AdvancedResolver::resolve_program(&program, gs, node_ty_map); (program, prog_scope.handler.diagnostics.clone(), gs) } else { (parse_result.program, IndexSet::default(), gs) diff --git a/kclvm/sema/src/advanced_resolver/mod.rs b/kclvm/sema/src/advanced_resolver/mod.rs index a1da53410..074828c95 100644 --- a/kclvm/sema/src/advanced_resolver/mod.rs +++ b/kclvm/sema/src/advanced_resolver/mod.rs @@ -34,6 +34,8 @@ └─────────────────────┘ */ +use std::{cell::RefCell, rc::Rc, time::Instant}; + use indexmap::IndexSet; use kclvm_error::Position; @@ -60,12 +62,12 @@ mod node; /// so that toolchain can query semantic information about the AST pub struct AdvancedResolver<'ctx> { pub(crate) ctx: Context<'ctx>, - pub(crate) gs: GlobalState, + pub(crate) gs: &'ctx mut GlobalState, } pub struct Context<'ctx> { pub program: &'ctx Program, - node_ty_map: NodeTyMap, + node_ty_map: Rc>, scopes: Vec, current_pkgpath: Option, current_filename: Option, @@ -93,9 +95,9 @@ impl<'ctx> Context<'ctx> { impl<'ctx> AdvancedResolver<'ctx> { pub fn resolve_program( program: &'ctx Program, - gs: GlobalState, - node_ty_map: NodeTyMap, - ) -> GlobalState { + gs: &'ctx mut GlobalState, + node_ty_map: Rc>, + ) { let mut advanced_resolver = Self { gs, ctx: Context { @@ -111,9 +113,8 @@ impl<'ctx> AdvancedResolver<'ctx> { maybe_def: false, }, }; - for (name, modules) in advanced_resolver.ctx.program.pkgs.iter() { - if !advanced_resolver.gs.new_or_invalidate_pkgs.contains(name){ + if !advanced_resolver.gs.new_or_invalidate_pkgs.contains(name) { continue; } advanced_resolver.ctx.current_pkgpath = Some(name.clone()); @@ -139,7 +140,7 @@ impl<'ctx> AdvancedResolver<'ctx> { advanced_resolver.gs.build_sema_db(); advanced_resolver.gs.new_or_invalidate_pkgs.clear(); - advanced_resolver.gs + // advanced_resolver.gs } fn enter_root_scope( @@ -294,8 +295,9 @@ mod tests { let mut program = load_program(sess.clone(), &[&path], None, None) .unwrap() .program; - let gs = GlobalState::default(); - let gs = Namer::find_symbols(&program, gs); + let mut gs = GlobalState::default(); + // let gs = Namer::find_symbols(&program, gs); + Namer::find_symbols(&program, &mut gs); let node_ty_map = resolver::resolve_program_with_opts( &mut program, @@ -307,7 +309,8 @@ mod tests { None, ) .node_ty_map; - let gs = AdvancedResolver::resolve_program(&program, gs, node_ty_map); + // let gs = AdvancedResolver::resolve_program(&program, gs, node_ty_map); + AdvancedResolver::resolve_program(&program, &mut gs, node_ty_map); let base_path = Path::new(".").canonicalize().unwrap(); // print_symbols_info(&gs); let except_symbols = vec![ @@ -1233,10 +1236,12 @@ mod tests { let mut program = load_program(sess.clone(), &[&path], None, None) .unwrap() .program; - let gs = GlobalState::default(); - let gs = Namer::find_symbols(&program, gs); + let mut gs = GlobalState::default(); + // let gs = Namer::find_symbols(&program, gs); + Namer::find_symbols(&program, &mut gs); let node_ty_map = resolver::resolve_program(&mut program).node_ty_map; - let gs = AdvancedResolver::resolve_program(&program, gs, node_ty_map); + // let gs = AdvancedResolver::resolve_program(&program, gs, node_ty_map); + AdvancedResolver::resolve_program(&program, &mut gs, node_ty_map); let base_path = Path::new(".").canonicalize().unwrap(); let test_cases = vec![ @@ -1310,10 +1315,12 @@ mod tests { let mut program = load_program(sess.clone(), &[&path], None, None) .unwrap() .program; - let gs = GlobalState::default(); - let gs = Namer::find_symbols(&program, gs); + let mut gs = GlobalState::default(); + // let gs = Namer::find_symbols(&program, gs); + Namer::find_symbols(&program, &mut gs); let node_ty_map = resolver::resolve_program(&mut program).node_ty_map; - let gs = AdvancedResolver::resolve_program(&program, gs, node_ty_map); + // let gs = AdvancedResolver::resolve_program(&program, gs, node_ty_map); + AdvancedResolver::resolve_program(&program, &mut gs, node_ty_map); let base_path = Path::new(".").canonicalize().unwrap(); let scope_test_cases = vec![ diff --git a/kclvm/sema/src/advanced_resolver/node.rs b/kclvm/sema/src/advanced_resolver/node.rs index 99cba7f57..1437b904e 100644 --- a/kclvm/sema/src/advanced_resolver/node.rs +++ b/kclvm/sema/src/advanced_resolver/node.rs @@ -72,6 +72,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&type_alias_stmt.type_name.id)) .map(|ty| ty.clone()), doc: None, @@ -140,10 +141,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { .get_symbols() .get_symbol_by_fully_qualified_name(&import_stmt.path.node)?; unresolved.def = Some(package_symbol); - let unresolved_ref = self - .gs - .get_symbols_mut() - .alloc_unresolved_symbol(unresolved, self.ctx.get_node_key(&ast_id)); + let unresolved_ref = self.gs.get_symbols_mut().alloc_unresolved_symbol( + unresolved, + self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), + ); self.gs .get_symbols_mut() .symbols_info @@ -161,6 +163,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let schema_ty = self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&schema_stmt.name.id)) .unwrap() .clone(); @@ -197,6 +200,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let func_symbol_ref = self.gs.get_symbols_mut().alloc_value_symbol( func_value, self.ctx.get_node_key(&ast::AstIndex::default()), + self.ctx.current_pkgpath.clone().unwrap(), ); schema_builtin_member.insert(name.to_string(), func_symbol_ref); } @@ -270,12 +274,14 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let value = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(key_name.clone(), start, end, Some(schema_symbol), false), self.ctx.get_node_key(&index_signature.id), + self.ctx.current_pkgpath.clone().unwrap(), ); if let Some(symbol) = self.gs.get_symbols_mut().values.get_mut(value.get_id()) { symbol.sema_info = KCLSymbolSemanticInfo { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&index_signature.id)) .map(|ty| ty.clone()), doc: None, @@ -339,6 +345,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let rule_ty = self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&rule_stmt.name.id))? .clone(); let rule_symbol = self @@ -355,6 +362,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&rule_stmt.name.id)) .map(|ty| ty.clone()), doc: rule_stmt.doc.as_ref().map(|doc| doc.node.clone()), @@ -405,6 +413,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let value = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(name.clone(), start_pos, end_pos, None, false), self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), ); self.gs .get_scopes_mut() @@ -414,6 +423,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(ast_id)) .map(|ty| ty.clone()), doc: None, @@ -459,6 +469,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&schema_attr.name.id)) .map(|ty| ty.clone()), doc, @@ -498,6 +509,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let mut parent_ty = self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&selector_expr.value.id))? .clone(); for name in &selector_expr.attr.node.names { @@ -511,10 +523,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let ast_id = name.id.clone(); let mut unresolved = UnresolvedSymbol::new(name.node.clone(), start_pos, end_pos, None); unresolved.def = Some(def_symbol_ref); - let unresolved_ref = self - .gs - .get_symbols_mut() - .alloc_unresolved_symbol(unresolved, self.ctx.get_node_key(&ast_id)); + let unresolved_ref = self.gs.get_symbols_mut().alloc_unresolved_symbol( + unresolved, + self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), + ); let cur_scope = *self.ctx.scopes.last().unwrap(); self.gs .get_scopes_mut() @@ -523,6 +536,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { parent_ty = self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&name.id))? .clone(); } @@ -659,6 +673,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let schema_ty = self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&schema_expr.name.id))? .clone(); let schema_symbol = self @@ -777,9 +792,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { fn walk_comment(&mut self, comment: &'ctx ast::Comment) -> Self::Result { let (start, end) = (self.ctx.start_pos.clone(), self.ctx.end_pos.clone()); let comment_symbol = CommentSymbol::new(start, end, comment.text.clone()); - self.gs - .get_symbols_mut() - .alloc_comment_symbol(comment_symbol, self.ctx.get_node_key(&self.ctx.cur_node)) + self.gs.get_symbols_mut().alloc_comment_symbol( + comment_symbol, + self.ctx.get_node_key(&self.ctx.cur_node), + self.ctx.current_pkgpath.clone().unwrap(), + ) } fn walk_missing_expr(&mut self, _missing_expr: &'ctx ast::MissingExpr) -> Self::Result { @@ -804,7 +821,12 @@ impl<'ctx> AdvancedResolver<'ctx> { } self.ctx.cur_node = expr.id.clone(); match self.walk_expr(&expr.node) { - None => match self.ctx.node_ty_map.get(&self.ctx.get_node_key(&expr.id)) { + None => match self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&expr.id)) + { Some(ty) => { if let ast::Expr::Missing(_) = expr.node { return None; @@ -817,9 +839,11 @@ impl<'ctx> AdvancedResolver<'ctx> { None, ); expr_symbol.sema_info.ty = Some(ty.clone()); - self.gs - .get_symbols_mut() - .alloc_expression_symbol(expr_symbol, self.ctx.get_node_key(&expr.id)) + self.gs.get_symbols_mut().alloc_expression_symbol( + expr_symbol, + self.ctx.get_node_key(&expr.id), + self.ctx.current_pkgpath.clone().unwrap(), + ) } None => None, }, @@ -872,6 +896,7 @@ impl<'ctx> AdvancedResolver<'ctx> { if let Some(ty) = self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&first_name.id)) { self.gs @@ -893,10 +918,11 @@ impl<'ctx> AdvancedResolver<'ctx> { let mut first_unresolved = UnresolvedSymbol::new(first_name.node.clone(), start_pos, end_pos, None); first_unresolved.def = Some(symbol_ref); - let first_unresolved_ref = self - .gs - .get_symbols_mut() - .alloc_unresolved_symbol(first_unresolved, self.ctx.get_node_key(&ast_id)); + let first_unresolved_ref = self.gs.get_symbols_mut().alloc_unresolved_symbol( + first_unresolved, + self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), + ); let cur_scope = *self.ctx.scopes.last().unwrap(); self.gs .get_scopes_mut() @@ -906,7 +932,9 @@ impl<'ctx> AdvancedResolver<'ctx> { let mut parent_ty = self .ctx .node_ty_map - .get(&self.ctx.get_node_key(&first_name.id))?; + .borrow() + .get(&self.ctx.get_node_key(&first_name.id))? + .clone(); for index in 1..names.len() { let name = names.get(index).unwrap(); @@ -921,17 +949,23 @@ impl<'ctx> AdvancedResolver<'ctx> { let mut unresolved = UnresolvedSymbol::new(name.node.clone(), start_pos, end_pos, None); unresolved.def = Some(def_symbol_ref); - let unresolved_ref = self - .gs - .get_symbols_mut() - .alloc_unresolved_symbol(unresolved, self.ctx.get_node_key(&ast_id)); + let unresolved_ref = self.gs.get_symbols_mut().alloc_unresolved_symbol( + unresolved, + self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), + ); let cur_scope = *self.ctx.scopes.last().unwrap(); self.gs .get_scopes_mut() .add_ref_to_scope(cur_scope, unresolved_ref); - parent_ty = self.ctx.node_ty_map.get(&self.ctx.get_node_key(&name.id))?; + parent_ty = self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&name.id))? + .clone(); if index == names.len() - 1 { return Some(unresolved_ref); } @@ -946,6 +980,7 @@ impl<'ctx> AdvancedResolver<'ctx> { let first_value = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(first_name.node.clone(), start_pos, end_pos, None, false), self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), ); self.gs.get_scopes_mut().add_def_to_scope( cur_scope, @@ -963,6 +998,7 @@ impl<'ctx> AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&first_name.id)) .map(|ty| ty.clone()), doc: None, @@ -976,6 +1012,7 @@ impl<'ctx> AdvancedResolver<'ctx> { let value = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(name.node.clone(), start_pos, end_pos, None, false), self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), ); self.gs.get_scopes_mut().add_def_to_scope( @@ -991,6 +1028,7 @@ impl<'ctx> AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&name.id)) .map(|ty| ty.clone()), doc: None, @@ -1034,6 +1072,7 @@ impl<'ctx> AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(id)) .map(|ty| ty.clone()), doc: None, @@ -1116,6 +1155,7 @@ impl<'ctx> AdvancedResolver<'ctx> { let value = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(kw.node.arg.node.get_name(), start_pos, end_pos, None, false), self.ctx.get_node_key(&kw.id), + self.ctx.current_pkgpath.clone().unwrap(), ); if let Some(value) = self.gs.get_symbols_mut().values.get_mut(value.get_id()) { @@ -1123,6 +1163,7 @@ impl<'ctx> AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&kw.id)) .map(|ty| ty.clone()), doc: None, @@ -1183,7 +1224,7 @@ impl<'ctx> AdvancedResolver<'ctx> { if let Some(def_symbol_ref) = symbols.get_symbol(key_symbol_ref).unwrap().get_definition() { if let Some(node_key) = symbols.symbols_info.symbol_node_map.get(&def_symbol_ref) { - if let Some(def_ty) = self.ctx.node_ty_map.get(node_key) { + if let Some(def_ty) = self.ctx.node_ty_map.borrow().get(node_key) { if let Some(ty) = get_possible_schema_ty(def_ty.clone()) { self.ctx.current_schema_symbol = self.gs.get_symbols().get_type_symbol(&ty, None); @@ -1216,6 +1257,7 @@ impl<'ctx> AdvancedResolver<'ctx> { self.gs.get_symbols_mut().alloc_decorator_symbol( decorator_symbol, self.ctx.get_node_key(&self.ctx.cur_node), + self.ctx.current_pkgpath.clone().unwrap(), ); } } diff --git a/kclvm/sema/src/core/global_state.rs b/kclvm/sema/src/core/global_state.rs index 7336d2294..0f4da3163 100644 --- a/kclvm/sema/src/core/global_state.rs +++ b/kclvm/sema/src/core/global_state.rs @@ -1,6 +1,6 @@ use std::collections::HashSet; -use indexmap::IndexMap; +use indexmap::{IndexMap, IndexSet}; use kclvm_error::Position; use super::{ @@ -53,6 +53,10 @@ impl GlobalState { pub fn get_sema_db(&self) -> &SemanticDB { &self.sema_db } + + pub fn get_sema_db_mut(&mut self) -> &mut SemanticDB { + &mut self.sema_db + } } impl GlobalState { @@ -292,18 +296,26 @@ impl GlobalState { } impl GlobalState { - fn build_sema_db_with_symbols(&self, file_sema_map: &mut IndexMap) { + fn build_sema_db_with_symbols( + &self, + file_sema_map_cache: &mut IndexMap, + ) { // put symbols + let mut file_sema_map: IndexMap = IndexMap::new(); + for (index, symbol) in self.symbols.schemas.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Schema, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -314,15 +326,18 @@ impl GlobalState { ); } for (index, symbol) in self.symbols.type_aliases.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::TypeAlias, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -333,15 +348,18 @@ impl GlobalState { ); } for (index, symbol) in self.symbols.attributes.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Attribute, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -352,15 +370,18 @@ impl GlobalState { ); } for (index, symbol) in self.symbols.rules.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Rule, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -371,15 +392,18 @@ impl GlobalState { ); } for (index, symbol) in self.symbols.values.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Value, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -390,15 +414,18 @@ impl GlobalState { ); } for (index, symbol) in self.symbols.unresolved.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Unresolved, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -410,15 +437,19 @@ impl GlobalState { } for (index, symbol) in self.symbols.exprs.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } + let symbol_ref = SymbolRef { kind: SymbolKind::Expression, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -430,15 +461,18 @@ impl GlobalState { } for (index, symbol) in self.symbols.comments.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Comment, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -450,15 +484,18 @@ impl GlobalState { } for (index, symbol) in self.symbols.decorators.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Decorator, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -477,6 +514,8 @@ impl GlobalState { .symbols .sort_by_key(|symbol_ref| sema_info.symbol_locs.get(symbol_ref).unwrap()) } + + file_sema_map_cache.extend(file_sema_map); } fn build_sema_db_with_scopes(&self, file_sema_map: &mut IndexMap) { // put scope @@ -485,11 +524,11 @@ impl GlobalState { kind: ScopeKind::Local, id: index, }; - let filename = scope.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &scope.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.local_scope_locs.insert( scope_ref, CachedRange { @@ -504,7 +543,7 @@ impl GlobalState { }, ); file_sema_map - .get_mut(&filename) + .get_mut(filename) .unwrap() .scopes .push(scope_ref); @@ -539,11 +578,43 @@ impl GlobalState { } pub(crate) fn build_sema_db(&mut self) { - let mut file_sema_map = IndexMap::::default(); - self.build_sema_db_with_symbols(&mut file_sema_map); - self.build_sema_db_with_scopes(&mut file_sema_map); - self.sort_local_scopes(&mut file_sema_map); + let mut file_sema_map_cache = self.get_sema_db_mut().file_sema_map.clone(); + + self.build_sema_db_with_symbols(&mut file_sema_map_cache); + self.build_sema_db_with_scopes(&mut file_sema_map_cache); + self.sort_local_scopes(&mut file_sema_map_cache); + + self.sema_db.file_sema_map = file_sema_map_cache; + } + + pub fn clear_cache(&mut self) { + let invalidate_pkgs = self.new_or_invalidate_pkgs.clone(); + self.clear_sema_db_cache(&invalidate_pkgs); + self.get_scopes_mut().clear_cache(&invalidate_pkgs); + self.get_packages_mut().clear_cache(&invalidate_pkgs); + self.get_symbols_mut().clear_cache(&invalidate_pkgs); + } - self.sema_db.file_sema_map = file_sema_map; + fn clear_sema_db_cache(&mut self, invalidate_pkgs: &HashSet) { + let mut to_remove: Vec = Vec::new(); + let mut files: IndexSet = IndexSet::new(); + for invalidate_pkg in invalidate_pkgs { + if let Some(symbols) = self + .get_symbols() + .symbols_info + .pkg_symbol_map + .get(invalidate_pkg) + { + to_remove.extend(symbols.iter().cloned()); + } + } + for symbol in to_remove { + if let Some(s) = self.get_symbols().get_symbol(symbol) { + files.insert(s.get_range().0.filename); + } + } + for file in files { + self.sema_db.file_sema_map.remove(&file); + } } } diff --git a/kclvm/sema/src/core/package.rs b/kclvm/sema/src/core/package.rs index b0de5be90..4c4eb989a 100644 --- a/kclvm/sema/src/core/package.rs +++ b/kclvm/sema/src/core/package.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use indexmap::{IndexMap, IndexSet}; #[derive(Default, Debug, Clone)] @@ -39,6 +41,12 @@ impl PackageDB { pub fn get_module_info(&self, name: &str) -> Option<&ModuleInfo> { self.module_info.get(name) } + + pub fn clear_cache(&mut self, invalidate_pkgs: &HashSet) { + for invalidate_pkg in invalidate_pkgs { + self.package_info.remove(invalidate_pkg); + } + } } #[derive(Debug, Clone)] pub struct PackageInfo { diff --git a/kclvm/sema/src/core/scope.rs b/kclvm/sema/src/core/scope.rs index 0d98861c3..b1baf688b 100644 --- a/kclvm/sema/src/core/scope.rs +++ b/kclvm/sema/src/core/scope.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use indexmap::{IndexMap, IndexSet}; use kclvm_error::Position; @@ -108,6 +108,17 @@ impl ScopeData { } } + pub fn remove_scope(&mut self, scope: &ScopeRef) { + match scope.get_kind() { + ScopeKind::Local => { + self.locals.remove(scope.get_id()); + } + ScopeKind::Root => { + self.roots.remove(scope.get_id()); + } + } + } + pub fn try_get_local_scope(&self, scope: &ScopeRef) -> Option<&LocalSymbolScope> { match scope.get_kind() { ScopeKind::Local => Some(self.locals.get(scope.get_id())?), @@ -180,6 +191,24 @@ impl ScopeData { kind: ScopeKind::Local, } } + + pub fn clear_cache(&mut self, invalidate_pkgs: &HashSet) { + for invalidate_pkg in invalidate_pkgs { + if let Some(scope_ref) = self.root_map.remove(invalidate_pkg) { + self.clear_scope_and_child(scope_ref); + self.roots.remove(scope_ref.get_id()); + } + } + } + + pub fn clear_scope_and_child(&mut self, scope_ref: ScopeRef) { + if let Some(scope) = self.get_scope(&scope_ref) { + for c in scope.get_children() { + self.clear_scope_and_child(c) + } + } + self.remove_scope(&scope_ref) + } } #[derive(Debug, Clone)] diff --git a/kclvm/sema/src/core/symbol.rs b/kclvm/sema/src/core/symbol.rs index 772b2bc65..19b183f04 100644 --- a/kclvm/sema/src/core/symbol.rs +++ b/kclvm/sema/src/core/symbol.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::{collections::HashSet, sync::Arc}; use generational_arena::Arena; use indexmap::{IndexMap, IndexSet}; @@ -54,6 +54,7 @@ pub struct KCLSymbolSemanticInfo { } pub(crate) const BUILTIN_STR_PACKAGE: &'static str = "@str"; +pub(crate) const BUILTIN_FUNCTION_PACKAGE: &'static str = "@builtin"; #[derive(Default, Debug, Clone)] pub struct SymbolData { @@ -79,6 +80,7 @@ pub struct SymbolDB { pub(crate) schema_builtin_symbols: IndexMap>, pub(crate) node_symbol_map: IndexMap, pub(crate) symbol_node_map: IndexMap, + pub(crate) pkg_symbol_map: IndexMap>, } impl SymbolData { @@ -175,6 +177,41 @@ impl SymbolData { } } + pub fn remove_symbol(&mut self, id: &SymbolRef) { + match id.get_kind() { + SymbolKind::Schema => { + self.schemas.remove(id.get_id()); + } + SymbolKind::Attribute => { + self.attributes.remove(id.get_id()); + } + SymbolKind::Value => { + self.values.remove(id.get_id()); + } + SymbolKind::Package => { + self.packages.remove(id.get_id()); + } + SymbolKind::TypeAlias => { + self.type_aliases.remove(id.get_id()); + } + SymbolKind::Unresolved => { + self.unresolved.remove(id.get_id()); + } + SymbolKind::Rule => { + self.rules.remove(id.get_id()); + } + SymbolKind::Expression => { + self.exprs.remove(id.get_id()); + } + SymbolKind::Comment => { + self.comments.remove(id.get_id()); + } + SymbolKind::Decorator => { + self.decorators.remove(id.get_id()); + } + } + } + pub fn set_symbol_type(&mut self, id: SymbolRef, ty: TypeRef) { match id.get_kind() { SymbolKind::Schema => { @@ -490,17 +527,37 @@ impl SymbolData { } } - pub fn alloc_package_symbol(&mut self, pkg: PackageSymbol) -> SymbolRef { + pub fn insert_package_symbol(&mut self, symbol_ref: SymbolRef, pkg_name: String) { + if !self.symbols_info.pkg_symbol_map.contains_key(&pkg_name) { + self.symbols_info + .pkg_symbol_map + .insert(pkg_name.clone(), IndexSet::default()); + } + + self.symbols_info + .pkg_symbol_map + .get_mut(&pkg_name) + .unwrap() + .insert(symbol_ref); + } + + pub fn alloc_package_symbol(&mut self, pkg: PackageSymbol, pkg_name: String) -> SymbolRef { let symbol_id = self.packages.insert(pkg); let symbol_ref = SymbolRef { id: symbol_id, kind: SymbolKind::Package, }; self.packages.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } - pub fn alloc_schema_symbol(&mut self, schema: SchemaSymbol, node_key: NodeKey) -> SymbolRef { + pub fn alloc_schema_symbol( + &mut self, + schema: SchemaSymbol, + node_key: NodeKey, + pkg_name: String, + ) -> SymbolRef { self.symbols_info.symbol_pos_set.insert(schema.end.clone()); let symbol_id = self.schemas.insert(schema); let symbol_ref = SymbolRef { @@ -514,6 +571,7 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.schemas.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } @@ -521,6 +579,7 @@ impl SymbolData { &mut self, unresolved: UnresolvedSymbol, node_key: NodeKey, + pkg_name: String, ) -> SymbolRef { self.symbols_info .symbol_pos_set @@ -537,6 +596,7 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.unresolved.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } @@ -544,6 +604,7 @@ impl SymbolData { &mut self, alias: TypeAliasSymbol, node_key: NodeKey, + pkg_name: String, ) -> SymbolRef { self.symbols_info.symbol_pos_set.insert(alias.end.clone()); let symbol_id = self.type_aliases.insert(alias); @@ -558,10 +619,16 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.type_aliases.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } - pub fn alloc_rule_symbol(&mut self, rule: RuleSymbol, node_key: NodeKey) -> SymbolRef { + pub fn alloc_rule_symbol( + &mut self, + rule: RuleSymbol, + node_key: NodeKey, + pkg_name: String, + ) -> SymbolRef { self.symbols_info.symbol_pos_set.insert(rule.end.clone()); let symbol_id = self.rules.insert(rule); let symbol_ref = SymbolRef { @@ -575,6 +642,7 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.rules.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } @@ -582,6 +650,7 @@ impl SymbolData { &mut self, attribute: AttributeSymbol, node_key: NodeKey, + pkg_name: String, ) -> SymbolRef { self.symbols_info .symbol_pos_set @@ -598,10 +667,16 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.attributes.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } - pub fn alloc_value_symbol(&mut self, value: ValueSymbol, node_key: NodeKey) -> SymbolRef { + pub fn alloc_value_symbol( + &mut self, + value: ValueSymbol, + node_key: NodeKey, + pkg_name: String, + ) -> SymbolRef { self.symbols_info.symbol_pos_set.insert(value.end.clone()); let symbol_id = self.values.insert(value); let symbol_ref = SymbolRef { @@ -615,6 +690,7 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.values.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } @@ -622,6 +698,7 @@ impl SymbolData { &mut self, expr: ExpressionSymbol, node_key: NodeKey, + pkg_name: String, ) -> Option { if self.symbols_info.symbol_pos_set.contains(&expr.end) { return None; @@ -639,6 +716,7 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.exprs.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); Some(symbol_ref) } @@ -646,6 +724,7 @@ impl SymbolData { &mut self, comment: CommentSymbol, node_key: NodeKey, + pkg_name: String, ) -> Option { let symbol_id = self.comments.insert(comment); let symbol_ref = SymbolRef { @@ -659,6 +738,7 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.comments.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); Some(symbol_ref) } @@ -666,6 +746,7 @@ impl SymbolData { &mut self, decorator: DecoratorSymbol, node_key: NodeKey, + pkg_name: String, ) -> Option { let symbol_id = self.decorators.insert(decorator); let symbol_ref = SymbolRef { @@ -679,6 +760,7 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.decorators.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); Some(symbol_ref) } @@ -701,6 +783,19 @@ impl SymbolData { pub fn get_builtin_symbols(&self) -> &IndexMap { &self.symbols_info.global_builtin_symbols } + + pub fn clear_cache(&mut self, invalidate_pkgs: &HashSet) { + let mut to_remove: Vec = Vec::new(); + + for invalidate_pkg in invalidate_pkgs { + if let Some(symbols) = self.symbols_info.pkg_symbol_map.get(invalidate_pkg) { + to_remove.extend(symbols.iter().cloned()); + } + } + for symbol in to_remove { + self.remove_symbol(&symbol); + } + } } #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)] diff --git a/kclvm/sema/src/namer/mod.rs b/kclvm/sema/src/namer/mod.rs index 70125637d..b3d9f2dd7 100644 --- a/kclvm/sema/src/namer/mod.rs +++ b/kclvm/sema/src/namer/mod.rs @@ -45,7 +45,9 @@ use crate::builtin::{ }; use crate::core::global_state::GlobalState; use crate::core::package::{ModuleInfo, PackageInfo}; -use crate::core::symbol::{PackageSymbol, SymbolRef, ValueSymbol, BUILTIN_STR_PACKAGE}; +use crate::core::symbol::{ + PackageSymbol, SymbolRef, ValueSymbol, BUILTIN_FUNCTION_PACKAGE, BUILTIN_STR_PACKAGE, +}; use crate::resolver::scope::NodeKey; use indexmap::IndexSet; use kclvm_ast::ast::AstIndex; @@ -57,7 +59,7 @@ mod node; pub const BUILTIN_SYMBOL_PKG_PATH: &str = "@builtin"; pub struct Namer<'ctx> { - gs: GlobalState, + gs: &'ctx mut GlobalState, ctx: NamerContext<'ctx>, } @@ -83,7 +85,7 @@ impl<'ctx> NamerContext<'ctx> { } impl<'ctx> Namer<'ctx> { - fn new(program: &'ctx Program, gs: GlobalState) -> Self { + fn new(program: &'ctx Program, gs: &'ctx mut GlobalState) -> Self { Self { ctx: NamerContext { program, @@ -97,7 +99,7 @@ impl<'ctx> Namer<'ctx> { } // serial namer pass - pub fn find_symbols(program: &'ctx Program, gs: GlobalState) -> GlobalState { + pub fn find_symbols(program: &'ctx Program, gs: &'ctx mut GlobalState) { let mut namer = Self::new(program, gs); namer.ctx.current_package_info = Some(PackageInfo::new( BUILTIN_SYMBOL_PKG_PATH.to_string(), @@ -136,7 +138,10 @@ impl<'ctx> Namer<'ctx> { }; let pkg_symbol = PackageSymbol::new(name.clone(), pkg_pos.clone(), pkg_pos); - let symbol_ref = namer.gs.get_symbols_mut().alloc_package_symbol(pkg_symbol); + let symbol_ref = namer + .gs + .get_symbols_mut() + .alloc_package_symbol(pkg_symbol, name.to_string()); namer.ctx.owner_symbols.push(symbol_ref); namer.ctx.current_package_info = @@ -169,7 +174,7 @@ impl<'ctx> Namer<'ctx> { namer.define_symbols(); - namer.gs + // namer.gs } fn init_builtin_symbols(&mut self) { @@ -184,10 +189,11 @@ impl<'ctx> Namer<'ctx> { ); value_symbol.sema_info.ty = Some(Arc::new(builtin_func.clone())); value_symbol.sema_info.doc = builtin_func.ty_doc(); - let symbol_ref = self - .gs - .get_symbols_mut() - .alloc_value_symbol(value_symbol, self.ctx.get_node_key(&AstIndex::default())); + let symbol_ref = self.gs.get_symbols_mut().alloc_value_symbol( + value_symbol, + self.ctx.get_node_key(&AstIndex::default()), + BUILTIN_FUNCTION_PACKAGE.to_string(), + ); self.gs .get_symbols_mut() .symbols_info @@ -197,14 +203,14 @@ impl<'ctx> Namer<'ctx> { //add system modules for system_pkg_name in STANDARD_SYSTEM_MODULES { - let package_symbol_ref = - self.gs - .get_symbols_mut() - .alloc_package_symbol(PackageSymbol::new( - system_pkg_name.to_string(), - Position::dummy_pos(), - Position::dummy_pos(), - )); + let package_symbol_ref = self.gs.get_symbols_mut().alloc_package_symbol( + PackageSymbol::new( + system_pkg_name.to_string(), + Position::dummy_pos(), + Position::dummy_pos(), + ), + system_pkg_name.to_string(), + ); for func_name in get_system_module_members(system_pkg_name) { let func_ty = get_system_member_function_ty(*system_pkg_name, func_name); let mut value_symbol = ValueSymbol::new( @@ -216,10 +222,11 @@ impl<'ctx> Namer<'ctx> { ); value_symbol.sema_info.ty = Some(func_ty.clone()); value_symbol.sema_info.doc = func_ty.ty_doc(); - let func_symbol_ref = self - .gs - .get_symbols_mut() - .alloc_value_symbol(value_symbol, self.ctx.get_node_key(&AstIndex::default())); + let func_symbol_ref = self.gs.get_symbols_mut().alloc_value_symbol( + value_symbol, + self.ctx.get_node_key(&AstIndex::default()), + system_pkg_name.to_string(), + ); self.gs .get_symbols_mut() .packages @@ -231,14 +238,14 @@ impl<'ctx> Namer<'ctx> { } //add string builtin function - let package_symbol_ref = - self.gs - .get_symbols_mut() - .alloc_package_symbol(PackageSymbol::new( - BUILTIN_STR_PACKAGE.to_string(), - Position::dummy_pos(), - Position::dummy_pos(), - )); + let package_symbol_ref = self.gs.get_symbols_mut().alloc_package_symbol( + PackageSymbol::new( + BUILTIN_STR_PACKAGE.to_string(), + Position::dummy_pos(), + Position::dummy_pos(), + ), + BUILTIN_STR_PACKAGE.to_string(), + ); for (name, builtin_func) in STRING_MEMBER_FUNCTIONS.iter() { let mut value_symbol = ValueSymbol::new( name.to_string(), @@ -249,10 +256,11 @@ impl<'ctx> Namer<'ctx> { ); value_symbol.sema_info.ty = Some(Arc::new(builtin_func.clone())); value_symbol.sema_info.doc = builtin_func.ty_doc(); - let symbol_ref = self - .gs - .get_symbols_mut() - .alloc_value_symbol(value_symbol, self.ctx.get_node_key(&AstIndex::default())); + let symbol_ref = self.gs.get_symbols_mut().alloc_value_symbol( + value_symbol, + self.ctx.get_node_key(&AstIndex::default()), + BUILTIN_STR_PACKAGE.to_string(), + ); self.gs .get_symbols_mut() .packages @@ -288,8 +296,9 @@ mod tests { ) .unwrap() .program; - let gs = GlobalState::default(); - let gs = Namer::find_symbols(&program, gs); + let mut gs = GlobalState::default(); + // let gs = Namer::find_symbols(&program, gs); + Namer::find_symbols(&program, &mut gs); let symbols = gs.get_symbols(); diff --git a/kclvm/sema/src/namer/node.rs b/kclvm/sema/src/namer/node.rs index 71e0cb1bf..d1e4d1e5b 100644 --- a/kclvm/sema/src/namer/node.rs +++ b/kclvm/sema/src/namer/node.rs @@ -68,6 +68,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { let value_ref = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(value_name, start_pos, end_pos, Some(owner), true), self.ctx.get_node_key(&unification_stmt.target.id), + self.ctx + .current_package_info + .clone() + .unwrap() + .fully_qualified_name, ); self.ctx .value_fully_qualified_name_set @@ -92,6 +97,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { owner, ), self.ctx.get_node_key(&type_alias_stmt.type_name.id), + self.ctx + .current_package_info + .clone() + .unwrap() + .fully_qualified_name, ); Some(vec![type_alias_ref]) } @@ -117,6 +127,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { let value_ref = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(value_name, start_pos, end_pos, Some(owner), true), self.ctx.get_node_key(&target.id), + self.ctx + .current_package_info + .clone() + .unwrap() + .fully_qualified_name, ); self.ctx .value_fully_qualified_name_set @@ -172,6 +187,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { let shcema_ref = self.gs.get_symbols_mut().alloc_schema_symbol( SchemaSymbol::new(schema_stmt.name.node.clone(), start_pos, end_pos, *owner), self.ctx.get_node_key(&schema_stmt.name.id), + self.ctx + .current_package_info + .clone() + .unwrap() + .fully_qualified_name, ); self.ctx.owner_symbols.push(shcema_ref); @@ -214,6 +234,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { let rule_ref = self.gs.get_symbols_mut().alloc_rule_symbol( RuleSymbol::new(rule_stmt.name.node.clone(), start_pos, end_pos, owner), self.ctx.get_node_key(&rule_stmt.name.id), + self.ctx + .current_package_info + .clone() + .unwrap() + .fully_qualified_name, ); Some(vec![rule_ref]) } @@ -228,6 +253,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { let attribute_ref = self.gs.get_symbols_mut().alloc_attribute_symbol( AttributeSymbol::new(schema_attr.name.node.clone(), start_pos, end_pos, owner), self.ctx.get_node_key(&schema_attr.name.id), + self.ctx + .current_package_info + .clone() + .unwrap() + .fully_qualified_name, ); Some(vec![attribute_ref]) } diff --git a/kclvm/sema/src/resolver/arg.rs b/kclvm/sema/src/resolver/arg.rs index 9570a32db..0e8b4c785 100644 --- a/kclvm/sema/src/resolver/arg.rs +++ b/kclvm/sema/src/resolver/arg.rs @@ -49,6 +49,7 @@ impl<'ctx> Resolver<'ctx> { check_table.insert(arg_name.to_string()); let arg_value_type = self.expr_or_any_type(&kw.node.value); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(kw.id.clone()), arg_value_type.clone()); kwarg_types.push((arg_name.to_string(), arg_value_type.clone())); } else { diff --git a/kclvm/sema/src/resolver/mod.rs b/kclvm/sema/src/resolver/mod.rs index bfd63d5e7..0204ca6b9 100644 --- a/kclvm/sema/src/resolver/mod.rs +++ b/kclvm/sema/src/resolver/mod.rs @@ -22,6 +22,7 @@ mod tests; use indexmap::IndexMap; use kclvm_error::diagnostic::Range; use std::sync::Arc; +use std::time::Instant; use std::{cell::RefCell, rc::Rc}; use crate::lint::{CombinedLintPass, Linter}; @@ -43,7 +44,7 @@ pub struct Resolver<'ctx> { pub scope_map: IndexMap>>, pub scope: Rc>, pub scope_level: usize, - pub node_ty_map: NodeTyMap, + pub node_ty_map: Rc>, pub builtin_scope: Rc>, pub ctx: Context, pub options: Options, @@ -61,7 +62,7 @@ impl<'ctx> Resolver<'ctx> { builtin_scope, scope, scope_level: 0, - node_ty_map: IndexMap::default(), + node_ty_map: Rc::new(RefCell::new(IndexMap::default())), ctx: Context::default(), options, handler: Handler::default(), @@ -180,14 +181,14 @@ pub fn resolve_program_with_opts( resolver.resolve_import(); if let Some(cached_scope) = cached_scope.as_ref() { if let Ok(mut cached_scope) = cached_scope.try_lock() { + cached_scope.invalidate_pkgs.clear(); cached_scope.update(program); resolver.scope_map = cached_scope.scope_map.clone(); resolver.scope_map.remove(kclvm_ast::MAIN_PKG); + resolver.node_ty_map = cached_scope.node_ty_map.clone(); cached_scope - .gs - .new_or_invalidate_pkgs + .invalidate_pkgs .insert(kclvm_ast::MAIN_PKG.to_string()); - resolver.node_ty_map = cached_scope.node_ty_map.clone() } } let scope = resolver.check_and_lint(kclvm_ast::MAIN_PKG); @@ -198,8 +199,7 @@ pub fn resolve_program_with_opts( cached_scope.node_ty_map = scope.node_ty_map.clone(); cached_scope.scope_map.remove(kclvm_ast::MAIN_PKG); cached_scope - .gs - .new_or_invalidate_pkgs + .invalidate_pkgs .insert(kclvm_ast::MAIN_PKG.to_string()); } } diff --git a/kclvm/sema/src/resolver/node.rs b/kclvm/sema/src/resolver/node.rs index bf8bed63c..622e83d70 100644 --- a/kclvm/sema/src/resolver/node.rs +++ b/kclvm/sema/src/resolver/node.rs @@ -118,7 +118,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { doc: None, }, ); - self.node_ty_map.insert( + self.node_ty_map.borrow_mut().insert( self.get_node_key(type_alias_stmt.type_name.id.clone()), ty.clone(), ); @@ -375,7 +375,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { .get_type_of_attr(name) .map_or(self.any_ty(), |ty| ty); - self.node_ty_map.insert( + self.node_ty_map.borrow_mut().insert( self.get_node_key(schema_attr.name.id.clone()), expected_ty.clone(), ); @@ -511,6 +511,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { selector_expr.attr.get_span_pos(), ); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), value_ty.clone()); } @@ -927,7 +928,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { ); let init_stack_depth = self.switch_config_expr_context(Some(obj)); self.expr(&schema_expr.config); - self.node_ty_map.insert( + self.node_ty_map.borrow_mut().insert( self.get_node_key(schema_expr.config.id.clone()), def_ty.clone(), ); @@ -1012,6 +1013,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { }; if let Some(name) = arg.node.names.last() { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), ty.clone()); } @@ -1080,6 +1082,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { let ty = self.parse_ty_with_scope(ty, arg.get_span_pos()); if let Some(name) = arg.node.names.last() { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), ty.clone()); } let value = &arguments.defaults[i]; @@ -1118,6 +1121,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { ); for (index, name) in identifier.names.iter().enumerate() { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), tys[index].clone()); } tys.last().unwrap().clone() @@ -1220,6 +1224,7 @@ impl<'ctx> Resolver<'ctx> { } let ty = self.walk_expr(&expr.node); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(expr.id.clone()), ty.clone()); ty } @@ -1231,6 +1236,7 @@ impl<'ctx> Resolver<'ctx> { self.ctx.end_pos = end; let ty = self.walk_stmt(&stmt.node); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(stmt.id.clone()), ty.clone()); ty } @@ -1244,6 +1250,7 @@ impl<'ctx> Resolver<'ctx> { Some(expr) => { let ty = self.walk_expr(&expr.node); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(expr.id.clone()), ty.clone()); ty } @@ -1263,10 +1270,12 @@ impl<'ctx> Resolver<'ctx> { ); for (index, name) in identifier.node.names.iter().enumerate() { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), tys[index].clone()); } let ident_ty = tys.last().unwrap().clone(); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(identifier.id.clone()), ident_ty.clone()); ident_ty diff --git a/kclvm/sema/src/resolver/schema.rs b/kclvm/sema/src/resolver/schema.rs index 043716bcb..bd1e97d22 100644 --- a/kclvm/sema/src/resolver/schema.rs +++ b/kclvm/sema/src/resolver/schema.rs @@ -24,6 +24,7 @@ impl<'ctx> Resolver<'ctx> { let ty = self.lookup_type_from_scope(&schema_stmt.name.node, schema_stmt.name.get_span_pos()); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(schema_stmt.name.id.clone()), ty.clone()); let scope_ty = if ty.is_schema() { ty.into_schema_type() @@ -47,6 +48,7 @@ impl<'ctx> Resolver<'ctx> { let ty = self.parse_ty_with_scope(ty, arg.get_span_pos()); if let Some(name) = arg.node.names.last() { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), ty.clone()); } } @@ -136,6 +138,7 @@ impl<'ctx> Resolver<'ctx> { self.resolve_unique_key(&rule_stmt.name.node, &rule_stmt.name.get_span_pos()); let ty = self.lookup_type_from_scope(&rule_stmt.name.node, rule_stmt.name.get_span_pos()); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(rule_stmt.name.id.clone()), ty.clone()); let scope_ty = if ty.is_schema() { ty.into_schema_type() diff --git a/kclvm/sema/src/resolver/scope.rs b/kclvm/sema/src/resolver/scope.rs index f68d46b9e..e105e4e99 100644 --- a/kclvm/sema/src/resolver/scope.rs +++ b/kclvm/sema/src/resolver/scope.rs @@ -17,7 +17,6 @@ use std::{ rc::{Rc, Weak}, }; -use crate::core::global_state::GlobalState; use crate::resolver::Resolver; use crate::ty::TypeRef; use crate::{builtin::BUILTIN_FUNCTIONS, ty::TypeInferMethods}; @@ -285,7 +284,7 @@ impl Scope { pub struct ProgramScope { pub scope_map: IndexMap>>, pub import_names: IndexMap>, - pub node_ty_map: NodeTyMap, + pub node_ty_map: Rc>, pub handler: Handler, } @@ -459,6 +458,7 @@ impl<'ctx> Resolver<'ctx> { let mut obj = obj.borrow_mut(); let infer_ty = self.ctx.ty_ctx.infer_to_variable_type(ty); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(node.id.clone()), infer_ty.clone()); obj.ty = infer_ty; } @@ -509,8 +509,9 @@ pub type KCLScopeCache = Arc>; pub struct CachedScope { pub program_root: String, pub scope_map: IndexMap>>, - pub node_ty_map: NodeTyMap, - pub gs: GlobalState, + pub node_ty_map: Rc>, + // pub gs: GlobalState, + pub invalidate_pkgs: HashSet, dependency_graph: DependencyGraph, } @@ -674,7 +675,7 @@ impl CachedScope { program_root: program.root.to_string(), scope_map: scope.scope_map.clone(), node_ty_map: scope.node_ty_map.clone(), - gs: GlobalState::default(), + invalidate_pkgs: HashSet::default(), dependency_graph: DependencyGraph::default(), }; let invalidated_pkgs = cached_scope.dependency_graph.update(program); @@ -684,9 +685,10 @@ impl CachedScope { pub fn clear(&mut self) { self.scope_map.clear(); - self.node_ty_map.clear(); + self.node_ty_map.borrow_mut().clear(); self.dependency_graph.clear(); - self.gs = GlobalState::default(); + self.invalidate_pkgs.clear(); + // self.gs = GlobalState::default(); } pub fn invalidate_cache(&mut self, invalidated_pkgs: Result<&HashSet, &String>) { @@ -695,7 +697,7 @@ impl CachedScope { for invalidated_pkg in invalidated_pkgs.iter() { self.scope_map.remove(invalidated_pkg); } - self.gs.new_or_invalidate_pkgs = invalidated_pkgs.clone(); + self.invalidate_pkgs = invalidated_pkgs.clone(); } Err(_) => self.clear(), } diff --git a/kclvm/sema/src/resolver/ty.rs b/kclvm/sema/src/resolver/ty.rs index 8e23f9b1e..3636879e4 100644 --- a/kclvm/sema/src/resolver/ty.rs +++ b/kclvm/sema/src/resolver/ty.rs @@ -77,6 +77,7 @@ impl<'ctx> Resolver<'ctx> { ); if let Some(ty) = ty_node { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(ty.id.clone()), ret_ty.clone()); }; ret_ty @@ -369,10 +370,12 @@ impl<'ctx> Resolver<'ctx> { if let ast::Type::Named(identifier) = &ty_node.node { for (index, name) in identifier.names.iter().enumerate() { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), tys[index].clone()); } let ident_ty = tys.last().unwrap().clone(); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(ty_node.id.clone()), ident_ty.clone()); } }; diff --git a/kclvm/tools/src/LSP/src/find_refs.rs b/kclvm/tools/src/LSP/src/find_refs.rs index 2b3472e4e..2e4a46d69 100644 --- a/kclvm/tools/src/LSP/src/find_refs.rs +++ b/kclvm/tools/src/LSP/src/find_refs.rs @@ -3,13 +3,11 @@ use crate::goto_def::{find_def_with_gs, goto_definition_with_gs}; use crate::to_lsp::lsp_location; use crate::util::{compile_with_params, Params}; -use crate::state::{KCLCompileUnitCache, KCLVfs, KCLWordIndexMap}; +use crate::state::{KCLVfs, KCLWordIndexMap}; use anyhow::Result; use kclvm_ast::ast::Program; use kclvm_error::Position as KCLPos; -use kclvm_parser::KCLModuleCache; use kclvm_sema::core::global_state::GlobalState; -use kclvm_sema::resolver::scope::KCLScopeCache; use lsp_types::Location; const FIND_REFS_LIMIT: usize = 20; @@ -22,9 +20,6 @@ pub(crate) fn find_refs Result<(), anyhow::Error>>( vfs: Option, logger: F, gs: &GlobalState, - module_cache: Option, - scope_cache: Option, - compile_unit_cache: Option, ) -> Result, String> { let def = find_def_with_gs(kcl_pos, gs, true); match def { @@ -41,9 +36,6 @@ pub(crate) fn find_refs Result<(), anyhow::Error>>( include_declaration, Some(FIND_REFS_LIMIT), logger, - module_cache, - scope_cache, - compile_unit_cache, )) } else { Err(format!("Invalid file path: {0}", start.filename)) @@ -67,9 +59,6 @@ pub(crate) fn find_refs_from_def Result<(), anyhow::Error>>( include_declaration: bool, limit: Option, logger: F, - module_cache: Option, - scope_cache: Option, - compile_unit_cache: Option, ) -> Vec { let mut ref_locations = vec![]; for word_index in (*word_index_map.write()).values_mut() { @@ -92,10 +81,11 @@ pub(crate) fn find_refs_from_def Result<(), anyhow::Error>>( Ok(file_path) => { match compile_with_params(Params { file: file_path.clone(), - module_cache: module_cache.clone(), - scope_cache: scope_cache.clone(), + module_cache: None, + scope_cache: None, vfs: vfs.clone(), - compile_unit_cache: compile_unit_cache.clone(), + compile_unit_cache: None, + gs_cache: None, }) { Ok((prog, _, gs)) => { let ref_pos = kcl_pos(&file_path, ref_loc.range.start); @@ -218,9 +208,6 @@ mod tests { true, Some(20), logger, - None, - None, - None, ), ); } @@ -276,9 +263,6 @@ mod tests { false, Some(20), logger, - None, - None, - None, ), ); } @@ -334,9 +318,6 @@ mod tests { true, Some(20), logger, - None, - None, - None, ), ); } @@ -385,9 +366,6 @@ mod tests { true, Some(20), logger, - None, - None, - None, ), ); } diff --git a/kclvm/tools/src/LSP/src/quick_fix.rs b/kclvm/tools/src/LSP/src/quick_fix.rs index ea2e5cf28..5ba2acb53 100644 --- a/kclvm/tools/src/LSP/src/quick_fix.rs +++ b/kclvm/tools/src/LSP/src/quick_fix.rs @@ -156,6 +156,7 @@ mod tests { scope_cache: None, vfs: Some(KCLVfs::default()), compile_unit_cache: None, + gs_cache: None, }) .unwrap(); diff --git a/kclvm/tools/src/LSP/src/rename.rs b/kclvm/tools/src/LSP/src/rename.rs index 5b21549bf..86716f30c 100644 --- a/kclvm/tools/src/LSP/src/rename.rs +++ b/kclvm/tools/src/LSP/src/rename.rs @@ -190,12 +190,12 @@ where None, ); - let gs = GlobalState::default(); - let gs = Namer::find_symbols(&program, gs); - let node_ty_map = prog_scope.node_ty_map.clone(); - let global_state = AdvancedResolver::resolve_program(&program, gs, node_ty_map); + let mut gs = GlobalState::default(); + Namer::find_symbols(&program, &mut gs); + let node_ty_map = prog_scope.node_ty_map; + AdvancedResolver::resolve_program(&program, &mut gs, node_ty_map); - Ok((program, global_state)) + Ok((program, gs)) } fn apply_rename_changes( diff --git a/kclvm/tools/src/LSP/src/request.rs b/kclvm/tools/src/LSP/src/request.rs index 61dcf6f8d..4c457876c 100644 --- a/kclvm/tools/src/LSP/src/request.rs +++ b/kclvm/tools/src/LSP/src/request.rs @@ -265,9 +265,6 @@ pub(crate) fn handle_reference( let db = snapshot.get_db(&path.clone().into())?; let pos = kcl_pos(&file, params.text_document_position.position); let log = |msg: String| log_message(msg, &sender); - let module_cache = snapshot.module_cache.clone(); - let _scope_cache = snapshot.scope_cache.clone(); - let compile_unit_cache = snapshot.compile_unit_cache.clone(); match find_refs( &db.prog, &pos, @@ -276,9 +273,6 @@ pub(crate) fn handle_reference( Some(snapshot.vfs.clone()), log, &db.gs, - Some(module_cache), - None, - Some(compile_unit_cache), ) { core::result::Result::Ok(locations) => Ok(Some(locations)), Err(msg) => { @@ -386,9 +380,6 @@ pub(crate) fn handle_rename( Some(snapshot.vfs.clone()), log, &db.gs, - Some(snapshot.module_cache), - Some(snapshot.scope_cache), - Some(snapshot.compile_unit_cache), ); match references { Result::Ok(locations) => { diff --git a/kclvm/tools/src/LSP/src/state.rs b/kclvm/tools/src/LSP/src/state.rs index 8d9b26655..a2fced075 100644 --- a/kclvm/tools/src/LSP/src/state.rs +++ b/kclvm/tools/src/LSP/src/state.rs @@ -8,6 +8,7 @@ use crate::word_index::build_word_index; use anyhow::Result; use crossbeam_channel::{select, unbounded, Receiver, Sender}; use kclvm_parser::{KCLModuleCache, LoadProgramOptions}; +use kclvm_sema::core::global_state::GlobalState; use kclvm_sema::resolver::scope::KCLScopeCache; use lsp_server::{ReqQueue, Request, Response}; use lsp_types::Url; @@ -18,6 +19,7 @@ use lsp_types::{ use parking_lot::RwLock; use ra_ap_vfs::{ChangeKind, ChangedFile, FileId, Vfs}; use std::collections::HashMap; +use std::sync::Mutex; use std::thread; use std::time::Duration; use std::{sync::Arc, time::Instant}; @@ -49,6 +51,7 @@ pub(crate) type KCLVfs = Arc>; pub(crate) type KCLWordIndexMap = Arc>>>>; pub(crate) type KCLCompileUnitCache = Arc, Option)>>>; +pub(crate) type KCLGlobalStateCache = Arc>; /// State for the language server pub(crate) struct LanguageServerState { @@ -96,6 +99,8 @@ pub(crate) struct LanguageServerState { /// KCL compile unit cache cache pub compile_unit_cache: KCLCompileUnitCache, + + pub gs_cache: KCLGlobalStateCache, } /// A snapshot of the state of the language server @@ -150,6 +155,7 @@ impl LanguageServerState { module_cache: KCLModuleCache::default(), scope_cache: KCLScopeCache::default(), compile_unit_cache: KCLCompileUnitCache::default(), + gs_cache: KCLGlobalStateCache::default(), }; let word_index_map = state.word_index_map.clone(); @@ -238,6 +244,7 @@ impl LanguageServerState { let module_cache = Arc::clone(&self.module_cache); let scope_cache = Arc::clone(&self.scope_cache); let compile_unit_cache = Arc::clone(&self.compile_unit_cache); + let gs_cache = Arc::clone(&self.gs_cache); move || match url(&snapshot, file.file_id) { Ok(uri) => { let version = @@ -249,6 +256,7 @@ impl LanguageServerState { scope_cache: Some(scope_cache), vfs: Some(snapshot.vfs), compile_unit_cache: Some(compile_unit_cache), + gs_cache: Some(gs_cache), }) { Ok((prog, diags, gs)) => { let current_version = snapshot diff --git a/kclvm/tools/src/LSP/src/tests.rs b/kclvm/tools/src/LSP/src/tests.rs index 6811f0977..5c7c8288d 100644 --- a/kclvm/tools/src/LSP/src/tests.rs +++ b/kclvm/tools/src/LSP/src/tests.rs @@ -76,6 +76,7 @@ use crate::goto_def::goto_definition_with_gs; use crate::hover::hover; use crate::main_loop::main_loop; use crate::state::KCLCompileUnitCache; +use crate::state::KCLGlobalStateCache; use crate::state::KCLVfs; use crate::to_lsp::kcl_diag_to_lsp_diags; use crate::util::compile_unit_with_cache; @@ -132,6 +133,7 @@ pub(crate) fn compile_test_file( scope_cache: Some(KCLScopeCache::default()), vfs: Some(KCLVfs::default()), compile_unit_cache: Some(KCLCompileUnitCache::default()), + gs_cache: Some(KCLGlobalStateCache::default()), }) .unwrap(); (file, program, diags, gs) @@ -294,6 +296,7 @@ fn diagnostics_test() { scope_cache: None, vfs: Some(KCLVfs::default()), compile_unit_cache: Some(KCLCompileUnitCache::default()), + gs_cache: Some(KCLGlobalStateCache::default()), }) .unwrap(); @@ -481,6 +484,7 @@ fn complete_import_external_file_test() { scope_cache: None, vfs: Some(KCLVfs::default()), compile_unit_cache: Some(KCLCompileUnitCache::default()), + gs_cache: Some(KCLGlobalStateCache::default()), }) .unwrap(); @@ -539,6 +543,7 @@ fn goto_import_external_file_test() { scope_cache: None, vfs: Some(KCLVfs::default()), compile_unit_cache: Some(KCLCompileUnitCache::default()), + gs_cache: Some(KCLGlobalStateCache::default()), }) .unwrap(); @@ -1384,6 +1389,7 @@ fn konfig_goto_def_test_base() { scope_cache: None, vfs: Some(KCLVfs::default()), compile_unit_cache: Some(KCLCompileUnitCache::default()), + gs_cache: Some(KCLGlobalStateCache::default()), }) .unwrap(); @@ -1476,6 +1482,7 @@ fn konfig_goto_def_test_main() { scope_cache: None, vfs: Some(KCLVfs::default()), compile_unit_cache: Some(KCLCompileUnitCache::default()), + gs_cache: Some(KCLGlobalStateCache::default()), }) .unwrap(); @@ -1540,6 +1547,7 @@ fn konfig_completion_test_main() { scope_cache: None, vfs: Some(KCLVfs::default()), compile_unit_cache: Some(KCLCompileUnitCache::default()), + gs_cache: Some(KCLGlobalStateCache::default()), }) .unwrap(); @@ -1650,6 +1658,7 @@ fn konfig_hover_test_main() { scope_cache: None, vfs: Some(KCLVfs::default()), compile_unit_cache: Some(KCLCompileUnitCache::default()), + gs_cache: Some(KCLGlobalStateCache::default()), }) .unwrap(); @@ -2076,6 +2085,7 @@ fn compile_unit_test() { scope_cache: None, vfs: Some(KCLVfs::default()), compile_unit_cache: Some(KCLCompileUnitCache::default()), + gs_cache: Some(KCLGlobalStateCache::default()), }) .unwrap(); // b.k is not contained in kcl.yaml but need to be contained in main pkg diff --git a/kclvm/tools/src/LSP/src/util.rs b/kclvm/tools/src/LSP/src/util.rs index 877278721..cbe57a7fe 100644 --- a/kclvm/tools/src/LSP/src/util.rs +++ b/kclvm/tools/src/LSP/src/util.rs @@ -19,14 +19,14 @@ use kclvm_sema::resolver::resolve_program_with_opts; use kclvm_sema::resolver::scope::KCLScopeCache; use crate::from_lsp; -use crate::state::{KCLCompileUnitCache, KCLVfs}; +use crate::state::{KCLCompileUnitCache, KCLGlobalStateCache, KCLVfs}; use lsp_types::Url; use parking_lot::RwLockReadGuard; use ra_ap_vfs::{FileId, Vfs}; use serde::{de::DeserializeOwned, Serialize}; +use std::collections::HashSet; use std::path::Path; -use std::time::Instant; use std::{fs, panic}; #[allow(unused)] @@ -66,6 +66,7 @@ pub(crate) struct Params { pub scope_cache: Option, pub vfs: Option, pub compile_unit_cache: Option, + pub gs_cache: Option, } pub(crate) fn compile_unit_with_cache( @@ -93,7 +94,6 @@ pub(crate) fn compile_with_params( ) -> anyhow::Result<(Program, IndexSet, GlobalState)> { // Lookup compile unit (kcl.mod or kcl.yaml) from the entry file. let (mut files, opt) = compile_unit_with_cache(¶ms.compile_unit_cache, ¶ms.file); - if !files.contains(¶ms.file) { files.push(params.file.clone()); } @@ -105,6 +105,7 @@ pub(crate) fn compile_with_params( let mut k_code_list = load_files_code_from_vfs(&files, vfs)?; opt.k_code_list.append(&mut k_code_list); } + match panic::catch_unwind(move || { // Parser let sess = ParseSessionRef::default(); @@ -121,28 +122,35 @@ pub(crate) fn compile_with_params( }, params.scope_cache.clone(), ); - let gs = if let Some(cache) = ¶ms.scope_cache { - match cache.try_lock() { - // todo: remove clone - Ok(cache) => cache.gs.clone(), - Err(_) => GlobalState::default(), - } - } else { - GlobalState::default() + let mut default = GlobalState::default(); + let mut gs_ref; + + let mut gs = match ¶ms.gs_cache { + Some(cache) => match cache.try_lock() { + Ok(locked_state) => { + gs_ref = locked_state; + &mut gs_ref + } + Err(_) => &mut default, + }, + None => &mut default, }; - let gs = Namer::find_symbols(&program, gs); - let gs = AdvancedResolver::resolve_program(&program, gs, prog_scope.node_ty_map.clone()); + gs.new_or_invalidate_pkgs = match ¶ms.scope_cache { + Some(cache) => match cache.try_lock() { + Ok(scope) => scope.invalidate_pkgs.clone(), + Err(_) => HashSet::new(), + }, + None => HashSet::new(), + }; + gs.clear_cache(); - if let Some(cache) = ¶ms.scope_cache { - // todo: remove clone - cache.lock().unwrap().gs = gs.clone(); - } + Namer::find_symbols(&program, &mut gs); + AdvancedResolver::resolve_program(&program, &mut gs, prog_scope.node_ty_map); - // Merge parse diagnostic and resolve diagnostic sess.append_diagnostic(prog_scope.handler.diagnostics.clone()); let diags = sess.1.borrow().diagnostics.clone(); - Ok((program, diags, gs)) + return Ok((program, diags, gs.clone())); }) { Ok(res) => return res, Err(e) => Err(anyhow::anyhow!("Compile failed: {:?}", e)),