✨ feat(vscode): React 钩子卡片按变量讲,属性表加操作列、调用树能查所有引用

- 钩子调用讲成状态、引用、记忆值、记忆函数、上下文值、过渡、副作用、钩子返回值、钩子调用几种卡片,行照签名表 reactHooks.ts 排,去掉 react.hook
- 解构接住时名称一行写出解构,展开是「第几项 | 名称 | 说明」表,每项一个调用树操作;单个名字的按钮在名称一行最右边
- 属性表的行、子行可以带操作(RowAction),表格多一列「操作」,宿主按块记号加序号起键
- 调用树服务按键数次数,新增查所有引用(references):按所在函数分组,去掉定义处和依赖数组里的
- 钩子收的函数参数都收成小框,函数体是卡片子块,直接返回的表达式由 functionBody 排成「返回 …」卡片;小框和卡片折叠箭头同一个开关
- 规则卡片可指定语言种类图标(languageKind)、种类图标悬停字和颜色(KindBadge.tooltip / iconColor)
This commit is contained in:
cruldra committed 2026-10-16 22:16:09 +11:00
1 parent a139341132
commit 86beaac371
38 files changed
+1971 -813

No files matched your search

+14 -5
View File
@@ -307,10 +307,10 @@ function extendsBases(clause: Node): BaseFacts[] {
}
/**
* 读代码块树的一套函数。typed:TypeScript(typescript、typescriptreact),分得出抽象类、仅类型导入;
* JavaScript 没有这两个概念,facts 里不填(见 classFacts、importFacts)。
* 读代码块树的一套函数:整份源码(file),一个函数值的主体(body,见 [LanguageAdapter.functionBody])。
* typed:TypeScript(typescript、typescriptreact),分得出抽象类、仅类型导入;JavaScript 没有这两个概念,facts 里不填(见 classFacts、importFacts)。
*/
function blockReader(typed: boolean): (root: Node) => CodeBlock[] {
function blockReader(typed: boolean): { file: (root: Node) => CodeBlock[], body: (fn: Node) => CodeBlock[] } {
function statements(items: Node[], top: boolean, afterRow: number): CodeBlock[] {
return listBlocks(items, afterRow, item => statementBlocks(item, top), COMMENTS)
}
@@ -558,7 +558,15 @@ function blockReader(typed: boolean): (root: Node) => CodeBlock[] {
return [leafBlock('field', member)]
}
return root => statements(named(root), true, -1)
/** 函数值的主体:语句块是各句,直接返回的表达式是一个返回块(节点是那个表达式,源码里没写 return)。 */
function body(fn: Node): CodeBlock[] {
const main = fn.childForFieldName('body')
if (!main)
return []
return main.type === 'statement_block' ? statements(named(main), false, main.startPosition.row) : [leafBlock('return', main)]
}
return { file: root => statements(named(root), true, -1), body }
}
// ─── 异常类 ───────────────────────────────────────────────────────────────────
@@ -792,7 +800,8 @@ export function createTypeScriptAdapter(wasmDir: string): LanguageAdapter {
throw new Error(`TypeScript 语言插件不支持 ${languageId}`)
return path.join(wasmDir, file)
},
toBlocks: (root, _source, languageId) => withExceptions(attachComments(blockReader(TYPED_LANGUAGES.has(languageId))(root), aboutFile), TYPESCRIPT_EXCEPTIONS),
toBlocks: (root, _source, languageId) => withExceptions(attachComments(blockReader(TYPED_LANGUAGES.has(languageId)).file(root), aboutFile), TYPESCRIPT_EXCEPTIONS),
functionBody: (fn, languageId) => withExceptions(attachComments(blockReader(TYPED_LANGUAGES.has(languageId)).body(fn), aboutFile, false), TYPESCRIPT_EXCEPTIONS),
tokenRole: typescriptTokenRole,
lineComment: '//',
freshDoc,