-
Notifications
You must be signed in to change notification settings - Fork 0
Typed Document
TDoc 序列化并还原 AuroraScript 值,同时保留支持的运行时类型。
适用于 4.0.0。
首页 · 脚本 TDoc API · .NET TDoc API
TDoc 是 AuroraScript 的 typed 文本数据格式。它将一个 AuroraScript 值写为独立文档,并在读取时还原普通对象、数组、packed array、Date、Path、Regex、HashMap、StringBuffer 以及宿主注册的 CLR/CIL 对象。
独立 TDoc 文档不是第二种脚本语法:其内容不执行代码,不支持变量、调用、脚本 tdoc 标记或内联表达式;它直接从根值开始。
- 持久化必须保留 AuroraScript 类型标识的配置、快照或状态。
- 在 AuroraScript 宿主之间交换数据,当 packed array 或
Date等类型必须保留时。 - 将通过
AuroraEngine.RegisterType显式注册的 CLR/CIL 对象写入受控数据契约。
TDoc 不将运行时行为视为持久数据。写入时,函数、代理、访问器属性、未注册的 CLR/CIL 对象、非有限 Number,以及当前文档中已见过的循环/共享引用,均作为可跳过值处理,而非使整个 stringify 失败。
Object {
readonly String id "u-001",
String name "Aurora",
Number version 4,
Int8Array payload [-128, 0, 127],
Date createdAt "2026-08-20 10:00:00",
}
上述根值为 ScriptObject;id 为浅只读属性,payload 保持为 ScriptInt8Array,而非变为通用 Array。
在脚本中使用 TDoc:
var profile = TDoc.parse('Object { String name "Aurora", Int8Array levels [1, 2] }');
var text = TDoc.stringify(profile, false);
return text;
在宿主中使用 AuroraTypedDocument:
var tdoc = new AuroraTypedDocument(engine);
var text = tdoc.Serialize(ScriptDatum.FromString("Aurora"));
var value = tdoc.Deserialize(text);在 .as 脚本中,小写 tdoc 直接构造 TDoc 值。它是编译器识别的表达式边界,而非 TDoc 全局上的方法调用;结果是可赋值、返回或在模块初始化器中创建的正常 AuroraScript 运行时值。
func createProfile(user, baseAge) {
return tdoc Object {
readonly String id $(user.id),
name "Aurora",
age $(baseAge + 1),
tags [String "system", Number 4],
};
}
语法形状为:
tdoc-literal = "tdoc" typed-value ;
typed-value = [ type-name ] raw-value ;
raw-value = "null" | boolean | number | string | array | object | interpolation ;
array = "[" [ typed-value { "," typed-value } [ "," ] ] "]" ;
object = "{" [ member { "," member } [ "," ] ] "}" ;
member = [ "readonly" ] [ type-name ] property-name raw-value ;
property-name = identifier | string ;
interpolation = "$(" aurora-expression ")" ;-
tdoc为小写,后接单个 TDoc 值;独立.tdoc文件不写入此前缀。 - 类型名可选。可从字面量唯一推断的类型(如
Object、Array、String、Number、Boolean)可省略;Int8Array、Date、Path、Regex、HashMap、StringBuffer等内置类型可显式写入以保留标识。 - 原生脚本字面量不从类型名构造已注册的 CLR/CIL 对象;现有实例可通过
$()提供。已注册别名的文本往返由TDoc.parse、TDoc.stringify和宿主AuroraTypedDocumentAPI 提供。 - 对象成员使用空格分隔的
type-name property-name value语法,而非:。单个标识符为属性名,如name "Aurora";两个相邻标识符表示显式类型和属性名,如String name "Aurora"。 -
readonly仅适用于对象成员,创建浅只读属性;不会冻结该属性中存储的对象。
仅值位置接受 $()。内容为脚本运行时求值的普通 AuroraScript 表达式;可用于数组元素、对象成员值和根值。
func createProfile(user, baseAge) {
return tdoc Object {
readonly String id $(user.id),
role $(user.role),
age $(baseAge + 1),
tags [$(user.role), "system"],
};
}
属性名和类型名必须为静态文本;不支持动态注入:
tdoc Object { $(key) "value" } // invalid: dynamic property name
tdoc $(typeName) { enabled true } // invalid: dynamic type name
纯 TDoc 数据部分不执行调用或其他脚本表达式;动态计算必须在 $() 内显式进行。模板字符串、任意一元表达式和未包装的调用不能直接用作 TDoc 值。
原生脚本字面量与独立文档共享对象、数组、类型名、尾随逗号和 readonly,但入口不同:
| 入口 | 根语法 | $() |
典型用途 |
|---|---|---|---|
.as 脚本 |
tdoc Object { ... } |
仅值位置允许 | 在代码中构造配置或请求 |
.tdoc 文件 / TDoc.parse
|
Object { ... } |
禁止 | 配置、持久化与宿主交换 |
tdoc 表达式本身不产生文本。需要文本时调用 TDoc.stringify(value, indented, emitTypes),从文本还原值时使用 TDoc.parse(text)。独立 .tdoc 文件不能包含变量、调用或 $()。
普通 ScriptObject 从其脚本可见的可枚举属性写入:先自有属性,再沿原型链未遮蔽的属性。生成的 TDoc 为扁平对象;原型标识、原型链和访问器本身不保留。
stringify 对不可表示的运行时值使用固定的非抛出降级:对象属性(包括通过原型可见的属性)被省略;数组元素变为 null 以保留索引;HashMap 条目中不可表示的键或值变为 null;不可表示的根变为 null。因此 TDoc 是数据快照,而非完整对象图的无损克隆。
var action = () => true;
var value = { name: "Aurora", cancel: action, values: [1, action, 3] };
TDoc.stringify(value, false);
// {name "Aurora",values [1,null,3,],}
文档允许一个根值。类型名可显式;省略时,仅由原始字面量唯一确定的值自动推断。
document = typed-value EOF ;
typed-value = [ type-name ] raw-value ;
raw-value = "null" | boolean | number | string | array | object ;
array = "[" [ typed-value { "," typed-value } [ "," ] ] "]" ;
object = "{" [ member { "," member } [ "," ] ] "}" ;
member = [ "readonly" ] [ type-name ] property-name raw-value ;
property-name = identifier | string ;
type-name = identifier ;在对象成员中,两个连续标识符表示「类型名 + 属性名」;一个标识符为属性名。例如,String name "Aurora" 显式声明 String,而 name "Aurora" 让读取器推断为字符串。
字符串值必须使用单引号或双引号。Object { id UX01 } 和 Object { id UX01-03 } 均无效:前者中 UX01 位于标识符位置,后者中 - 不是标识符的一部分。应写 Object { id "UX01" } 或 Object { id "UX01-03" }。
支持行注释(//)、块注释(/* ... */)和尾随逗号。脚本 tdoc 标记在独立文档中无效并产生语法错误。
| 文本形状 | 读取结果 | 默认发出的类型名 |
|---|---|---|
null |
Null |
No |
true / false
|
Boolean |
No |
42 / 1.5 / 0xFF
|
Number (double) |
No |
"text" / 'text'
|
String |
No |
[ ... ] |
ScriptArray |
No |
{ ... } |
ScriptObject |
No |
StringBuffer "text" |
StringBuffer |
Yes |
Date "..." / Date 14425655658
|
ScriptDate |
Yes |
Regex { ... } |
ScriptRegex |
Yes |
Path "a/b.as" |
ScriptPathValue |
Yes |
HashMap [ [key, value] ] |
ScriptHashMap |
Yes |
Int8Array, UInt8Array, Int16Array, UInt16Array, Int32Array, UInt32Array, Int64Array, UInt64Array, Float64Array, BooleanArray
|
对应的 packed array | Always |
已注册类型,例如 User { ... }
|
已注册的 CLR/CIL 实例 | Always |
该表列出读取结果及默认是否发出类型名。
EmitTypeNames 默认为 false,因此写入器仅发出无法从原始字面量唯一推断的类型名。Object、Array、String、Number 和 Boolean 默认省略;Date、所有类对象内置类型、所有 packed array 和已注册 CLR/CIL 类型仍强制类型名。将 EmitTypeNames 设为 true 可强制发出每个可用类型名。
Float32Array 在当前运行时中不是支持的 TDoc 或脚本类型。浮点 packed 数据使用 Float64Array,或在宿主中于序列化前后转换单精度数据。
// default: EmitTypeNames = false
{ name "Aurora", Int8Array bytes [1, 2] }
// EmitTypeNames = true
Object { String name "Aurora", Int8Array bytes [1, 2] }
readonly 是对象属性描述符,而非类型。它阻止属性再次被写入,但不冻结其对象值。
Object {
readonly Object settings { retries 3 },
}
读取后,settings = other 失败,而 settings.retries = 4 仍有效。TDoc 写入器保留 readonly 标记。
Date 字符串必须匹配当前 AuroraEngine EngineOptions.Runtime.DateTimeFormat;数值形式为 .NET ticks,必须是范围内整数。写入始终使用引擎日期格式产生字符串。
Date "2026-08-20 10:00:00"
Regex { pattern "ab+", flags "gi" }
HashMap [["name", "Aurora"], [1, true]]
HashMap 使用两元素数组表示键和值,因此非字符串键不会降级为对象属性。
文档中的 CLR/CIL 类型名必须是当前引擎上已注册的别名。TDoc 不会从程序集名、.NET 类型名或反射自动加载类型。
engine.RegisterType<User>("User");
var tdoc = new AuroraTypedDocument(engine);
var user = tdoc.Deserialize("User { String Name \"Hanks\", Number Age 18 }");读取时,未注册对象的显式别名、未知别名、不可构造类型或违反已注册成员契约的文本会失败。写入时,未注册或不可写的 CLR/CIL 值遵循可跳过值规则。已注册类型名如 User 即使 EmitTypeNames 为 false 也不会省略。
宿主 API 抛出 TypedDocumentException。其 SourceName、Line、Column 和 DataPath 定位错误;例如 $.meta.tags[2] 标识嵌套数组中的第三项。
脚本 API 将此异常转换为 AuroraRuntimeException,消息以 TDoc.parse error: 或 TDoc.stringify error: 开头。
AuroraScript.JIT 4.0.0 · 文档首页 · 仓库 · MIT License