The problem: In advanced mode, Closure Compiler removes most (or all) cljs$lang$type properties from generated constructor prototypes. It probably thinks that they are not referenced anywhere so it is safe to remove them.
There are two functions in cljs.core which depend on cljs$lang$type test and are definitely broken in advanced mode compilation: 1. pr-writer-impl method does the check to write user-friendly constructor name 2. missing-protocol method does the check as well (used in very rare scenario)
I spent a good chunk of my day trying to find externs declaration which is IMO not possible.
None of these worked:
var cljs$lang$type; Object.prototype.cljs$lang$type;
Note: This problem is not only affecting cljs$lang$type, it affects all properties set on type prototypes via (set! ...). It does not affect code which directly calls getBasis or reads a property on a specific type (Closure compiler sees that and prevents removal). It affects all code accessing those properties via "unknown" object when Closure compiler has no information about the object and it could be of any type so it does not connect the dots.
—
A proposal for a possible solution:
1. find a way how to instruct closure compiler to not remove cljs$lang$type and friend under without changing cljs.core implementation (I failed) 2. or use aset instead of set! to prevent closure compiler to reason about those things and leave them alone 3. or some better solution?
This is a follow up to https://github.com/swannodette/mori/issues/144.
The problem:
In advanced mode, Closure Compiler removes most (or all) cljs$lang$type properties from generated constructor prototypes. It probably thinks that they are not referenced anywhere so it is safe to remove them.
There are two functions in cljs.core which depend on cljs$lang$type test and are definitely broken in advanced mode compilation:
1. pr-writer-impl method does the check to write user-friendly constructor name
2. missing-protocol method does the check as well (used in very rare scenario)
This is a test to reproduce the problem with bare clojurescript checkout:
https://gist.github.com/darwin/a83ea91f2e365946f076
I spent a good chunk of my day trying to find externs declaration which is IMO not possible.
None of these worked:
var cljs$lang$type;
Object.prototype.cljs$lang$type;
Note: This problem is not only affecting cljs$lang$type, it affects all properties set on type prototypes via (set! ...). It does not affect code which directly calls getBasis or reads a property on a specific type (Closure compiler sees that and prevents removal). It affects all code accessing those properties via "unknown" object when Closure compiler has no information about the object and it could be of any type so it does not connect the dots.
—
A proposal for a possible solution:
1. find a way how to instruct closure compiler to not remove cljs$lang$type and friend under without changing cljs.core implementation (I failed)
2. or use aset instead of set! to prevent closure compiler to reason about those things and leave them alone
3. or some better solution?