目前ExceptionInfo被实现为一个原始构造函数,它继承自js/Error,并通过一些非常规的javascript级别的补丁来满足deftype功能的一个小子集的(主要是为了打印)。
不幸的是,这并不与cljs-devtools(链接:1)很好地配合。这个问题在我开始尝试ExceptionInfo和cljs-devtools v0.8时浮出水面,它新支持打印deftype(链接: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实现移动到deftime本身。
(链接:1) https://github.com/binaryage/cljs-devtools/issues/23
(链接:2) https://github.com/binaryage/cljs-devtools/releases/tag/v0.8.0