⚡ perf(vscode): 代码阅读预览注释里的引用解析过就记着:标坏链接、悬停、点击同一个引用只问一次 Pylance,同时问的等同一个结果,文档版本或块树、导入、用到的名字换了才作废,指到的别的文件改过再问,找不到和语言自带的不留;悬停看别的文件里的定义时读成的文档各预览共用,同一版不再重新解析,留最近 8 份,注册的插件变了全部重读
This commit is contained in:
1 parent
3983032356
commit
cfde0fedf5
9 files changed
+595
-70
No files matched your search
@@ -6,7 +6,8 @@ import type { SymbolNode } from '../symbolLinks'
|
||||
import type { CodeColors } from '../theme/codeColors'
|
||||
import type { ExtensionToWebview, WebviewToExtension } from './messages'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { commands, window, workspace } from 'vscode'
|
||||
import { commands, Range, Uri, window, workspace } from 'vscode'
|
||||
import { languageDefinitions } from './definitions'
|
||||
import { documentMessage } from './documentMessage'
|
||||
import { documentSymbolNodes } from './documentSymbols'
|
||||
import { FIND_CONTEXT } from './findCommands'
|
||||
@@ -22,6 +23,8 @@ vi.mock('vscode', () => ({
|
||||
getConfiguration: () => ({ get: (_key: string, fallback: unknown) => fallback }),
|
||||
openTextDocument: vi.fn(),
|
||||
applyEdit: vi.fn(async () => true),
|
||||
textDocuments: [],
|
||||
asRelativePath: (uri: { fsPath: string }) => uri.fsPath,
|
||||
},
|
||||
/** 记下换了哪儿、换成什么 */
|
||||
WorkspaceEdit: class {
|
||||
@@ -33,7 +36,10 @@ vi.mock('vscode', () => ({
|
||||
get start() { return { line: this.startLine, character: this.startCharacter } }
|
||||
get end() { return { line: this.endLine, character: this.endCharacter } }
|
||||
},
|
||||
Uri: { file: (fsPath: string) => ({ fsPath, scheme: 'file', toString: () => `file://${fsPath}` }) },
|
||||
Uri: {
|
||||
file: (fsPath: string) => ({ fsPath, scheme: 'file', toString: () => `file://${fsPath}` }),
|
||||
parse: (value: string) => ({ fsPath: value.replace('file://', ''), scheme: 'file', toString: () => value }),
|
||||
},
|
||||
EndOfLine: { LF: 1, CRLF: 2 },
|
||||
}))
|
||||
vi.mock('../../logging/logger', () => ({ logger: { add: vi.fn() } }))
|
||||
@@ -55,6 +61,11 @@ vi.mock('./documentMessage', async importOriginal => ({
|
||||
}))
|
||||
/** 文档符号由各个测试给 */
|
||||
vi.mock('./documentSymbols', () => ({ documentSymbolNodes: vi.fn(async () => []) }))
|
||||
/** 语言扩展答的定义由各个测试给,默认没答 */
|
||||
vi.mock('./definitions', async importOriginal => ({
|
||||
...await importOriginal<typeof import('./definitions')>(),
|
||||
languageDefinitions: vi.fn(async () => []),
|
||||
}))
|
||||
/** 仓库在 /workspace,里面只有这几个文件 */
|
||||
vi.mock('./repoPath', async importOriginal => ({
|
||||
...await importOriginal<typeof import('./repoPath')>(),
|
||||
@@ -74,7 +85,7 @@ function preview(rewrite: (uri: unknown, request: RewriteRequest) => Promise<str
|
||||
const qa = { imageRoot: () => undefined, onDidChange: subscribe, onDidAnswer: subscribe, onDidRewrite: subscribe, profiles: { ask: { subscribe }, rewrite: { subscribe } }, rewrite: vi.fn(rewrite) }
|
||||
const provider = new PreviewEditorProvider(...[
|
||||
{},
|
||||
{},
|
||||
{ onDidChange: subscribe },
|
||||
{},
|
||||
{ subscribe },
|
||||
{ subscribe },
|
||||
@@ -211,7 +222,7 @@ function opening(profiles = { ask: profileSet(''), rewrite: profileSet('') }, co
|
||||
}
|
||||
const provider = new PreviewEditorProvider(...[
|
||||
{},
|
||||
{ selectedTranslator: () => undefined, languageFor },
|
||||
{ selectedTranslator: () => undefined, languageFor, onDidChange: subscribe },
|
||||
{},
|
||||
{ subscribe, current: { excluded: {}, onlyChanges: false } },
|
||||
colors,
|
||||
@@ -587,6 +598,50 @@ describe('注释里不带路径的引用按它写在哪块的注释里找', () =
|
||||
expect(page.posted()).toContainEqual({ type: 'repoLinkBuiltin', symbol: 'Error', block: HELPER })
|
||||
expect(page.posted()).not.toContainEqual(expect.objectContaining({ type: 'repoLinkBroken' }))
|
||||
})
|
||||
|
||||
it('检查过的引用再悬停、再点:文档符号、定义都只问一次;悬停两次,定义所在的别的文件也只读一次', async () => {
|
||||
const BUILTINS = '/typeshed/builtins.pyi'
|
||||
const builtins = { uri: Uri.file(BUILTINS), version: 1, languageId: 'python', fileName: BUILTINS, getText: () => 'class RuntimeError: ...', positionAt: () => ({ line: 0, character: 6 }), offsetAt: () => 6 }
|
||||
vi.mocked(documentMessage).mockImplementationOnce(async input => ({
|
||||
message: { type: 'document', version: input.version, languageId: input.languageId, blocks: [declared(HELPER, 950)], source: '', colors: { roles: [], runs: [] }, attributes: [], translators: [], translatorId: '', names: [] },
|
||||
displayNames: [],
|
||||
symbols: [],
|
||||
imports: [{ name: 'RuntimeError', offset: 7, range: { startIndex: 0, endIndex: 20 } }],
|
||||
kinds: [],
|
||||
bindings: [],
|
||||
}) as never)
|
||||
vi.mocked(documentSymbolNodes).mockReset().mockResolvedValue([symbol('helper', 950, 990)])
|
||||
vi.mocked(languageDefinitions).mockClear().mockResolvedValue([{ uri: builtins.uri, range: new Range(0, 6, 0, 18) }] as never)
|
||||
const { provider, document } = opening()
|
||||
Object.assign(document, { positionAt: (offset: number) => ({ line: 0, character: offset }) })
|
||||
Object.assign(workspace, { textDocuments: [document, builtins] })
|
||||
vi.mocked(workspace.openTextDocument).mockImplementation((async (uri: { toString: () => string }) => uri.toString() === builtins.uri.toString() ? builtins : document) as never)
|
||||
try {
|
||||
const page = tab()
|
||||
provider.resolveCustomTextEditor(document as never, page.panel)
|
||||
await page.send({ type: 'ready' })
|
||||
await vi.waitFor(() => expect(page.posted()).toContainEqual(expect.objectContaining({ type: 'document' })))
|
||||
vi.mocked(documentMessage).mockClear()
|
||||
|
||||
const reference = { symbol: 'RuntimeError', block: HELPER }
|
||||
await page.send({ type: 'checkRepoLinks', id: 1, paths: [], references: [reference] })
|
||||
expect(page.posted()).toContainEqual({ type: 'repoLinksChecked', id: 1, missing: [], unresolved: [], builtin: [] })
|
||||
await page.send({ type: 'peekLink', id: 2, ...reference })
|
||||
await page.send({ type: 'peekLink', id: 3, ...reference })
|
||||
await page.send({ type: 'openRepoLink', ...reference })
|
||||
|
||||
expect(page.posted()).toContainEqual(expect.objectContaining({ type: 'repoLinkOpened', ...reference }))
|
||||
expect(commands.executeCommand).toHaveBeenCalledWith('vscode.open', expect.objectContaining({ fsPath: BUILTINS }), expect.anything())
|
||||
expect(documentSymbolNodes).toHaveBeenCalledTimes(1)
|
||||
expect(languageDefinitions).toHaveBeenCalledTimes(1)
|
||||
expect(documentMessage).toHaveBeenCalledTimes(1)
|
||||
expect(documentMessage).toHaveBeenCalledWith(expect.objectContaining({ fileName: BUILTINS }), expect.anything(), expect.anything(), expect.any(Function))
|
||||
}
|
||||
finally {
|
||||
Object.assign(workspace, { textDocuments: [] })
|
||||
vi.mocked(workspace.openTextDocument).mockReset()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('点了带几行的仓库链接', () => {
|
||||
|
||||
Reference in new issue
Block a user