diff --git a/kclvm/api/src/service/service_impl.rs b/kclvm/api/src/service/service_impl.rs index cce3184e5..f5a95ed8d 100644 --- a/kclvm/api/src/service/service_impl.rs +++ b/kclvm/api/src/service/service_impl.rs @@ -231,7 +231,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 a79a6dbcf..f418e6c5c 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,8 @@ 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())?; + Namer::find_symbols(&program, gs); + AdvancedResolver::resolve_program(&program, gs, node_ty_map.clone())?; (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 3d647de96..e2cbd1a4f 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}; + 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, - ) -> anyhow::Result { + gs: &'ctx mut GlobalState, + node_ty_map: Rc>, + ) -> anyhow::Result<()> { let mut advanced_resolver = Self { gs, ctx: Context { @@ -111,8 +113,10 @@ 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) { + continue; + } advanced_resolver.ctx.current_pkgpath = Some(name.clone()); if let Some(pkg_info) = advanced_resolver.gs.get_packages().get_package_info(name) { if modules.is_empty() { @@ -135,7 +139,8 @@ impl<'ctx> AdvancedResolver<'ctx> { } advanced_resolver.gs.build_sema_db(); - Ok(advanced_resolver.gs) + advanced_resolver.gs.new_or_invalidate_pkgs.clear(); + Ok(()) } fn enter_root_scope( @@ -290,8 +295,8 @@ 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(); + Namer::find_symbols(&program, &mut gs); let node_ty_map = resolver::resolve_program_with_opts( &mut program, @@ -303,7 +308,7 @@ mod tests { None, ) .node_ty_map; - let gs = AdvancedResolver::resolve_program(&program, gs, node_ty_map).unwrap(); + AdvancedResolver::resolve_program(&program, &mut gs, node_ty_map).unwrap(); let base_path = Path::new(".").canonicalize().unwrap(); // print_symbols_info(&gs); let except_symbols = vec![ @@ -1229,10 +1234,10 @@ 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(); + 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).unwrap(); + AdvancedResolver::resolve_program(&program, &mut gs, node_ty_map).unwrap(); let base_path = Path::new(".").canonicalize().unwrap(); let test_cases = vec![ @@ -1306,10 +1311,10 @@ 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(); + 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).unwrap(); + AdvancedResolver::resolve_program(&program, &mut gs, node_ty_map).unwrap(); 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 8a475ac68..da2d82521 100644 --- a/kclvm/sema/src/advanced_resolver/node.rs +++ b/kclvm/sema/src/advanced_resolver/node.rs @@ -77,6 +77,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, @@ -149,10 +150,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { None => return Ok(None), }; 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 @@ -170,8 +172,10 @@ 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)) - .ok_or(anyhow!("schema_ty not found"))?; + .ok_or(anyhow!("schema_ty not found"))? + .clone(); let schema_symbol = self .gs .get_symbols() @@ -204,6 +208,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); } @@ -277,12 +282,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, @@ -346,6 +353,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)) .ok_or(anyhow!("rule_ty not found"))? .clone(); @@ -364,6 +372,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()), @@ -419,6 +428,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() @@ -428,6 +438,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, @@ -478,6 +489,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, @@ -517,6 +529,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let mut parent_ty = match self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&selector_expr.value.id)) { Some(ty) => ty.clone(), @@ -536,16 +549,22 @@ 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() .add_ref_to_scope(cur_scope, unresolved_ref); - parent_ty = match self.ctx.node_ty_map.get(&self.ctx.get_node_key(&name.id)) { + parent_ty = match self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&name.id)) + { Some(ty) => ty.clone(), None => return Ok(None), }; @@ -683,6 +702,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)) .ok_or(anyhow!("schema_ty not found"))? .clone(); @@ -804,10 +824,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()); - Ok(self - .gs - .get_symbols_mut() - .alloc_comment_symbol(comment_symbol, self.ctx.get_node_key(&self.ctx.cur_node))) + Ok(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 { @@ -832,7 +853,12 @@ impl<'ctx> AdvancedResolver<'ctx> { } self.ctx.cur_node = expr.id.clone(); - if let Some(expr_ty) = self.ctx.node_ty_map.get(&self.ctx.get_node_key(&expr.id)) { + if let Some(expr_ty) = self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&expr.id)) + { match &expr_ty.kind { TypeKind::Schema(_) => { let schema_symbol = self @@ -852,7 +878,12 @@ impl<'ctx> AdvancedResolver<'ctx> { self.ctx.schema_symbol_stack.pop(); match expr_symbol { - Ok(None) => match self.ctx.node_ty_map.get(&self.ctx.get_node_key(&expr.id)) { + Ok(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 Ok(None); @@ -865,10 +896,11 @@ impl<'ctx> AdvancedResolver<'ctx> { None, ); expr_symbol.sema_info.ty = Some(ty.clone()); - Ok(self - .gs - .get_symbols_mut() - .alloc_expression_symbol(expr_symbol, self.ctx.get_node_key(&expr.id))) + Ok(self.gs.get_symbols_mut().alloc_expression_symbol( + expr_symbol, + self.ctx.get_node_key(&expr.id), + self.ctx.current_pkgpath.clone().unwrap(), + )) } None => Ok(None), }, @@ -921,6 +953,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 @@ -946,10 +979,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() @@ -959,6 +993,7 @@ impl<'ctx> AdvancedResolver<'ctx> { let mut parent_ty = match self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&first_name.id)) { Some(ty) => ty.clone(), @@ -981,17 +1016,22 @@ 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 = match self.ctx.node_ty_map.get(&self.ctx.get_node_key(&name.id)) + parent_ty = match self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&name.id)) { Some(ty) => ty.clone(), None => return Ok(None), @@ -1010,6 +1050,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, @@ -1027,6 +1068,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, @@ -1040,6 +1082,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( @@ -1055,6 +1098,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, @@ -1098,6 +1142,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, @@ -1183,6 +1228,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()) { @@ -1190,6 +1236,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, @@ -1257,6 +1304,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 b5ec23208..bd938c607 100644 --- a/kclvm/sema/src/core/global_state.rs +++ b/kclvm/sema/src/core/global_state.rs @@ -1,4 +1,6 @@ -use indexmap::IndexMap; +use std::collections::HashSet; + +use indexmap::{IndexMap, IndexSet}; use kclvm_error::Position; use super::{ @@ -19,6 +21,8 @@ pub struct GlobalState { packages: PackageDB, // store semantic information after analysis pub(crate) sema_db: SemanticDB, + // new and invalidate(changed and affected by changed) pkg from CachedScope::update() + pub new_or_invalidate_pkgs: HashSet, } impl GlobalState { @@ -49,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 { @@ -288,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, @@ -310,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, @@ -329,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, @@ -348,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, @@ -367,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, @@ -386,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, @@ -406,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, @@ -426,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, @@ -446,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, @@ -473,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 @@ -481,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 { @@ -500,7 +543,7 @@ impl GlobalState { }, ); file_sema_map - .get_mut(&filename) + .get_mut(filename) .unwrap() .scopes .push(scope_ref); @@ -535,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 3854fa9d4..a8488767c 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 37ace5323..ccd1e799f 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 { @@ -183,6 +185,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 => { @@ -498,17 +535,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 { @@ -522,6 +579,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 } @@ -529,6 +587,7 @@ impl SymbolData { &mut self, unresolved: UnresolvedSymbol, node_key: NodeKey, + pkg_name: String, ) -> SymbolRef { self.symbols_info .symbol_pos_set @@ -545,6 +604,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 } @@ -552,6 +612,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); @@ -566,10 +627,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 { @@ -583,6 +650,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 } @@ -590,6 +658,7 @@ impl SymbolData { &mut self, attribute: AttributeSymbol, node_key: NodeKey, + pkg_name: String, ) -> SymbolRef { self.symbols_info .symbol_pos_set @@ -606,10 +675,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 { @@ -623,6 +698,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 } @@ -630,6 +706,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; @@ -647,6 +724,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) } @@ -654,6 +732,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 { @@ -667,6 +746,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) } @@ -674,6 +754,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 { @@ -687,6 +768,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) } @@ -709,6 +791,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 8f2d14a1d..67143f2a3 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(), @@ -111,6 +113,16 @@ impl<'ctx> Namer<'ctx> { .add_package(namer.ctx.current_package_info.take().unwrap()); for (name, modules) in namer.ctx.program.pkgs.iter() { + // new pkgs or invalidate pkg + if namer.gs.get_packages().get_package_info(name).is_some() + && !namer.gs.new_or_invalidate_pkgs.contains(name) + { + continue; + } + + // add new pkgs to invalidate pkgs + namer.gs.new_or_invalidate_pkgs.insert(name.clone()); + { if modules.is_empty() { continue; @@ -131,7 +143,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 = @@ -164,7 +179,7 @@ impl<'ctx> Namer<'ctx> { namer.define_symbols(); - namer.gs + // namer.gs } fn init_builtin_symbols(&mut self) { @@ -179,10 +194,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 @@ -192,14 +208,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( @@ -211,10 +227,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 @@ -226,14 +243,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(), @@ -244,10 +261,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 @@ -283,8 +301,8 @@ mod tests { ) .unwrap() .program; - let gs = GlobalState::default(); - let gs = Namer::find_symbols(&program, gs); + let mut gs = GlobalState::default(); + 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 ab923cef7..e07af9545 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]) } @@ -234,6 +259,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { schema_attr.is_optional, ), 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 e3c7aa0bc..9be8fbf61 100644 --- a/kclvm/sema/src/resolver/arg.rs +++ b/kclvm/sema/src/resolver/arg.rs @@ -57,6 +57,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 a49f1523b..a7f60c0dd 100644 --- a/kclvm/sema/src/resolver/mod.rs +++ b/kclvm/sema/src/resolver/mod.rs @@ -43,7 +43,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 +61,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(), @@ -181,11 +181,15 @@ 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(); resolver.ctx.schema_mapping = cached_scope.schema_mapping.clone(); + cached_scope + .invalidate_pkgs + .insert(kclvm_ast::MAIN_PKG.to_string()); } } let scope = resolver.check_and_lint(kclvm_ast::MAIN_PKG); @@ -196,9 +200,11 @@ 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.schema_mapping = resolver.ctx.schema_mapping; + cached_scope + .invalidate_pkgs + .insert(kclvm_ast::MAIN_PKG.to_string()); } } - if opts.type_erasure { let type_alias_mapping = resolver.ctx.type_alias_mapping.clone(); // Erase all the function type to a named type "function" diff --git a/kclvm/sema/src/resolver/node.rs b/kclvm/sema/src/resolver/node.rs index 1e9d4cfa7..7f9ba1801 100644 --- a/kclvm/sema/src/resolver/node.rs +++ b/kclvm/sema/src/resolver/node.rs @@ -119,7 +119,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(), ); @@ -191,7 +191,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { expected_ty.clone(), &assign_stmt.value.get_span_pos(), ); - self.node_ty_map.insert( + self.node_ty_map.borrow_mut().insert( self.get_node_key(assign_stmt.value.id.clone()), upgrade_schema_type.clone(), ); @@ -226,7 +226,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { expected_ty.clone(), &assign_stmt.value.get_span_pos(), ); - self.node_ty_map.insert( + self.node_ty_map.borrow_mut().insert( self.get_node_key(assign_stmt.value.id.clone()), upgrade_schema_type.clone(), ); @@ -402,7 +402,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(), ); @@ -534,7 +534,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { ); } - self.node_ty_map.insert( + self.node_ty_map.borrow_mut().insert( self.get_node_key(selector_expr.attr.id.clone()), value_ty.clone(), ); @@ -546,6 +546,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()); } @@ -973,7 +974,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(), ); @@ -1061,6 +1062,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()); } @@ -1137,6 +1139,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]; @@ -1175,6 +1178,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() @@ -1287,9 +1291,11 @@ impl<'ctx> Resolver<'ctx> { let upgrade_ty = self.upgrade_dict_to_schema(ty.clone(), expected_ty, &expr.get_span_pos()); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(expr.id.clone()), upgrade_ty); } else { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(expr.id.clone()), ty.clone()); } @@ -1303,6 +1309,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 } @@ -1316,6 +1323,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 } @@ -1335,10 +1343,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 01691c904..4b42df4f7 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 e543af75a..e2ad853d8 100644 --- a/kclvm/sema/src/resolver/scope.rs +++ b/kclvm/sema/src/resolver/scope.rs @@ -286,7 +286,7 @@ pub struct ProgramScope { pub scope_map: IndexMap>>, pub import_names: IndexMap>, pub schema_mapping: IndexMap>>, - pub node_ty_map: NodeTyMap, + pub node_ty_map: Rc>, pub handler: Handler, } @@ -460,6 +460,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; } @@ -511,7 +512,8 @@ pub struct CachedScope { pub program_root: String, pub scope_map: IndexMap>>, pub schema_mapping: IndexMap>>, - pub node_ty_map: NodeTyMap, + pub node_ty_map: Rc>, + pub invalidate_pkgs: HashSet, dependency_graph: DependencyGraph, } @@ -674,6 +676,7 @@ impl CachedScope { program_root: program.root.to_string(), scope_map: scope.scope_map.clone(), node_ty_map: scope.node_ty_map.clone(), + invalidate_pkgs: HashSet::default(), dependency_graph: DependencyGraph::default(), schema_mapping: scope.schema_mapping.clone(), }; @@ -684,8 +687,9 @@ 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.invalidate_pkgs.clear(); } pub fn invalidate_cache(&mut self, invalidated_pkgs: Result<&HashSet, &String>) { @@ -694,6 +698,7 @@ impl CachedScope { for invalidated_pkg in invalidated_pkgs.iter() { self.scope_map.remove(invalidated_pkg); } + 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 2971ed5a5..b8e338f24 100644 --- a/kclvm/sema/src/resolver/ty.rs +++ b/kclvm/sema/src/resolver/ty.rs @@ -76,6 +76,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 @@ -451,10 +452,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 f62a29344..37ed99ea6 100644 --- a/kclvm/tools/src/LSP/src/find_refs.rs +++ b/kclvm/tools/src/LSP/src/find_refs.rs @@ -9,9 +9,7 @@ use crate::state::{KCLEntryCache, KCLVfs, KCLWordIndexMap}; use anyhow::Result; use kclvm_driver::toolchain; 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; use parking_lot::lock_api::RwLock; @@ -24,8 +22,6 @@ pub(crate) fn find_refs Result<(), anyhow::Error>>( vfs: Option, logger: F, gs: &GlobalState, - module_cache: Option, - scope_cache: Option, entry_cache: Option, ) -> Result, String> { let def = find_def(kcl_pos, gs, true); @@ -43,8 +39,6 @@ pub(crate) fn find_refs Result<(), anyhow::Error>>( include_declaration, Some(FIND_REFS_LIMIT), logger, - module_cache, - scope_cache, entry_cache, )) } else { @@ -69,8 +63,6 @@ pub(crate) fn find_refs_from_def Result<(), anyhow::Error>>( include_declaration: bool, limit: Option, logger: F, - module_cache: Option, - scope_cache: Option, entry_cache: Option, ) -> Vec { let mut ref_locations = vec![]; @@ -94,9 +86,10 @@ 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(), + gs_cache: None, entry_cache: entry_cache.clone(), tool: Arc::new(RwLock::new(toolchain::default())), }) @@ -222,8 +215,6 @@ mod tests { Some(20), logger, None, - None, - None, ), ); } @@ -280,8 +271,6 @@ mod tests { Some(20), logger, None, - None, - None, ), ); } @@ -338,8 +327,6 @@ mod tests { Some(20), logger, None, - None, - None, ), ); } @@ -389,8 +376,6 @@ mod tests { 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 00c8f050c..c0ae2ddd8 100644 --- a/kclvm/tools/src/LSP/src/quick_fix.rs +++ b/kclvm/tools/src/LSP/src/quick_fix.rs @@ -190,6 +190,7 @@ mod tests { vfs: Some(KCLVfs::default()), entry_cache: None, tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: None, }) .0; diff --git a/kclvm/tools/src/LSP/src/rename.rs b/kclvm/tools/src/LSP/src/rename.rs index ff08e6a08..31ea7f02a 100644 --- a/kclvm/tools/src/LSP/src/rename.rs +++ b/kclvm/tools/src/LSP/src/rename.rs @@ -189,12 +189,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 d911cfc70..48bfb3fb0 100644 --- a/kclvm/tools/src/LSP/src/request.rs +++ b/kclvm/tools/src/LSP/src/request.rs @@ -273,8 +273,6 @@ pub(crate) fn handle_reference( }; 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 entry_cache = snapshot.entry_cache.clone(); match find_refs( &pos, @@ -283,8 +281,6 @@ pub(crate) fn handle_reference( Some(snapshot.vfs.clone()), log, &db.gs, - Some(module_cache), - None, Some(entry_cache), ) { core::result::Result::Ok(locations) => Ok(Some(locations)), @@ -410,8 +406,6 @@ pub(crate) fn handle_rename( Some(snapshot.vfs.clone()), log, &db.gs, - Some(snapshot.module_cache), - Some(snapshot.scope_cache), Some(snapshot.entry_cache), ); match references { diff --git a/kclvm/tools/src/LSP/src/state.rs b/kclvm/tools/src/LSP/src/state.rs index b7e257eef..af671e2ab 100644 --- a/kclvm/tools/src/LSP/src/state.rs +++ b/kclvm/tools/src/LSP/src/state.rs @@ -8,6 +8,7 @@ use crossbeam_channel::{select, unbounded, Receiver, Sender}; use kclvm_driver::toolchain::{self, Toolchain}; use kclvm_driver::CompileUnitOptions; use kclvm_parser::KCLModuleCache; +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 KCLEntryCache = Arc>>; pub(crate) type KCLToolChain = Arc>; +pub(crate) type KCLGlobalStateCache = Arc>; /// State for the language server pub(crate) struct LanguageServerState { @@ -82,6 +85,8 @@ pub(crate) struct LanguageServerState { pub entry_cache: KCLEntryCache, /// Toolchain is used to provider KCL tool features for the language server. pub tool: KCLToolChain, + /// KCL globalstate cache + pub gs_cache: KCLGlobalStateCache, } /// A snapshot of the state of the language server @@ -134,6 +139,7 @@ impl LanguageServerState { scope_cache: KCLScopeCache::default(), entry_cache: KCLEntryCache::default(), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: KCLGlobalStateCache::default(), }; let word_index_map = state.word_index_map.clone(); @@ -223,6 +229,7 @@ impl LanguageServerState { let scope_cache = Arc::clone(&self.scope_cache); let entry = Arc::clone(&self.entry_cache); let tool = Arc::clone(&self.tool); + let gs_cache = Arc::clone(&self.gs_cache); move || match url(&snapshot, file.file_id) { Ok(uri) => { let version = @@ -235,6 +242,7 @@ impl LanguageServerState { vfs: Some(snapshot.vfs), entry_cache: Some(entry), tool, + gs_cache: Some(gs_cache), }); let current_version = diff --git a/kclvm/tools/src/LSP/src/tests.rs b/kclvm/tools/src/LSP/src/tests.rs index 7f4ba0cd8..31f37cd5c 100644 --- a/kclvm/tools/src/LSP/src/tests.rs +++ b/kclvm/tools/src/LSP/src/tests.rs @@ -77,6 +77,7 @@ use crate::goto_def::goto_def; use crate::hover::hover; use crate::main_loop::main_loop; use crate::state::KCLEntryCache; +use crate::state::KCLGlobalStateCache; use crate::state::KCLVfs; use crate::to_lsp::kcl_diag_to_lsp_diags; use crate::util::lookup_compile_unit_with_cache; @@ -134,6 +135,7 @@ pub(crate) fn compile_test_file( vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }); let (program, gs) = compile_res.unwrap(); (file, program, diags, gs) @@ -297,6 +299,7 @@ fn diagnostics_test() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .0; @@ -485,6 +488,7 @@ fn complete_import_external_file_test() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .1 .unwrap(); @@ -546,6 +550,7 @@ fn goto_import_external_file_test() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }); let gs = compile_res.unwrap().1; @@ -1401,6 +1406,7 @@ fn konfig_goto_def_test_base() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .1 .unwrap(); @@ -1495,6 +1501,7 @@ fn konfig_goto_def_test_main() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .1 .unwrap(); @@ -1561,6 +1568,7 @@ fn konfig_completion_test_main() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .1 .unwrap(); @@ -1676,6 +1684,7 @@ fn konfig_hover_test_main() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .1 .unwrap(); @@ -2111,6 +2120,7 @@ fn compile_unit_test() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .1 .unwrap() diff --git a/kclvm/tools/src/LSP/src/util.rs b/kclvm/tools/src/LSP/src/util.rs index aab9c7661..fd63b9403 100644 --- a/kclvm/tools/src/LSP/src/util.rs +++ b/kclvm/tools/src/LSP/src/util.rs @@ -19,12 +19,14 @@ use kclvm_sema::resolver::resolve_program_with_opts; use kclvm_sema::resolver::scope::KCLScopeCache; use crate::from_lsp; -use crate::state::{KCLEntryCache, KCLToolChain, KCLVfs}; +use crate::state::{KCLEntryCache, KCLToolChain}; +use crate::state::{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::fs; use std::path::Path; @@ -66,6 +68,7 @@ pub(crate) struct Params { pub entry_cache: Option, pub vfs: Option, pub tool: KCLToolChain, + pub gs_cache: Option, } pub(crate) fn lookup_compile_unit_with_cache( @@ -125,6 +128,7 @@ pub(crate) fn compile_with_params( Err(e) => return (diags, Err(anyhow::anyhow!("Parse failed: {:?}", e))), }; diags.extend(sess.1.borrow().diagnostics.clone()); + // Resolver let prog_scope = resolve_program_with_opts( &mut program, @@ -133,15 +137,37 @@ pub(crate) fn compile_with_params( type_erasure: false, ..Default::default() }, - params.scope_cache, + params.scope_cache.clone(), ); diags.extend(prog_scope.handler.diagnostics); - // Please note that there is no global state cache at this stage. - let gs = GlobalState::default(); - let gs = Namer::find_symbols(&program, gs); - match AdvancedResolver::resolve_program(&program, gs, prog_scope.node_ty_map.clone()) { - Ok(gs) => (diags, Ok((program, gs))), + 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, + }; + + 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(); + + Namer::find_symbols(&program, &mut gs); + + match AdvancedResolver::resolve_program(&program, gs, prog_scope.node_ty_map) { + Ok(_) => (diags, Ok((program, gs.clone()))), Err(e) => (diags, Err(anyhow::anyhow!("Resolve failed: {:?}", e))), } }