47 lines
2.2 KiB
TypeScript
47 lines
2.2 KiB
TypeScript
import type { BlockKind, CallFacts } from './contract'
|
|
import { DeferredAnswers } from './deferredAnswers'
|
|
|
|
/**
|
|
* 调用的名字的定义是哪种块(SourceDocument.calleeKind):翻译插件靠它分新建对象还是调用函数。
|
|
* 按被调用的表达式原文记(`user_service.update_user`),同一份文档里写法一样的调用按一处查;问语言扩展时问它最后那个名字。这里不碰 VS Code。
|
|
*/
|
|
|
|
/** 问的一次调用:被调用的表达式原文,和它最后那个名字在源码里的下标。 */
|
|
export interface CalleeRequest { callee: string, offset: number }
|
|
|
|
/** 这份文档里 offset 处名字的定义是哪种块:查了没有是 null,语言扩展没答(还没起来)是 undefined。 */
|
|
export type CalleeSource = (offset: number) => Promise<BlockKind | null | undefined>
|
|
|
|
/** 排一遍视图数据用的:交给翻译插件的 calleeKind,和这一遍问了哪些调用。 */
|
|
export interface CalleeSession {
|
|
calleeKind: (call: CallFacts) => BlockKind | undefined
|
|
requests: () => CalleeRequest[]
|
|
}
|
|
|
|
/** 一份打开着的文档里调用的名字查到定义成哪种块;什么时候查、查到了怎么叫宿主重排见 DeferredAnswers。 */
|
|
export class DocumentCallees {
|
|
private readonly answers: DeferredAnswers<CalleeRequest, BlockKind>
|
|
|
|
constructor(changed: () => void, delays?: readonly number[], schedule?: (run: () => void, ms: number) => ReturnType<typeof setTimeout>) {
|
|
this.answers = new DeferredAnswers(({ callee }) => callee, (a, b) => (a ?? null) === (b ?? null), changed, delays, schedule)
|
|
}
|
|
|
|
/** 被调用的不是名字(没有 CallFacts.name)的不问,按调用算。 */
|
|
session(): CalleeSession {
|
|
const session = this.answers.session()
|
|
return {
|
|
calleeKind: call => call.name ? session.ask({ callee: call.callee.text, offset: call.name.startIndex }) : undefined,
|
|
requests: session.questions,
|
|
}
|
|
}
|
|
|
|
/** 查 version 这一版问的调用:这个版本查过的不再查。 */
|
|
resolve(version: number, requests: readonly CalleeRequest[], source: CalleeSource): void {
|
|
this.answers.resolve(version, requests, ({ offset }) => source(offset))
|
|
}
|
|
|
|
dispose(): void {
|
|
this.answers.dispose()
|
|
}
|
|
}
|