✨ feat(vscode): 代码阅读的调用与构造:跨多行写的调用排成「新建 / 调用 名字 · N 个参数」一行,实参摊成参数 / 值表;Python 查被调用名字的定义分新建和调用,查到后刷新
This commit is contained in:
1 parent
ebf228cdc7
commit
ecc415d763
30 files changed
+1033
-157
No files matched your search
@@ -0,0 +1,84 @@
|
||||
import type { BlockKind, CallFacts, Node } from './contract'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { DocumentCallees } from './calleeKinds'
|
||||
|
||||
/** 一次调用:只用到被调用的表达式原文,和最后那个名字的下标。 */
|
||||
function call(callee: string, nameAt?: number): CallFacts {
|
||||
const facts = { callee: { text: callee } as Node, argumentList: {} as Node, arguments: [] }
|
||||
return nameAt === undefined ? facts : { ...facts, name: { startIndex: nameAt } as Node }
|
||||
}
|
||||
|
||||
/** 各下标处名字的定义是哪种块(语言扩展答的;没有的是没答);记下问了哪些下标。 */
|
||||
function source(kinds: Record<number, BlockKind | null>): { asked: number[], kindOf: (offset: number) => Promise<BlockKind | null | undefined> } {
|
||||
const asked: number[] = []
|
||||
return {
|
||||
asked,
|
||||
kindOf: async (offset) => {
|
||||
asked.push(offset)
|
||||
return kinds[offset]
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
describe('调用的名字定义成哪种块(DocumentCallees)', () => {
|
||||
it('第一遍当没查到,按被调用的表达式原文记下问了什么(写法一样的按一处问);查到后叫宿主重排,再排时交出来', async () => {
|
||||
let changed = 0
|
||||
const callees = new DocumentCallees(() => changed++, [])
|
||||
const first = callees.session()
|
||||
expect(first.calleeKind(call('UserDetailResponse', 40))).toBeUndefined()
|
||||
expect(first.calleeKind(call('UserDetailResponse', 90))).toBeUndefined()
|
||||
expect(first.calleeKind(call('user_service.update_user', 120))).toBeUndefined()
|
||||
expect(first.requests()).toEqual([{ callee: 'UserDetailResponse', offset: 40 }, { callee: 'user_service.update_user', offset: 120 }])
|
||||
|
||||
const from = source({ 40: 'class', 120: 'function' })
|
||||
callees.resolve(1, first.requests(), from.kindOf)
|
||||
await vi.waitFor(() => expect(changed).toBe(1))
|
||||
const second = callees.session()
|
||||
expect(second.calleeKind(call('UserDetailResponse', 12))).toBe('class')
|
||||
expect(second.calleeKind(call('user_service.update_user', 7))).toBe('function')
|
||||
|
||||
// 同一版本再发一遍:问过的不再查
|
||||
callees.resolve(1, first.requests(), from.kindOf)
|
||||
await Promise.resolve()
|
||||
expect(from.asked).toEqual([40, 120])
|
||||
})
|
||||
|
||||
it('被调用的不是名字(没有 name)不问;查了没有(null)不算变了', async () => {
|
||||
let changed = 0
|
||||
const callees = new DocumentCallees(() => changed++, [])
|
||||
const session = callees.session()
|
||||
expect(session.calleeKind(call('handlers[k]'))).toBeUndefined()
|
||||
session.calleeKind(call('build', 5))
|
||||
expect(session.requests()).toEqual([{ callee: 'build', offset: 5 }])
|
||||
const from = source({ 5: null })
|
||||
callees.resolve(1, session.requests(), from.kindOf)
|
||||
await vi.waitFor(() => expect(from.asked).toEqual([5]))
|
||||
await Promise.resolve()
|
||||
expect(changed).toBe(0)
|
||||
})
|
||||
|
||||
it('语言扩展还没起来(没答):隔一会儿只再查没答的,查到了再叫重排', async () => {
|
||||
let changed = 0
|
||||
const pending: (() => void)[] = []
|
||||
const scheduled: number[] = []
|
||||
const callees = new DocumentCallees(() => changed++, [5, 10], (task, ms) => {
|
||||
scheduled.push(ms)
|
||||
pending.push(task)
|
||||
return setTimeout(() => {}, 0)
|
||||
})
|
||||
const session = callees.session()
|
||||
session.calleeKind(call('Detail', 40))
|
||||
session.calleeKind(call('run', 60))
|
||||
const kinds: Record<number, BlockKind | null> = { 60: 'function' }
|
||||
const from = source(kinds)
|
||||
callees.resolve(1, session.requests(), from.kindOf)
|
||||
await vi.waitFor(() => expect(scheduled).toEqual([5]))
|
||||
expect(changed).toBe(1)
|
||||
|
||||
kinds[40] = 'class'
|
||||
pending.shift()?.()
|
||||
await vi.waitFor(() => expect(changed).toBe(2))
|
||||
expect(from.asked).toEqual([40, 60, 40])
|
||||
expect(callees.session().calleeKind(call('Detail', 40))).toBe('class')
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user