tunnckoCore/parse-function

ES2015+ Support

Closed this issue · 14 comments

cmtt commented

Hello tunnckoCore,

I am currently using parse-function to extract function parameters in "gulp-di". Under certain circumstances, it might not support ES2015+ code, as its dependency parse-function seems currently to be limited to ES5 function declarations.

Gulp can be used in conjunction with ES2015 code in two ways:

  1. Writing ES2015+ code - the "gulpfile.js" would be written in ES2015+, as Node.js supports already a subset of the new standard.
  2. Writing ES2015+ code using the "Babel" transpiler - the "gulpfile.babel.js" and all imported modules would be transpiled back to ES5 code. In this case, parse-function would work as intended.

Do you plan adding support for the new standard?

I am currently experimenting with replacing parse-function with ECMAScript parsers like acorn or esprima, but it seems like an overkill to me.

The following links might be useful:

Hm, yea, I'll do something. It was in my mind and was discussed somewhere in the issues around me.
So yea, thanks using it :)

Cheers,
Charlike.

cmtt commented

Thanks a lot for working on this issue! 👍

Thanks for the bump, I'll push something tonight.

Hm.. Okey I'm working on function-regex and almost done..
Facing only one problem there: the "body" matching group would have { and } which won't be so nice thing.

http://regexr.com/3clpp or:

var fnRegex = /^(?:function\s*([\w$]*)\s*)*\(*([\w\s,$]*)\)*(?:[\s=>]*)(.*)$/

// (a, b) => a * b
// () => 42
// () => function () {}
// () => x => x * x
// (x) => {var abc = function () {return x};\n var foo = true;}
// y => x => x * y
// x => x * x
// x => { return x * x }
// (x, y) => { return x + x }

function named (z, y) { return z / y }

named.toString().match(fnRegex())
// => [1] = 'named'
// => [2] = 'z, y'
// => [3] = '{ return z / y }'

Any ideas?

@cmtt i'm done, just waiting inspect-js/is-arrow-function#2 if it will be merged.

Haha, okey... Redone with just walking each character with loop - no dependencies. I should test the performance against regex approach, lol.

@cmtt say what you think.

Changes (no breaking changes)

  • added value and orig hidden properties
    • value string representation of the given value (string or function)
    • orig original representation of the value, if function - function, if string - string
  • arguments and parameters properties are now hidden, but they are there in object

I will update docs, write some benchmarks, release and publish as soon as possible, but i have to write coursework for the university. But it is stable, you can use the repo where you need.

Cheers 🍻,
Charlike!

Resolved. See the change log for more detailed info. Released and published as v2.1.0.

@cmtt thanks!

cmtt commented

Hello Charlike,

thanks a lot for the hard work in resolving this issue.
I didn't have had the time to reply earlier.

As mentioned, concerns about the performance might be reasonable.
Nevertheless, string operations have been optimized the recent years in browsers and users still have a choice by using the previous dependency "parse-function" instead.

I will check the recent changes soon for my library.

Again, thanks a lot!

cmtt commented

Hi @tunnckoCore,

it seems that the chosen solution might not be as error-prone as the previous regular expression solution.

Consider this function (it was shortened):

var fn = function (gulp, basePath, configuration) {
  gulp.task('karma', function (done) {
    server.on('run_complete', function (browers, results) {
      var hasError = results.failed > 0;
    });
  });
}

parse-function returns the following object:

{ name: 'anonymous',
  body: ';\n    });\n  });\n',
  params: 'unction (gulp, basePath, configuration) {\n  gulp.task(\'karma\', function (done) {\n    server.on(\'run_complete\', function (browers, results) {\n      var hasError = results.faile',
  args:
   [ 'unction (gulp',
     'basePath',
     'configuration) {\n  gulp.task(\'karma\'',
     'function (done) {\n    server.on(\'run_complete\'',
     'function (browers',
     'results) {\n      var hasError = results.faile' ] }

Interestingly, when I change the line var hasError = results.failed > 0; to something else, it works flawlessly.

I will see if I can do something about that, it might be useful to check more edge cases

cmtt commented

Apparently, the parser doesn't check for the equals sign, thus a line like var hasError = results.failed > 0; might be interpreted as an arrow function.

The majority of string parsers I know implement a variable or method to peek at least one character ahead. I guess, you might want to implement a peek() function or a variable containing the next character when you are parsing the function body, too

👍 and #5 (comment) and i've just opened #7

cmtt commented

You rock. Thank you a lot!

@cmtt hahah, thanks.

Hope latest release (v2.2.2) works for everyone.