✨ 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

+37 -3
View File
@@ -12,7 +12,7 @@ export type { Node }
*/
export type BlockKind
= | 'import' | 'function' | 'class' | 'enum' | 'exception' | 'type' | 'field' | 'const' | 'variable'
| 'trait' | 'impl' | 'module'
| 'trait' | 'impl' | 'module' | 'attribute'
| 'if' | 'else' | 'loop' | 'try' | 'catch' | 'finally' | 'return' | 'statement' | 'comment'
| 'interpreter' | 'options' | 'case' | 'command' | 'pipeline'
| 'directive' | 'stage' | 'run' | 'copy' | 'setting' | 'label' | 'health' | 'start'
@@ -214,6 +214,35 @@ export interface ClassFacts {
implements: Node[]
}
/** Rust 的内部属性 `#![…]`:`cfg_attr(条件, a, b)` 拆成生效条件和 a、b 两个属性,别的属性就是它自己一个。 */
export interface AttributeFacts {
/** 生效的各个属性,照写的顺序。 */
attributes: AttributeItem[]
/** `cfg_attr` 的生效条件;别的属性没有。 */
condition?: CfgPredicate
/** 写在哪一层:文件顶层、`mod` 身体、`impl` 身体;别处(`extern` 块里)没有。作用范围按它定,文件顶层还要看是不是 crate 根文件。 */
placement?: 'file' | 'module' | 'impl'
}
/** 一个属性:`名字`、`名字 = 值` 或 `名字(各项)`。 */
export interface AttributeItem {
/** 整个属性(名字连参数)在源码里的范围,预览照原文着色。 */
span: SourceSpan
/** 名字,路径照写(`rustfmt::skip`)。 */
name: string
/** `名字 = 值` 的值:字符串去掉引号,别的照原文。 */
value?: string
/** `名字(…)` 括号里逗号隔开的各项,照原文(`clippy::too_many_arguments` 是一项);没写括号是空的。 */
arguments: string[]
}
/** `cfg` 条件:`not(…)`、`all(…)`、`any(…)`,一个配置项(`test`、`target_os = "windows"`),认不出的写法照原文。 */
export type CfgPredicate
= | { kind: 'not', operand: CfgPredicate }
| { kind: 'all' | 'any', operands: CfgPredicate[] }
| { kind: 'option', name: string, value?: string }
| { kind: 'other', text: string }
/** 枚举的一个成员;节点都指向源码。 */
export interface EnumMemberFacts {
name: Node
@@ -480,6 +509,8 @@ export interface TraitBlock extends BlockShape { kind: 'trait', facts: ClassFact
/** Rust 的 impl:标题是「某类型 的方法」,方法是子块,放进方法表的某一行。 */
export interface ImplBlock extends BlockShape { kind: 'impl', facts: ClassFacts }
export interface ModuleBlock extends BlockShape { kind: 'module', facts: ClassFacts }
/** Rust 的内部属性 `#![…]`:写给所在 crate 或模块的编译属性。 */
export interface AttributeBlock extends BlockShape { kind: 'attribute', facts: AttributeFacts }
/** 枚举块的头部是整个枚举(成员都在属性表里讲),没有子块;库规则认出来的枚举(Python)是整个类,留下的方法等是子块。 */
export interface EnumBlock extends BlockShape { kind: 'enum', facts: EnumFacts }
/** 异常块的头部是整个类(类属性都在属性表里讲),留下的方法(含构造函数)等是子块。 */
@@ -497,7 +528,7 @@ export interface StageBlock extends BlockShape { kind: 'stage', facts: StageFact
export interface HealthBlock extends BlockShape { kind: 'health', facts: HealthFacts }
export interface StartBlock extends BlockShape { kind: 'start', facts: StartFacts }
export type FactBlock
= | FunctionBlock | ClassBlock | TraitBlock | ImplBlock | ModuleBlock | EnumBlock | ExceptionBlock | ImportBlock | VariableBlock | InterpreterBlock | OptionsBlock
= | FunctionBlock | ClassBlock | TraitBlock | ImplBlock | ModuleBlock | AttributeBlock | EnumBlock | ExceptionBlock | ImportBlock | VariableBlock | InterpreterBlock | OptionsBlock
| DirectiveBlock | StageBlock | HealthBlock | StartBlock
/** 带说明(facts.doc)的块。 */
@@ -695,6 +726,8 @@ export interface DisplayNameReader {
export interface SourceDocument {
source: string
language: LanguageAdapter
/** 文件路径(VS Code 的 TextDocument.fileName);宿主没给(嵌着的代码、只读一段源码)时没有,按文件名定的说法写成判断不了的那种。 */
fileName?: string
/** 写在注释里给代码阅读看的记号(中文名记号,见 DisplayNameFacts.markers):不是说明文字,翻注释、说明时去掉 */
markers: SourceRange[]
/**
@@ -743,7 +776,7 @@ export interface ThemeColor { dark: string, light: string }
/**
* 种类图标:插件自己定义的一组 lucide 图标(https://lucide.dev/icons 上的 kebab-case 名字)。前 26 个给内置种类(几种共用一个:
* 命令、管道、执行共用 square-terminal,解释器、解析指令共用 terminal,选项、设置共用 sliders-horizontal,字段、标签共用 tag),
* 命令、管道、执行共用 square-terminal,解释器、解析指令共用 terminal,选项、设置、编译属性共用 sliders-horizontal,字段、标签共用 tag),
* 宿主标的入口块也用这组里的 play(entries/entryMarks.ts 的 ENTRY_CONCEPT),
* 后面的给库规则的种类(React 的组件、状态、引用、数据源、派生值、副作用、事件处理函数、渲染输出也在里面);库规则的种类(KindBadge.icon)只能从这组里挑,要新图标就加进这组(webview 的 kindIcons.tsx 同时给它配上图标),
* 没有按任意名字找图标的路。
@@ -804,6 +837,7 @@ export const KIND_ICONS: Record<BlockKind, KindIconName> = {
trait: 'network',
impl: 'square-function',
module: 'layers',
attribute: 'sliders-horizontal',
type: 'braces',
enum: 'list-ordered',
exception: 'triangle-alert',