⚡ perf(vscode): 认调用分新建还是调用时,定义所在的文件按版本记着解析结果,同一版不再整份重解析;定义就在本文件时用发文档时读出的
This commit is contained in:
1 parent
80d9962856
commit
e9c1c67d6f
8 files changed
+194
-45
No files matched your search
@@ -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()
|
||||
|
||||
Reference in new issue
Block a user