diff --git a/kclvm/sema/src/pre_process/config.rs b/kclvm/sema/src/pre_process/config.rs index d3cff8c6e..d5668fd7d 100644 --- a/kclvm/sema/src/pre_process/config.rs +++ b/kclvm/sema/src/pre_process/config.rs @@ -12,11 +12,30 @@ impl ConfigNestAttrTransformer { pub fn walk_config_entry(&mut self, config_entry: &mut Box>) { if let Some(key) = config_entry.node.key.as_mut() { if let ast::Expr::Identifier(identifier) = &mut key.node { + // desuger config expr, e.g., desuger + // ``` + // foo = Foo { + // bar.baz : xxx + // } + // ``` + // to: + // ``` + // foo = Foo { + // bar : Bar { + // baz : xxx + // } + // } + // ``` if identifier.names.len() > 1 { let mut names = identifier.names.clone(); let names = &mut names[1..]; names.reverse(); identifier.names = vec![identifier.names[0].clone()]; + key.filename = identifier.names[0].filename.clone(); + key.line = identifier.names[0].line; + key.column = identifier.names[0].column; + key.end_line = identifier.names[0].end_line; + key.end_column = identifier.names[0].end_column; let mut value = config_entry.node.value.clone(); for (i, name) in names.iter().enumerate() { @@ -29,11 +48,11 @@ impl ConfigNestAttrTransformer { let entry_value = ast::ConfigEntry { key: Some(Box::new(ast::Node::new( ast::Expr::Identifier(name_node), - key.filename.clone(), - key.line, - key.column, - key.end_line, - key.end_column, + name.filename.clone(), + name.line, + name.column, + name.end_line, + name.end_column, ))), value: value.clone(), operation: if is_last_item { @@ -47,8 +66,8 @@ impl ConfigNestAttrTransformer { items: vec![Box::new(ast::Node::new( entry_value, config_entry.filename.clone(), - config_entry.line, - config_entry.column, + name.line, + name.column, config_entry.end_line, config_entry.end_column, ))], @@ -56,8 +75,8 @@ impl ConfigNestAttrTransformer { value = Box::new(ast::Node::new( ast::Expr::Config(config_expr), value.filename.clone(), - value.line, - value.column, + name.line, + name.column, value.end_line, value.end_column, )) diff --git a/kclvm/tools/src/LSP/src/goto_def.rs b/kclvm/tools/src/LSP/src/goto_def.rs index c5a243db4..a7468f974 100644 --- a/kclvm/tools/src/LSP/src/goto_def.rs +++ b/kclvm/tools/src/LSP/src/goto_def.rs @@ -1031,4 +1031,20 @@ mod tests { let res = goto_definition(&program, &pos, &prog_scope); compare_goto_res(res, (&file, 18, 4, 18, 8)); } + + #[test] + #[bench_test] + fn config_desuger_def_goto_def() { + let (file, program, prog_scope, _) = + compile_test_file("src/test_data/goto_def_test/goto_def.k"); + + let pos = KCLPos { + filename: file.clone(), + line: 82, + column: Some(9), + }; + + let res = goto_definition(&program, &pos, &prog_scope); + compare_goto_res(res, (&file, 81, 6, 81, 10)); + } } 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 473cd80ab..5614a9894 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 @@ -77,3 +77,7 @@ items1 = [item | { "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")] + +p4 = Person { + n.name: "a" +}