Arrow function with inner function fails to parse
pimlie opened this issue · 7 comments
The following snippet fails to parse because result.value is erroneously(?) wrapped in { ... } on line https://github.com/tunnckoCoreLabs/parse-function/blob/master/src/index.js#L119-L121
import parseFunction from 'parse-function'
parseFunction().parse(arg => new Promise(resolve => {
function inner() {}
inner()
}))babylon / @babel/parser throws the following error:
SyntaxError: Unexpected token, expected "," (1:6)
at Parser.raise (node_modules/babylon/lib/index.js:776:15)
at Parser.unexpected (node_modules/babylon/lib/index.js:2079:16)
at Parser.expect (node_modules/babylon/lib/index.js:2067:28)
at Parser.parseObj (node_modules/babylon/lib/index.js:3465:14)
at Parser.parseExprAtom (node_modules/babylon/lib/index.js:3123:21)
at Parser.parseExprSubscripts (node_modules/babylon/lib/index.js:2757:21)
at Parser.parseMaybeUnary (node_modules/babylon/lib/index.js:2736:21)
at Parser.parseExprOps (node_modules/babylon/lib/index.js:2643:21)
at Parser.parseMaybeConditional (node_modules/babylon/lib/index.js:2615:21)
at Parser.parseMaybeAssign (node_modules/babylon/lib/index.js:2562:21)Maybe just add isArrow to the if on line 119? Or might that cause problems with arrow functions in normal function bodies because the includes('=>') is too greedy and should only look at the start?
Thanks for the report.
Interesting, I'll look on it.
For some reason, wrapping it as string works.
import parseFunction from 'parse-function';
const res = parseFunction().parse(
`(arg, bar) =>
new Promise((resolve) => {
function inner() {}
inner();
})`,
);
console.log(res);
/*
{ name: null,
body:
'new Promise((resolve) => {\n function inner() {}\n\n inner();\n })',
args: [ 'arg', 'bar' ],
params: 'arg, bar' }
*/Actually, forget that. When I initially pasted it and executed it really it failed. But when it is formatted, your snippet works too.
import parseFunction from 'parse-function';
parseFunction().parse(
(arg) =>
new Promise((resolve) => {
function inner() {}
inner();
}),
);Does not fail. But you are kind of right, it's probably something with the wrapping. But it's done that way because we use .parseExpression.
This works too
parseFunction().parse(arg => {
return new Promise(resolve => {
function inner() {}
inner();
});
});but this doesn't
parseFunction().parse(arg => new Promise(resolve => {
function inner() {}
inner();
});
);So, please use Eslint and/or Prettier.
Thanks for the quick update. Actually I am using eslint already and it didnt report anytning because it has 'arrow-parens': [2, 'as-needed', { requireForBlockBody: true }], set and the rule doesnt think I need a block'ed body I guess.
-- edit --
hmm sorry, this rule is about () around the args ofc. I extend some other configs, will have a look at them what they do
-- /edit --
Really strange adding a linebreak works, from all the things I did to debug this thats one of the only things I didnt try ;)
Just wondering, if it is about the new Promise expression I would've expected the following to work too (but it doesnt):
parseFunction().parse(arg => (new Promise(resolve => {
function inner() {}
inner();
}));
);@pimlie yea, I'm not sure why it is happening too. I have a pretty big eslint config, so I'm not sure if ESLint-only approach will help either. That's one of the things why Prettier is amazing.
It's kinda strange because it's perfectly valid javascript.
'use strict'
const foo = arg => new Promise(resolve => {
function inner() {}
inner()
})
foo(123)I would've expected the following to work too
Agree on that too.
Hey, @pimlie did you found something? I'm just looking around because finished moving it to tunnckoCore/opensource#62
Nope, unfortunately not.
But in the mean time my requirements changed and I also needed to be able to parse full code snippets, not just functions, which means I am currently using babel to parse/transform the code.
So feel free to close this issue if you want and thanks again for all the feedback!