目前,ExceptionInfo以原生构造函数的形式实现,继承自js/Error,并对JavaScript级别进行了一些临时的修补,以满足deftype功能的一小部分需求(主要是用于打印)。
不幸的是,这与cljs-devtools(链接:1)不兼容。当我在尝试使用ExceptionInfo和新的支持打印deftype的cljs-devtools v0.8时,这个问题出现了。(链接: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,该构造函数包装了deftype的构造函数以实现向后兼容。
我们还修补了ExceptionInfo的原型,使其以与原始代码相同的方式从js/Error继承。
注意:有了正常工作的deftype,我们可以将IPrintWithWriter和toString实现移动到deftype本身中。
(链接:1) https://github.com/binaryage/cljs-devtools/issues/23
(链接:2) https://github.com/binaryage/cljs-devtools/releases/tag/v0.8.0