1122 lines
37 KiB
Markdown
1122 lines
37 KiB
Markdown
# TSL API 文档标准
|
||
|
||
本文件是 TSL codegen API 文档的唯一标准,包含 markdown 存储格式、tsf 源码
|
||
文档格式、yaml/json 录入格式和统一索引格式。
|
||
|
||
适用范围:`references/codegen/**/*.md` 中的 function、class 和 unit API。
|
||
|
||
## 目录
|
||
|
||
- [TSL API 文档标准](#tsl-api-文档标准)
|
||
- [目录](#目录)
|
||
- [基本原则](#基本原则)
|
||
- [markdown 存储格式](#markdown-存储格式)
|
||
- [页面与统一顶级声明](#页面与统一顶级声明)
|
||
- [function](#function)
|
||
- [class](#class)
|
||
- [unit](#unit)
|
||
- [综合示例](#综合示例)
|
||
- [tsf 源码文档格式](#tsf-源码文档格式)
|
||
- [function](#function-1)
|
||
- [class](#class-1)
|
||
- [unit](#unit-1)
|
||
- [录入数据结构](#录入数据结构)
|
||
- [function](#function-2)
|
||
- [class](#class-2)
|
||
- [unit](#unit-2)
|
||
- [录入文件格式](#录入文件格式)
|
||
- [yaml](#yaml)
|
||
- [json](#json)
|
||
- [统一 API 索引](#统一-api-索引)
|
||
|
||
## 基本原则
|
||
|
||
- 发布的 API 文档使用本标准定义的 markdown 存储格式
|
||
- tsf 源码文档、yaml/json 录入数据与 markdown 的字段映射以本标准为准
|
||
- 一个录入文件对应一个 markdown 叶子页;录入根固定为
|
||
`module`、`path`、`declarations`
|
||
- `declarations` 是非空有序列表,function、class、unit 可以混合;列表顺序即文档顺序
|
||
- function 调用签名只记录显式名称和参数名,不包含类型、默认值或语义推断内容
|
||
- API 标题的反引号内只写名称或调用签名,不写 function、class、property 等声明术语
|
||
- 每个 API 用独立的 `声明:...` 行记录声明种类
|
||
- 描述紧跟声明行;tags 是描述的检索补充,位于完整描述之后
|
||
- 描述末尾不写句号
|
||
- 示例输出必须全部写成 `//` 注释,不得把裸结果写成 TSL 语句
|
||
- 一个 `tsl` 代码块只放一个独立示例
|
||
|
||
## markdown 存储格式
|
||
|
||
### 页面与统一顶级声明
|
||
|
||
每个 markdown 叶子页使用一个 H1 模块标题,并包含一个或多个 H2 顶级声明。
|
||
function、class、unit 都是同级的顶级声明,可以出现在同一页面中;每个 H2 的声明
|
||
种类写在自身正文的 `声明:function|class|unit` 行中。
|
||
|
||
目录承担领域或模块分组,叶子页承担 API 主题分组,H2 承担顶级声明分组。markdown
|
||
不要求一个 class 对应一个 md;多个独立 class 声明可以进入同一叶子页,也可以在
|
||
内容过长或主题不同时拆到同一目录下的多个叶子页。例如
|
||
`OpenXmlAttribute` 和 `OpenXmlElement` 可以作为两个 H2 同处
|
||
`officexml/openxml/elements.md`。一个 markdown 叶子页可以收录多个对外顶级声明。
|
||
|
||
顶级声明和成员都按文档顺序存储,不按名称、种类或可见性重新排序。每个顶级声明
|
||
按以下共同顺序开始:
|
||
|
||
1. H2 标题:function 写调用签名,class 和 unit 写简单名称
|
||
2. 唯一且精确的 `声明:function`、`声明:class` 或 `声明:unit`
|
||
3. 描述,必填;声明行之后的首个非空正文必须是描述
|
||
4. `<!-- tags: 关键词1 关键词2 -->`,可选;位于完整描述之后
|
||
|
||
标题层级和声明值必须符合下表,不允许在其他层级使用这些声明值:
|
||
|
||
| 位置 | 标题层级 | 允许的声明值 |
|
||
| ---------------------------- | -------- | ------------------------------------------------------------------------------------------ |
|
||
| 顶级声明 | H2 | `function`、`class`、`unit` |
|
||
| 顶级 class 成员 | H3 | `function`、`class function`、`property`、`field`、`static field`、`const`、`static const` |
|
||
| unit interface direct member | H3 | `function`、`var`、`const`、`class` |
|
||
| unit interface class 成员 | H4 | 与顶级 class 成员相同 |
|
||
|
||
H2、H3、H4 中反引号包围的内容是 API 名称或调用签名。`function`、
|
||
`class function`、`property` 等声明术语只写在声明行中,不写进标题。
|
||
|
||
本标准中的“调用签名”只包含名称和参数名,例如 `abs(x)`,不是 TSL 声明语句
|
||
`function abs(x);`。声明行只参与文档结构识别,不属于名称、调用签名或调用语法。
|
||
例如 class 下的 H3 标题 `Save()` 紧跟 `声明:function`,表示实例 function;可调用
|
||
内容仍是 `Save()`,不能把两行拼成 `function Save()`。
|
||
|
||
每个 API 必须且只能写一行 `声明:...`,并将它作为标题后的第一条非空正文。
|
||
`声明` 后使用全角冒号,声明值使用本标准规定的小写形式。普通内容标题不包含
|
||
反引号,也不紧跟声明行,因此不进入 API 索引;普通 H2 同时结束前一个顶级声明的
|
||
正文范围。
|
||
|
||
同一所属范围和声明种类内,重复 class/unit 名称或重复 function 调用签名不允许;
|
||
function 重载和跨声明种类同名允许。
|
||
|
||
### function
|
||
|
||
#### 页面结构
|
||
|
||
顶级 function 使用 H2,function 的示例标题使用 H3。每个 function 声明按以下
|
||
顺序书写:
|
||
|
||
1. `## \`调用签名\``
|
||
2. `声明:function`
|
||
3. 函数描述,必填
|
||
4. `<!-- tags: 关键词1 关键词2 -->`,可选
|
||
5. 参数表,有参数时必填
|
||
6. 参数取值说明,可选
|
||
7. `返回:类型`
|
||
8. `### 示例`,可选;包含一个或多个“范例NN:说明”和独立的 `tsl` 代码块
|
||
|
||
#### 标签
|
||
|
||
标签位于完整函数描述之后,用空格分隔检索关键词:
|
||
|
||
```markdown
|
||
<!-- tags: 数组 排序 去重 -->
|
||
```
|
||
|
||
没有关键词时删除整行,不保留空标签。
|
||
|
||
#### 参数表
|
||
|
||
参数表固定为三列:
|
||
|
||
```markdown
|
||
| 参数 | 类型 | 说明 |
|
||
| --- | --- | --- |
|
||
| `src` | array | 待处理数组 |
|
||
```
|
||
|
||
规则:
|
||
|
||
- 参数名必须与 function 调用签名一致
|
||
- 必填参数说明直接写用途
|
||
- 可选参数说明以 `可选。` 开头,并说明默认值
|
||
- 多类型使用 `\|`,例如 `nil\|array`
|
||
- 变参使用 `...` 作为参数名
|
||
- 无参 function 省略参数表
|
||
|
||
#### 参数取值
|
||
|
||
枚举参数在参数表之后、返回类型之前列出:
|
||
|
||
```markdown
|
||
**mode 取值**
|
||
|
||
- `0` — 原样返回
|
||
- `1` — 去重
|
||
```
|
||
|
||
#### 返回类型
|
||
|
||
每个顶层 function 必须包含非空返回类型:
|
||
|
||
```markdown
|
||
返回:array
|
||
```
|
||
|
||
#### 示例代码
|
||
|
||
- 每个示例以“范例NN:说明”开头,编号按出现顺序排列并至少保留两位
|
||
- 代码围栏使用 `tsl`
|
||
- 一个代码围栏只放一个独立示例
|
||
- 字符串使用直引号 `'` 或 `"`
|
||
- 注释使用 `//`,不使用 `(* *)`
|
||
- 每条语句保留分号
|
||
- 没有输出时可以省略输出注释
|
||
- 单行输出写成 `// 输出:<值>`
|
||
- 多行输出第一行写 `// 输出:`,后续每一行输出都以 `//` 开头
|
||
|
||
多行输出示例:
|
||
|
||
```tsl
|
||
return demoLines();
|
||
// 输出:
|
||
// 第一行
|
||
// 第二行
|
||
```
|
||
|
||
#### 完整页面示例
|
||
|
||
以下 API 仅用于说明存储格式,不代表真实 TSL API:
|
||
|
||
````markdown
|
||
# 示例 / 数组
|
||
|
||
## `demoFn(src, mode, factor, ...)`
|
||
|
||
声明:function
|
||
|
||
按指定模式处理数组并返回结果
|
||
|
||
<!-- tags: 示例 数组 -->
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
| -------- | ---------- | -------------------------------- |
|
||
| `src` | array | 待处理数组 |
|
||
| `mode` | integer | 处理模式,取值见下 |
|
||
| `factor` | float | 可选。默认 1.0,结果乘以该系数 |
|
||
| `...` | nil\|array | 可选。需要追加处理的其他数组 |
|
||
|
||
**mode 取值**
|
||
|
||
- `0` — 原样返回
|
||
- `1` — 去重
|
||
|
||
返回:array
|
||
|
||
### 示例
|
||
|
||
范例01:指定处理模式和系数
|
||
|
||
```tsl
|
||
src := array(1, 1, 2);
|
||
return demoFn(src, 1, 2.0);
|
||
// 输出:array(2,4)
|
||
```
|
||
|
||
范例02:使用默认系数
|
||
|
||
```tsl
|
||
src := array(1, 1, 2);
|
||
return demoFn(src, 0);
|
||
```
|
||
|
||
## `demoNow()`
|
||
|
||
声明:function
|
||
|
||
返回示例值
|
||
|
||
返回:integer
|
||
````
|
||
|
||
### class
|
||
|
||
#### 页面结构
|
||
|
||
顶级 class 使用 H2,class 成员使用 H3,function 的参数取值或示例使用 H4。H2 正文
|
||
按以下顺序书写:
|
||
|
||
1. `## \`ClassName\``
|
||
2. `声明:class`
|
||
3. class 描述,必填
|
||
4. tags,可选;位于完整描述之后
|
||
5. `父类:BaseClass`,可选;多父类按声明顺序列出
|
||
6. class 成员,按声明顺序书写
|
||
|
||
#### 成员标题与正文
|
||
|
||
class 成员标题统一只写反引号包围的名称或调用签名,例如
|
||
`### \`Create(name)\``、`### \`Title\``。成员的声明种类由标题后的声明行表达:
|
||
|
||
- 实例方法:`声明:function`
|
||
- 类方法:`声明:class function`
|
||
- property:`声明:property`
|
||
- 实例/静态字段:`声明:field` / `声明:static field`
|
||
- 实例/静态常量:`声明:const` / `声明:static const`
|
||
|
||
每个成员都按“标题、声明行、描述、tags、成员数据”的共同顺序开始。function 的
|
||
正文结构与顶级 function 相同,实例 function 和 class function 都按描述、tags、
|
||
参数表、参数取值、返回类型、示例的顺序书写。源码声明了返回类型时必须写
|
||
`返回:类型`;没有返回类型时省略,不补写 `void`。位于 class 中时,
|
||
标题及其子标题整体下移一级:function 标题从 H2 变为 H3,参数取值和示例标题从 H3
|
||
变为 H4。成员另外必须写 `可见性:public|protected`,并可写 `修饰符`;类方法由
|
||
`声明:class function` 表达。
|
||
|
||
property 必须写访问方式;有类型时写 `类型:...`,没有类型时省略。field 必须写
|
||
类型,const 必须写值。
|
||
|
||
#### 完整页面示例
|
||
|
||
以下示例以 `OpenXmlAttribute` 的公开成员为基础,并加入一个 class function,用于
|
||
说明 class 的 markdown 存储格式:
|
||
|
||
```markdown
|
||
# OfficeXml / OpenXml
|
||
|
||
## `OpenXmlAttribute`
|
||
|
||
声明:class
|
||
|
||
表示一个 OpenXml 属性
|
||
|
||
<!-- tags: OpenXml XML 属性 -->
|
||
|
||
### `create(_prefix, _local_name)`
|
||
|
||
声明:function
|
||
|
||
创建不带初始值的 OpenXml 属性
|
||
|
||
<!-- tags: OpenXml 属性 创建 -->
|
||
|
||
可见性:`public`
|
||
|
||
修饰符:`overload`
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
| ------------- | ------ | ------------ |
|
||
| `_prefix` | string | 命名空间前缀 |
|
||
| `_local_name` | string | 本地名称 |
|
||
|
||
### `create(_prefix, _local_name, _value)`
|
||
|
||
声明:function
|
||
|
||
创建带初始值的 OpenXml 属性
|
||
|
||
<!-- tags: OpenXml 属性 创建 -->
|
||
|
||
可见性:`public`
|
||
|
||
修饰符:`overload`
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
| ------------- | ------ | ------------ |
|
||
| `_prefix` | string | 命名空间前缀 |
|
||
| `_local_name` | string | 本地名称 |
|
||
| `_value` | any | 属性值 |
|
||
|
||
### `CreateVirtual(position, row_index, _story)`
|
||
|
||
声明:class function
|
||
|
||
创建虚段落
|
||
|
||
可见性:`public`
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
| ----------- | --------- | -------- |
|
||
| `position` | integer | 段落位置 |
|
||
| `row_index` | integer | 行索引 |
|
||
| `_story` | StoryNode | 故事节点 |
|
||
|
||
返回:ParagraphSegment
|
||
|
||
### `Prefix`
|
||
|
||
声明:property
|
||
|
||
命名空间前缀
|
||
|
||
可见性:`public`
|
||
|
||
类型:string
|
||
|
||
访问:read / write
|
||
|
||
### `LocalName`
|
||
|
||
声明:property
|
||
|
||
本地名称
|
||
|
||
可见性:`public`
|
||
|
||
类型:string
|
||
|
||
访问:read / write
|
||
|
||
### `ElementName`
|
||
|
||
声明:property
|
||
|
||
包含前缀的完整属性名称
|
||
|
||
可见性:`public`
|
||
|
||
类型:string
|
||
|
||
访问:read / write
|
||
|
||
### `Value`
|
||
|
||
声明:property
|
||
|
||
属性值
|
||
|
||
可见性:`public`
|
||
|
||
类型:any
|
||
|
||
访问:read / write
|
||
|
||
### `NamespaceUri`
|
||
|
||
声明:property
|
||
|
||
命名空间 URI
|
||
|
||
可见性:`public`
|
||
|
||
类型:string
|
||
|
||
访问:read / write
|
||
```
|
||
|
||
### unit
|
||
|
||
#### 页面结构
|
||
|
||
顶级 unit 使用 H2,interface direct member 使用 H3,interface class 的成员或
|
||
unit function 的参数取值/示例使用 H4,interface class function 的参数取值/示例
|
||
使用 H5。H2 正文按以下顺序书写:
|
||
|
||
1. `## \`UnitName\``
|
||
2. `声明:unit`
|
||
3. unit 描述,必填
|
||
4. tags,可选;位于完整描述之后
|
||
5. interface direct member,按声明顺序书写
|
||
|
||
#### 成员标题与正文
|
||
|
||
H3 direct member 标题只写名称或调用签名。标题后的声明行只允许:
|
||
|
||
- interface function:`声明:function`
|
||
- variable:`声明:var`
|
||
- constant:`声明:const`
|
||
- interface class:`声明:class`
|
||
|
||
每个 direct member 都按“标题、声明行、描述、tags、成员数据”的共同顺序开始。
|
||
unit direct member 都来自 interface,visibility 固定为 `public`,正文不重复记录。
|
||
unit function 复用顶级 function 格式并要求返回
|
||
类型,var 必须写类型,const 必须写值。interface class 的 H4 成员复用顶级
|
||
class 的成员格式,并显式写 `可见性:public|protected`。
|
||
|
||
#### 完整页面示例
|
||
|
||
```markdown
|
||
# 示例 / 文档运行时
|
||
|
||
## `DocumentUnit`
|
||
|
||
声明:unit
|
||
|
||
提供文档运行时接口
|
||
|
||
<!-- tags: 运行时 文档 -->
|
||
|
||
### `DefaultSize`
|
||
|
||
声明:const
|
||
|
||
默认缓冲区大小
|
||
|
||
值:`100`
|
||
|
||
### `CurrentDocument`
|
||
|
||
声明:var
|
||
|
||
当前文档
|
||
|
||
类型:Document
|
||
|
||
### `OpenDocument(path)`
|
||
|
||
声明:function
|
||
|
||
打开文档
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
| ------ | ------ | -------- |
|
||
| `path` | string | 文档路径 |
|
||
|
||
返回:Document
|
||
|
||
### `Document`
|
||
|
||
声明:class
|
||
|
||
文档对象
|
||
|
||
父类:`BaseDocument`
|
||
|
||
#### `Save()`
|
||
|
||
声明:function
|
||
|
||
保存文档
|
||
|
||
可见性:`public`
|
||
|
||
返回:boolean
|
||
```
|
||
|
||
### 综合示例
|
||
|
||
同一叶子页可以按文档顺序混合三种顶级声明。以下 API 仅用于说明存储格式,不代表
|
||
真实 TSL API:
|
||
|
||
````markdown
|
||
# OfficeXml / OpenXml
|
||
|
||
## `OpenXmlAttribute`
|
||
|
||
声明:class
|
||
|
||
表示 OpenXml 属性
|
||
|
||
<!-- tags: OpenXml XML 属性 -->
|
||
|
||
### `create(_prefix, _local_name)`
|
||
|
||
声明:function
|
||
|
||
创建属性
|
||
|
||
<!-- tags: OpenXml 属性 创建 -->
|
||
|
||
可见性:`public`
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
| ------------- | ------ | ------------ |
|
||
| `_prefix` | string | 命名空间前缀 |
|
||
| `_local_name` | string | 本地名称 |
|
||
|
||
## `ParseOpenXml(xml)`
|
||
|
||
声明:function
|
||
|
||
解析 OpenXml 文本
|
||
|
||
<!-- tags: OpenXml XML 解析 -->
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
| ----- | ------ | ------------ |
|
||
| `xml` | string | OpenXml 文本 |
|
||
|
||
返回:OpenXmlElement
|
||
|
||
### 示例
|
||
|
||
范例01:解析文本
|
||
|
||
```tsl
|
||
return ParseOpenXml('<root/>');
|
||
```
|
||
|
||
## `OpenXmlRuntime`
|
||
|
||
声明:unit
|
||
|
||
提供 OpenXml 运行时接口
|
||
|
||
<!-- tags: OpenXml 运行时 -->
|
||
|
||
### `OpenXmlElement`
|
||
|
||
声明:class
|
||
|
||
表示文档元素
|
||
|
||
<!-- tags: OpenXml XML 元素 -->
|
||
|
||
#### `Save()`
|
||
|
||
声明:function
|
||
|
||
保存元素
|
||
|
||
可见性:`public`
|
||
|
||
返回:boolean
|
||
````
|
||
|
||
## tsf 源码文档格式
|
||
|
||
tsf 主要使用 `function`、`unit` 和 `type` 三种顶层组织方式。本标准按这三种方式
|
||
分别定义源码文档格式。每个 tsf 源码文档对应一个对外顶级声明。
|
||
|
||
### function
|
||
|
||
独立顶层 `function` 可以在源码中记录函数级文档。签名、参数类型、默认参数和返回
|
||
类型由源码声明提供,描述、标签、参数说明、枚举值和示例由文档块提供。
|
||
|
||
- 一个 function tsf 文件只以第一个顶层 function 作为对外主函数;后续辅助函数不属于
|
||
该文件的对外文档
|
||
- 顶层 `procedure` 不在本节规定的 function 文档格式范围内
|
||
- `module` 和 `path` 是页面级录入字段,不属于单个函数的文档块
|
||
|
||
#### 文档块位置
|
||
|
||
文档块必须是主函数 `begin` 之后的第一段非空内容,并且位于任何可执行语句、
|
||
编译指令或其他注释之前
|
||
|
||
文档块由连续的 `///` 行组成,并允许按照函数体缩进。`///` 之前的空白以及其后的
|
||
一个可选空格不属于文档内容。遇到第一行非 `///` 内容时,文档块结束;函数体后续
|
||
位置的注释是普通注释
|
||
|
||
TSL 解释器将 `///` 作为普通的 `//` 行注释;本标准使用第三个 `/` 区分文档行与普通
|
||
注释
|
||
|
||
#### 文档块结构
|
||
|
||
文档块按以下顺序书写:
|
||
|
||
1. 函数描述,一行或多行,必填
|
||
2. `@tags: 标签1 标签2`,可选,最多一行,标签使用空白分隔
|
||
3. 参数组,按声明顺序书写;每组先写 `@param: name 参数说明`,再按需紧跟一个
|
||
`@values: name`
|
||
4. `@returns: 类型`,可选,最多一行
|
||
5. 示例组,可选,可以重复;所有示例组必须位于文档块末尾
|
||
|
||
空的 `///` 行可以在多行函数描述或示例中保留空行。指令名固定为小写;未知指令、
|
||
重复的 `@tags:`/`@returns:`、同一参数重复的 `@param:`/`@values:`,以及不符合上述
|
||
顺序的指令均不符合本标准。`@example:` 可以重复,`@output:` 在同一示例组内最多出现
|
||
一次。
|
||
|
||
| 写法 | 必填 | json 映射 | 规则 |
|
||
| ----------------------- | -------- | ---------------------------------- | -------------------------------------------------------------- |
|
||
| 描述正文 | 是 | `declarations[].desc` | 第一条指令之前的所有正文,保留换行 |
|
||
| `@tags: 标签1 标签2` | 否 | `declarations[].tags` | 使用一个或多个空白字符分隔;忽略首尾空白;标签本身不得包含空白 |
|
||
| `@param: name 参数说明` | 有参时 | `declarations[].params[].desc` | 第一个词是参数名,其余内容是说明;说明不得为空 |
|
||
| `@values: name` | 否 | `declarations[].params[].values` | 值表规则见下;参数必须已经由 `@param:` 声明 |
|
||
| `@returns: 类型` | 否 | `declarations[].returns` | 类型不得为空;与声明返回类型同时存在时必须一致 |
|
||
| `@example: 示例说明` | 否 | `declarations[].examples[].desc` | 开始一个示例组;说明不得为空 |
|
||
| 示例代码 | 示例组内 | `declarations[].examples[].code` | 内容行额外缩进两个空格;至少包含一个非空代码行 |
|
||
| `@output:` | 否 | `declarations[].examples[].output` | 原始输出额外缩进两个空格;存在时不得为空 |
|
||
|
||
`@param:` 和 `@values:` 中的参数名与函数声明大小写无关地匹配;映射后的参数名保留
|
||
函数声明中的拼写。
|
||
|
||
#### 字段来源与映射
|
||
|
||
以下字段由主函数声明以及必要的文档指令确定:
|
||
|
||
| tsf 声明内容 | json 字段 | 映射规则 |
|
||
| -------------- | ---------------------------------- | ------------------------------------------------- |
|
||
| 函数名 | `declarations[].name` | 保留声明名称 |
|
||
| 函数名和参数名 | `declarations[].signature` | 规范化为只含名称的调用形式,不复制类型或默认值 |
|
||
| 参数类型 | `declarations[].params[].type` | 保留声明中的类型 |
|
||
| 参数默认值 | `declarations[].params[].optional` | 存在默认值时为 `true`,默认表达式不另建 json 字段 |
|
||
| 返回类型 | `declarations[].returns` | 取自声明和 `@returns:`,按下述规则合并 |
|
||
|
||
完整录入数据必须包含每个参数的显式类型和非空说明,并通过函数声明或 `@returns:`
|
||
提供返回类型。
|
||
可选参数的说明仍应写清默认值含义;`optional: true` 只表达该参数可以省略。
|
||
|
||
返回类型按以下规则合并:
|
||
|
||
- 只有函数声明时,使用声明中的拼写
|
||
- 只有 `@returns:` 时,去除首尾空白后使用指令中的拼写
|
||
- 两处同时存在时,使用相同的词法规则拆分类型,忽略 token 之间的空白,并按 TSL
|
||
标识符大小写无关的规则比较标识符 token;其他 token 必须一致。两处类型必须匹配,
|
||
映射后使用声明中的拼写
|
||
- 两处都不存在时,不满足顶级 function 的 `returns` 必填要求
|
||
|
||
本标准只定义类型的词法一致性,不定义类型别名等语义等价关系。
|
||
|
||
#### 枚举值表
|
||
|
||
枚举值表使用分组格式,每一项在 `///` 标记后额外缩进两个空格:
|
||
|
||
```text
|
||
/// @param: mode 处理模式,默认 0
|
||
/// @values: mode
|
||
/// 0: 原样返回
|
||
/// 1: 去重
|
||
/// "auto": 自动判断
|
||
```
|
||
|
||
规则:
|
||
|
||
- 枚举值使用 json 标量写法:数字直接写,字符串使用双引号,布尔值使用
|
||
`true`/`false`;`nil` 等符号值按字符串写成 `"nil"`
|
||
- 不接受数组、对象或 json `null`
|
||
- 值和说明以值后的第一个分隔冒号分开;说明不得为空
|
||
- 保留枚举项的声明顺序
|
||
- 同一参数最多有一个非空值表,不允许重复值;不同 json 类型的值不视为重复,
|
||
例如数字 `1` 与字符串 `"1"` 是两个值
|
||
- `@values:` 引用的参数必须存在
|
||
- tsf 作者必须保证枚举值与参数类型在语义上兼容
|
||
|
||
#### 示例组
|
||
|
||
每个示例组以非空的 `@example: 示例说明` 开始。其后的代码行必须在 `///` 标记后
|
||
额外缩进两个空格。可选的 `@output:` 结束代码部分,其后的缩进行记录原始输出;下一个
|
||
`@example:` 开始新的示例组。第一个示例组出现后,不得再写参数、返回类型等其他函数
|
||
级指令。
|
||
|
||
映射到录入数据时,移除代码和输出的两个结构缩进,保留其余空白和换行。示例说明、
|
||
代码和输出分别映射为 `examples[].desc`、`examples[].code` 和 `examples[].output`。`desc` 与
|
||
`code` 必填且非空;`output` 可选,但出现时必须包含至少一个非空行。示例顺序保持
|
||
不变。
|
||
|
||
`code` 只记录示例源码,不得包含标准输出标记 `// 输出:`。`output` 只记录原始输出,
|
||
不写 `//` 注释标记。映射到 markdown 时:
|
||
|
||
- 所有示例共用一个 `### 示例` 标题
|
||
- 每项按顺序写为“范例01:说明”“范例02:说明”
|
||
- 每项使用一个独立的 `tsl` 代码块
|
||
- 没有 `output` 时,代码块只包含 `code`
|
||
- 单行 `output` 在代码末尾写为 `// 输出:<值>`
|
||
- 多行 `output` 先写 `// 输出:`,再为每个输出行添加 `//` 和一个空格;空输出行使用
|
||
单独的 `//`
|
||
|
||
#### 完整 tsf 示例
|
||
|
||
以下内容应保存为 `Normalize.tsf`:
|
||
|
||
```tsl
|
||
function Normalize(mode: integer = 0): integer;
|
||
begin
|
||
/// 按指定模式处理并返回模式值
|
||
/// @tags: 示例 枚举
|
||
/// @param: mode 处理模式,默认 0
|
||
/// @values: mode
|
||
/// 0: 原样返回
|
||
/// 1: 去重
|
||
/// 2: 排序
|
||
/// @returns: integer
|
||
/// @example: 使用默认模式
|
||
/// return Normalize();
|
||
/// @output:
|
||
/// 0
|
||
/// @example: 指定模式
|
||
/// return Normalize(1);
|
||
return mode;
|
||
end;
|
||
```
|
||
|
||
对应的顶级 function 录入对象为:
|
||
|
||
```json
|
||
{
|
||
"kind": "function",
|
||
"name": "Normalize",
|
||
"signature": "Normalize(mode)",
|
||
"desc": "按指定模式处理并返回模式值",
|
||
"tags": ["示例", "枚举"],
|
||
"params": [
|
||
{
|
||
"name": "mode",
|
||
"type": "integer",
|
||
"optional": true,
|
||
"desc": "处理模式,默认 0",
|
||
"values": [
|
||
{"value": 0, "desc": "原样返回"},
|
||
{"value": 1, "desc": "去重"},
|
||
{"value": 2, "desc": "排序"}
|
||
]
|
||
}
|
||
],
|
||
"returns": "integer",
|
||
"examples": [
|
||
{
|
||
"desc": "使用默认模式",
|
||
"code": "return Normalize();",
|
||
"output": "0"
|
||
},
|
||
{
|
||
"desc": "指定模式",
|
||
"code": "return Normalize(1);"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### class
|
||
|
||
`Counter.tsf`
|
||
|
||
```tsl
|
||
type Counter = class
|
||
/// 表示计数器
|
||
/// @tags: 示例 计数
|
||
public
|
||
/// 创建计数器
|
||
/// @param: initial_value 初始值
|
||
function create(initial_value: integer);
|
||
|
||
/// 计算两个整数之和
|
||
/// @tags: 示例 加法
|
||
/// @param: x 第一个整数
|
||
/// @param: y 第二个整数
|
||
/// @returns: integer
|
||
class function Add(x: integer; y: integer): integer;
|
||
begin
|
||
return x + y;
|
||
end;
|
||
|
||
/// 增加当前值
|
||
/// @param: step 增量
|
||
/// @returns: integer
|
||
/// @example: 增加计数
|
||
/// counter := new Counter(1);
|
||
/// return counter.Increase(2);
|
||
/// @output:
|
||
/// 3
|
||
function Increase(step: integer): integer;
|
||
|
||
/// 当前值
|
||
/// @tags: 状态
|
||
property Value read value_ write value_;
|
||
|
||
/// 显示名称
|
||
Label: string;
|
||
|
||
/// 最小值
|
||
const Minimum = 0;
|
||
|
||
protected
|
||
/// 已创建的计数器数量
|
||
static CreatedCount: integer;
|
||
|
||
/// 最大值
|
||
static const Maximum = 100;
|
||
|
||
private
|
||
/// 内部值
|
||
value_: integer;
|
||
end;
|
||
|
||
type CounterState = class
|
||
/// 表示内部状态
|
||
public
|
||
/// 状态码
|
||
Code: integer;
|
||
end;
|
||
|
||
function Counter.create(initial_value: integer);
|
||
begin
|
||
value_ := initial_value;
|
||
end;
|
||
|
||
function Counter.Increase(step: integer): integer;
|
||
begin
|
||
value_ := value_ + step;
|
||
return value_;
|
||
end;
|
||
```
|
||
|
||
对应的 class 录入对象为:
|
||
|
||
```json
|
||
{
|
||
"kind": "class",
|
||
"name": "Counter",
|
||
"desc": "表示计数器",
|
||
"tags": ["示例", "计数"],
|
||
"members": [
|
||
{
|
||
"kind": "method",
|
||
"name": "create",
|
||
"visibility": "public",
|
||
"binding": "instance",
|
||
"signature": "create(initial_value)",
|
||
"desc": "创建计数器",
|
||
"params": [
|
||
{
|
||
"name": "initial_value",
|
||
"type": "integer",
|
||
"desc": "初始值"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"kind": "method",
|
||
"name": "Add",
|
||
"visibility": "public",
|
||
"binding": "class",
|
||
"signature": "Add(x, y)",
|
||
"desc": "计算两个整数之和",
|
||
"tags": ["示例", "加法"],
|
||
"params": [
|
||
{
|
||
"name": "x",
|
||
"type": "integer",
|
||
"desc": "第一个整数"
|
||
},
|
||
{
|
||
"name": "y",
|
||
"type": "integer",
|
||
"desc": "第二个整数"
|
||
}
|
||
],
|
||
"returns": "integer"
|
||
},
|
||
{
|
||
"kind": "method",
|
||
"name": "Increase",
|
||
"visibility": "public",
|
||
"binding": "instance",
|
||
"signature": "Increase(step)",
|
||
"desc": "增加当前值",
|
||
"params": [
|
||
{
|
||
"name": "step",
|
||
"type": "integer",
|
||
"desc": "增量"
|
||
}
|
||
],
|
||
"returns": "integer",
|
||
"examples": [
|
||
{
|
||
"desc": "增加计数",
|
||
"code": "counter := new Counter(1);\nreturn counter.Increase(2);",
|
||
"output": "3"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"kind": "property",
|
||
"name": "Value",
|
||
"visibility": "public",
|
||
"desc": "当前值",
|
||
"tags": ["状态"],
|
||
"access": "readwrite"
|
||
},
|
||
{
|
||
"kind": "field",
|
||
"name": "Label",
|
||
"visibility": "public",
|
||
"desc": "显示名称",
|
||
"type": "string"
|
||
},
|
||
{
|
||
"kind": "constant",
|
||
"name": "Minimum",
|
||
"visibility": "public",
|
||
"desc": "最小值",
|
||
"value": "0"
|
||
},
|
||
{
|
||
"kind": "field",
|
||
"name": "CreatedCount",
|
||
"visibility": "protected",
|
||
"desc": "已创建的计数器数量",
|
||
"type": "integer",
|
||
"static": true
|
||
},
|
||
{
|
||
"kind": "constant",
|
||
"name": "Maximum",
|
||
"visibility": "protected",
|
||
"desc": "最大值",
|
||
"value": "100",
|
||
"static": true
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### unit
|
||
|
||
本标准的 unit 源码文档采用包含显式 `interface`、`implementation` 并以 `end.` 结束的
|
||
完整形态;简写 unit 不在本标准范围内。unit 名称必须与文件名大小写无关地一致。
|
||
|
||
unit 文档块位于 `unit Name;` 之后、`interface` 之前,只允许描述和可选
|
||
`@tags:`。对外文档按声明顺序包含 interface 中的 function、var、const 和 class;
|
||
`uses` 只表示依赖,不属于 API。interface class 完整复用独立 class 的成员规则,
|
||
interface 中的所有 class 均属于对外文档。每个 `///` 文档块必须绑定到 unit 或
|
||
interface 成员。
|
||
|
||
implementation 中的函数、类、变量、常量和 `///` 文档块不属于对外文档。interface
|
||
中的 procedure 和非 class type 不在本标准范围内。interface function 复用 function
|
||
文档指令并要求返回类型;var/const 只允许描述和可选 `@tags:`,且一项一条声明。
|
||
|
||
## 录入数据结构
|
||
|
||
一个录入文件对应一个 markdown 叶子页。录入根只允许 `module`、`path`、
|
||
`declarations`。`declarations` 必须是非空有序列表,function、class、unit 可以
|
||
任意混合;数组顺序即 markdown 中的 H2 声明顺序。
|
||
|
||
顶层字段:
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
| -------------- | ---- | -------------------------------------------------------------------------------------------------------------------- |
|
||
| `module` | 是 | markdown 一级标题内容;不是目录名或文件名。例如 `module: 示例 / 数组` 对应 `# 示例 / 数组` |
|
||
| `path` | 是 | markdown 在所属 scope 下的相对路径,使用 `/` 分隔且不含 `.md` 后缀。例如 `path: base/example` 对应 `base/example.md` |
|
||
| `declarations` | 是 | 非空顶级声明列表;每项由 `kind` 判别并要求 `name`,数组顺序即 H2 顺序 |
|
||
|
||
### function
|
||
|
||
顶级 function 对象字段:
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
| ----------- | ------ | ------------------------------------------------------ |
|
||
| `kind` | 是 | 固定为 `function` |
|
||
| `name` | 是 | function 简单名称;必须与 `signature` 中的名称一致 |
|
||
| `signature` | 是 | 只包含名称和参数名的调用签名 |
|
||
| `desc` | 是 | 函数描述,可包含多行 |
|
||
| `tags` | 否 | 检索关键词列表;推荐填写,有助于更准确地识别和检索函数 |
|
||
| `params` | 有参时 | 参数列表;无参函数省略 |
|
||
| `returns` | 是 | 返回类型 |
|
||
| `examples` | 否 | 示例列表;按顺序映射为独立的 TSL 代码块 |
|
||
|
||
参数字段:
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
| ---------- | ---- | ------------------------------------------------------ |
|
||
| `name` | 是 | 参数名,与签名一致 |
|
||
| `type` | 是 | 参数类型 |
|
||
| `desc` | 是 | 参数说明 |
|
||
| `optional` | 否 | `true` 表示可选参数;markdown 参数说明以 `可选。` 开头 |
|
||
| `values` | 否 | 枚举值列表,对应参数取值说明 |
|
||
|
||
`values` 每项包含:
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
| ------- | ---- | -------- |
|
||
| `value` | 是 | 枚举值 |
|
||
| `desc` | 是 | 枚举含义 |
|
||
|
||
`examples` 每项包含:
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
| -------- | ---- | ---------------------------------------------- |
|
||
| `desc` | 是 | 示例场景说明;对应“范例NN:说明” |
|
||
| `code` | 是 | 不含代码围栏和标准输出注释的 TSL 代码 |
|
||
| `output` | 否 | 原始输出;按单行或多行规则映射为 `//` 输出注释 |
|
||
|
||
### class
|
||
|
||
class 对象字段:
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
| --------- | ---- | ----------------------------------------- |
|
||
| `kind` | 是 | 固定为 `class` |
|
||
| `name` | 是 | class 简单名称 |
|
||
| `desc` | 是 | class 描述 |
|
||
| `tags` | 否 | 检索关键词列表 |
|
||
| `bases` | 否 | 按声明顺序保存的直接父类列表 |
|
||
| `members` | 是 | method/property/field/constant 的有序列表 |
|
||
|
||
所有 class member 都要求 `name`、`desc` 和 `visibility`。
|
||
所有 class member 都可以包含可选的 `tags`。visibility 只能是 `public` 或
|
||
`protected`。成员判别字段如下:
|
||
|
||
| kind | 关键字段 |
|
||
| ---------- | --------------------------------------------------------------------------------- |
|
||
| `method` | `signature`、`binding: instance\|class`;可选 `params/returns/modifiers/examples` |
|
||
| `property` | `access: read\|write\|readwrite`;可选 `type`,参数化时包含 `params` |
|
||
| `field` | `type`;可选 `static: true` |
|
||
| `constant` | `value`;可选 `type`、`static: true` |
|
||
|
||
`kind: method` 对象不使用 `static` 字段;class function 由 `binding: class` 唯一
|
||
表达。`value` 的存在性与真假值分开判断,因此数字 `0` 和布尔值 `false` 都是合法
|
||
常量值。
|
||
这里的 `method` 是录入结构内部用于统一表达实例 function 和 class function 的 kind,
|
||
不对应 markdown 标题或 `声明:...` 行中的声明值。
|
||
|
||
### unit
|
||
|
||
顶级 unit 对象包含固定的 `kind: unit`,以及必填的 `name`、`desc`、`members`
|
||
和可选 `tags`。direct member 按 interface 源码顺序保存,kind 只允许:
|
||
|
||
| kind | 关键字段 |
|
||
| ---------- | -------------------------------------------------------- |
|
||
| `function` | 复用顶层 function 数据;`returns` 必填 |
|
||
| `variable` | `name`、`desc`、`type`,可选 `tags` |
|
||
| `constant` | `name`、`desc`、`value`,可选 `tags/type` |
|
||
| `class` | 复用完整 class 数据,并以 `kind: class` 作为成员判别字段 |
|
||
|
||
录入数据不保存 unit 的 `uses`、implementation、initialization 或 finalization。
|
||
|
||
## 录入文件格式
|
||
|
||
### yaml
|
||
|
||
yaml 录入文件应符合以下规则:
|
||
|
||
- `examples[].code` 和多行 `examples[].output` 使用 `|` 块标量
|
||
- 参数名 `...` 必须加引号
|
||
- `nil|array` 可直接作为普通字符串值
|
||
|
||
完整例子:[examples/example.yaml](examples/example.yaml)
|
||
|
||
### json
|
||
|
||
json 录入文件应符合以下规则:
|
||
|
||
- json 不支持注释
|
||
- 多行 `examples[].code` 和 `examples[].output` 使用 `\n`
|
||
- 字符串内部的双引号使用 `\"`
|
||
- 结构标点必须使用半角字符
|
||
|
||
完整例子:[examples/example.json](examples/example.json)
|
||
|
||
## 统一 API 索引
|
||
|
||
`function_index.tsv` 固定为 13 列:
|
||
|
||
```text
|
||
name scope module signature page anchor tags summary kind binding visibility owner qualified_name
|
||
```
|
||
|
||
字段含义:
|
||
|
||
- `kind`:`function|class|method|property|field|constant|unit|variable`
|
||
- `binding`:不适用时为空,否则为 `instance|class|static|unit`
|
||
- `visibility`:class member 为 `public|protected`,unit direct member 为 `public`
|
||
- `owner`:不含该 API 名称的完整所属路径
|
||
- `qualified_name`:点分隔的稳定文档身份
|
||
|
||
索引的 `kind` 和 `binding` 由声明行和所属层级按下表确定:
|
||
|
||
| markdown 位置 | `声明:...` | 录入对象表达 | 索引 `kind` | 索引 `binding` |
|
||
| ---------------------------- | ---------------- | --------------------------------- | ----------- | -------------- |
|
||
| H2 顶级声明 | `function` | `kind: function` | `function` | 空 |
|
||
| H2 顶级声明 | `class` | `kind: class` | `class` | 空 |
|
||
| H2 顶级声明 | `unit` | `kind: unit` | `unit` | 空 |
|
||
| 顶级/interface class 成员 | `function` | `kind: method, binding: instance` | `method` | `instance` |
|
||
| 顶级/interface class 成员 | `class function` | `kind: method, binding: class` | `method` | `class` |
|
||
| 顶级/interface class 成员 | `property` | `kind: property` | `property` | `instance` |
|
||
| 顶级/interface class 成员 | `field` | `kind: field` | `field` | `instance` |
|
||
| 顶级/interface class 成员 | `static field` | `kind: field, static: true` | `field` | `static` |
|
||
| 顶级/interface class 成员 | `const` | `kind: constant` | `constant` | `instance` |
|
||
| 顶级/interface class 成员 | `static const` | `kind: constant, static: true` | `constant` | `static` |
|
||
| unit interface direct member | `function` | `kind: function` | `function` | `unit` |
|
||
| unit interface direct member | `var` | `kind: variable` | `variable` | `unit` |
|
||
| unit interface direct member | `const` | `kind: constant` | `constant` | `unit` |
|
||
| unit interface direct member | `class` | `kind: class` | `class` | `unit` |
|
||
|
||
表中的 interface class 成员指 unit interface class 的 H4 成员;其允许的声明值和
|
||
派生规则与顶级 class 的 H3 成员完全相同。
|
||
|
||
例如 class function `Widget.Create` 的 owner 是 `Widget`;unit interface class
|
||
function `DemoUnit.Document.Save` 的 owner 是 `DemoUnit.Document`。重载共享
|
||
`qualified_name`,由 `signature` 和唯一的 `page#anchor` 区分。
|