docs(objects): explain capability conformance and annotation resolution
This commit is contained in:
+125
-2
@@ -975,16 +975,22 @@ impl ObjectStore {
|
||||
})
|
||||
}
|
||||
|
||||
/// 类型附着、字段/方法更新和能力查询共用:沿父链收集去重的借用能力身份。
|
||||
fn inherited_traits(&self, definition: ObjectRef) -> Result<Vec<ObjectRef>, VmError> {
|
||||
// 去重能力身份,不建立堆外拥有注册表或延长能力寿命。
|
||||
let mut found = std::collections::BTreeSet::new();
|
||||
// 从类型自身开始,继承能力和本层能力一起核对。
|
||||
let mut current = Some(definition);
|
||||
// 沿固定基类链逐层读取,不按名称猜测类型。
|
||||
while let Some(definition) = current {
|
||||
// 验证类型载荷后才读取其基类或能力列表。
|
||||
let definition = self.payload::<EndorTypeObject>(definition, "Type")?;
|
||||
found.extend(definition.traits.iter().copied());
|
||||
current = definition.base;
|
||||
}
|
||||
Ok(found.into_iter().collect())
|
||||
}
|
||||
/// 能力验证单项方法存在及数量,完整签名存在时再调用 contracts 的替换检查。
|
||||
fn validate_requirement(
|
||||
&self,
|
||||
capability: ObjectRef,
|
||||
@@ -993,6 +999,7 @@ impl ObjectStore {
|
||||
definition: ObjectRef,
|
||||
defer_unknown: bool,
|
||||
) -> Result<(), VmError> {
|
||||
// 构造带能力名/方法名的错误,调用方不需要解析诊断文本定位失败。
|
||||
let invalid = |reason| VmError::TraitViolation {
|
||||
capability: self
|
||||
.payload::<EndorTraitObject>(capability, "Trait")
|
||||
@@ -1002,15 +1009,19 @@ impl ObjectStore {
|
||||
method: requirement.name.clone(),
|
||||
reason,
|
||||
};
|
||||
// 能力要求的方法必须实际存在,不能以缺少元数据替代。
|
||||
let function = function.ok_or_else(|| invalid("required method is missing"))?;
|
||||
// 查询函数可见数量约束;缺失原生数量元数据不能证明满足能力。
|
||||
let arity = self
|
||||
.call_arity(function)?
|
||||
.ok_or_else(|| invalid("required member has no positional signature"))?;
|
||||
// 能力最小数量不含 self,校验时加一个显式接收者。
|
||||
if !arity.accepts(requirement.parameters + 1) {
|
||||
return Err(invalid(
|
||||
"positional parameter count does not match (including self)",
|
||||
));
|
||||
}
|
||||
// 完整签名存在时还要验证参数/返回/效果,不只检查数量。
|
||||
if let Some(expected) = self
|
||||
.payload::<EndorTraitObject>(capability, "Trait")?
|
||||
.signatures
|
||||
@@ -1027,14 +1038,18 @@ impl ObjectStore {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
/// 能力声明/查询检查全部要求,递归定义通过 with_trait_check 防止无限重入。
|
||||
fn validate_trait(
|
||||
&self,
|
||||
definition: ObjectRef,
|
||||
capability: ObjectRef,
|
||||
defer_unknown: bool,
|
||||
) -> Result<(), VmError> {
|
||||
// 递归检查对按定义/能力区分,回调结束后 RAII 清理标记。
|
||||
self.with_trait_check(definition, capability, || {
|
||||
// 能力载荷先验证,再借用名称/完整签名/最小要求。
|
||||
let contract = self.payload::<EndorTraitObject>(capability, "Trait")?;
|
||||
// 遍历能力全部要求,任一失败阻止声明/更新。
|
||||
for requirement in &contract.requirements {
|
||||
self.validate_requirement(
|
||||
capability,
|
||||
@@ -1047,7 +1062,9 @@ impl ObjectStore {
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
/// 源码类创建后检查所有继承能力,允许暂缓尚未解析的源码注解。
|
||||
fn validate_inherited_traits(&self, definition: ObjectRef) -> Result<(), VmError> {
|
||||
// 全部继承能力都参与,不以首个成功项短路。
|
||||
for capability in self.inherited_traits(definition)? {
|
||||
self.validate_trait(definition, capability, true)?;
|
||||
}
|
||||
@@ -1055,9 +1072,12 @@ impl ObjectStore {
|
||||
}
|
||||
// Enumerate borrowed heap handles only while validating a definition update;
|
||||
// no global type registry or owning descendant index is introduced.
|
||||
/// 方法/能力更新前扫描存活类型,返回包含 base 自身的全部子类型借用身份。
|
||||
fn descendant_types(&self, base: ObjectRef) -> Result<Vec<ObjectRef>, VmError> {
|
||||
self.payload::<EndorTypeObject>(base, "Type")?;
|
||||
// 去重能力身份,不建立堆外拥有注册表或延长能力寿命。
|
||||
let mut found = vec![];
|
||||
// 扫描当前存活对象;只选类型载荷及其名义子类型。
|
||||
for reference in self.heap.live_references() {
|
||||
if self
|
||||
.object(reference)?
|
||||
@@ -1071,34 +1091,46 @@ impl ObjectStore {
|
||||
}
|
||||
Ok(found)
|
||||
}
|
||||
/// define_method 提交前只检查真实会受该父方法变化影响的后代能力要求。
|
||||
fn validate_method_update(
|
||||
&self,
|
||||
changed: ObjectRef,
|
||||
name: &str,
|
||||
function: ObjectRef,
|
||||
) -> Result<(), VmError> {
|
||||
// 父定义变更必须考虑现有后代,不能只核对当前类型。
|
||||
for descendant in self.descendant_types(changed)? {
|
||||
// 从后代向父层寻找当前方法的实际来源。
|
||||
let mut current = Some(descendant);
|
||||
// 记录是否在遇到更近覆盖前到达 changed。
|
||||
let mut affected = false;
|
||||
// 沿固定基类链逐层读取,不按名称猜测类型。
|
||||
while let Some(definition) = current {
|
||||
// 查找会使用此次变更的方法,该后代属于影响范围。
|
||||
if definition == changed {
|
||||
affected = true;
|
||||
break;
|
||||
}
|
||||
// 验证类型载荷后才读取其基类或能力列表。
|
||||
let definition = self.payload::<EndorTypeObject>(definition, "Type")?;
|
||||
// 更近后代已覆盖同名方法,父层更新不会改变该后代查找结果。
|
||||
if definition.methods.contains_key(name) {
|
||||
break;
|
||||
}
|
||||
current = definition.base;
|
||||
}
|
||||
// 未受查找影响的后代跳过能力重验。
|
||||
if !affected {
|
||||
continue;
|
||||
}
|
||||
// 全部继承能力都参与,不以首个成功项短路。
|
||||
for capability in self.inherited_traits(descendant)? {
|
||||
// 遍历能力全部要求,任一失败阻止声明/更新。
|
||||
for requirement in &self
|
||||
.payload::<EndorTraitObject>(capability, "Trait")?
|
||||
.requirements
|
||||
{
|
||||
// 只校验当前被替换方法对应要求,其他方法表项没有变化。
|
||||
if requirement.name == name {
|
||||
self.validate_requirement(
|
||||
capability,
|
||||
@@ -1113,23 +1145,27 @@ impl ObjectStore {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
/// 宿主/VM 显式声明能力;先验证后代和已有实例,再提交定义强边。
|
||||
pub fn implement_trait(
|
||||
&mut self,
|
||||
definition: ObjectRef,
|
||||
capability: ObjectRef,
|
||||
) -> Result<(), VmError> {
|
||||
self.payload::<EndorTraitObject>(capability, "Trait")?;
|
||||
// 父定义变更必须考虑现有后代,不能只核对当前类型。
|
||||
for descendant in self.descendant_types(definition)? {
|
||||
self.validate_trait(descendant, capability, false)?;
|
||||
}
|
||||
// Existing objects must satisfy the same storage invariant as new writes.
|
||||
// Borrowed heap enumeration adds no owning instance registry.
|
||||
// 已有实例也必须满足新写入的存储约束;堆枚举只借用,不延长实例寿命。
|
||||
// 类型化能力才需要扫描实例存储,最小数量能力没有遮蔽签名要求。
|
||||
if !self
|
||||
.payload::<EndorTraitObject>(capability, "Trait")?
|
||||
.signatures
|
||||
.is_empty()
|
||||
{
|
||||
// 枚举已有实例检查同一存储不变量,不建立持有实例的注册表。
|
||||
for object in self.heap.live_references() {
|
||||
// 按有效类型判断是否属于被声明类型及后代,兼容类型转发门面。
|
||||
if let Some(actual) = self.type_of(object)?
|
||||
&& self.is_subtype(actual, definition)?
|
||||
{
|
||||
@@ -1137,20 +1173,25 @@ impl ObjectStore {
|
||||
}
|
||||
}
|
||||
}
|
||||
// 复制定义准备提交;此前检查失败不改变真实能力列表。
|
||||
let mut updated = self.payload::<EndorTypeObject>(definition, "Type")?.clone();
|
||||
// 重复声明是无操作,首次声明才更新载荷边与版本。
|
||||
if !updated.traits.contains(&capability) {
|
||||
updated.traits.push(capability);
|
||||
self.heap.replace_payload(definition, updated)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
/// 名义能力查询要求显式声明/继承,命中后重验当前方法,不以结构相似猜测。
|
||||
pub fn implements_trait(
|
||||
&self,
|
||||
definition: ObjectRef,
|
||||
capability: ObjectRef,
|
||||
) -> Result<bool, VmError> {
|
||||
self.payload::<EndorTraitObject>(capability, "Trait")?;
|
||||
// 显式声明或继承才算支持能力,方法形状相同也不会自动成为声明。
|
||||
let declared = self.inherited_traits(definition)?.contains(&capability);
|
||||
// 命中声明后重验当前方法/实例,避免把历史声明当作永久有效证明。
|
||||
if declared {
|
||||
self.validate_trait(definition, capability, false)?;
|
||||
}
|
||||
@@ -1158,12 +1199,15 @@ impl ObjectStore {
|
||||
}
|
||||
/// Typed capability methods belong to the method table. Instance fields
|
||||
/// cannot replace them independently of dispatch through that table.
|
||||
/// Store 属性读写及元数据查找防止字段遮蔽类型化能力方法,带按线程递归守卫。
|
||||
pub(crate) fn check_typed_method_write(
|
||||
&self,
|
||||
object: ObjectRef,
|
||||
name: &str,
|
||||
) -> Result<(), VmError> {
|
||||
// 递归属性检查按线程隔离。
|
||||
let thread = std::thread::current().id();
|
||||
// 同线程同对象检查重入时返回,避免 type_target 读取自身属性导致无限递归。
|
||||
if !self
|
||||
.active_attribute_checks
|
||||
.lock()
|
||||
@@ -1174,14 +1218,19 @@ impl ObjectStore {
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
// 成功登记后建立守卫,错误和正常返回都清理本次对象检查标记。
|
||||
let _guard = AttributeCheckGuard {
|
||||
store: self,
|
||||
thread,
|
||||
object,
|
||||
};
|
||||
// 仅有有效名义类型时才有继承能力可检查。
|
||||
if let Some(definition) = self.type_of(object)? {
|
||||
// 全部继承能力都参与,不以首个成功项短路。
|
||||
for capability in self.inherited_traits(definition)? {
|
||||
// 能力载荷先验证,再借用名称/完整签名/最小要求。
|
||||
let contract = self.payload::<EndorTraitObject>(capability, "Trait")?;
|
||||
// 实例字段不得取代能力方法表分派,拒绝同名属性遮蔽。
|
||||
if contract.signatures.contains_key(name) {
|
||||
return Err(VmError::TraitViolation {
|
||||
capability: contract.name.clone(),
|
||||
@@ -1194,26 +1243,34 @@ impl ObjectStore {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 类型附着/能力声明/宿主分派前核对实际属性存储及固有属性不遮蔽能力方法。
|
||||
fn check_capability_storage(
|
||||
&self,
|
||||
object: ObjectRef,
|
||||
capability: ObjectRef,
|
||||
) -> Result<(), VmError> {
|
||||
// 能力载荷先验证,再借用名称/完整签名/最小要求。
|
||||
let contract = self.payload::<EndorTraitObject>(capability, "Trait")?;
|
||||
// 没有完整签名时无此处的类型化方法存储不变量。
|
||||
if contract.signatures.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
// 沿属性转发链确定实际存储终点,attribute_path 成功时链必非空。
|
||||
let storage = *self
|
||||
.attribute_path(object)?
|
||||
.last()
|
||||
.expect("nonempty attribute path");
|
||||
// 检查每个类型化方法名的固有元数据及存储属性冲突。
|
||||
for name in contract.signatures.keys() {
|
||||
// 查询原对象固有属性身份,而不是只查看转发终点。
|
||||
let payload = self.object(object)?.payload();
|
||||
// Type 的 name/base/类方法与 Trait 的 name 都是固有属性,可能与能力方法冲突。
|
||||
let intrinsic = if payload.as_any().is::<EndorTypeObject>() {
|
||||
name == "name" || name == "base" || self.lookup_method(object, name)?.is_some()
|
||||
} else {
|
||||
payload.as_any().is::<EndorTraitObject>() && name == "name"
|
||||
};
|
||||
// 固有属性无法经普通存储删除,声明该冲突能力必须失败。
|
||||
if intrinsic {
|
||||
return Err(VmError::TraitViolation {
|
||||
capability: contract.name.clone(),
|
||||
@@ -1221,6 +1278,7 @@ impl ObjectStore {
|
||||
reason: "intrinsic attribute shadows a typed capability method",
|
||||
});
|
||||
}
|
||||
// 字段命中即冲突;不存在或不允许属性可继续,其他错误传播。
|
||||
match self.heap.get_attr(storage, name) {
|
||||
Ok(_) => {
|
||||
return Err(VmError::TraitViolation {
|
||||
@@ -1240,9 +1298,13 @@ impl ObjectStore {
|
||||
|
||||
/// Method names whose instance storage participates in typed capability
|
||||
/// validity. Hosts can subscribe to these attribute keys when caching.
|
||||
/// 宿主缓存查询当前类型化能力涉及的属性键,返回去重名称,不建立订阅。
|
||||
pub fn typed_method_names(&self, object: ObjectRef) -> Result<Vec<String>, VmError> {
|
||||
// 按名称去重,多个能力共用方法名只返回一次。
|
||||
let mut names = std::collections::BTreeSet::new();
|
||||
// 仅有有效名义类型时才有继承能力可检查。
|
||||
if let Some(definition) = self.type_of(object)? {
|
||||
// 全部继承能力都参与,不以首个成功项短路。
|
||||
for capability in self.inherited_traits(definition)? {
|
||||
names.extend(
|
||||
self.payload::<EndorTraitObject>(capability, "Trait")?
|
||||
@@ -1257,8 +1319,11 @@ impl ObjectStore {
|
||||
|
||||
/// Validate instance storage before host dispatch that bypasses attribute
|
||||
/// lookup. Raw storage access is trusted but cannot certify conformance.
|
||||
/// 绕过普通属性查找的宿主分派必须显式重验实例存储,原始载荷读取不能证明符合能力。
|
||||
pub fn check_typed_instance_storage(&self, object: ObjectRef) -> Result<(), VmError> {
|
||||
// 仅有有效名义类型时才有继承能力可检查。
|
||||
if let Some(definition) = self.type_of(object)? {
|
||||
// 全部继承能力都参与,不以首个成功项短路。
|
||||
for capability in self.inherited_traits(definition)? {
|
||||
self.check_capability_storage(object, capability)?;
|
||||
}
|
||||
@@ -1266,11 +1331,15 @@ impl ObjectStore {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 值级能力查询:先验证有效类型显式声明,再检查实例实际存储,旧无类型对象为 false。
|
||||
pub fn supports(&self, object: ObjectRef, capability: ObjectRef) -> Result<bool, VmError> {
|
||||
self.payload::<EndorTraitObject>(capability, "Trait")?;
|
||||
// 无有效类型返回 false,有类型还需显式能力声明及实例存储检查。
|
||||
match self.type_of(object)? {
|
||||
Some(definition) => {
|
||||
// 显式声明或继承才算支持能力,方法形状相同也不会自动成为声明。
|
||||
let declared = self.implements_trait(definition, capability)?;
|
||||
// 命中声明后重验当前方法/实例,避免把历史声明当作永久有效证明。
|
||||
if declared {
|
||||
self.check_capability_storage(object, capability)?;
|
||||
}
|
||||
@@ -1285,19 +1354,31 @@ impl ObjectStore {
|
||||
/// while validating the return, so rebinding globals cannot release it mid-call.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum AnnotationType {
|
||||
/// 内建 Object 注解,接受所有有效值,不等于特定 Object 名义定义。
|
||||
Any,
|
||||
/// 只接受 Value::Nil。
|
||||
Unit,
|
||||
/// 接受直接 Number 或堆数值载荷。
|
||||
Number,
|
||||
/// 接受直接 Text 或堆字符串载荷。
|
||||
String,
|
||||
/// 只接受直接 Bool。
|
||||
Bool,
|
||||
/// 按载荷 is_function 判定,不接受所有可调用 Type。
|
||||
Function,
|
||||
/// 要求 Type 载荷。
|
||||
Type,
|
||||
/// 要求 Trait 载荷。
|
||||
Trait,
|
||||
/// 借用名义类型定义,按实例继承关系匹配。
|
||||
Nominal(ObjectRef),
|
||||
/// 借用显式能力定义,按 supports 完整检查。
|
||||
Capability(ObjectRef),
|
||||
}
|
||||
impl AnnotationType {
|
||||
/// 帧/签名 trace 和保护逻辑取得注解携带的借用定义引用,直接类别没有引用。
|
||||
pub fn reference(self) -> Option<ObjectRef> {
|
||||
// 只有 Nominal/Capability 携带定义强边来源,其余注解是直接类别。
|
||||
match self {
|
||||
Self::Nominal(reference) | Self::Capability(reference) => Some(reference),
|
||||
_ => None,
|
||||
@@ -1305,7 +1386,9 @@ impl AnnotationType {
|
||||
}
|
||||
}
|
||||
impl ObjectStore {
|
||||
/// 源码字段/函数解析内建注解名,优先于环境同名绑定;Text 与 String 同义。
|
||||
fn primitive_annotation(name: &str) -> Option<AnnotationType> {
|
||||
// 内建注解直接映射固定类别,不访问语言全局空间。
|
||||
match name {
|
||||
"Object" => Some(AnnotationType::Any),
|
||||
"Unit" => Some(AnnotationType::Unit),
|
||||
@@ -1319,6 +1402,7 @@ impl ObjectStore {
|
||||
}
|
||||
}
|
||||
|
||||
/// Store 字段写入/删除按对象有效类型查字段真实声明层,返回借用定义及字段。
|
||||
pub(crate) fn declared_field(
|
||||
&self,
|
||||
object: ObjectRef,
|
||||
@@ -1327,17 +1411,22 @@ impl ObjectStore {
|
||||
self.declared_field_in_type(self.type_of(object)?, name)
|
||||
}
|
||||
|
||||
/// 字段验证沿继承链只搜索每层自有后缀,使继承字段使用原声明环境。
|
||||
fn declared_field_in_type(
|
||||
&self,
|
||||
mut current: Option<ObjectRef>,
|
||||
name: &str,
|
||||
) -> Result<Option<(ObjectRef, &ClassField)>, VmError> {
|
||||
// 沿固定基类链逐层读取,不按名称猜测类型。
|
||||
while let Some(definition) = current {
|
||||
// 先验证定义/函数载荷,再访问字段表或声明环境。
|
||||
let data = self.payload::<EndorTypeObject>(definition, "Type")?;
|
||||
// 父字段占当前布局前缀,当前层只搜索其后的自有声明。
|
||||
let inherited = match data.base {
|
||||
Some(base) => self.payload::<EndorTypeObject>(base, "Type")?.fields.len(),
|
||||
None => 0,
|
||||
};
|
||||
// 命中字段时返回当前声明 owner,让后续注解解析使用正确环境。
|
||||
if let Some(field) = data.fields[inherited..]
|
||||
.iter()
|
||||
.find(|field| field.name == name)
|
||||
@@ -1349,12 +1438,14 @@ impl ObjectStore {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Store 开启字段检查时校验已声明字段,未声明动态属性不在此限制。
|
||||
pub(crate) fn check_field_write(
|
||||
&self,
|
||||
object: ObjectRef,
|
||||
name: &str,
|
||||
value: &Value,
|
||||
) -> Result<(), VmError> {
|
||||
// 动态未声明字段允许通过;已声明字段按原 owner 的约束验证。
|
||||
let Some((owner, field)) = self.declared_field(object, name)? else {
|
||||
return Ok(());
|
||||
};
|
||||
@@ -1363,12 +1454,15 @@ impl ObjectStore {
|
||||
|
||||
/// NativeTyped allocators can validate their field suffix before any effects.
|
||||
/// Count is always checked; annotation matching follows the opt-in setting.
|
||||
/// Record/NativeTyped 构造器在副作用前校验字段后缀;数量始终检查,类型匹配由开关控制。
|
||||
pub fn check_class_field_arguments(
|
||||
&self,
|
||||
definition: ObjectRef,
|
||||
arguments: &[Value],
|
||||
) -> Result<(), VmError> {
|
||||
// 先验证定义/函数载荷,再访问字段表或声明环境。
|
||||
let data = self.payload::<EndorTypeObject>(definition, "Type")?;
|
||||
// 字段构造数量始终严格相等,错误发生在逐字段类型检查之前。
|
||||
if arguments.len() != data.fields.len() {
|
||||
return Err(VmError::ArgumentCount {
|
||||
name: data.name.clone(),
|
||||
@@ -1377,8 +1471,11 @@ impl ObjectStore {
|
||||
provided: arguments.len(),
|
||||
});
|
||||
}
|
||||
// 可选类型检查开关不改变字段数量规则。
|
||||
if self.field_type_checks {
|
||||
// 依照完整继承字段顺序匹配实参,每项还原真实声明层。
|
||||
for (field, value) in data.fields.iter().zip(arguments) {
|
||||
// 完整字段表与继承前缀不变量保证声明层存在。
|
||||
let (owner, field) = self
|
||||
.declared_field_in_type(Some(definition), &field.name)?
|
||||
.expect("class field has a declaring type");
|
||||
@@ -1388,13 +1485,16 @@ impl ObjectStore {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 声明字段按自身 owner/内建名/声明函数环境解析类型,再执行值匹配。
|
||||
fn check_field_value(
|
||||
&self,
|
||||
owner: ObjectRef,
|
||||
field: &ClassField,
|
||||
value: &Value,
|
||||
) -> Result<(), VmError> {
|
||||
// 验证类型载荷后才读取其基类或能力列表。
|
||||
let definition = self.payload::<EndorTypeObject>(owner, "Type")?;
|
||||
// 自类名优先、其次内建注解,再查声明函数环境,无环境则未知注解。
|
||||
let expected = if field.type_name == definition.name {
|
||||
AnnotationType::Nominal(owner)
|
||||
} else if let Some(primitive) = Self::primitive_annotation(&field.type_name) {
|
||||
@@ -1404,6 +1504,7 @@ impl ObjectStore {
|
||||
} else {
|
||||
return Err(VmError::UnknownAnnotation(field.type_name.clone()));
|
||||
};
|
||||
// 类型化能力才需要扫描实例存储,最小数量能力没有遮蔽签名要求。
|
||||
if !self.matches_annotation(value, expected)? {
|
||||
return Err(VmError::TypeMismatch {
|
||||
function: definition.name.clone(),
|
||||
@@ -1415,25 +1516,33 @@ impl ObjectStore {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// eval 参数/返回与字段契约解析源码注解,返回借用描述符,不 retain 定义。
|
||||
pub fn annotation_type(
|
||||
&self,
|
||||
function: ObjectRef,
|
||||
name: &str,
|
||||
receiver: Option<ObjectRef>,
|
||||
) -> Result<AnnotationType, VmError> {
|
||||
// 先验证定义/函数载荷,再访问字段表或声明环境。
|
||||
let data = self.payload::<crate::EndorFunctionObject>(function, "function")?;
|
||||
// 方法 owner 解析需要代码中的源码声明元数据,函数本身只持有代码引用。
|
||||
let signature = self
|
||||
.payload::<crate::EndorCodeObject>(data.code(), "code")?
|
||||
.code()
|
||||
.source_signature();
|
||||
// Bind a method's own class to the definition that actually owns it,
|
||||
// including inherited methods and old instances after REPL redefinition.
|
||||
// 只对声明自身 owner 名称且有接收者的场景沿真实类型链查找。
|
||||
if signature.and_then(|s| s.method_owner.as_deref()) == Some(name)
|
||||
&& let Some(receiver) = receiver
|
||||
{
|
||||
// 从接收者当前名义类型向父类查找实际拥有该源码方法的定义。
|
||||
let mut current = self.type_of(receiver)?;
|
||||
// 沿固定基类链逐层读取,不按名称猜测类型。
|
||||
while let Some(definition) = current {
|
||||
// 借用继承链类型,要求名称相同且方法表仍持有当前函数。
|
||||
let payload = self.payload::<EndorTypeObject>(definition, "Type")?;
|
||||
// 同时检查名称和函数身份,避免 REPL 同名重定义误绑定旧实例。
|
||||
if payload.name == name
|
||||
&& payload.methods.values().any(|method| *method == function)
|
||||
{
|
||||
@@ -1442,26 +1551,33 @@ impl ObjectStore {
|
||||
current = payload.base;
|
||||
}
|
||||
}
|
||||
// 内建注解先于普通环境绑定,避免同名用户对象改变内建语义。
|
||||
if let Some(primitive) = Self::primitive_annotation(name) {
|
||||
return Ok(primitive);
|
||||
}
|
||||
// 普通注解查函数全局及内置空间;Option::or 的参数会先求值,因此内置读取不是惰性。
|
||||
let value = self
|
||||
.dict_get_name(data.globals(), name)?
|
||||
.or(match data.builtins() {
|
||||
Some(builtins) => self.dict_get_name(builtins, name)?,
|
||||
None => None,
|
||||
});
|
||||
// 普通名称必须指向 Type 或 Trait 载荷,其他值不能充当类型注解。
|
||||
if let Some(Value::Object(definition)) = value {
|
||||
// 查询原对象固有属性身份,而不是只查看转发终点。
|
||||
let payload = self.object(definition)?.payload();
|
||||
// 识别名义类型,描述符只借用该定义身份。
|
||||
if payload.as_any().is::<EndorTypeObject>() {
|
||||
return Ok(AnnotationType::Nominal(definition));
|
||||
}
|
||||
// 识别显式能力定义,不以类名字符串替代能力身份。
|
||||
if payload.as_any().is::<EndorTraitObject>() {
|
||||
return Ok(AnnotationType::Capability(definition));
|
||||
}
|
||||
}
|
||||
Err(VmError::UnknownAnnotation(name.into()))
|
||||
}
|
||||
/// 调用/字段检查把类型验证读取标记为 validation,普通程序读取仍可另行记录。
|
||||
pub fn matches_annotation(
|
||||
&self,
|
||||
value: &Value,
|
||||
@@ -1471,14 +1587,17 @@ impl ObjectStore {
|
||||
.with_validation_reads(|| self.matches_annotation_value(value, expected))
|
||||
}
|
||||
|
||||
/// 匹配已解析注解;对象先校验存活,直接类别可同时支持直接值和相应堆载荷。
|
||||
fn matches_annotation_value(
|
||||
&self,
|
||||
value: &Value,
|
||||
expected: AnnotationType,
|
||||
) -> Result<bool, VmError> {
|
||||
// Any 也不能接受失效句柄,先验证对象存活再匹配类别。
|
||||
if let Value::Object(object) = value {
|
||||
self.object(*object)?;
|
||||
}
|
||||
// 直接类别与名义/能力匹配分开;Type/Function 类别不等于任意可调用对象。
|
||||
Ok(match expected {
|
||||
AnnotationType::Any => true,
|
||||
AnnotationType::Unit => matches!(value, Value::Nil),
|
||||
@@ -1510,7 +1629,9 @@ impl ObjectStore {
|
||||
},
|
||||
})
|
||||
}
|
||||
/// 类型错误诊断格式化预期名称;名义/能力定义仍验证句柄和载荷。
|
||||
pub fn annotation_type_name(&self, expected: AnnotationType) -> Result<String, VmError> {
|
||||
// 直接类别与名义/能力匹配分开;Type/Function 类别不等于任意可调用对象。
|
||||
Ok(match expected {
|
||||
AnnotationType::Any => "Object".into(),
|
||||
AnnotationType::Unit => "Unit".into(),
|
||||
@@ -1530,7 +1651,9 @@ impl ObjectStore {
|
||||
.clone(),
|
||||
})
|
||||
}
|
||||
/// 类型错误诊断显示实际类型,优先有效名义类型,无类型才回退载荷类别。
|
||||
pub fn value_type_name(&self, value: &Value) -> Result<String, VmError> {
|
||||
// 直接值显示内建类别;对象优先显示有效名义类型名。
|
||||
Ok(match value {
|
||||
Value::Nil => "Unit".into(),
|
||||
Value::Bool(_) => "Bool".into(),
|
||||
|
||||
Reference in New Issue
Block a user