Skip to content
This repository has been archived by the owner on Feb 8, 2020. It is now read-only.

Arrow function with inner function fails to parse #179

Open
pimlie opened this issue Mar 14, 2019 · 7 comments
Open

Arrow function with inner function fails to parse #179

pimlie opened this issue Mar 14, 2019 · 7 comments

Comments

@pimlie
Copy link

pimlie commented Mar 14, 2019

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?

@tunnckoCore
Copy link
Owner

Thanks for the report.

Interesting, I'll look on it.

@tunnckoCore
Copy link
Owner

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' }
*/

@tunnckoCore
Copy link
Owner

tunnckoCore commented Mar 14, 2019

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.

@pimlie
Copy link
Author

pimlie commented Mar 14, 2019

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();
  }));
);

@tunnckoCore
Copy link
Owner

tunnckoCore commented Mar 14, 2019

@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)

@tunnckoCore tunnckoCore added bug and removed bug labels Mar 14, 2019
@tunnckoCore
Copy link
Owner

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

@pimlie
Copy link
Author

pimlie commented Oct 19, 2019

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!

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

No branches or pull requests

2 participants