-
Notifications
You must be signed in to change notification settings - Fork 2k
Selectively ignore CS-only keywords in ES imports and exports #4347
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this!
This should also be submitted against master, this is basically a bug in the current modules implementation.
test/modules.coffee
Outdated
| eq toJS(input), output | ||
|
|
||
| test "CS only keywords can't be used as unaliased names in import lists", -> | ||
| throws -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and the following test should be in error_messages.coffee.
src/lexer.coffee
Outdated
| @token 'AS', id | ||
| return id.length | ||
| if id is 'as' and @seenImport | ||
| # loop hack |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
“Loop hack”? Why isn’t this block:
if id is 'as' and @seenImport
if @value() is '*'
@tokens[@tokens.length - 1][0] = 'IMPORT_ALL'
else if @value() in COFFEE_KEYWORDS
@tokens[@tokens.length - 1][0] = 'IDENTIFIER'
@token 'AS', id
return id.lengthThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the code is more selective with the loop. In your case when encountering an as after an { on an import line, the as would always become an AS token, which would prevent its currently allowed usage as an import variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure about that?
coffee -ne "import { as as as } from 'lib'"
Block
ImportDeclaration
ImportClause
ImportSpecifierList
ImportSpecifier IdentifierLiteral: as IdentifierLiteral: as StringLiteral: 'lib'
See https://github.com/jashkenas/coffeescript/blob/master/test/modules.coffee#L587-L609
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think, are you using a version of CS with that code in it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That’s from 1.11.1. See the link.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I haven't tried it but I think those tests would fail with the code you're suggesting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those tests pass in 1.11.1. They should still pass after your PR. I didn’t test the code I put in the comment, it was just meant to pose a question about the loop. I don’t like the idea of loop, which becomes while (true). I feel like whatever you’re trying to do here, you should be able to do with a simple if/else tree. Is there a reason we need a loop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not ideal, I basically wan't to reach the @token 'AS', id and return only for a select few token types. So basically if none of the conditionals run, I want to skip that part and not return. Since CS doesn't have goto, I used this as a hack.
It's possible to do it without a loop, but it would require more code.
src/lexer.coffee
Outdated
| if @value() is '!' | ||
| poppedToken = @tokens.pop() | ||
| id = '!' + id | ||
| unless @exportList and id in COFFEE_KEYWORDS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Combine these two lines:
if tag is 'IDENTIFIER' and (id in JS_KEYWORDS or id in COFFEE_KEYWORDS) and
not (@exportList and id in COFFEE_KEYWORDS)|
If I |
|
You would need to do |
|
@lydell Right, so this PR prevents that. |
|
I moved the error tests to |
|
The following is valid JavaScript, according to Babel: import { if } from 'lib';I’m not sure how you would access this |
|
This looks good to me. @lydell, @jashkenas? |
|
@GeoffreyBooth I don't think we need to worry about it for now, plus Babel isn't always standards compliant anyway. |
|
Looks good to me too. Good work! |
@GeoffreyBooth To address your JS interoperability concerns in #3757, this PR enables usage of CS-only keywords as local names in import lists and as any name in export lists. This will enable people to do the following