Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specification Proposal #66

Closed
silkentrance opened this issue Mar 23, 2016 · 6 comments
Closed

Specification Proposal #66

silkentrance opened this issue Mar 23, 2016 · 6 comments

Comments

@silkentrance
Copy link

ROUTE 66 - WORK IN PROGRESS

With babylon having problems parsing decorated generator functions it seems that the current specification of a decorator is too lax and by that overly complex.

While it is surely nice to have something like

@f?f:f1

it is way too much considering the common and thus standard use cases for decorators, which are

@decorate(options)
@decorate
class Foo {
...
}

and also considering that one is currently unable to

class Foo
{
    @decorate
    * gen() { yield 1; }
}

due to the fact that the current specification is based on LeftHandSideExpression, which for example causes the babylon parser to parse this as

BinaryExpression
    left: 'decorate'
    operator: '*'
    right: 'gen()'

How about limiting decorators to specialized variants of CallExpressionS and MemberExpressionS, which are presumably the most used forms of decorators. And, with that in place, the babylon parser could be fixed in order to support decoration of generator methods.

PROPOSAL

MemberReference [Yield] :
  IdentifierName [?Yield]
  MemberReference [?Yield] [ Expression [In, ?Yield] ]
  MemberReference [?Yield] . IdentifierName [?Yield]

DecoratorCallExpression [Yield] :
  MemberReference [?Yield] Arguments [?Yield]
  DecoratorCallExpression [?Yield] Arguments [?Yield]
  DecoratorCallExpression [?Yield] . IdentifierName [?Yield]
  DecoratorCallExpression [?Yield] [ Expression [In, ?Yield] ]

Decorator [Yield] :
  @DecoratorExpression [?Yield]

DecoratorExpression [Yield] :
  DecoratorCallExpression [?Yield]
  MemberReference [?Yield]

The above will allow us to

@decorators[Symbol](options)
@decorator(options)
@lib.decorator
class Foo
{
    // not sure about this one, production rule wise that is, though
    @broker.getInstance(IFancyDecorators).decorate()
    * gen() {}
}

and so on.

RATIONALE

The current specification of LeftHandSideExpression is way too lax and will prevent users from decorating generator methods, see the referenced babylon issue above.

With Angular2 using TypeScript, the available docs do present use of above depicted two use cases only. And even in Python and frameworks thereof, you will never see anything more complex than the above two use cases. The same with annotations in Java or similar such languages, where these two use cases have been made a fixed idiom of the language, which is actually true for Python, also.

@lukescott, @wycats, @loganfsmyth, @jayphelps, @Download You have already discussed this in #23 and I think that we should discuss this further.

@Download
Copy link

@silkentrance I would fully support this change (not that I have any say in the matter mind you :) This represents the most elegant solution to the 'parentheses problem' I think. I have to admit I always have trouble reading those syntax descriptions... I would expect the literal parentheses characters ( and ) to appear somewhere in them though? This must already be in the ES spec somewhere as in constructor invocations parentheses are also optional right?

Anyway, if the syntax means what I think it does I fully agree it would be much better than left hand side expression.

I think this proposal could actually be combined with the one from #65 could it not? Because I think that being able to intercept the decoration process would be valuable in and of itself.

@silkentrance
Copy link
Author

@Download CallExpression is exactly what you have in mind. And it can be combined with either #65 or #62.

And since this is a community project we can at least try to propose, whatever the outcome will be.

@lukescott
Copy link

So I'm assuming with this the arguments are not being captured. This is simply restricting the grammar to allow generators to be decorated, right? Which would make sense.

If the arguments are being captured at the end, I would advise against it. Simply because the arguments passed in at the end should match 1:1. That's what led me to believe LeftHandSideExpression was the right solution. But I agree that it needs to be restricted to support generators.

So IMO, the result of the expression should be considered the decorator just as it was with LeftHandSideExpression. The decorator duck typing issue should be handled separately.

@silkentrance
Copy link
Author

@lukescott arguments passed to a parameterizable decorator are captured by

DecoratorCallExpression [Yield] :
  MemberReference [?Yield] Arguments [?Yield]
  DecoratorCallExpression [?Yield] Arguments [?Yield]
...

The other issue you are referring to is implementation / runtime specific and is not part of the grammar. It simply deals with the available notations one can use when using decorators.

@silkentrance
Copy link
Author

Given the new spec proposal, it will remain a LeftHandSideExpression. It seems that the fault lies in the parser transformer, in that case babel.

@silkentrance
Copy link
Author

No need to keep this open any longer. Must try convince babel to work as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants