⚡ 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

+23 -18
View File
@@ -507,13 +507,14 @@ export function toBlockViews(
/**
* 一份源码的视图数据,和它里面起了中文名的定义(预览找用到它们的各处要用,见 displayNames.ts)、
* 语言插件自己认得出的名字(LanguageAdapter.symbols,语言扩展查不到定义、各处出现时用)、
* 各条导入引进来的名字(注释里不带路径的引用按它找导入的定义,见 symbolLinks.ts)。
* 各条导入引进来的名字(注释里不带路径的引用按它找导入的定义,见 symbolLinks.ts)、各块自己的名字和种类(调用的定义就在这份源码里时,分新建还是调用用它,见 NamedKind)。
*/
export interface DocumentViews {
blocks: BlockView[]
displayNames: DisplayName[]
symbols: LocalSymbol[]
imports: ImportedName[]
kinds: NamedKind[]
}
/**
@@ -586,7 +587,7 @@ export async function readBlockViews(
...adapter.symbols?.(tree.rootNode, source, languageId) ?? [],
...[...parts.values()].flatMap(part => part.document.language.symbols?.(part.root, source, part.code.languageId) ?? []),
]
return { blocks, displayNames: names, symbols, imports: importedNames(importsIn(codeBlocks)) }
return { blocks, displayNames: names, symbols, imports: importedNames(importsIn(codeBlocks)), kinds: namedKinds(codeBlocks) }
}
finally {
for (const parsed of trees)
@@ -594,30 +595,34 @@ export async function readBlockViews(
}
}
/** 块树里自己的名字(见 ownName)盖住 offset 的最里层那块的种类;offset 不在哪块的名字上时没有。 */
export function blockKindAt(blocks: readonly CodeBlock[], offset: number): BlockKind | undefined {
for (const block of blocks) {
const inner = blockKindAt(block.children, offset)
if (inner)
return inner
const name = ownName(block)
if (name && name.startIndex <= offset && offset < name.endIndex)
return block.kind
}
return undefined
/** 块树里各块自己的名字(见 ownName)在源码里的范围和块的种类,子块排在父块前面(后序):盖住某个下标的第一个就是最里层那块。 */
export interface NamedKind extends SourceRange {
kind: BlockKind
}
/** 解析一份源码,offset 处的名字定义的是哪种块(见 blockKindAt);语法树用完即释放。 */
export async function readDefinitionKind(
/** 块树里有自己名字的块,按后序排(见 NamedKind)。 */
export function namedKinds(blocks: readonly CodeBlock[]): NamedKind[] {
return blocks.flatMap((block) => {
const name = ownName(block)
return [...namedKinds(block.children), ...(name ? [{ startIndex: name.startIndex, endIndex: name.endIndex, kind: block.kind }] : [])]
})
}
/** 自己的名字盖住 offset 的最里层那块的种类;offset 不在哪块的名字上时没有。 */
export function kindAt(kinds: readonly NamedKind[], offset: number): BlockKind | undefined {
return kinds.find(name => name.startIndex <= offset && offset < name.endIndex)?.kind
}
/** 解析一份源码,读出各块自己的名字和种类(见 NamedKind);语法树用完即释放。 */
export async function readNamedKinds(
runtime: Pick<TreeSitterRuntime, 'parse'>,
adapter: LanguageAdapter,
languageId: string,
source: string,
offset: number,
): Promise<BlockKind | undefined> {
): Promise<NamedKind[]> {
const tree = await runtime.parse(adapter, languageId, source)
try {
return blockKindAt(adapter.toBlocks(tree.rootNode, source, languageId), offset)
return namedKinds(adapter.toBlocks(tree.rootNode, source, languageId))
}
finally {
tree.delete()