From 481584bcb567a463b14f638bb68060c2679b56c2 Mon Sep 17 00:00:00 2001 From: He1pa <18012015693@163.com> Date: Wed, 30 Aug 2023 11:59:47 +0800 Subject: [PATCH] bugfix: fix ConfigEntry and ConfigIfEntry expr position err in ast and scope --- kclvm/parser/src/parser/expr.rs | 23 +++--- kclvm/sema/src/pre_process/config.rs | 10 +-- kclvm/sema/src/resolver/config.rs | 14 ++-- kclvm/sema/src/resolver/node.rs | 5 +- .../src/test_data/goto_def_test/goto_def.k | 22 +++++- kclvm/tools/src/LSP/src/tests.rs | 70 +++++++++++++++++++ kclvm/tools/src/LSP/src/util.rs | 12 +++- 7 files changed, 134 insertions(+), 22 deletions(-) diff --git a/kclvm/parser/src/parser/expr.rs b/kclvm/parser/src/parser/expr.rs index 4b3c99266..b853fb61a 100644 --- a/kclvm/parser/src/parser/expr.rs +++ b/kclvm/parser/src/parser/expr.rs @@ -1512,6 +1512,7 @@ impl<'a> Parser<'a> { /// (ELSE COLON if_entry_exec_block)? fn parse_if_entry_expr(&mut self) -> NodeRef { let mut need_skip_newlines = false; + let token = self.token; let mut if_entry = { self.bump_keyword(kw::If); @@ -1616,13 +1617,10 @@ impl<'a> Parser<'a> { if_entry.node.orelse = Some(Box::new(t)); } - Box::new(Node::new( + + Box::new(Node::node( Expr::ConfigIfEntry(if_entry.node), - if_entry.filename, - if_entry.line, - if_entry.column, - if_entry.end_line, - if_entry.end_column, + self.sess.struct_token_loc(token, self.prev_token), )) } @@ -1768,8 +1766,16 @@ impl<'a> Parser<'a> { }; let expr1 = this.parse_expr(); - - let pos = expr1.pos(); + let expr0_pos = expr0.clone().unwrap().pos(); + let expr1_pos = expr1.pos(); + + let pos = ( + expr0_pos.0, + expr0_pos.1, + expr0_pos.2, + expr1_pos.3, + expr1_pos.4, + ); body.items.push(node_ref!( ConfigEntry { @@ -1801,7 +1807,6 @@ impl<'a> Parser<'a> { if need_skip_newlines { self.skip_newlines(); self.bump_token(TokenKind::Dedent); - Box::new(Node::node( body, self.sess.struct_token_loc(token, self.prev_token), diff --git a/kclvm/sema/src/pre_process/config.rs b/kclvm/sema/src/pre_process/config.rs index bff5e6ac9..d3cff8c6e 100644 --- a/kclvm/sema/src/pre_process/config.rs +++ b/kclvm/sema/src/pre_process/config.rs @@ -46,11 +46,11 @@ impl ConfigNestAttrTransformer { let config_expr = ast::ConfigExpr { items: vec![Box::new(ast::Node::new( entry_value, - key.filename.clone(), - key.line, - key.column, - key.end_line, - key.end_column, + config_entry.filename.clone(), + config_entry.line, + config_entry.column, + config_entry.end_line, + config_entry.end_column, ))], }; value = Box::new(ast::Node::new( diff --git a/kclvm/sema/src/resolver/config.rs b/kclvm/sema/src/resolver/config.rs index 1e7c9952c..d3960ec50 100644 --- a/kclvm/sema/src/resolver/config.rs +++ b/kclvm/sema/src/resolver/config.rs @@ -390,11 +390,15 @@ impl<'ctx> Resolver<'ctx> { &mut self, entries: &'ctx [ast::NodeRef], ) -> TypeRef { - self.enter_scope( - self.ctx.start_pos.clone(), - self.ctx.end_pos.clone(), - ScopeKind::Config, - ); + let (start, end) = match entries.len() { + 0 => (self.ctx.start_pos.clone(), self.ctx.end_pos.clone()), + 1 => entries[0].get_span_pos(), + _ => ( + entries.first().unwrap().get_pos(), + entries.last().unwrap().get_end_pos(), + ), + }; + self.enter_scope(start, end, ScopeKind::Config); let mut key_types: Vec = vec![]; let mut val_types: Vec = vec![]; let mut attrs = IndexMap::new(); diff --git a/kclvm/sema/src/resolver/node.rs b/kclvm/sema/src/resolver/node.rs index c7534db02..6e31e6eb8 100644 --- a/kclvm/sema/src/resolver/node.rs +++ b/kclvm/sema/src/resolver/node.rs @@ -284,7 +284,10 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { fn walk_quant_expr(&mut self, quant_expr: &'ctx ast::QuantExpr) -> Self::Result { let iter_ty = self.expr(&quant_expr.target); - let (start, end) = (self.ctx.start_pos.clone(), self.ctx.end_pos.clone()); + let (start, mut end) = quant_expr.test.get_span_pos(); + if let Some(if_cond) = &quant_expr.if_cond { + end = if_cond.get_end_pos(); + } self.enter_scope(start, end, ScopeKind::Loop); let (mut key_name, mut val_name) = (None, None); let mut target_node = None; diff --git a/kclvm/tools/src/LSP/src/test_data/goto_def_test/goto_def.k b/kclvm/tools/src/LSP/src/test_data/goto_def_test/goto_def.k index 2451eba9c..431c39fb8 100644 --- a/kclvm/tools/src/LSP/src/test_data/goto_def_test/goto_def.k +++ b/kclvm/tools/src/LSP/src/test_data/goto_def_test/goto_def.k @@ -56,4 +56,24 @@ schema_map: {str: Person} = { person1: p2 } -p3 = schema_map.person.n.name \ No newline at end of file +p3 = schema_map.person.n.name + +params = option("params") +toMatch = params.toMatch +toAdd = params.toAdd +items = [item | { + # If all annotations are matched, patch more annotations + if all key, value in toMatch { + item.metadata.annotations[key] == value + }: + metadata.annotations: toAdd +} for item in option("items")] + + +capabilities = option("params").capabilities or ["SETUID", "SETFCAP"] +items1 = [item | { + if item.kind == "Pod": + spec.containers: [{ + "securityContext": {"capabilities": {"add" += [cc] if cc not in (container?.securityContext?.capabilities?.drop or []) else [] for cc in capabilities}} + } for container in item.spec.containers] +} for item in option("items")] \ 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 3d4c66b20..1993a329c 100644 --- a/kclvm/tools/src/LSP/src/tests.rs +++ b/kclvm/tools/src/LSP/src/tests.rs @@ -444,6 +444,76 @@ fn goto_schema_def_test() { ); } +#[test] +fn goto_var_def_in_config_and_config_if_test() { + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + + let (file, program, prog_scope, _) = + compile_test_file("src/test_data/goto_def_test/goto_def.k"); + + let mut expected_path = path; + expected_path.push("src/test_data/goto_def_test/pkg/schema_def.k"); + + let pos = KCLPos { + filename: file.clone(), + line: 67, + column: Some(36), + }; + let res = goto_definition(&program, &pos, &prog_scope); + compare_goto_res(res, (&file, 65, 11, 65, 14)); + + let pos = KCLPos { + filename: file.clone(), + line: 67, + column: Some(44), + }; + let res = goto_definition(&program, &pos, &prog_scope); + compare_goto_res(res, (&file, 65, 16, 65, 21)); + + let pos = KCLPos { + filename: file.clone(), + line: 64, + column: Some(11), + }; + let res = goto_definition(&program, &pos, &prog_scope); + compare_goto_res(res, (&file, 69, 6, 69, 10)); + + let pos = KCLPos { + filename: file.clone(), + line: 67, + column: Some(10), + }; + let res = goto_definition(&program, &pos, &prog_scope); + compare_goto_res(res, (&file, 69, 6, 69, 10)); +} + +#[test] +fn goto_var_def_in_dict_comp_test() { + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + + let (file, program, prog_scope, _) = + compile_test_file("src/test_data/goto_def_test/goto_def.k"); + + let mut expected_path = path; + expected_path.push("src/test_data/goto_def_test/pkg/schema_def.k"); + + let pos = KCLPos { + filename: file.clone(), + line: 77, + column: Some(68), + }; + let res = goto_definition(&program, &pos, &prog_scope); + compare_goto_res(res, (&file, 76, 143, 76, 145)); + + let pos = KCLPos { + filename: file.clone(), + line: 77, + column: Some(61), + }; + let res = goto_definition(&program, &pos, &prog_scope); + compare_goto_res(res, (&file, 76, 143, 76, 145)); +} + #[test] fn goto_dict_key_def_test() { let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); diff --git a/kclvm/tools/src/LSP/src/util.rs b/kclvm/tools/src/LSP/src/util.rs index 5f5c088f6..23bae4603 100644 --- a/kclvm/tools/src/LSP/src/util.rs +++ b/kclvm/tools/src/LSP/src/util.rs @@ -447,7 +447,17 @@ pub(crate) fn inner_most_expr( walk_if_contains!(starred_exor.value, pos, schema_def); (Some(expr.clone()), schema_def) } - Expr::DictComp(_) => (Some(expr.clone()), schema_def), + Expr::DictComp(dict_comp) => { + walk_option_if_contains!(dict_comp.entry.key, pos, schema_def); + walk_if_contains!(dict_comp.entry.value, pos, schema_def); + + for generator in &dict_comp.generators { + if generator.contains_pos(pos) { + walk_if_contains_with_new_expr!(generator, pos, schema_def, Expr::CompClause); + } + } + (Some(expr.clone()), schema_def) + } Expr::ConfigIfEntry(config_if_entry_expr) => { walk_if_contains!(config_if_entry_expr.if_cond, pos, schema_def); for item in &config_if_entry_expr.items {