⚡ perf(vscode): 代码阅读预览注释里的引用解析过就记着:标坏链接、悬停、点击同一个引用只问一次 Pylance,同时问的等同一个结果,文档版本或块树、导入、用到的名字换了才作废,指到的别的文件改过再问,找不到和语言自带的不留;悬停看别的文件里的定义时读成的文档各预览共用,同一版不再重新解析,留最近 8 份,注册的插件变了全部重读

This commit is contained in:
cruldra committed 2026-10-14 19:57:20 +11:00
1 parent 3983032356
commit cfde0fedf5
9 files changed
+595 -70

No files matched your search

+11 -28
View File
@@ -2,6 +2,7 @@ import type { NamedKind } from './blockView'
import type { BlockKind, LanguageAdapter } from './contract'
import type { TreeSitterRuntime } from './runtime'
import { kindAt, readNamedKinds } from './blockView'
import { RecentPromises } from './recentPromises'
/** 定义所在的那份文件(TextDocument 的子集):uri、版本、语言、内容。 */
export interface KindSource {
@@ -20,17 +21,19 @@ const LIMIT = 64
* 最近用过的留 limit 份。这里不碰 VS Code。
*/
export class DefinitionKinds {
private readonly files = new Map<string, { version: number, kinds: Promise<NamedKind[] | undefined> }>()
private readonly files: RecentPromises<NamedKind[] | undefined>
constructor(
private readonly languageFor: (languageId: string) => LanguageAdapter | undefined,
private readonly runtime: Pick<TreeSitterRuntime, 'parse'>,
private readonly limit = LIMIT,
) {}
limit = LIMIT,
) {
this.files = new RecentPromises(limit)
}
/** uri 这份文件 version 这一版各块的名字和种类(预览发文档时读出的)。 */
remember(uri: string, version: number, kinds: NamedKind[]): void {
this.keep(uri, version, Promise.resolve(kinds))
this.files.set(uri, version, Promise.resolve(kinds))
}
/** file 里 offset 处的名字定义的是哪种块;没有语言插件、不在哪块的名字上时没有。 */
@@ -40,32 +43,12 @@ export class DefinitionKinds {
}
private kindsOf(file: KindSource): Promise<NamedKind[] | undefined> {
const known = this.files.get(file.uri)
if (known?.version === file.version) {
this.keep(file.uri, known.version, known.kinds)
return known.kinds
}
const known = this.files.get(file.uri, file.version)
if (known)
return known
const adapter = this.languageFor(file.languageId)
if (!adapter)
return Promise.resolve(undefined)
const kinds = readNamedKinds(this.runtime, adapter, file.languageId, file.getText())
this.keep(file.uri, file.version, kinds)
// 解析失败的不记,下次重来
kinds.catch(() => {
if (this.files.get(file.uri)?.kinds === kinds)
this.files.delete(file.uri)
})
return kinds
}
/** 记下(或用到了)一份:挪到最近用过的那头,多了丢最久没用的。 */
private keep(uri: string, version: number, kinds: Promise<NamedKind[] | undefined>): void {
this.files.delete(uri)
this.files.set(uri, { version, kinds })
for (const oldest of this.files.keys()) {
if (this.files.size <= this.limit)
break
this.files.delete(oldest)
}
return this.files.set(file.uri, file.version, readNamedKinds(this.runtime, adapter, file.languageId, file.getText()))
}
}