⚡ perf(vscode): 认调用分新建还是调用时,定义所在的文件按版本记着解析结果,同一版不再整份重解析;定义就在本文件时用发文档时读出的

This commit is contained in:
cruldra committed 2026-10-13 14:15:33 +11:00
1 parent 80d9962856
commit e9c1c67d6f
8 files changed
+194 -45

No files matched your search

+10 -3
View File
@@ -26,6 +26,7 @@ import { DocumentCallees } from '../calleeKinds'
import { loadBlockCalls } from '../callTree/query'
import { CallTreeSession } from '../callTree/session'
import { commentFollowUp, commentJob, commentRewritePrompt, findBlock, writeCommentBody } from '../commentRewrite'
import { DefinitionKinds } from '../definitionKinds'
import { PreviewDiff } from '../diff/previewDiff'
import { blockReplacement } from '../editText'
import { locate } from '../folderStore'
@@ -77,6 +78,8 @@ export class PreviewEditorProvider implements CustomTextEditorProvider {
private readonly requests = new Map<string, OpenRequest>()
/** 哪个预览眼下能用键盘在高亮的各处出现之间跳,跟着它设快捷键 when 子句用的上下文键 */
readonly navigation = new NavigationContext<Preview>(value => void commands.executeCommand('setContext', OCCURRENCES_CONTEXT, value))
/** 调用的名字的定义是哪种块:各预览共用,定义所在的文件同一版只解析一次 */
readonly definitionKinds: DefinitionKinds
constructor(
private readonly extensionUri: Uri,
@@ -101,7 +104,9 @@ export class PreviewEditorProvider implements CustomTextEditorProvider {
readonly revealInTree: (uri: Uri) => Promise<boolean>,
/** 「了解一块代码」的对话页里接着说(subject 是那个功能,见 featureSubjectUri);说不了时返回给人看的原因 */
readonly askFeature: (subject: Uri, request: TopRequest) => Promise<string | undefined>,
) {}
) {
this.definitionKinds = new DefinitionKinds(languageId => registry.languageFor(languageId), runtime)
}
/**
* 注册成预览编辑器。标签页切走时页面留着(`retainContextWhenHidden`):切回来不用重新生成、重发文档(切走期间改过的才补一次),页面也不用整份重画,
@@ -404,12 +409,14 @@ class Preview {
const source = this.document.getText()
const session = this.lookups.session()
const callees = this.callees.session()
const { message, displayNames, symbols, imports } = await documentMessage({ languageId, version, getText: () => source, fileName: this.document.fileName, entryNames: this.owner.entries.namesOf(this.document.uri) }, this.registry, this.runtime, (text) => {
const { message, displayNames, symbols, imports, kinds } = await documentMessage({ languageId, version, getText: () => source, fileName: this.document.fileName, entryNames: this.owner.entries.namesOf(this.document.uri) }, this.registry, this.runtime, (text) => {
logger.add({ level: 'warn', source: 'codeReader', message: `${this.document.uri.fsPath}:${text}` })
}, session.lookup, callees.calleeKind)
if (request !== this.latest)
return
this.definitions.remember(message.version, message.blocks)
// 调用的定义就在这份文档里时,认种类直接用这一遍读出的,不再解析一遍
this.owner.definitionKinds.remember(this.document.uri.toString(), version, kinds)
// 解析失败的文档没有块:问 AI 找不到块,也不拿它比差异
this.sent = message.error === undefined ? { version: message.version, blocks: message.blocks, source } : undefined
this.symbols = { version, list: symbols }
@@ -452,7 +459,7 @@ class Preview {
if (found.length === 0)
return undefined
for (const location of found) {
const kind = await definitionKind(location, languageId => this.registry.languageFor(languageId), this.runtime)
const kind = await definitionKind(location, this.owner.definitionKinds)
if (kind)
return kind
}