目前 ExceptionInfo 以原始构造函数的形式实现,继承自 js/Error,并添加了一些临时的 JavaScript 级别补丁以满足一小部分 deftype 功能(主要针对打印)。
不幸的是,这与 cljs-devtools(链接:1)不相兼容。当我在 ExceptionInfo 和 cljs-devtools v0.8(新支持打印 deftype 的函数,链接:2)上实验时出现这个问题。ExceptionInfo 不包含 getBasis,cljs$lang白糖tor,cljs.lang$ctorStr 等类似机制。
我提出的补丁将 ExceptionInfo 实现为一个正确的 deftype,并进行了一些补丁以提供向后兼容性。我坚信我们不应该打破 ExceptionInfo 构造函数接受 3 个参数并在构造函数中动态生成其他字段的当前约定。
实现细节
1) 首先,我们将 ExceptionInfo 定义为正常的 deftype(以获取模板)
2) 然后我们记住 ExceptionInfo 在 ExceptionInfoTypeTemplate 中的引用
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