Skip to content
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

JS: Static initializer blocks and "for await ... of ..." #5694

Merged
merged 6 commits into from
Apr 2, 2023

Conversation

matthiasblaesing
Copy link
Contributor

This PR adds support for parsing static initializer blocks:

class Example{
  static attrib;
  static {
   this.attrib = "exampleValue";
  }
}

and "for await ... of ..." loops:

async function* foo() {
  yield 1;
  yield 2;
}

(async function() {
  for await (const num of foo()) {
    console.log(num);   // expected output: 1
    break;              // closes iterator, triggers return
  }
})();

Closes: #4262
Closes: #4757

@matthiasblaesing matthiasblaesing added JavaScript [ci] enable web job and extra JavaScript tests (webcommon/javascript2.editor) Upgrade Library Library (Dependency) Upgrade ci:dev-build [ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page) labels Mar 21, 2023
@matthiasblaesing matthiasblaesing added this to the NB18 milestone Mar 21, 2023
@matthiasblaesing
Copy link
Contributor Author

The first two commits are identical to #5677 and that PR should be merged first.

Special attention is advised for the commits f17e17d, 0b818e0 and e7a40ce. These commits import/regenerate code, that was externalized in the donation process. While Oracle was indeed not in the situation to donate the code, Apache projects can import code under MIT/BSD and UPL licenses.

The JS parser is based on GraalJS, which was later relicensed to UPL. @jtulach rebased the NetBeans specific changes onto that branch, which resulted in a uniformly UPL licensed codebase. That codebase was then further updated by me to cover more JS features. The resulting binary was already part of the release, the change is here, that now the code is also in the project.

The testfiles for the javascript2.editor were taken from external projects and licensed under the BSD/MIT license. Both can be incorporated into Apache projects, which is done now. This was necessary as the AST structure changed and thus the goldenfiles had to be regenerated.

@matthiasblaesing
Copy link
Contributor Author

@vieiro thank you for checking. I pushed an update with three more changes (to be partially squashed with their base commits):

  • I created a new formatted version of the graaljs license with the year range covering the files that are part of the first integration commit
  • I added a second commit, that also covers the new ClassElement.java file imported, to be squashed with the corresponding commit
  • I relicensed the tests to ALv2 and removed the UPL header as the author I'm in the position to do that.

This should improve the situation.

Copy link
Contributor

Choose a reason for hiding this comment

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

Wow! Thanks for BCCing me.

The resulting binary was already part of the release ... now the code is also in the project.

If Apache Foundation is OK with hosting UPL code in its repositories, then I believe this is legally OK move. Go on.

From an engineering perspective: This means NetBeans project is going to host a fork of Graal.js parser. So far NetBeans only relied on a fork of the Graal.js parser created by me. The difference is: now it is going to be easier to add further diverging commits to the fork. That may get us into problems when trying to support new features of JavaScript offered by new versions of Graal.js project.

The original plan always was to change NetBeans JavaScript Editor to work with 21.+ version of Graal.js parser. By maintaining our own fork we are diverging from that goal. Diverging may have some positive effect now, but may hurt us in the future.

Whether such a "divergence" is bad remains to be seen. Moreover it is my personal failure that I haven't managed to convince anyone in OracleLabs (probably @sdedic) to work on reworking the JavaScript support in NetBeans onto new versions of Graal.js. My bad and I have no right to complain.

Copy link
Contributor

@vieiro vieiro left a comment

Choose a reason for hiding this comment

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

  • Code provenance is crystal clear.
  • Licenses and copyrights are correct in all imported files.
  • rat and verify-libs-and-licenses pass.
  • UPL is indeed approved as a Category A license.

I have the same concern as @jtulach about maintaining a fork of this parser, but from my point of view @matthiasblaesing has been pushing JavaScript in NetBeans to the latest improvements during a long time now, no doubt he'll continue doing it and this is going to make things faster in the NetBeans side.

It would be good to coordinate to try to keep things in sync somehow, to try to reach a win-win situation.

Out of curiosity: com.oracle.js.parser.ir.PropertyNode in libs.nashorn is no more public final but it's understandable (it's required for ClassElement to compile) but, why isn't com.oracle.js.parser.js.ClassNode declared public final? Used somewhere else perhaps?

@matthiasblaesing
Copy link
Contributor Author

@jtulach thank for looking into this and no reason to apologize. The current code that is proposed to be integrated here has already an outside history, ontop of your work. I looked into the divergence between the upstream graaljs and the version you thankfully created and faced to much for me to handle. So I created my own fork (https://github.com/matthiasblaesing/graaljs-nb) and modified the parser in a manor I could manage to support new JS features. This was also motivated by the fact, that graaljs upstream does not support JSX and thus a move fully to upstream would kill that feature in NetBeans.

We can try to get the fork more in-line with upstream again and reduce differences, but I don't see us switching back to upstream again. So I agree with you and @vieiro, that better alignment would be good, I also have to be realistic what I can archive.

@matthiasblaesing
Copy link
Contributor Author

@jtulach for the "Can it be integrated?" question: The ASF 3rd party license policy lists the UPL as Category-A ("For inclusion in an Apache Software Foundation product, we consider the following licenses to be similar in terms to the Apache License 2.0") https://www.apache.org/legal/resolved.html#category-a).

I'd like to integrate as is, do you object or is it ok from your perspective?

BSD and MIT licensed code may be directly included.
UPL licensed code can be directly imported and this simplifies
development.

The code is identical with:

https://github.com/matthiasblaesing/graaljs-nb

Tag: graaljs-parser-1.2
class Example{
  static attrib;
  static {
   this.attrib = "exampleValue";
  }
}

As a side effect the classElements field of the ClassNode switched from
being a List of PropertyNodes to a List of ClassElements.

The use sites in the codebase and the unittests, that verify the AST
were adjusted accordingly.

Closes: apache#4262
async function* foo() {
  yield 1;
  yield 2;
}

(async function() {
  for await (const num of foo()) {
    console.log(num);   // expected output: 1
    break;              // closes iterator, triggers return
  }
})();


Closes: apache#4757
As the author I'm in the position to do this.
@matthiasblaesing
Copy link
Contributor Author

I did the squashing and will merge tomorrow once the tests are green.

@matthiasblaesing matthiasblaesing merged commit 163c2d5 into apache:master Apr 2, 2023
@matthiasblaesing matthiasblaesing deleted the js_improvements2 branch April 7, 2023 10:15
@paulongithub
Copy link

I still have this error in Netbeans 17. Is there something I need to do to the IDE to make it recognise for await in an async function? Note, code runs fine. It's just showing the row and file in error in the IDE.

@matthiasblaesing
Copy link
Contributor Author

This is tagged NB18, it is not part of NB17.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ci:dev-build [ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page) JavaScript [ci] enable web job and extra JavaScript tests (webcommon/javascript2.editor) Upgrade Library Library (Dependency) Upgrade
Projects
None yet
Development

Successfully merging this pull request may close these issues.

JavaScript to support "for await of" Support JavaScript static initializer blocks for JS Classes
4 participants