From 7bb22c2d220a9a7dfc946a9a780ae218e0ac4f1a Mon Sep 17 00:00:00 2001 From: He1pa <56333845+He1pa@users.noreply.github.com> Date: Mon, 14 Oct 2024 15:10:37 +0800 Subject: [PATCH] fix: fix advanced resolver panic when walk aug asssign stmt (#1690) Signed-off-by: he1pa <18012015693@163.com> --- kclvm/sema/src/advanced_resolver/node.rs | 158 +++++++++--------- .../error_code/aug_assign/aug_assign.k | 1 + kclvm/tools/src/LSP/src/tests.rs | 7 + 3 files changed, 87 insertions(+), 79 deletions(-) create mode 100644 kclvm/tools/src/LSP/src/test_data/error_code/aug_assign/aug_assign.k diff --git a/kclvm/sema/src/advanced_resolver/node.rs b/kclvm/sema/src/advanced_resolver/node.rs index 057da6a6c..f1ffa49b5 100644 --- a/kclvm/sema/src/advanced_resolver/node.rs +++ b/kclvm/sema/src/advanced_resolver/node.rs @@ -154,9 +154,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { } fn walk_aug_assign_stmt(&mut self, aug_assign_stmt: &'ctx ast::AugAssignStmt) -> Self::Result { - self.ctx.maybe_def = true; self.walk_target_expr(&aug_assign_stmt.target)?; - self.ctx.maybe_def = false; self.expr(&aug_assign_stmt.value)?; Ok(None) } @@ -953,7 +951,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { } fn walk_target(&mut self, target: &'ctx ast::Target) -> Self::Result { - let symbol_ref = self.resolve_target(&target)?; + let symbol_ref = self.resolve_target(&target, self.ctx.maybe_def)?; Ok(symbol_ref) } @@ -1355,7 +1353,7 @@ impl<'ctx> AdvancedResolver<'ctx> { } } - fn resolve_target(&mut self, target: &'ctx ast::Target) -> ResolvedResult { + fn resolve_target(&mut self, target: &'ctx ast::Target, maybe_def: bool) -> ResolvedResult { let first_name = &target.name; let cur_scope = *self.ctx.scopes.last().unwrap(); @@ -1490,84 +1488,86 @@ impl<'ctx> AdvancedResolver<'ctx> { Ok(Some(symbol_ref)) } None => { - let (start_pos, end_pos): Range = first_name.get_span_pos(); - let ast_id = first_name.id.clone(); - 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, - first_name.node.clone(), - first_value, - ); + if maybe_def { + let (start_pos, end_pos): Range = first_name.get_span_pos(); + let ast_id = first_name.id.clone(); + 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, + first_name.node.clone(), + first_value, + ); - if let Some(symbol) = self - .gs - .get_symbols_mut() - .values - .get_mut(first_value.get_id()) - { - symbol.sema_info = SymbolSemanticInfo { - ty: self - .ctx - .node_ty_map - .borrow() - .get(&self.ctx.get_node_key(&first_name.id)) - .map(|ty| ty.clone()), - doc: None, - }; - } + if let Some(symbol) = self + .gs + .get_symbols_mut() + .values + .get_mut(first_value.get_id()) + { + symbol.sema_info = SymbolSemanticInfo { + ty: self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&first_name.id)) + .map(|ty| ty.clone()), + doc: None, + }; + } + + for (index, path) in target.paths.iter().enumerate() { + match path { + ast::MemberOrIndex::Member(member) => { + let name = member; + let (start_pos, end_pos): Range = name.get_span_pos(); + let ast_id = name.id.clone(); + 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(), + ); - for (index, path) in target.paths.iter().enumerate() { - match path { - ast::MemberOrIndex::Member(member) => { - let name = member; - let (start_pos, end_pos): Range = name.get_span_pos(); - let ast_id = name.id.clone(); - let value = self.gs.get_symbols_mut().alloc_value_symbol( - ValueSymbol::new( + self.gs.get_scopes_mut().add_def_to_scope( + cur_scope, 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, - name.node.clone(), - value, - ); - - if let Some(symbol) = - self.gs.get_symbols_mut().values.get_mut(value.get_id()) - { - symbol.sema_info = SymbolSemanticInfo { - ty: self - .ctx - .node_ty_map - .borrow() - .get(&self.ctx.get_node_key(&name.id)) - .map(|ty| ty.clone()), - doc: None, - }; - } - if index == target.paths.len() { - return Ok(Some(value)); + value, + ); + + if let Some(symbol) = + self.gs.get_symbols_mut().values.get_mut(value.get_id()) + { + symbol.sema_info = SymbolSemanticInfo { + ty: self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&name.id)) + .map(|ty| ty.clone()), + doc: None, + }; + } + if index == target.paths.len() { + return Ok(Some(value)); + } } - } - ast::MemberOrIndex::Index(index_expr) => { - let last_maybe_def = self.ctx.maybe_def; - self.ctx.maybe_def = false; - let symbol = self.expr(index_expr); - self.ctx.maybe_def = last_maybe_def; - if index == target.paths.len() { - return symbol; + ast::MemberOrIndex::Index(index_expr) => { + let last_maybe_def = self.ctx.maybe_def; + self.ctx.maybe_def = false; + let symbol = self.expr(index_expr); + self.ctx.maybe_def = last_maybe_def; + if index == target.paths.len() { + return symbol; + } } } } @@ -1634,7 +1634,7 @@ impl<'ctx> AdvancedResolver<'ctx> { } identifier_symbol } else { - match self.resolve_target(&target.node)? { + match self.resolve_target(&target.node, self.ctx.maybe_def)? { Some(symbol) => symbol, None => return Ok(None), } diff --git a/kclvm/tools/src/LSP/src/test_data/error_code/aug_assign/aug_assign.k b/kclvm/tools/src/LSP/src/test_data/error_code/aug_assign/aug_assign.k new file mode 100644 index 000000000..e27c7eaad --- /dev/null +++ b/kclvm/tools/src/LSP/src/test_data/error_code/aug_assign/aug_assign.k @@ -0,0 +1 @@ +a += 1 \ No newline at end of file diff --git a/kclvm/tools/src/LSP/src/tests.rs b/kclvm/tools/src/LSP/src/tests.rs index 676b58df0..a17a100d2 100644 --- a/kclvm/tools/src/LSP/src/tests.rs +++ b/kclvm/tools/src/LSP/src/tests.rs @@ -2502,3 +2502,10 @@ fn pkg_mod_test() { } assert_eq!(diags.iter().filter(|diag| diag.is_error()).count(), 0); } + +#[test] +fn aug_assign_without_define() { + let (_file, _program, diags, _gs) = + compile_test_file("src/test_data/error_code/aug_assign/aug_assign.k"); + assert_eq!(diags.len(), 1); +}