⚡ perf(vscode): 标差异时旧版本的解析结果按旧内容记着,晚到的答案、翻译插件没变就不再重新解析
This commit is contained in:
1 parent
e9c1c67d6f
commit
5a0c5490ea
8 files changed
+87
-8
No files matched your search
@@ -23,11 +23,12 @@ function base(text: string | null, key = 'k'): DiffBase & { read: ReturnType<typ
|
||||
return { label: '上一次提交', key, read: vi.fn(async () => text), missing: '上一次提交里没有这个文件' }
|
||||
}
|
||||
|
||||
function setup(current: { base: DiffBase | undefined }) {
|
||||
function setup(current: { base: DiffBase | undefined, inputs?: string }) {
|
||||
const posted: (DocumentDiff | null)[] = []
|
||||
const reports: string[] = []
|
||||
const diff = new PreviewDiff(() => current.base, parse, value => posted.push(value), message => reports.push(message))
|
||||
return { diff, posted, reports }
|
||||
const read = vi.fn(parse)
|
||||
const diff = new PreviewDiff(() => current.base, read, () => current.inputs ?? '', value => posted.push(value), message => reports.push(message))
|
||||
return { diff, posted, reports, read }
|
||||
}
|
||||
|
||||
describe('previewDiff', () => {
|
||||
@@ -75,6 +76,24 @@ describe('previewDiff', () => {
|
||||
expect(second.read).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('旧版本解析出来的按旧内容和解析时看的东西(翻译插件、晚到的答案……)记着:都没变不再解析,哪个变了重新解析', async () => {
|
||||
const current: { base: DiffBase | undefined, inputs: string } = { base: base('x = 1\n', 'a'), inputs: 'v1' }
|
||||
const { diff, posted, read } = setup(current)
|
||||
await diff.update(await sent('x = 2\n', 1))
|
||||
await diff.update(await sent('x = 3\n', 2))
|
||||
expect(read).toHaveBeenCalledTimes(1)
|
||||
expect(posted.at(-1)).toMatchObject({ version: 2, stats: { mod: 1 } })
|
||||
current.inputs = 'v2'
|
||||
await diff.update(await sent('x = 3\n', 3))
|
||||
expect(read).toHaveBeenCalledTimes(2)
|
||||
current.base = base('y = 1\n', 'b')
|
||||
await diff.update(await sent('x = 3\n', 4))
|
||||
expect(read).toHaveBeenCalledTimes(3)
|
||||
current.base = base('y = 1\n', 'c')
|
||||
await diff.update(await sent('x = 3\n', 5))
|
||||
expect(read).toHaveBeenCalledTimes(3)
|
||||
})
|
||||
|
||||
it('同一份文档、同一个基准不再比', async () => {
|
||||
const { diff, posted } = setup({ base: base('x = 1\n') })
|
||||
const doc = await sent('x = 2\n')
|
||||
|
||||
@@ -61,12 +61,14 @@ export function documentDiff(base: DiffBase, sent: SentDocument, old: { source:
|
||||
|
||||
/**
|
||||
* 一个打开着的预览的差异:每发出一份文档之后、对比基准变了之后按眼下的基准重新比,比完再发,预览先照常画、不等它。
|
||||
* 取过的旧内容按基准的 key 记着(编辑时不用每次去问 git),旧版本每次重新解析:规则查到的定义、调用的种类这些晚到的答案两边要一样。
|
||||
* 这里不碰 VS Code。
|
||||
* 取过的旧内容按基准的 key 记着(编辑时不用每次去问 git);旧版本解析出来的按旧内容和解析时还看的东西(oldInputs)记着,
|
||||
* 都没变不再解析,规则查到的定义、调用的种类这些晚到的答案变了才重新解析,两边同样的写法翻得一样。这里不碰 VS Code。
|
||||
*/
|
||||
export class PreviewDiff {
|
||||
/** 取过的旧内容;key 相同不再取,取失败了下次重取 */
|
||||
private old: { key: string, text: Promise<string | null> } | undefined
|
||||
/** 解析过的旧版本;旧内容、oldInputs 都没变不再解析,解析出错了下次重来 */
|
||||
private parsed: { text: string, inputs: string, document: Promise<OldDocument | undefined> } | undefined
|
||||
/** 只发最后一次比的结果:慢的旧结果不能盖掉新的 */
|
||||
private latest = 0
|
||||
/** 上一次比的是哪份文档、哪个基准:都没变就不再比(git 状态变了、基准没挪) */
|
||||
@@ -79,6 +81,8 @@ export class PreviewDiff {
|
||||
private readonly baseOf: () => DiffBase | undefined,
|
||||
/** 用这份文档的语言、翻译插件和库规则解析旧版本;解析失败是 undefined */
|
||||
private readonly readOld: (source: string) => Promise<OldDocument | undefined>,
|
||||
/** 解析旧版本除了旧内容还看的东西(翻译插件、项目入口、晚到的答案)拼成的一串:变了旧版本要重新解析 */
|
||||
private readonly oldInputs: () => string,
|
||||
private readonly post: (diff: DocumentDiff | null) => void,
|
||||
private readonly report: (message: string) => void,
|
||||
) {}
|
||||
@@ -97,7 +101,7 @@ export class PreviewDiff {
|
||||
}
|
||||
try {
|
||||
const text = await this.oldText(base)
|
||||
const document = text === null ? undefined : await this.readOld(text)
|
||||
const document = text === null ? undefined : await this.oldDocument(text)
|
||||
if (request !== this.latest)
|
||||
return
|
||||
if (text !== null && !document) {
|
||||
@@ -135,4 +139,17 @@ export class PreviewDiff {
|
||||
}
|
||||
return this.old.text
|
||||
}
|
||||
|
||||
private oldDocument(text: string): Promise<OldDocument | undefined> {
|
||||
const inputs = this.oldInputs()
|
||||
if (this.parsed?.text !== text || this.parsed.inputs !== inputs) {
|
||||
const document = this.readOld(text)
|
||||
this.parsed = { text, inputs, document }
|
||||
document.catch(() => {
|
||||
if (this.parsed?.document === document)
|
||||
this.parsed = undefined
|
||||
})
|
||||
}
|
||||
return this.parsed.document
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user