-
Notifications
You must be signed in to change notification settings - Fork 64
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
Support Async/Await based on #12 #125
base: master
Are you sure you want to change the base?
Conversation
Now that I think about it, should it be the responsible of buble to transpile async code by default? I’m happy to introduce a “dangerous” flag for it? What do you guys think? |
Need some tests for:
Also, in this test case, could we get |
{ | ||
description: 'transpiles await arrow function call', | ||
input: `async () => await a()`, | ||
output: `!function() { return Promise.resolve().then(function() { return 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.
What's the point of !function
? Just to draw attention that it's not being used?
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 turns it from a function declaration into an expression, see: https://stackoverflow.com/questions/3755606/what-does-the-exclamation-mark-do-before-the-function
As for why I'm not entirely sure.
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.
The input is a function expression, too.
Is this going to be released some day? It's kinda good stuff but seems like no one is going to merge and release it... |
@mrTimofey Lots of edge cases are unaccounted for in this PR, and the author is MIA. |
please add test making sure this works: this doesn't work correctly in Bable, and it caused some nasty bugs for us. |
description: 'transpiles await function call with more than one line of code', | ||
input: `async function f() { await a(); thing(); await a2(); stuff(); await a3(); await a4(); }`, | ||
output: `function f() { return Promise.resolve().then(function() { return a(); }) .then(function() { thing(); }) .then(function() { return a2(); }) .then(function() { stuff(); }) .then(function() { return a3(); }) .then(function() { return a4(); }).then(function() {}) }` | ||
} |
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.
there is not test that verifies return values and closures
{
description: 'transpiles await function call with normal return statement',
input: `async function f() { var x = 1; await a(); return x; }`,
output: `...`
},
Sorry guys seems this PR is far from perfect, I have only taken it from an existing PR. Will try my best to resolve. |
src/support.js
Outdated
} | ||
}; | ||
|
||
export const features = [ | ||
'arrow', | ||
'asyncAwait', | ||
'classes', | ||
'computedProperty', | ||
'conciseMethodProperty', |
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 whole file can stay as it is, since I already added asyncAwait
.
src/index.js
Outdated
@@ -15,8 +15,8 @@ const dangerousTransforms = ['dangerousTaggedTemplateString', 'dangerousForOf']; | |||
export function target(target) { | |||
const targets = Object.keys(target); | |||
let bitmask = targets.length | |||
? 0b11111111111111111111 | |||
: 0b01000000000000000000; |
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 change is not necessary anymore.
.eslintrc
Outdated
@@ -5,6 +5,7 @@ | |||
"semi": [ 2, "always" ], | |||
"keyword-spacing": [ 2, { "before": true, "after": true } ], | |||
"space-before-blocks": [ 2, "always" ], | |||
"space-in-parens": [ 2, "never" ], | |||
"no-mixed-spaces-and-tabs": [ 2, "smart-tabs" ], | |||
"no-cond-assign": [ 0 ] | |||
}, |
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 should be a separate change.
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.
Needs more work here but excited to see the feature land some day!
const last = this.body[this.body.length - 1]; | ||
const hasOnlyOneLine = this.body.length === 1; | ||
|
||
// TODO refactor :) |
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.
Refactor how? Who wrote this comment?
Better refactor now before merging, as later it will most likely not ever be refactored.
} | ||
|
||
} else if (this.parent.type === 'ArrowFunctionExpression') { | ||
// TODO merge with ^ |
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.
TODOs should be new issues IMO, and not included in the code.
export default class AwaitExpression extends Node { | ||
static removeAsync(code, transforms, async, start, callback = noop) { | ||
if (transforms.asyncAwait && async) { | ||
code.remove(start, start + 6); |
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.
Magic number 6 is mysterious here. Better as named variable, or with a comment?
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.
could this be "async ".length?
Is this ever going to be merged? |
@dy It looks like the author of this PR @Van-Nguyen is not able to put in more time here and wrap it up. Someone else probably needs to make a new PR based on this one, and clean it up. I'm not sure who. |
I've rebased the commit and already merged the unrelated linting part as acd791f. |
const hasOnlyOneLine = this.body.length === 1; | ||
|
||
// TODO refactor :) | ||
if (this.parent.type === 'FunctionDeclaration') { |
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 does not handle FunctionExpression
s.
if (this.parent.type === 'FunctionDeclaration') { | ||
if (hasOnlyOneLine) { | ||
if (first.type === 'ReturnStatement') { | ||
code.insertLeft(first.argument.start, 'Promise.resolve().then(function() { '); |
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.
insertLeft
has been replaced by appendLeft
.
|
||
transpile (code, transforms) { | ||
AwaitExpression.removeAsync(code, transforms, true, this.start, () => { | ||
code.insertLeft(this.argument.start, 'return '); |
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 handles the expression as though it was a statement. See for example async () => await 1 + await 2
.
@KutnerUri @aleclarson Could you open pull requests adding tests for the cases you mentioned to |
@adrianheine - ok! thinking about the tests, I think variables should be hoisted to the top of the function, otherwise it is going to be very difficult to transpile. I think we need to add 'run code' tests, with expected results instead of expected transpiled. |
@KutnerUri No, there is already a file |
yes, tests on the produced code are a must, but the code should also pass correctness tests. so should I just replace errors in |
ok so I went ahead and did that. But I don't seem to be able to push? Should I clone the project and send a pull request to master or something like that? |
Yes, you have to clone the project and open a PR to master. |
created - #170 I am thinking about
But this does not:
It breaks code symmetry, and will require scaffolding when working with code fragments. So, I'm suggesting that Bublé will support this, but with a flag. It could be
|
Current master should already support top-level |
not to derail the effort here, but there's a babel plugin with extensive support that might be easier to port than duplicating the effort to add all cases it already handles? https://github.com/rpetrich/babel-plugin-transform-async-to-promises |
When running
@adrianheine Do you know how I could fix this? edit: Nevermind, I think I can figure it out. |
It's been a very long time since there has been activity to this pull request #12 I have cleanly integrated the code using latest master with minor improvements and seems to pass all tests. Hope this is appreciated and merged to codebase as I believe many have requested this feature.
Closes #90, Closes #108, Closes #109, Closes #113