✨ feat(vscode): 代码阅读认出代码里起的中文名(Annotated[…, Comment("…")]、@Comment 装饰器、行尾 # @Comment、docstring / JSDoc 的参数说明),预览里定义和用到它的各处都写中文名,悬停看原名,定义处后面淡淡写原名

This commit is contained in:
cruldra committed 2026-09-27 00:56:39 +08:00
1 parent 1b1299dc1f
commit 44c221ea2b
45 files changed
+1685 -128

No files matched your search

@@ -53,7 +53,7 @@ const translator = createZhTemplateTranslator({
function translateFirst(language: LanguageAdapter, source: string): Promise<string> {
return withBlocks(language, 'fake', source, ([block]) => {
const translation = translator.translate(block as TextBlock, { source, language })
const translation = translator.translate(block as TextBlock, { source, language, markers: [] })
return 'markdown' in translation ? translation.markdown : segmentText(translation)
})
}
@@ -19,8 +19,8 @@ function stringContent(node: Node): string {
}
/** `#` 注释去掉井号;docstring 只取引号里的内容。 */
function commentText(node: Node): string {
return node.type === 'comment' ? node.text.replace(/^#+\s?/, '') : stringContent(node)
function commentText(node: Node, text: string): string {
return node.type === 'comment' ? text.replace(/^#+\s?/, '') : stringContent(node)
}
export const pythonZhTranslator: Translator = createZhTemplateTranslator({
@@ -1,8 +1,7 @@
import type { Node, Translator } from '../contract'
import { createZhTemplateTranslator } from './zhTemplate'
function commentText(node: Node): string {
const text = node.text
function commentText(_node: Node, text: string): string {
if (text.startsWith('//'))
return text.replace(/^\/{2,}\s?/, '')
return text
@@ -22,7 +22,7 @@ function translateAll(adapter: LanguageAdapter, languageId: string, translator:
const line = block.header.startRow + 1
if (byLine.has(line) || 'facts' in block)
return
const translation = translator.translate(block, { source, language: adapter })
const translation = translator.translate(block, { source, language: adapter, markers: [] })
byLine.set(line, 'markdown' in translation
? { kind: block.kind, segments: [], markdown: translation.markdown }
: { kind: block.kind, segments: translation })
@@ -38,7 +38,7 @@ function describeAll(adapter: LanguageAdapter, languageId: string, translator: T
walk(blocks, (block) => {
const line = block.header.startRow + 1
if (!byLine.has(line) && 'facts' in block)
byLine.set(line, translator.describe(block, { source, language: adapter }))
byLine.set(line, translator.describe(block, { source, language: adapter, markers: [] }))
})
return byLine
})
@@ -1,4 +1,4 @@
import type { Access, AttributeNames, BaseFacts, BlockKind, ClassFacts, CommonAttribute, Defines, EntryFacts, EnumFacts, FactBlock, FunctionFacts, ImportFacts, ImportItem, Inline, IterationClause, IterationFacts, IterationResult, LanguageAdapter, Markdown, Node, PreviewText, PropertyItem, PropertyRow, Segment, SegmentGroup, SourceDocument, SourceSpan, TextBlock, TokenRole, Translator, VariableBlock } from '../contract'
import type { Access, AttributeNames, BaseFacts, BlockKind, ClassFacts, CommonAttribute, Defines, EntryFacts, EnumFacts, FactBlock, FunctionFacts, ImportFacts, ImportItem, Inline, IterationClause, IterationFacts, IterationResult, LanguageAdapter, Markdown, Node, PreviewText, PropertyItem, PropertyRow, Segment, SegmentGroup, SourceDocument, SourceRange, SourceSpan, TextBlock, TokenRole, Translator, VariableBlock } from '../contract'
import { commonIndent, splitLines } from '../editText'
/** 按所在语法节点区分译法的关键字,例如 Python 的 else:if 后「否则」,for / while 后「未中断时」。 */
@@ -44,8 +44,8 @@ export interface ZhTable {
mapLiterals: Record<string, string>
/** 整段原样照抄、按字符串着色的节点。 */
stringNodes: string[]
/** 注释(或 docstring)节点去掉注释符号后的原文,可以多行。 */
commentText: (node: Node) => string
/** 注释(或 docstring)节点去掉注释符号后的原文,可以多行;text 是节点的源码去掉代码阅读的记号(SourceDocument.markers)以后剩下的。 */
commentText: (node: Node, text: string) => string
/**
* 节点模板:节点类型 → 按中文语序重排的译文。命中的节点只输出模板里的译词和槽位,节点自己的关键字、标点不再输出;
* 槽位里的子节点照常递归翻译。模板引用的子节点缺了,或节点没整个落在要翻的这一段里,就不重排、照常翻。
@@ -95,6 +95,17 @@ function commentsWithin(node: Node, span: SourceSpan): Node[] {
return node.children.flatMap(child => child ? commentsWithin(child, span) : [])
}
/** 节点的源码去掉整个落在它里面的记号(中文名记号 `@Comment 当前用户` 不是说明文字)。 */
function withoutMarkers(node: Node, markers: readonly SourceRange[]): string {
let text = ''
let cursor = node.startIndex
for (const marker of markers.filter(m => m.startIndex >= node.startIndex && m.endIndex <= node.endIndex).sort((a, b) => a.startIndex - b.startIndex)) {
text += node.text.slice(cursor - node.startIndex, marker.startIndex - node.startIndex)
cursor = Math.max(cursor, marker.endIndex)
}
return text + node.text.slice(cursor - node.startIndex)
}
function isComment(token: Token): boolean {
return token.text === '' && !token.group
}
@@ -380,16 +391,21 @@ export function createZhTemplateTranslator(table: ZhTable): Translator {
return segments
}
function translateComment(block: TextBlock): Markdown {
/** 注释节点去掉注释符号和记号后的原文。 */
function commentOf(node: Node, { markers }: SourceDocument): string {
return table.commentText(node, withoutMarkers(node, markers))
}
function translateComment(block: TextBlock, document: SourceDocument): Markdown {
const { startIndex, endIndex } = block.header
const root = block.node.tree.rootNode
const nodes = block.node.type === 'comment' ? commentsWithin(root.descendantForIndex(startIndex, endIndex) ?? root, block.header) : [block.node]
return { markdown: docText(nodes.map(table.commentText)) }
return { markdown: docText(nodes.map(node => commentOf(node, document))) }
}
function translate(block: TextBlock, document: SourceDocument): PreviewText {
if (block.kind === 'comment')
return translateComment(block)
return translateComment(block, document)
const tokens = tokensIn(block.node, block.header, document)
const compound = block.children.length > 0 || block.header.endIndex < block.node.endIndex
const last = tokens.at(-1)
@@ -402,8 +418,8 @@ export function createZhTemplateTranslator(table: ZhTable): Translator {
return joinTokens(tokensIn(node, nodeSpan(node), document))
}
function doc(node: Node): Markdown | undefined {
const markdown = docText([table.commentText(node)])
function doc(node: Node, document: SourceDocument): Markdown | undefined {
const markdown = docText([commentOf(node, document)])
return markdown ? { markdown } : undefined
}
@@ -426,7 +442,7 @@ export function createZhTemplateTranslator(table: ZhTable): Translator {
// 点分模块名逐节照抄,每一节各自能跳到定义,和 VS Code 里一样
module: node => stringNodes.has(node.type) ? [segment(node.text, 'string', offsetOf(node, language))] : verbatim(node, document, 'type'),
name: (node, role) => [segment(node.text, role, offsetOf(node, language))],
doc,
doc: node => doc(node, document),
}
switch (block.kind) {
case 'function':