Context:
I am on a quest to make classes and properties that are modified by calls to `__decorate` (TypeScript experimental decorators) able to be removed as dead code by the compiler.
The decorators appear as two distinct variations.
```
let A = class A {
myMethod() { return 'a';}
}
A = __decorate([ClassDecorator], A);
__decorate([MethodDecorator], A.prototype, goog.reflect.objectProperty("myMethod", A.prototype));
```
If I extern `__decorate` with `@nosideeffects`, it is able to inline the first, but not the second call to `__decorate`, this is fine, because it is suspicious code.
If I extern it with `@modifies {arguments}`, then the compiler makes no attempt to remove either call.
I have spent a few hours attempting to add support for `@modifies {arguments}` to the `RemoveUnusedCode` pass, and I've got it mostly working, but I am wondering if anyone else would like to chime in on some design decisions before I start trying to author tests.
Proposed solution:
Allow `@modifies` to accept a parameter name, e.g. `@modifies {target}`
Only change `RemoveUnusedCode` in the simple case where there is only a either a single parameter with `@modifies {arguments}`, or there is only a single `@modifies {variable}`.
In `RemoveUnusedCode`, when it is removing an assignment, it takes into account the `@modifies` tag for determining if it should keep the RHS.
In `RemoveUnusedCode` add logic to `traverseCall` to have it remove the call if the given argument is not used. Only traverse the call in the continuation of that (if the variable is eventually used). Only support the simple case where the argument is not computed.
My reasoning for only supporting a single argument is that I don't think there is a mechanism to add a Removable that is conditional on multiple `VarInfo` being removable. Though now that I've written that out, I suppose a class that implements `VarInfo`, but is really just a collection of `VarInfo` under the hood is not unfeasible.
Does this all seem sensible? Is there something obvious I've missed?
Is there a better layer for this change to exist at (like `allArgsAreUnescapedLocal`)?
Let me know if it would be easier to talk about this in a different forum, or on a draft PR.
Thank you.
David Neil