-
Notifications
You must be signed in to change notification settings - Fork 143
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
fix: #322 #337
fix: #322 #337
Conversation
I'll need some more context on how Sucrase works to move this further. |
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! Sigh, this is getting into some details...
If you take a look at RootTransformer.processBalancedCode
, it's tracking all parentheses and braces so that it can stop when it sees a )
or }
that it hasn't seen. For example, this is useful when walking classes and functions so we can stop at the correct }
and know that we're at the end of the class/function. But that assumes that the this.processToken()
call will never consume an unbalanced number of parens, and I guess your change is the first one to do that.
Two high-level options that I can think of:
- Change the
processToken
contract to return how many parens and braces of each type it consumed, so thatprocessBalancedCode
can update accordingly. - Rather than directly consuming the close-parens and replacing the open-paren, your code could just "leave a note" in class state and then replace the open-paren in the later call to
CJSImportTransformer.process
. - Rework the way of doing brace and paren depth. If it was kept in more of a shared place, it could maybe be updated by
rootTransformer.processToken
and others. - Get rid of brace and paren accounting in the first place. It might be needed with some smarter info from the parser.
Option 2 seems like maybe the best one here. I'll also keep thinking if there are other options.
Oh, and this might be an argument for going back to the _id
strategy, since that one is more self-contained syntactically.
Are there two calls to each transformer's |
I think option 2 is the best... of those options. This is a good argument for conditionally replacing based on existence of closing parens, as I mentioned earlier. |
Generally speaking, The implementation is at What I'm saying is that |
I'm not totally sure, but my impression is that with the |
1d61f86
to
b87ee4a
Compare
Take 2 is ready. Apart from |
I also have it default to |
b87ee4a
to
e854781
Compare
e854781
to
a386945
Compare
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.
Some comments. As you may have noticed, Sucrase can get pretty complex 😄. I want to be really cautious about adding more complexity, and I think some of your code adds complexity to make the output code a little cleaner, which I'd rather avoid unless there's a strong justification for it.
Also, looks like tests are failing because this breaks when used with constructors (new f()
becoming new _myModule.f.call()
, which isn't valid). Turns out that's an example of the case I was previously worrying about where the (
isn't a plain function call.
I'm still thinking the _id
approach may be nicer since it has much less need to interpret the tokens around you. Worth considering.
I also realized that this code already doesn't handle TypeScript type arguments: https://sucrase.io/#code=%0Aimport%20f%20from%20'f'%3B%0A%0Af%3Cnumber%3E() . It would be great if this change either handled that or was built in a way that didn't make it harder to fix that in the future.
Take 3. Cleaner than ever. LGTM? |
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.
Cool, getting close, but looks like this still breaks the build because new
expressions get transformed wrong. I think it's safe to just do the (0, f)
strategy for those, and you can just look backward to see if there's a previous new
token to detect that.
if (this.tokens.tokens[possibleOpenParenIndex].type === tt.parenL) { | ||
this.tokens.replaceToken(`(0, ${replacement})`); | ||
if (this.tokens.tokenAtRelativeIndex(1).type == tt.parenL) { |
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.
===
please. (This breaks lint, and you should be able to do yarn test
locally to catch it.)
Also, maybe you could do this.tokens.currentIndex() + 1 === possibleOpenParenIndex
?
I think you should be able to handle the new
issues by just making sure the prior token is not new
in this conditional.
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.
Sorry, I live on the edge. Will fix it. (regarding yarn test
: I've been using jest -i
with a jest.config.js
I setup, because I can't stand mocha)
Also, maybe you could do this.tokens.currentIndex() + 1 === possibleOpenParenIndex?
Nice! At this point, we could just merge it and you fix the nit picks. :P
Test case for Now using |
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.
Looks like new
parsing is busted 😳 . From https://sucrase.io/#compareWithBabel=false&showTokens=true&code=const%20a%20%3D%20new%20B()%3B , the new
token is listed as an identifier token with name "new" when actually it should be a _new
token.
Looks like this change to src/parser/traverser/expression.ts is a quick fix that doesn't break tests, and if you do that, it should hopefully fix your stuff.
function parseNew(): void {
- parseIdentifier();
+ expect(tt._new);
if (eat(tt.dot)) {
Consider it done |
Codecov Report
@@ Coverage Diff @@
## master #337 +/- ##
==========================================
+ Coverage 77.47% 77.64% +0.17%
==========================================
Files 41 42 +1
Lines 5305 5351 +46
Branches 1289 1304 +15
==========================================
+ Hits 4110 4155 +45
- Misses 827 829 +2
+ Partials 368 367 -1
Continue to review full report at Codecov.
|
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.
Cool, LGTM, thanks!
((a))(); | ||
a(b)(); | ||
(a + b)(); | ||
new (a)(); |
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.
Technically this doesn't exercise your case, since it's surrounded by parens here, but no big deal.
@aleclarson published in 3.7.1! Thanks for working through all of the details! |
Cheers! |
This is a work-in-progress. Currently, it spits out an error.
Fixes #322