✨ feat(vscode): 新增「了解一块代码」:AI 找功能代码占一栏,对话里接着改
主栏标题栏的放大镜问要了解哪一块,占一个栏位建一栏(和收藏共用 30 个栏位,视图改名 slot1..30,按 slotKindN 分收藏 / 功能挂标题栏按钮),同时开对话页让 Claude 只读地在全部工作区文件夹里找,按 --json-schema 交回环节 → 文件 + 符号 + 一句话。 对话复用预览顶部的聊天(CodeQa.askTop:会话续接、进行中的一轮、记录存 workspaceState);结构不合格算这一轮没答成、留着能再画出来。 条目每次画、点时按眼下的代码找:有语言插件的解析成代码块按「类名.方法名」找,没有的问 VS Code 文档符号;找不到画成灰的。
This commit is contained in:
1 parent
16d27004d8
commit
880bf7fc57
38 files changed
+3386
-378
No files matched your search
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 「了解一块代码」的条目按符号名找位置:用语言插件把源码解析成代码块(同预览),在有名字的块里按 `类名.方法名` 一层层找。
|
||||
* 每次画栏、点条目时按眼下的代码现找,代码改过也找得到。不碰 VS Code;语言没有插件时用 VS Code 的文档符号(见 featureViews.ts)。
|
||||
*/
|
||||
|
||||
import type { BlockKind, CodeBlock, LanguageAdapter, Node, SourceRange } from '../contract'
|
||||
import type { TreeSitterRuntime } from '../runtime'
|
||||
import { ownName } from '../blockView'
|
||||
import { findRepoSymbol } from '../editor/repoPath'
|
||||
|
||||
/** 块树上有名字的一块:名字、种类、名字在源码里的范围;子孙里有名字的挂在下面。 */
|
||||
export interface NamedBlock {
|
||||
name: string
|
||||
kind: BlockKind
|
||||
range: SourceRange
|
||||
children: NamedBlock[]
|
||||
}
|
||||
|
||||
/** 语言插件不给名字、按语法树里的声明找名字的块:类型(TypeScript 的 interface、type)、类型里的成员、别的声明语句(Rust 的 type)。 */
|
||||
const DECLARATIONS = new Set<BlockKind>(['type', 'field', 'statement'])
|
||||
|
||||
/**
|
||||
* 块的名字:函数、类、组件、变量(见 ownName),Rust 的 impl、trait(`impl Order` 里的方法写成 `Order.pay`);
|
||||
* DECLARATIONS 那几种按语法树里声明的 name 字段找,export 语句先进到它导出的声明里。
|
||||
*/
|
||||
function nameOf(block: CodeBlock): Node | undefined {
|
||||
if (block.kind === 'impl' || block.kind === 'trait')
|
||||
return block.facts.name
|
||||
if (!DECLARATIONS.has(block.kind))
|
||||
return ownName(block)
|
||||
const declaration = block.node.childForFieldName('declaration') ?? block.node
|
||||
return declaration.childForFieldName('name') ?? undefined
|
||||
}
|
||||
|
||||
/** 块树里有名字的那些;没名字的块(条件、调用语句)跳过,它里面有名字的往上提一层。 */
|
||||
export function namedBlocks(blocks: readonly CodeBlock[]): NamedBlock[] {
|
||||
return blocks.flatMap((block): NamedBlock[] => {
|
||||
const children = namedBlocks(block.children)
|
||||
const name = nameOf(block)
|
||||
return name ? [{ name: name.text, kind: block.kind, range: { startIndex: name.startIndex, endIndex: name.endIndex }, children }] : children
|
||||
})
|
||||
}
|
||||
|
||||
/** 用语言插件解析 source,按 symbol(`login`、`AuthService.login`)找那一块;找不到没有。语法树用完即释放。 */
|
||||
export async function locateInSource(
|
||||
runtime: Pick<TreeSitterRuntime, 'parse'>,
|
||||
adapter: LanguageAdapter,
|
||||
languageId: string,
|
||||
source: string,
|
||||
symbol: string,
|
||||
): Promise<NamedBlock | undefined> {
|
||||
const tree = await runtime.parse(adapter, languageId, source)
|
||||
try {
|
||||
return findRepoSymbol(namedBlocks(adapter.toBlocks(tree.rootNode, source, languageId)), symbol)
|
||||
}
|
||||
finally {
|
||||
tree.delete()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user