目前ExceptionInfo以原始构造函数的形式实现,继承自js/Error,并带有一些临时的JavaScript级别补丁以满足deftype功能的一小部分需求(主要是用于打印)。
不幸的是,这并不与cljs-devtools(link: 1)协同工作。当我开始使用ExceptionInfo和 cljs-devtools v0.8(新支持打印deftype(link: 2))进行实验时,出现了这个问题。ExceptionInfo不包含getBasis,cljs$lang$type,cljs$lang$ctorStr以及类似的机制。
我提出的补丁将ExceptionInfo实现为正确的deftype,并进行了一些修改以提供向后兼容性。我非常确信我们不能打破ExceptionInfo构造函数接受3个参数并在构造函数中动态合成其他字段的当前约定。
实现细节
1) 首先,我们定义ExceptionInfo为正常的deftype(以获取模板)
2) 然后,我们在ExceptionInfoTypeTemplate中记住对ExceptionInfo的引用
3) 然后,我们使用原始构造函数重新定义ExceptionInfo,该构造函数应模仿原始行为(通过抓取新创建的js/Error实例,但是调用ExceptionInfoTypeTemplate以进行正确的deftype初始化)
4) 然后,我们将ExceptionInfoTypeTemplate的键复制到ExceptionInfo
5) 然后,我们将ExceptionInfo的原型设置为ExceptionInfoTypeTemplate的原型
6) 然后,我们将ExceptionInfo原型的构造函数修改为指向我们重新定义的构造函数
7) 然后,我们修补ExceptionInfo的原型,使其继承自js/Error(注意这将覆盖ExceptionInfoTypeTemplate - 但我们不在乎它)
这实际上为我们提供了一个正常工作的ExceptionInfo deftype,并使用定义类型的构造函数对重新定义的构造函数进行了包装,以实现向后兼容。
我们还修补了ExceptionInfo的原型,使其继承自js/Error,就像原始代码所做的那样。
注意:使用正常的工作deftype,我们可以将IPrintWithWriter和toString实现移动到deftype本身。
(link: 1) https://github.com/binaryage/cljs-devtools/issues/23
(link: 2) https://github.com/binaryage/cljs-devtools/releases/tag/v0.8.0