diff --git a/kclvm/compiler/src/codegen/llvm/node.rs b/kclvm/compiler/src/codegen/llvm/node.rs index d5e46d4c1..ac8264ae4 100644 --- a/kclvm/compiler/src/codegen/llvm/node.rs +++ b/kclvm/compiler/src/codegen/llvm/node.rs @@ -2964,11 +2964,8 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { _ => None, }; // Store a local variable for every entry key. - let key = match optional_name { - Some(name) => { - self.add_or_update_local_variable(&name, value); - self.string_value(&name) - } + let key = match &optional_name { + Some(name) => self.string_value(name), None => self.walk_expr(key)?, }; self.dict_insert_with_key_value( @@ -2978,6 +2975,11 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { item.node.operation.value(), insert_index as i32, ); + if let Some(name) = &optional_name { + let value = + self.dict_get(config_value, self.native_global_string(name, "").into()); + self.add_or_update_local_variable(name, value); + } } else { // If the key does not exist, execute the logic of unpacking expression `**expr` here. self.build_void_call( diff --git a/kclvm/sema/src/resolver/config.rs b/kclvm/sema/src/resolver/config.rs index 41888eba7..cbed61ad2 100644 --- a/kclvm/sema/src/resolver/config.rs +++ b/kclvm/sema/src/resolver/config.rs @@ -399,7 +399,7 @@ impl<'ctx> Resolver<'ctx> { self.enter_scope(start, end, ScopeKind::Config); let mut key_types: Vec = vec![]; let mut val_types: Vec = vec![]; - let mut attrs = IndexMap::new(); + let mut attrs: IndexMap = IndexMap::new(); for item in entries { let key = &item.node.key; let value = &item.node.value; @@ -423,10 +423,15 @@ impl<'ctx> Resolver<'ctx> { Rc::new(Type::str_lit(name)) }; self.check_attr_ty(&key_ty, key.get_span_pos()); + let ty = if let Some(attr) = attrs.get(name) { + sup(&[attr.ty.clone(), val_ty.clone()]) + } else { + val_ty.clone() + }; attrs.insert( name.to_string(), Attr { - ty: val_ty.clone(), + ty: ty.clone(), range: key.get_span_pos(), }, ); @@ -436,7 +441,7 @@ impl<'ctx> Resolver<'ctx> { name: name.to_string(), start: key.get_pos(), end: key.get_end_pos(), - ty: val_ty.clone(), + ty, kind: ScopeObjectKind::Attribute, doc: None, }, @@ -463,24 +468,29 @@ impl<'ctx> Resolver<'ctx> { let val_ty = self.expr(value); self.check_attr_ty(&key_ty, key.get_span_pos()); if let ast::Expr::StringLit(string_lit) = &key.node { + let ty = if let Some(attr) = attrs.get(&string_lit.value) { + sup(&[attr.ty.clone(), val_ty.clone()]) + } else { + val_ty.clone() + }; + attrs.insert( + string_lit.value.clone(), + Attr { + ty: ty.clone(), + range: key.get_span_pos(), + }, + ); self.insert_object( &string_lit.value, ScopeObject { name: string_lit.value.clone(), start: key.get_pos(), end: key.get_end_pos(), - ty: val_ty.clone(), + ty, kind: ScopeObjectKind::Attribute, doc: None, }, ); - attrs.insert( - string_lit.value.clone(), - Attr { - ty: val_ty.clone(), - range: key.get_span_pos(), - }, - ); } key_types.push(key_ty); val_types.push(val_ty.clone()); diff --git a/kclvm/tools/src/LSP/src/notification.rs b/kclvm/tools/src/LSP/src/notification.rs index ed22346bb..605f8497e 100644 --- a/kclvm/tools/src/LSP/src/notification.rs +++ b/kclvm/tools/src/LSP/src/notification.rs @@ -10,7 +10,7 @@ use std::path::Path; use crate::{ dispatcher::NotificationDispatcher, from_lsp, - state::{log_message, LanguageServerState}, + state::LanguageServerState, util::apply_document_changes, util::{build_word_index_for_file_content, word_index_add, word_index_subtract}, }; diff --git a/test/grammar/datatype/dict/mutual_ref_14/main.k b/test/grammar/datatype/dict/mutual_ref_14/main.k new file mode 100644 index 000000000..4b94a8d26 --- /dev/null +++ b/test/grammar/datatype/dict/mutual_ref_14/main.k @@ -0,0 +1,6 @@ +deployment = { + metadata.labels.k1 = "v1" + metadata.namespace = "default" + spec.selector.matchLabels = metadata.labels | {k2 = "v2"} +} +labels: {str:str} = deployment.metadata.labels diff --git a/test/grammar/datatype/dict/mutual_ref_14/stdout.golden b/test/grammar/datatype/dict/mutual_ref_14/stdout.golden new file mode 100644 index 000000000..30497ce0c --- /dev/null +++ b/test/grammar/datatype/dict/mutual_ref_14/stdout.golden @@ -0,0 +1,12 @@ +deployment: + metadata: + labels: + k1: v1 + namespace: default + spec: + selector: + matchLabels: + k1: v1 + k2: v2 +labels: + k1: v1