📝 docs(tsl): rebuild canonical syntax and routing manual

This commit is contained in:
csh
2026-04-22 16:59:20 +08:00
parent 3ed5052e61
commit 96b705b00b
83 changed files with 46446 additions and 323 deletions
@@ -0,0 +1,399 @@
# Object Runtime And Introspection
文档类型:语法主线
是否可直接用于生成代码:仅部分
是否含已验证可执行示例:是
是否含已验证反例:否
遇到不确定时跳转到:[09_objects_and_classes.md](09_objects_and_classes.md)、[24_builtin_runtime_objects.md](24_builtin_runtime_objects.md)、[32_object_overloads_and_iteration.md](32_object_overloads_and_iteration.md)
手册位置:第 23 篇,共 32 篇。上一篇:[22_namespace_libpath_and_unit_runtime.md](22_namespace_libpath_and_unit_runtime.md)。下一篇:[24_builtin_runtime_objects.md](24_builtin_runtime_objects.md)。
这一篇收拢对象模型里不适合继续堆在基础类主线里的运行时内容:类信息、函数句柄、对象状态、引用计数、运行时对象枚举。
## 这一篇解决什么问题
回答“类已经会声明、继承、构造之后,怎样检查类信息、函数信息和对象运行时状态”。
## 必须记住的规则
- 对象值当前可以用 `ifObj(...)` 做显式判定。
- `class(Name)``FindClass("Name")` 当前都可以拿到类类型。
- `obj is classType` 当前已验证可直接拿类类型变量来做实例判定。
- `FindClass("ParentName", obj)` 当前已验证可以把实例对象降成指定父类视图。
- `obj.ClassInfo(1)` 当前已验证会返回类类型,并且这个类类型可以继续交给 `CreateObject(...)`
- `obj.ClassInfo()` 当前至少已验证可以直接读出 `["classname"]`
- `objectstate(self)` 在构造函数内部的最小已验证结果是 `1`;构造结束后对实例再取 `objectstate(obj)` 的最小已验证结果是 `2`
- `tslassigning` 在属性写入函数里输出 `1`,在属性读取函数里输出 `0`
- `FindFunction("MethodName", obj)` 当前已验证可以拿到实例方法句柄。
- `FindFunction("MethodName", class(A))` 当前已验证可以拿到类方法句柄。
- `ThisFunction(obj.Method)``ThisFunction(class(A).Method)` 当前也已验证可用。
- 当前最稳的句柄调用方式是 `f.do(...)`
- `FindOverLoad(argc, "Name", obj)` 当前已验证可以按参数个数取到对应重载方法。
- `FunctionInfo` 当前至少已验证可以读出 `functionname``returntype``classname` 这几个字段。
- `TSLObjects(1)` 当前已验证会按类名分组返回对象信息,并且分组项里的 `"obj"` 字段可以重新拿到可调用对象。
- 对象赋值会延长对象存活;当前最小样例里,只有最后一个引用清空后才会触发 `destroy()`
## 已验证语法
对象值的最小显式判定:
代码块身份:已验证可执行示例
```tsl
program test;
begin
obj := CreateObject("TStringList");
WriteLn(ifObj(obj));
end.
```
已验证运行结果:
- 输出 `1`
- 说明 `CreateObject(...)` 得到的对象值当前可以用 `ifObj(...)` 判定
`FindClass(...)` 与类类型变量:
代码块身份:已验证可执行示例
```tsl
program test;
type A = class
class function FucA();
begin
return "ClassA";
end;
end;
begin
classA := FindClass("A");
obj := new A();
WriteLn(classA.FucA());
WriteLn(obj is classA);
end.
```
已验证运行结果:
- 依次输出 `ClassA``1`
- 说明 `FindClass("A")` 当前可以拿到类类型
- 说明类类型变量可以直接调用类方法
- 也说明 `obj is classA` 这种“实例对类类型变量做判定”的写法当前可用
`FindClass("Parent", obj)` 的父类视图:
代码块身份:已验证可执行示例
```tsl
program test;
type ClassA = class
function Fuc(); virtual;
begin
return "ClassA";
end;
end;
type ClassB = class(ClassA)
function Fuc(); override;
begin
return "ClassB";
end;
end;
begin
objb := new ClassB();
obj := FindClass("ClassA", objb);
WriteLn(obj.Fuc());
end.
```
已验证运行结果:
- 输出 `ClassA`
- 说明 `FindClass("ClassA", objb)` 当前可以把子类实例降成父类视图
- 也说明之后的方法分派会按父类视图执行
`ClassInfo(1)` 返回类类型:
代码块身份:已验证可执行示例
```tsl
program test;
type A = class
value;
end;
begin
obj := new A();
cls := obj.ClassInfo(1);
obj2 := CreateObject(cls);
WriteLn(obj2 is class(A));
end.
```
已验证运行结果:
- 输出 `1`
- 说明 `obj.ClassInfo(1)` 当前可以返回类类型
- 也说明这个类类型可以继续交给 `CreateObject(...)`
`ClassInfo()` 返回的映射字段:
代码块身份:已验证可执行示例
```tsl
program test;
type A = class
end;
begin
obj := new A();
info := obj.ClassInfo();
WriteLn(info["classname"]);
end.
```
已验证运行结果:
- 输出 `a`
- 说明 `ClassInfo()` 当前至少可以直接读出 `["classname"]`
- 当前这个最小例子里,类名表现为小写标识符
`objectstate(...)`
代码块身份:已验证可执行示例
```tsl
program test;
type ca = class
static sca;
function create(n);
begin
sca := self;
WriteLn(objectstate(self));
end;
end;
begin
oa := new ca("abc");
WriteLn(objectstate(oa));
end.
```
已验证运行结果:
- 依次输出 `1``2`
- 说明当前最小样例里,构造函数内部对象状态是 `1`
- 构造结束后,再对实例取 `objectstate(...)` 会得到 `2`
`tslassigning`
代码块身份:已验证可执行示例
```tsl
program test;
type ca = class
value;
property c read getc write setc;
function setc(v);
begin
WriteLn(tslassigning);
value := v;
end;
function getc();
begin
WriteLn(tslassigning);
return value;
end;
end;
begin
o := new ca();
o.c := 3;
WriteLn(o.c);
end.
```
已验证运行结果:
- 依次输出 `1``0``3`
- 说明属性写入函数里 `tslassigning``1`
- 属性读取函数里 `tslassigning``0`
`FindFunction(...)` 查找实例方法和类方法:
代码块身份:已验证可执行示例
```tsl
program test;
type A = class
function Add(x, y);
begin
return x + y;
end;
class function AddClass(x, y);
begin
return x + y;
end;
end;
begin
obj := new A();
f1 := FindFunction("Add", obj);
f2 := FindFunction("AddClass", class(A));
WriteLn(f1.do(3, 4));
WriteLn(f2.do(5, 6));
end.
```
已验证运行结果:
- 依次输出 `7``11`
- 说明 `FindFunction(..., obj)` 当前能拿到实例方法句柄
- 说明 `FindFunction(..., class(A))` 当前能拿到类方法句柄
- 也说明句柄调用方式 `f.do(...)` 当前稳定可用
`ThisFunction(...)` 也可以直接拿方法句柄:
代码块身份:已验证可执行示例
```tsl
program test;
type A = class
function Add(x, y);
begin
return x + y;
end;
class function AddClass(x, y);
begin
return x + y;
end;
end;
begin
obj := new A();
f1 := ThisFunction(obj.Add);
f2 := ThisFunction(class(A).AddClass);
WriteLn(f1.do(3, 4));
WriteLn(f2.do(5, 6));
end.
```
已验证运行结果:
- 依次输出 `7``11`
- 说明 `ThisFunction(...)` 当前也可以稳定得到实例方法和类方法句柄
`FindOverLoad(...)`
代码块身份:已验证可执行示例
```tsl
program test;
type TestClass = class
function fun(p1, p2); overload;
begin
return p1 + p2;
end;
function fun(p1); overload;
begin
return p1 + 10;
end;
end;
begin
t := FindOverLoad(2, "fun", CreateObject("TestClass"));
WriteLn(t.do(1, 2));
end.
```
已验证运行结果:
- 输出 `3`
- 说明 `FindOverLoad(2, "fun", obj)` 当前可以按参数个数拿到对应重载方法
`FunctionInfo` 的最小已验证字段:
代码块身份:已验证可执行示例
```tsl
program test;
type A = class
class function Add(a: lhs; b: rhs): sum_t;
begin
return a + b;
end;
end;
begin
f := ThisFunction(class(A).Add);
info := f.FunctionInfo;
WriteLn(info["functionname"]);
WriteLn(info["returntype"]);
WriteLn(info["classname"]);
end.
```
已验证运行结果:
- 依次输出 `add``sum_t``a`
- 说明 `FunctionInfo["functionname"]``["returntype"]``["classname"]` 当前都可直接读取
- 当前这个最小例子里,返回的函数名和类名表现为小写标识符
`TSLObjects(1)`
代码块身份:已验证可执行示例
```tsl
program test;
type TestClass01 = class
value;
function create(_value);
begin
value := _value;
end;
class function add(x, y);
begin
return x + y;
end;
end;
begin
objA := new TestClass01(100);
objB := new TestClass01(101);
objsInfo := TSLObjects(1);
WriteLn(length(objsInfo["TestClass01"]));
newObjA := objsInfo["TestClass01"][0, "obj"];
WriteLn(newObjA is class(TestClass01));
WriteLn(newObjA.add(1, 2));
end.
```
已验证运行结果:
- 依次输出 `2``1``3`
- 说明 `TSLObjects(1)` 当前可以按类名拿到对象分组
- 分组项里的 `"obj"` 字段当前可以重新拿到可调用对象
引用计数的最小行为:
代码块身份:已验证可执行示例
```tsl
program test;
type T1 = class
function destroy();
begin
WriteLn("destroy");
end;
end;
begin
o1 := new T1();
o2 := o1;
o1 := 0;
WriteLn("O1 to Zero");
o2 := 0;
WriteLn("O2 to Zero");
end.
```
已验证运行结果:
- 依次输出 `O1 to Zero``destroy``O2 to Zero`
- 说明只清空第一个别名时对象还不会释放
- 最后一个引用清空后才会触发 `destroy()`
## 跳转指引
- 回看类的基础语法:见 [09_objects_and_classes.md](09_objects_and_classes.md)
- 回看函数值与基础调用:见 [06_functions_and_calls.md](06_functions_and_calls.md)
- 看运行时内置对象:见 [24_builtin_runtime_objects.md](24_builtin_runtime_objects.md)
- 看对象算符重载:见 [32_object_overloads_and_iteration.md](32_object_overloads_and_iteration.md)