✨ feat(vscode): Rust 的 #![…] 内部属性做成「编译属性」卡片

This commit is contained in:
cruldra committed 2026-10-08 07:17:25 +08:00
1 parent 2f610e9cb8
commit 04a11eb0b2
14 files changed
+386 -20

No files matched your search

+28 -2
View File
@@ -1,5 +1,6 @@
import type { FactBlock, Node, PropertyRow, SourceDocument, Translator } from '../contract'
import { enumRows, functionRows, implRows, importRows, moduleRows, plainSay, structRows, traitRows } from '../rules/rustRows'
import type { FactBlock, Inline, Node, PropertyRow, SourceDocument, SourceSpan, Translator } from '../contract'
import { attributeRows, enumRows, functionRows, implRows, importRows, moduleRows, plainSay, structRows, traitRows } from '../rules/rustRows'
import { isCrateRoot } from '../rules/rustTree'
import { createZhTemplateTranslator, KIND_ZH, ZH_ATTRIBUTE_NAMES } from './zhTemplate'
const say = plainSay()
@@ -96,6 +97,8 @@ function describe(block: FactBlock, document: SourceDocument): PropertyRow[] {
return implRows(block, say)
case 'module':
return moduleRows(block, say)
case 'attribute':
return attributeRows(block, span => original(block.node, span, document), document.fileName === undefined ? undefined : isCrateRoot(document.fileName))
case 'const':
case 'variable':
return template.describe(block, document)
@@ -104,6 +107,29 @@ function describe(block: FactBlock, document: SourceDocument): PropertyRow[] {
}
}
/** node 里 span 那一段照原文:叶子按源码着色,叶子之间的空白照抄。 */
function original(node: Node, span: SourceSpan, { source, language }: SourceDocument): Inline[] {
const out: Inline[] = []
let cursor = span.startIndex
const visit = (current: Node): void => {
if (current.endIndex <= span.startIndex || current.startIndex >= span.endIndex || current.startIndex === current.endIndex)
return
if (current.childCount === 0) {
if (current.startIndex > cursor)
out.push({ text: source.slice(cursor, current.startIndex), role: 'plain' })
out.push({ text: current.text, role: language.tokenRole(current) })
cursor = current.endIndex
return
}
for (const child of current.children) {
if (child)
visit(child)
}
}
visit(node)
return out
}
/** 行注释去掉 `//`(文档注释连 `/`、`!`)和后面一个空格,缩进留给 Markdown;块注释去掉开头结尾的注释符号。 */
function commentText(node: Node, text: string): string {
if (node.type === 'line_comment')
@@ -207,6 +207,7 @@ export const KIND_ZH: Record<BlockKind, string> = {
trait: '特质',
impl: '实现',
module: '模块',
attribute: '编译属性',
enum: '枚举',
exception: '异常',
type: '类型',
@@ -722,6 +723,9 @@ export function createZhTemplateTranslator(table: ZhTable): Translator {
return healthRows(block.facts, phrases)
case 'start':
return startRows(block.facts, phrases)
// Rust 的编译属性由 Rust 的直译排(translators/rustZh.ts)
case 'attribute':
return []
default:
return block.facts.scope ? scopedVariableRows(block.facts.declarators, block.facts.scope, phrases) : variableRows(block, phrases)
}