Skip to content

Commit

Permalink
feat: index sign key name reference in the schema body (#582)
Browse files Browse the repository at this point in the history
* feat: impl index sign alias ref in the schema body

* test: add more grammar test suites for schema index signature
  • Loading branch information
Peefy committed Jun 25, 2023
1 parent ddf9a4f commit 44a6a37
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 57 deletions.
95 changes: 49 additions & 46 deletions kclvm/compiler/src/codegen/llvm/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -622,52 +622,6 @@ impl<'ctx> TypedResultWalker<'ctx> for LLVMCodeGenContext<'ctx> {
self.builder.position_at_end(do_check_block);
let schema_name_native_str = self.native_global_string_value(&schema_stmt.name.node);
let schema_pkgpath_native_str = self.native_global_string_value(&self.current_pkgpath());
// Schema runtime index signature and relaxed check
if let Some(index_signature) = &schema_stmt.index_signature {
let index_sign_value = if let Some(value) = &index_signature.node.value {
self.walk_expr(value).expect(kcl_error::COMPILE_ERROR_MSG)
} else {
self.none_value()
};
let key_name_str_ptr = if let Some(key_name) = &index_signature.node.key_name {
self.native_global_string(key_name.as_str(), "")
} else {
self.native_global_string("", "")
};
self.build_void_call(
&ApiFunc::kclvm_schema_value_check.name(),
&[
schema_value,
schema_config,
schema_config_meta,
schema_name_native_str,
index_sign_value,
key_name_str_ptr.into(),
self.native_global_string(index_signature.node.key_type.node.as_str(), "")
.into(),
self.native_global_string(index_signature.node.value_type.node.as_str(), "")
.into(),
self.native_i8(index_signature.node.any_other as i8).into(),
self.native_i8(false as i8).into(),
],
);
} else {
self.build_void_call(
&ApiFunc::kclvm_schema_value_check.name(),
&[
schema_value,
schema_config,
schema_config_meta,
schema_name_native_str,
self.none_value(),
self.native_global_string("", "").into(),
self.native_global_string("", "").into(),
self.native_global_string("", "").into(),
self.native_i8(0).into(),
self.native_i8(false as i8).into(),
],
);
}
{
let index_sign_key_name = if let Some(index_signature) = &schema_stmt.index_signature {
if let Some(key_name) = &index_signature.node.key_name {
Expand Down Expand Up @@ -772,6 +726,55 @@ impl<'ctx> TypedResultWalker<'ctx> for LLVMCodeGenContext<'ctx> {
.expect(kcl_error::INTERNAL_ERROR_MSG);
self.walk_arguments(&schema_stmt.args, args, kwargs);
self.schema_stack.borrow_mut().push(schema);
// Schema runtime index signature and relaxed check
if let Some(index_signature) = &schema_stmt.index_signature {
let index_sign_value = if let Some(value) = &index_signature.node.value {
self.walk_expr(value).expect(kcl_error::COMPILE_ERROR_MSG)
} else {
self.none_value()
};
let key_name_str_ptr = if let Some(key_name) = &index_signature.node.key_name {
self.native_global_string(key_name.as_str(), "")
} else {
self.native_global_string("", "")
};
self.build_void_call(
&ApiFunc::kclvm_schema_value_check.name(),
&[
schema_value,
schema_config,
schema_config_meta,
schema_name_native_str,
index_sign_value,
key_name_str_ptr.into(),
self.native_global_string(index_signature.node.key_type.node.as_str(), "")
.into(),
self.native_global_string(
index_signature.node.value_type.node.as_str(),
"",
)
.into(),
self.native_i8(index_signature.node.any_other as i8).into(),
self.native_i8(false as i8).into(),
],
);
} else {
self.build_void_call(
&ApiFunc::kclvm_schema_value_check.name(),
&[
schema_value,
schema_config,
schema_config_meta,
schema_name_native_str,
self.none_value(),
self.native_global_string("", "").into(),
self.native_global_string("", "").into(),
self.native_global_string("", "").into(),
self.native_i8(0).into(),
self.native_i8(false as i8).into(),
],
);
}
// Call base check function
if let Some(parent_name) = &schema_stmt.parent_name {
let base_constructor_func = self
Expand Down
37 changes: 27 additions & 10 deletions kclvm/runtime/src/value/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2154,7 +2154,7 @@ pub unsafe extern "C" fn kclvm_schema_value_check(
_config_meta: *const kclvm_value_ref_t,
schema_name: *const kclvm_char_t,
index_sign_value: *const kclvm_value_ref_t,
_key_name: *const kclvm_char_t,
key_name: *const kclvm_char_t,
key_type: *const kclvm_char_t,
_value_type: *const kclvm_char_t,
_any_other: kclvm_bool_t,
Expand All @@ -2164,26 +2164,43 @@ pub unsafe extern "C" fn kclvm_schema_value_check(
let schema_config = ptr_as_ref(schema_config);
let index_sign_value = ptr_as_ref(index_sign_value);
let key_type = c2str(key_type);
let index_key_name = c2str(key_name);
let has_index_signature = !key_type.is_empty();
let should_add_attr = is_relaxed != 0 || has_index_signature;

let ctx = Context::current_context_mut();
if ctx.cfg.disable_schema_check {
return;
}

let config = schema_config.as_dict_ref();
for (key, value) in &config.values {
let is_not_in_schema = schema_value.dict_get_value(key).is_none();
if should_add_attr && is_not_in_schema {
let value = index_sign_value
.deep_copy()
.union_entry(value, true, false, false, true);
let op = config
.ops
.get(key)
.unwrap_or(&ConfigEntryOperationKind::Union);
schema_value.dict_update_entry(key.as_str(), &value.clone(), op, &-1);
// Allow index signature value has different values
// related to the index signature key name.
let should_update =
if let Some(index_key_value) = schema_value.dict_get_value(index_key_name) {
if index_key_value.is_str() && key == &index_key_value.as_str() {
true
} else {
false
}
} else {
true
};
if should_update {
let op = config
.ops
.get(key)
.unwrap_or(&ConfigEntryOperationKind::Union);
schema_value.dict_update_entry(
key.as_str(),
&index_sign_value,
&ConfigEntryOperationKind::Override,
&-1,
);
schema_value.dict_insert(key.as_str(), &value, op.clone(), -1);
}
} else if !should_add_attr && is_not_in_schema {
let schema_name = c2str(schema_name);
panic!("{key}: No such member in the schema '{schema_name}'");
Expand Down
2 changes: 1 addition & 1 deletion kclvm/version/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2021 The KCL Authors. All rights reserved.

pub const VERSION: &str = "0.5.0-alpha.4";
pub const CHECK_SUM: &str = "51289ff122a3ea8eea7f8149b8956cd1";
pub const CHECK_SUM: &str = "eb13b547c76bd1eaf9b1ea0caa917fb1";

/// Get kCL full version string with the format `{version}-{check_sum}`.
#[inline]
Expand Down
12 changes: 12 additions & 0 deletions test/grammar/schema/index_signature/key_alias_0/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
schema TeamSpec[id: str]:
fullName: str
name = id
shortName: str = name

schema TeamMap:
[n: str]: TeamSpec = TeamSpec(n) # `n` does not work currently

teamMap = TeamMap {
a.fullName = "alpha"
b.fullName = "bravo"
}
9 changes: 9 additions & 0 deletions test/grammar/schema/index_signature/key_alias_0/stdout.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
teamMap:
b:
fullName: bravo
name: b
shortName: b
a:
fullName: alpha
name: a
shortName: a
14 changes: 14 additions & 0 deletions test/grammar/schema/index_signature/key_alias_1/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
schema TeamSpec:
fullName: str
name = id
shortName: str = name

schema TeamMap:
[n: str]: TeamSpec = TeamSpec {
name = n
}

teamMap = TeamMap {
a.fullName = "alpha"
b.fullName = "bravo"
}
9 changes: 9 additions & 0 deletions test/grammar/schema/index_signature/key_alias_1/stdout.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
teamMap:
b:
fullName: bravo
name: b
shortName: b
a:
fullName: alpha
name: a
shortName: a
2 changes: 2 additions & 0 deletions test/grammar/schema/index_signature/normal_1/stdout.golden
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namedMap:
key1:
default_key: default_value
key1: value1
key2: value2
key2:
default_key: default_value
key1: value1
key2: value2
15 changes: 15 additions & 0 deletions test/grammar/schema/index_signature/normal_5/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
schema LabelMap:
[str]: str | int

schema NamedMap:
[str]: {str:str} = {"default_key": "default_value"}

labelMap = LabelMap {
key1 = "value1"
key2 = 2
}

namedMap = NamedMap {
key1 = {key1 = "value1"}
key2 = {key2 = "value2"}
}
8 changes: 8 additions & 0 deletions test/grammar/schema/index_signature/normal_5/stdout.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
labelMap:
key1: value1
key2: 2
namedMap:
key1:
key1: value1
key2:
key2: value2

0 comments on commit 44a6a37

Please sign in to comment.