I created this issue because I feel that the discussion in class decorator optional opts #23 has become too broad to progress further. This is intended as a much narrower problem definition. I'm hoping we can use this issue to explore solutions so we can ultimately create a very concrete proposal.
Problem
There are members in the community that want to enable their decorators to be used with and without braces alike: @deco should have the same effect as @deco(). I'll call these 'universal decorators'.
Currently, to achieve this, we need to inspect the arguments passed to the decorator and infer from those whether the function is being called as a decorator (by the runtime), or directly from client code. For this we depend on checking e.g. argument.length, typeof <argument>, etc. This creates hard to read, fragile and error-prone code.
Constraints
The discussion in #23 explores many options, but for this issue I will set up some constraints to limit options:
- Fully backwards compatible. No code changes needed.
- It should be possible to determine beyond doubt whether we are being called as decorator or not
Options
I'll kick off with two options, both maybe far from ideal, but satisfying above conditions:
Augment the arguments object
The runtime sets some flag on the arguments object it passes to the decorator, so inside the decorator we can check this flag:
function deco() {
if (arguments.decoratorInvocation) {
// called as decorator by runtime
}
else {
// called as decorator factory by client code
}
}
Temporarily augment the decoration target
The runtime sets a non-enumerable flag on the decoration target before invoking the decorator and removes it again once the decorator has run. Inside the decorator we can simply check this flag:
function deco(target) {
if (target && target.__es_decorator_invocation__) {
// called as decorator by runtime
}
else {
// called as decorator factory by client code
}
}
Feedback on these options, and of course other options, very welcome!
I created this issue because I feel that the discussion in class decorator optional opts #23 has become too broad to progress further. This is intended as a much narrower problem definition. I'm hoping we can use this issue to explore solutions so we can ultimately create a very concrete proposal.
Problem
There are members in the community that want to enable their decorators to be used with and without braces alike:
@decoshould have the same effect as@deco(). I'll call these 'universal decorators'.Currently, to achieve this, we need to inspect the arguments passed to the decorator and infer from those whether the function is being called as a decorator (by the runtime), or directly from client code. For this we depend on checking e.g.
argument.length,typeof <argument>, etc. This creates hard to read, fragile and error-prone code.Constraints
The discussion in #23 explores many options, but for this issue I will set up some constraints to limit options:
Options
I'll kick off with two options, both maybe far from ideal, but satisfying above conditions:
Augment the arguments object
The runtime sets some flag on the arguments object it passes to the decorator, so inside the decorator we can check this flag:
Temporarily augment the decoration target
The runtime sets a non-enumerable flag on the decoration target before invoking the decorator and removes it again once the decorator has run. Inside the decorator we can simply check this flag:
Feedback on these options, and of course other options, very welcome!