⚡ perf(vscode): 代码阅读预览发给页面的块只记相对位置:块在源码里占的地方记成离前一块多远、自己多长,块里名字的下标从块的开头算,页面从文件开头累加回文件里的位置、和扩展端打交道的地方都在一处换算;靠前改了代码,后面内容没变的块发过去一模一样,扩展端自己的块和发给页面的块分成两种类型
This commit is contained in:
1 parent
3a2815c19c
commit
ad5f559e92
43 files changed
+980
-424
No files matched your search
@@ -0,0 +1,84 @@
|
||||
import type { BlockView as HostBlockView } from '../../../src/codeReader/blockView'
|
||||
import type { BlockView } from './types'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { toBlockViews } from '../../../src/codeReader/blockView'
|
||||
import { pageBlocks } from '../../../src/codeReader/editor/pageBlocks'
|
||||
import { createPythonAdapter } from '../../../src/codeReader/languages/python'
|
||||
import { WASM_DIR, withBlocks } from '../../../src/codeReader/testSupport'
|
||||
import { pythonZhTranslator } from '../../../src/codeReader/translators/pythonZh'
|
||||
import { placementOf } from './placement'
|
||||
|
||||
const py = createPythonAdapter(WASM_DIR)
|
||||
|
||||
async function views(source: string): Promise<HostBlockView[]> {
|
||||
return withBlocks(py, 'python', source, blocks => toBlockViews(blocks, { source, language: py, markers: [] }, pythonZhTranslator))
|
||||
}
|
||||
|
||||
function flatten<T extends { children: T[] }>(list: T[]): T[] {
|
||||
return list.flatMap(block => [block, ...flatten(block.children)])
|
||||
}
|
||||
|
||||
function byId(blocks: BlockView[]): Map<string, BlockView> {
|
||||
return new Map(flatten(blocks).map(block => [block.id, block]))
|
||||
}
|
||||
|
||||
/** 一块自己的样子(不连子块):子块变了不算它变了 */
|
||||
function own({ children: _, ...rest }: BlockView): Omit<BlockView, 'children'> {
|
||||
return rest
|
||||
}
|
||||
|
||||
const SOURCE = [
|
||||
'import os',
|
||||
'',
|
||||
'def helper(value):',
|
||||
' return value + 1',
|
||||
'',
|
||||
'class Store:',
|
||||
' def load(self, key):',
|
||||
' if key:',
|
||||
' return os.getenv(key)',
|
||||
' return None',
|
||||
'',
|
||||
'LIMIT = 3',
|
||||
].join('\n')
|
||||
|
||||
describe('块在文件里的位置:扩展端记成相对的,页面累加回来', () => {
|
||||
it('每块累加出来的首行、尾行、开头的下标同扩展端的一样;块里的下标加上块的开头就是文件里的', async () => {
|
||||
const host = await views(SOURCE)
|
||||
const placement = placementOf(pageBlocks(host, SOURCE))
|
||||
const lineStarts = SOURCE.split('\n').map((_, line, lines) => lines.slice(0, line).join('\n').length + (line > 0 ? 1 : 0))
|
||||
for (const block of flatten(host)) {
|
||||
expect(placement.of(block.id), block.id).toEqual({ offset: lineStarts[block.startLine], line: block.startLine, endLine: block.endLine })
|
||||
}
|
||||
const page = byId(pageBlocks(host, SOURCE))
|
||||
for (const block of flatten(host).filter(block => block.defines)) {
|
||||
const base = placement.of(block.id)!.offset
|
||||
const defines = page.get(block.id)!.defines!
|
||||
expect(SOURCE.slice(base + defines.startIndex, base + defines.endIndex), block.id).toBe(SOURCE.slice(block.defines!.startIndex, block.defines!.endIndex))
|
||||
}
|
||||
})
|
||||
|
||||
it('靠前的一块里改了一个字:只有那块变了,包着它的块只是长了一个字,后面的块发出去一模一样', async () => {
|
||||
const edited = SOURCE.replace('value + 1', 'value + 10')
|
||||
const before = byId(pageBlocks(await views(SOURCE), SOURCE))
|
||||
const after = byId(pageBlocks(await views(edited), edited))
|
||||
const changed = [...after.keys()].filter(id => JSON.stringify(own(after.get(id)!)) !== JSON.stringify(own(before.get(id)!)))
|
||||
expect(changed).toEqual(['1', '1.0'])
|
||||
expect(own(after.get('1')!)).toEqual({ ...own(before.get('1')!), span: { ...before.get('1')!.span, length: before.get('1')!.span.length + 1 } })
|
||||
})
|
||||
|
||||
it('上面多了几行:只有紧跟在后面的那块离前一块远了,其余块发出去一模一样,累加出来的位置都往后挪', async () => {
|
||||
const shifted = SOURCE.replace('import os\n', 'import os\n\n\n')
|
||||
const old = pageBlocks(await views(SOURCE), SOURCE)
|
||||
const page = pageBlocks(await views(shifted), shifted)
|
||||
const before = byId(old)
|
||||
const after = byId(page)
|
||||
const changed = [...after.keys()].filter(id => JSON.stringify(own(after.get(id)!)) !== JSON.stringify(own(before.get(id)!)))
|
||||
expect(changed).toEqual(['1'])
|
||||
expect(after.get('1')!.span).toEqual({ ...before.get('1')!.span, lineGap: before.get('1')!.span.lineGap + 2, gap: before.get('1')!.span.gap + 2 })
|
||||
for (const id of [...after.keys()].filter(id => id !== '0')) {
|
||||
const was = placementOf(old).of(id)!
|
||||
expect(placementOf(page).of(id), id).toEqual({ offset: was.offset + 2, line: was.line + 2, endLine: was.endLine + 2 })
|
||||
}
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user