From 4e9b8a224c89d6f99470619553d3ed6a46a44ae1 Mon Sep 17 00:00:00 2001 From: he1pa <18012015693@163.com> Date: Tue, 14 Jan 2025 11:11:41 +0800 Subject: [PATCH] feat: enhance evaluator func type_pack_and_check err msg Signed-off-by: he1pa <18012015693@163.com> --- kclvm/evaluator/src/ty.rs | 53 ++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/kclvm/evaluator/src/ty.rs b/kclvm/evaluator/src/ty.rs index 6b7b694d3..82821777a 100644 --- a/kclvm/evaluator/src/ty.rs +++ b/kclvm/evaluator/src/ty.rs @@ -1,7 +1,7 @@ use kclvm_runtime::{ - check_type, dereference_type, is_dict_type, is_list_type, is_type_union, schema_config_meta, - schema_runtime_type, separate_kv, split_type_union, val_plan, ConfigEntryOperationKind, - ValueRef, BUILTIN_TYPES, KCL_TYPE_ANY, PKG_PATH_PREFIX, + check_type, dereference_type, is_dict_type, is_list_type, is_schema_type, is_type_union, + schema_config_meta, schema_runtime_type, separate_kv, split_type_union, val_plan, + ConfigEntryOperationKind, ValueRef, BUILTIN_TYPES, KCL_TYPE_ANY, PKG_PATH_PREFIX, }; use scopeguard::defer; @@ -72,7 +72,7 @@ pub fn type_pack_and_check( let mut checked = false; let mut converted_value = value.clone(); let expected_type = &expected_types.join(" | ").replace('@', ""); - for tpe in expected_types { + for tpe in &expected_types { if !is_schema { converted_value = convert_collection_value(s, value, tpe); } @@ -88,9 +88,50 @@ pub fn type_pack_and_check( } } if !checked { + let mut error_msgs = vec![]; + for tpe in &expected_types { + if is_schema_type(tpe) { + let schema_type_name = if tpe.contains('.') { + if tpe.starts_with(PKG_PATH_PREFIX) { + tpe.to_string() + } else { + format!("{PKG_PATH_PREFIX}{tpe}") + } + } else { + format!("{}.{}", s.current_pkgpath(), tpe) + }; + + if let Some(index) = s.schemas.borrow().get(&schema_type_name) { + let frame = { + let frames = s.frames.borrow(); + frames + .get(*index) + .expect(kcl_error::INTERNAL_ERROR_MSG) + .clone() + }; + if let Proxy::Schema(caller) = &frame.proxy { + if value.is_config() { + let config = value.as_dict_ref(); + for (key, _) in &config.values { + let no_such_attr = + !SchemaEvalContext::has_attr(s, &caller.ctx, key) + && !key.starts_with('_'); + let has_index_signature = + SchemaEvalContext::has_index_signature(s, &caller.ctx); + if !has_index_signature && no_such_attr { + error_msgs + .push(format!("Schema {} not contains attr {}", tpe, key)); + } + } + } + } + } + } + } panic!( - "expect {expected_type}, got {}", - val_plan::type_of(value, true) + "expect {expected_type}, got {}. For details: {}", + val_plan::type_of(value, true), + error_msgs.join(" ") ); } converted_value