✨ feat(vscode): 代码阅读类块改成属性表并默认折叠,类的说明进「说明」行

This commit is contained in:
cruldra committed 2026-09-25 14:46:33 +08:00
1 parent 3329aca2e1
commit 43323659e1
22 files changed
+580 -121

No files matched your search

@@ -1,4 +1,4 @@
import type { Access, Defines, FactBlock, FunctionFacts, ImportFacts, ImportItem, Markdown, Node, PreviewText, PropertyRow, Segment, SourceSpan, TextBlock, TokenRole, Translator, VariableBlock } from '../contract'
import type { Access, ClassFacts, Defines, FactBlock, FunctionFacts, ImportFacts, ImportItem, Markdown, Node, PreviewText, PropertyRow, Segment, SourceSpan, TextBlock, TokenRole, Translator, VariableBlock } from '../contract'
import { commonIndent, splitLines } from '../editText'
/** 按所在语法节点区分译法的关键字,例如 Python 的 else:if 后「否则」,for / while 后「未中断时」。 */
@@ -307,6 +307,8 @@ export function createZhTemplateTranslator(table: ZhTable): Translator {
switch (block.kind) {
case 'function':
return functionRows(block.facts, phrases)
case 'class':
return classRows(block.facts, phrases)
case 'import':
return importRows(block.facts, phrases)
default:
@@ -361,9 +363,9 @@ interface Phrases {
verbatim: (node: Node) => Segment[]
/** 导入来源:字符串字面量按字符串着色,模块名按类型着色。 */
module: (node: Node) => Segment[]
/** 源码里的一个名字原样照抄、按 role 着色(函数名称)。 */
/** 源码里的一个名字原样照抄、按 role 着色(函数、类的名称)。 */
name: (node: Node, role: TokenRole) => Segment[]
/** 函数的说明(JSDoc、docstring):去掉注释符号、引号和共同缩进的 Markdown 原文;没有文字时没有。 */
/** 函数、类的说明(JSDoc、docstring):去掉注释符号、引号和共同缩进的 Markdown 原文;没有文字时没有。 */
doc: (node: Node) => Markdown | undefined
}
@@ -414,16 +416,14 @@ function aliased(item: Segment[], alias: Node | undefined, say: Phrases): Segmen
return [...item, { text: ' ', role: 'plain' }, { text: '作为', role: 'keyword' }, { text: ' ', role: 'plain' }, ...say.translated(alias)]
}
/** 函数:名称 / 访问级别 / 异步 / 装饰器 / 输入参数(每个参数一行:名称、类型、默认值)/ 输出参数。 */
/** 函数:名称 / 说明 / 访问级别 / 异步 / 装饰器 / 输入参数(每个参数一行:名称、类型、默认值)/ 输出参数。 */
function functionRows(facts: FunctionFacts, say: Phrases): PropertyRow[] {
const decorators = facts.decorators.map(say.verbatim)
const doc = facts.doc && say.doc(facts.doc)
return [
{ label: '名称', value: facts.name ? say.name(facts.name, 'function') : [hint('匿名')] },
...(doc ? [{ label: '说明', value: doc }] : []),
...docRows(facts.doc, say),
...accessRows(facts.access),
{ label: '异步', value: yesNo(facts.async) },
...(decorators.length > 0 ? [{ label: '装饰器', value: joined(decorators, '\n') }] : []),
...decoratorRows(facts.decorators, say),
{
label: '输入参数',
value: count(facts.parameters.length),
@@ -440,6 +440,36 @@ function functionRows(facts: FunctionFacts, say: Phrases): PropertyRow[] {
]
}
/**
* 类:名称 / 说明 / 访问级别 / 抽象(只有分这个的语言才有)/ 装饰器 / 类型参数 / 父类 / 实现的接口,
* 说明及以后各行有才显示;类型参数、父类、实现的接口各是一行,多项用逗号隔开。类型参数那一行讲的是这几个泛型参数的定义。
*/
function classRows(facts: ClassFacts, say: Phrases): PropertyRow[] {
const listRow = (label: string, parts: Segment[][], defines: Defines = {}): PropertyRow[] =>
parts.length > 0 ? [{ label, value: joined(parts, ', '), ...defines }] : []
return [
{ label: '名称', value: facts.name ? say.name(facts.name, 'type') : [hint('匿名')] },
...docRows(facts.doc, say),
...accessRows(facts.access),
...(facts.abstract === undefined ? [] : [{ label: '抽象', value: yesNo(facts.abstract) }]),
...decoratorRows(facts.decorators, say),
...listRow('类型参数', facts.typeParameters.map(say.translated), defining(...facts.typeParameters)),
...listRow('父类', facts.bases.map(base => base.typeArguments ? [...say.translated(base.value), ...say.translated(base.typeArguments)] : say.translated(base.value))),
...listRow('实现的接口', facts.implements.map(say.translated)),
]
}
/** 函数、类的说明:有文字才有这一行。 */
function docRows(doc: Node | undefined, say: Phrases): PropertyRow[] {
const markdown = doc && say.doc(doc)
return markdown ? [{ label: '说明', value: markdown }] : []
}
/** 装饰器:源码原样照抄,多个换行。 */
function decoratorRows(decorators: Node[], say: Phrases): PropertyRow[] {
return decorators.length > 0 ? [{ label: '装饰器', value: joined(decorators.map(say.verbatim), '\n') }] : []
}
/** 导入:来源 / 仅类型(只有分这个的语言才有)/ 导入项(每项一行,有别名写成「名称 作为 别名」)。 */
function importRows(facts: ImportFacts, say: Phrases): PropertyRow[] {
const itemText = (item: ImportItem): Segment[] => {