driver 子系统
packages/ttsc/driver 是 ttsc Go 侧的编译器外观层(facade)。它是整个引擎里唯一按设计允许直接 import shim/* 的包(见 driver/host.go:1 的包注释);下游所有代码消费一个与 shim 无关的小接口 *driver.Program。
理解 driver 就理解了"ttsc 如何在 tsgo 的 Program/Checker 之上叠加自己的行为"。
职责边界
driver 拥有:
- 用 tsgo 的
shim/compiler建Program、租用单个Checker(program.go)。 - 解析 tsconfig(含
extends、CLI flag 覆盖层)(program.go::ParseTSConfig)。 - 把诊断翻译成与 shim 无关的
Diagnostic结构,并提供富文本/纯文本渲染(program.go)。 - 两条 emit 路径:文本级重写(
rewrite.go)与 AST 集成的 emit transformer(emit_plugin.go)。 - 链接插件的注册、配对与生命周期 hook(
plugins.go)。 - 源码预置(source preamble)注入(
program.go::sourcePreambleFS)。 - 增量类型检查的常驻
Session(session.go)。 - sourcemap 前导调整(
sourcemap_preamble.go、overlay.go)。
driver 不拥有:决定加载哪些插件(JS 的活)、解析 npm 依赖、写 emit 文件到用户项目树(公共 API 走内存捕获)。
文件一览
子页
- Program 与 Checker:
LoadProgram全流程、单 checker 约束、诊断过滤、tsgo flag 覆盖。 - Emit 与重写:两条 emit 路径的设计对比、并行 emit 的串行化、文本 splice 的脆弱面。
- 链接插件:
SourcePreamblePlugin/ProgramPlugin/EmitTransformPlugin三类 hook 与按顺序配对。 - 增量 Session:为什么 transform 不能复用热程序、type-check 复用怎么做。
核心数据结构:Program
Program(program.go:186)是下游唯一看到的类型。它持有 tsgo 的真实 Program 与一个租来的 Checker,外加链接插件状态。Close() 释放 checker 池租约(checkerRelease)。
下游代码(cmd/ttsc、internal/graph、utility)只通过 Program 的方法(SourceFiles()、Diagnostics()、EmitAll()、ApplyLinkedPlugins() 等)工作,看不到任何 shim 类型。
设计取舍速览
最容易在 tsgo 升级时炸的地方
driver 是 typescript-go 知识的唯一汇聚点,因此也是升级最脆弱处:
emit_plugin.go手工组装 tsgo 的 emit 管线(GetSourceFilesToEmit、GetScriptTransformers、PrintFileWithSourceMap);任何 tsgo emit 内部重构都可能在这里断。guardedEmitResolver(emit_plugin.go:47)包住 const-enum 内联器的GetConstantValue,对插件构造的合成节点做 panic 恢复——这是对 tsgo checker 行为的脆弱假设。restoreOriginalDeclarationSymbols(emit_plugin.go:112)手工把 binder symbol 从原节点拷到插件重建的合成节点上,绕过 emit resolver 的 nil panic。
升级 tsgo 时优先回归这三处。详见 Emit 与重写。