Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

JSUtils modification to handle es6 constructs #13635

Merged
merged 5 commits into from
Aug 28, 2017
Merged

Conversation

swmitra
Copy link
Collaborator

@swmitra swmitra commented Aug 23, 2017

This PR will replace the existing regex based function def extraction with Acorn and also adds the capability to identify classes and methods (es6). Our current implementations is having some limitations and issues. One issue which is noticed during my dev test is wrong location information for function definition. Consider the following snippet -

Handsome.prototype.some = function () {
}

From the function/type list when we select some, instead of highlighting the member "some" , "some" from Handsome gets highlighted. With the new implementation, this issue is resolved as we get location information from the AST generated by Acorn.

Couple of other observations which are actually open questions to all reviewers, there are some odd syntax which is considered valid in our current regex based implementation. Consider the following snippets -

something: function () {
}
function hello() {
     something: function () {
     }
}   

It has been handled in the new implementation to let the existing tests pass, should we consider this to be valid?

Second observation is regarding a broken syntax for which we have a negative test case(this single test fails in the new implementation), but in the new implementation, Acorn parses it successfully. The snippet in consideration is -

function invalid name () {
}

How do we handle this case?

@zaggino @petetnt @ficristo @marcelgerber Can you please have a look at this PR?

Copy link
Collaborator

@petetnt petetnt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The functionality works great and I only have couple of nits.

match;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: whitespace


PerfUtils.addMeasurement(PerfUtils.JSUTILS_REGEXP);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: whitespace

/**
* Set of utilities for simple parsing of JS text.
*/
define(function (require, exports, module) {
"use strict";

var _ = require("thirdparty/lodash");
var Acorn_Loose = require("node_modules/acorn/dist/acorn_loose");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: Should we be consistent and use AcornLoose and ASTWalker?

@petetnt
Copy link
Collaborator

petetnt commented Aug 23, 2017

FWIW I think all of those three broken ones should be invalid

functionList.push(new FileLocation(null, funcEntry.lineStart, chFrom, chTo, funcEntry.name));
var chFrom = funcEntry.columnStart;
var chTo = funcEntry.columnEnd;
functionList.push(new FileLocation(null, funcEntry.nameLineStart, chFrom, chTo, funcEntry.label || funcEntry.name));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead, you can write directly
functionList.push(new FileLocation(null, funcEntry.nameLineStart, funcEntry.columnStart, funcEntry.columnEnd, funcEntry.label || funcEntry.name));

@swmitra
Copy link
Collaborator Author

swmitra commented Aug 24, 2017

@petetnt Addressed code review NITs . Added test cases for classes, inheritance, getter/setter and static methods.

var _ = require("thirdparty/lodash");
var _ = require("thirdparty/lodash"),
AcornLoose = require("node_modules/acorn/dist/acorn_loose"),
ASTWalker = require("node_modules/acorn/dist/walk");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm quite sure this will not work on dist.
You should add some logic here:

Maybe going forward we should use more webpack, but in another PR.

functionName = (match[2] || match[5]).trim();


var AST = AcornLoose.parse_dammit(text, {locations: true});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this work by checking indentation of the code.
So you need

  1. use always first Acorn.parse and if it fails use AcornLoose.parse_dammit
  2. add some tests of code not indented correctly (and / or without indentation at all)

function <functionName> () {}
*/
FunctionDeclaration: function (node) {
if (node.id.name !== '✖') { // A hack to reject anonymous declarations
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Acorn use '✖' I don't think the commit is really good.
Maybe something saying that Acorn use '✖' to detect anonymous declarations and we want to skip them.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider this snippet -

key: function () {
}

This is actually a broken syntax and acorn can't parse it, but acorn_loose does it. FYI the acorn_loose code which uses this as is -

LooseParser.prototype.dummyIdent = function dummyIdent () {
  var dummy = this.dummyNode("Identifier");
  dummy.name = "✖";
  return dummy
};

The problem here is FunctionDeclaration walk option catches this and if I don't have a check, ends up putting "✖" as a function name. To actually put key as function name we have a LabeledStatement walk option. For your reference this is how the node looks like -
image

This is not exactly a normal case but rather a broken syntax handler where this gets initialized with this name. I am not sure of any better way to handle this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @swmitra I meant comment not commit !
I simply want you to rephrase the commit to avoid the word hack, since is how acorn works.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sorry @ficristo , misinterpreted the comment 😞 . I have changed the comment in the code now and also added the ArrowFunctionExpression construct along with addressing other code review comments and test cases.

@ficristo
Copy link
Collaborator

Is JSUtils supposed to work on code not completed? If so you need to add some tests.

@ficristo
Copy link
Collaborator

Is it possible to detect arrow functions? i.e. var foo = () => {}
Does it work with async functions? i.e. var foo = { async bar() {} };

@petetnt
Copy link
Collaborator

petetnt commented Aug 24, 2017

Arrow functions (and functionProperties) worked when I tested, I assume that it works with async ones too

@ficristo
Copy link
Collaborator

ficristo commented Aug 24, 2017

worked when I tested

Great! Make sure to add some test (if there aren't)

@swmitra
Copy link
Collaborator Author

swmitra commented Aug 24, 2017

This never got handled though -

var foo = () => {}

Adding a walk option for this now 😃

@swmitra
Copy link
Collaborator Author

swmitra commented Aug 24, 2017

@ficristo Can you please have a look at the change list again? I have addressed all the comments .

@ficristo
Copy link
Collaborator

Are generator functions supposed to be handled? If so, please add a test.

I just want to note I actually didn't test this PR, but the code seems good.

@saurabh95 saurabh95 merged commit 9281909 into master Aug 28, 2017
@swmitra swmitra added this to the Release 1.11 milestone Sep 12, 2017
@ficristo ficristo deleted the swmitra/ES6Support branch September 19, 2017 18:45
ficristo pushed a commit to quadre-code/quadre that referenced this pull request Nov 26, 2017
* JSUtils modification to handle es6 constructs

* Addressed review comments and added es6 test cases

* Address Code review comments and add support for ArrowFunctionExpressions with new test case

* Update comments

* Refactor to remove extra variables
ficristo pushed a commit to quadre-code/quadre that referenced this pull request Nov 26, 2017
* JSUtils modification to handle es6 constructs

* Addressed review comments and added es6 test cases

* Address Code review comments and add support for ArrowFunctionExpressions with new test case

* Update comments

* Refactor to remove extra variables
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants