196 lines
8.6 KiB
TypeScript
196 lines
8.6 KiB
TypeScript
import type { Node } from '@vscode/tree-sitter-wasm'
|
||
import type { Disposable } from 'vscode'
|
||
|
||
export type { Node }
|
||
|
||
export type BlockKind
|
||
= | 'import' | 'function' | 'class' | 'type' | 'field' | 'const' | 'variable'
|
||
| 'if' | 'else' | 'loop' | 'try' | 'catch' | 'finally' | 'return' | 'statement' | 'comment'
|
||
|
||
/** 源码里一段的下标:源码字符串下标(web-tree-sitter 的 startIndex / endIndex),end 为开区间。 */
|
||
export interface SourceRange { startIndex: number, endIndex: number }
|
||
|
||
/** 源码里的一段,带起止行号(从 0 开始)。 */
|
||
export interface SourceSpan extends SourceRange { startRow: number, endRow: number }
|
||
|
||
/** 访问级别。 */
|
||
export type Access = 'public' | 'private' | 'protected'
|
||
|
||
/** 函数的一个参数;节点都指向源码。 */
|
||
export interface ParameterFacts {
|
||
/** 参数名;解构参数是整个模式,`...rest`、`*args`、`**kwargs` 带着前缀。 */
|
||
name: Node
|
||
/** TypeScript 的可省略参数 `x?`。 */
|
||
optional: boolean
|
||
type?: Node
|
||
default?: Node
|
||
}
|
||
|
||
export interface FunctionFacts {
|
||
/** 匿名函数(`export default function () {}`)没有。 */
|
||
name?: Node
|
||
/**
|
||
* 函数自己的说明:TypeScript 是紧贴在声明前面的 JSDoc 注释(以 `/**` 开头),Python 是主体开头的 docstring(字符串节点)。
|
||
* 它算在块的头部里,不再单独成一块注释。
|
||
*/
|
||
doc?: Node
|
||
/** 嵌套在函数体、条件等语句块里的函数没有。 */
|
||
access?: Access
|
||
async: boolean
|
||
decorators: Node[]
|
||
parameters: ParameterFacts[]
|
||
returnType?: Node
|
||
}
|
||
|
||
/**
|
||
* 父类的一项:TypeScript `extends Base<T>` 里的 Base(一个表达式)和跟在它后面的泛型实参 `<T>`(语法里是两个节点);
|
||
* Python 类参数列表里的一项,`metaclass=ABCMeta` 这类关键字参数、`*bases` 也算。
|
||
*/
|
||
export interface BaseFacts {
|
||
value: Node
|
||
typeArguments?: Node
|
||
}
|
||
|
||
export interface ClassFacts {
|
||
/** 匿名类(`export default class {}`)没有;赋给变量、类字段的类表达式取变量名、字段名。 */
|
||
name?: Node
|
||
/** 类自己的说明,同 FunctionFacts.doc:TypeScript 是紧贴在前面的 JSDoc,Python 是主体开头的 docstring。 */
|
||
doc?: Node
|
||
/** 同函数:嵌套在函数体、条件等语句块里的类没有。 */
|
||
access?: Access
|
||
/** 抽象类(TypeScript 的 `abstract class`);没有这个概念的语言不填。 */
|
||
abstract?: boolean
|
||
decorators: Node[]
|
||
/** 泛型参数,每个参数一项(TypeScript `<T extends X = Y>` 里的 `T extends X = Y`)。 */
|
||
typeParameters: Node[]
|
||
/** 按源码顺序。 */
|
||
bases: BaseFacts[]
|
||
/** 实现的接口(TypeScript 的 `implements A, B<T>`),每个接口一项。 */
|
||
implements: Node[]
|
||
}
|
||
|
||
/** 导入的一项。 */
|
||
export type ImportItem
|
||
= | { kind: 'named', name: Node, alias?: Node } // import { a as b }、from m import a as b
|
||
| { kind: 'default', alias: Node } // import x from 'm'
|
||
| { kind: 'namespace', alias?: Node } // import * as x、from m import *
|
||
| { kind: 'module', module: Node, alias?: Node } // import a.b as c、import x = require('m')
|
||
|
||
export interface ImportFacts {
|
||
/** 来源模块,节点就是源码里的写法:TypeScript 是字符串字面量,Python 是点分模块名;Python 的 `import a, b` 有多个。 */
|
||
sources: Node[]
|
||
/** 只导入类型(TypeScript 的 `import type`);没有这个概念的语言不填。 */
|
||
typeOnly?: boolean
|
||
/** 副作用导入(`import './x'`)没有。 */
|
||
items: ImportItem[]
|
||
}
|
||
|
||
export interface DeclaratorFacts {
|
||
/** 变量名;解构声明是整个模式。 */
|
||
name: Node
|
||
type?: Node
|
||
value?: Node
|
||
}
|
||
|
||
export interface VariableFacts {
|
||
/** 只有模块顶层(Python 还有类主体)的声明有。 */
|
||
access?: Access
|
||
/** 一条语句声明几个变量(`let a = 1, b = 2`)就有几项。 */
|
||
declarators: DeclaratorFacts[]
|
||
}
|
||
|
||
export interface BlockShape {
|
||
/** 这一块对应的语法树节点(整条语句)。 */
|
||
node: Node
|
||
/**
|
||
* 块自己显示 / 编辑的那一段:复合语句只到主体开始之前,其余是整条语句。
|
||
* 函数、类的说明(facts.doc)也算在里面:JSDoc 往上延到注释开头,docstring 往下延到字符串结尾。
|
||
*/
|
||
header: SourceSpan
|
||
children: CodeBlock[]
|
||
}
|
||
|
||
/** 预览成属性表的块:语言插件从语法树读出结构化信息(facts),翻译插件把它排成属性表。 */
|
||
export interface FunctionBlock extends BlockShape { kind: 'function', facts: FunctionFacts }
|
||
export interface ClassBlock extends BlockShape { kind: 'class', facts: ClassFacts }
|
||
export interface ImportBlock extends BlockShape { kind: 'import', facts: ImportFacts }
|
||
export interface VariableBlock extends BlockShape { kind: 'const' | 'variable', facts: VariableFacts }
|
||
export type FactBlock = FunctionBlock | ClassBlock | ImportBlock | VariableBlock
|
||
|
||
/** 带说明(facts.doc)的块。 */
|
||
export type DocumentedBlock = FunctionBlock | ClassBlock
|
||
|
||
export type TextKind = Exclude<BlockKind, FactBlock['kind']>
|
||
|
||
/** 预览成一行译文的块。 */
|
||
export interface TextBlock extends BlockShape { kind: TextKind }
|
||
|
||
export type CodeBlock = TextBlock | FactBlock
|
||
|
||
/** 着色用的词性,源码着色和译文着色共用。 */
|
||
export type TokenRole
|
||
= | 'keyword' // 流程关键字:import from export if else for return try catch await …
|
||
| 'storage' // 声明关键字与字面量关键字:const function async class interface new true false null …
|
||
| 'operator' // 被翻成文字的运算符:全等 并且 或者 非
|
||
| 'hint' // 属性表里的说明词:未标注 无 N 个 默认导出 …
|
||
| 'variable' | 'function' | 'type' | 'string' | 'number' | 'literal' | 'comment' | 'plain'
|
||
|
||
/**
|
||
* 一段着色的文字。offset:这段照抄自源码里的名字(标识符、属性名、类型名、点分模块名的一节)或字符串时,
|
||
* 它在源码里的起始下标(同 SourceSpan 的下标),预览拿它向 VS Code 查定义、跳过去;译词、提示词没有。
|
||
*/
|
||
export interface Segment { text: string, role: TokenRole, offset?: number }
|
||
|
||
/**
|
||
* 一段 Markdown 说明文字:注释、JSDoc、docstring 去掉注释符号、引号和共同缩进后的原文,不做别的转换
|
||
* (reStructuredText 的 `:func:`、JSDoc 的 `@param` 都照抄)。预览按 Markdown 渲染成注释色的段落、列表、代码块,源码里的 HTML 当文字显示。
|
||
*/
|
||
export interface Markdown { markdown: string }
|
||
|
||
/** 预览里显示的一段文字:着色的词(一行译文、属性值),或整段 Markdown 说明(注释块、函数和类的说明)。 */
|
||
export type PreviewText = Segment[] | Markdown
|
||
|
||
/**
|
||
* 属性表里的一行或一个子行讲的是哪个定义:定义出来的那个名字的节点(取自 facts,例如参数名、导入项的名称和别名、
|
||
* 声明的变量名、类的泛型参数)在源码里的范围。跳到定义时,定义处落在这个范围里就只闪这一行;不填(第三方翻译插件可以不填)就闪整块。
|
||
*/
|
||
export interface Defines { defines?: SourceRange }
|
||
|
||
/** 属性表里展开的一个子行:几列对齐的格子,例如参数的名称 / 类型 / 默认值。 */
|
||
export interface PropertyItem extends Defines { cells: Segment[][] }
|
||
|
||
/** 属性表的一行:左列属性名,右列着色的值或 Markdown 说明;items 是展开在这一行下面的子行(输入参数、导入项)。 */
|
||
export interface PropertyRow extends Defines {
|
||
label: string
|
||
value: PreviewText
|
||
items?: PropertyItem[]
|
||
}
|
||
|
||
/** 语言插件:语法树 → 代码块树。 */
|
||
export interface LanguageAdapter {
|
||
id: string
|
||
/** 覆盖的 VS Code languageId,例如 ['typescript', 'typescriptreact', 'javascript', 'javascriptreact']。 */
|
||
languageIds: string[]
|
||
/** 该 languageId 用的语法包 .wasm 的绝对路径(宿主负责加载,保证和解析器运行时是同一份)。 */
|
||
grammarPath: (languageId: string) => string
|
||
toBlocks: (root: Node, source: string) => CodeBlock[]
|
||
/** 源码着色:给语法树叶子节点定词性。 */
|
||
tokenRole: (leaf: Node) => TokenRole
|
||
}
|
||
|
||
/** 翻译插件:代码块 → 一行译文或属性表。 */
|
||
export interface Translator {
|
||
id: string // 'typescript.zh-template'
|
||
label: string // '中文直译'
|
||
languageIds: string[]
|
||
/** 只翻 header 那一段;注释块给去掉注释符号的 Markdown 原文。 */
|
||
translate: (block: TextBlock, source: string) => PreviewText
|
||
/** 函数、类、导入、常量、变量块 → 属性表。 */
|
||
describe: (block: FactBlock, source: string) => PropertyRow[]
|
||
}
|
||
|
||
export interface CodeReaderApi {
|
||
registerLanguage: (adapter: LanguageAdapter) => Disposable
|
||
registerTranslator: (translator: Translator) => Disposable
|
||
}
|