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

ES2020 Feature: BigInt #1988

Open
6 tasks
JosephPecoraro opened this issue Aug 15, 2019 · 8 comments
Open
6 tasks

ES2020 Feature: BigInt #1988

JosephPecoraro opened this issue Aug 15, 2019 · 8 comments

Comments

@JosephPecoraro
Copy link
Contributor

JosephPecoraro commented Aug 15, 2019

Syntax:

New NumericLiteral syntax with a n suffix. Only decimal numbers with a suffix are valid. LegacyOctal or leading zeros are not valid.

123n

Grammar changes are to NumericLiteral. Basically allowing the BigInt n suffix on modern binary, octal, and hex numbers, or non-legacy-octal decimal literals.

  NumericLiteral::
      LegacyOctalIntegerLiteral
      DecimalLiteral
+     DecimalIntegerLiteral BigIntLiteralSuffix
+     NumericLiteralBase
+     NumericLiteralBase BigIntLiteralSuffix
-     BinaryIntegerLiteral
-     OctalIntegerLiteral
-     HexIntegerLiteral
 
+ NumericLiteralBase::
+     BinaryIntegerLiteral
+     OctalIntegerLiteral
+     HexIntegerLiteral
+ 
+ BigIntLiteralSuffix  ::  n

Spec:

TC39:
https://github.com/tc39/proposal-bigint
https://tc39.es/proposal-bigint/

ESTree:
https://github.com/estree/estree/blob/master/es2020.md


Literal

extend interface Literal <: Expression {
    type: "Literal";
    value: string | boolean | null | number | RegExp | bigint;
}
  • value property can be a BigInt value to represent BigInt literals
    such as 100n.

BigIntLiteral

interface BigIntLiteral <: Literal {
  bigint: string;
}
  • bigint property is the string representation of the BigInt value.
    It doesn't include the suffix n.
  • In environments that don't support BigInt values, value property will be
    null as the BigInt value can't be represented natively.

Additional considerations

  • Supported in Chrome and Firefox. Experimental in WebKit
  • Supported in Node

Remaining Tasks:

  • Add new BigIntLiteral node (nodes.ts, docs/syntax-tree-format.md)
  • Update Scanner (scanner.ts changes for n numeric suffix)
  • Update Parser (parser.ts to create a BigIntLiteral node for those numeric literals)
  • Provide Unit Tests and Coverage (see below)
  • Update test262 (~test262.git#2ee3864136) / test262-stream (~1.3.0) (note that test.attrs.negative.phase === 'early' should also now handle test.attrs.negative.phase === 'parse')
  • Handle runtimes where globalThis.BigInt is available and not available (may require updating typescript to ~3.4

Test Cases

Valid:

0n
123n
0x123n
0o123n
0b101n

Invalid:

1.1n
1e1n
01n // Leading Zero (legacy hex) does not allow it
00n // Leading Zero does not allow it
09n // Leading Zero does not allow it
@JosephPecoraro
Copy link
Contributor Author

The tricky part about this is whether or not globalThis.BigInt is available.

If it is, then the BigIntLiteral's value property is a BigInt value.
If it is not, then the BitIntLiteral's value property is null.

Test coverage for that may require istanbul comments along the lines of:

const value = globalThis.BigInt ? globalThis.BigInt(string) : /* istanbul ignore next */ null;
return {
    type: Token.NumericLiteral,
    value: value,
    ...
};

Given unit tests run with a node where BigInt will be available but some browsers may not have it available.

yury-s pushed a commit to yury-s/webkit-http that referenced this issue Aug 16, 2019
…eatures

https://bugs.webkit.org/show_bug.cgi?id=200796

Reviewed by Ross Kirsling.

Source/WebInspectorUI:

Use a fork of Esprima to support modern JavaScript language features
while going through the process to upstream support:

  ES2018 Feature: Async Iteration (for-await-of)
  jquery/esprima#1990

  ES2019 Feature: Numeric Separator
  jquery/esprima#1989

  ES2019 Feature: Optional catch binding
  jquery/esprima#1953

  ES2020 Feature: BigInt
  jquery/esprima#1988

ESTree compatible AST changes are summarized as:

  - CatchClause `param` property is now nullable
  - ForOfStatement now has a boolean `await` property
  - Literal can be a `"bigint"` type (works if the environment has BigInt or not)

The pretty printer only needed to have additional handling for `for-await-of`.

* UserInterface/External/Esprima/esprima.js:
New version. Typescript output expects a modern JavaScript environment
instead of just ES6.

* Tools/Formatting/index.html:
Update the formatting tool for easier use in case of errors.

* UserInterface/Models/ScriptSyntaxTree.js:
(WI.ScriptSyntaxTree.prototype._createInternalSyntaxTree):

* UserInterface/Test/TestHarness.js:
(TestHarness.prototype.passOrFail):
Convenience for pass/fail with the same message based on a condition.

* UserInterface/Workers/Formatter/EsprimaFormatter.js:
(EsprimaFormatter.prototype._handleTokenAtNode):
Ensure a space after `await` in `for await` syntax.

LayoutTests:

* inspector/formatting/resources/javascript-tests/classes-expected.js:
* inspector/formatting/resources/javascript-tests/classes.js:
* inspector/formatting/resources/javascript-tests/for-statements-expected.js:
* inspector/formatting/resources/javascript-tests/for-statements.js:
* inspector/formatting/resources/javascript-tests/generators-expected.js:
* inspector/formatting/resources/javascript-tests/generators.js:
* inspector/formatting/resources/javascript-tests/numbers-expected.js: Added.
* inspector/formatting/resources/javascript-tests/numbers.js: Added.
* inspector/formatting/resources/javascript-tests/try-catch-finally-statements-expected.js:
* inspector/formatting/resources/javascript-tests/try-catch-finally-statements.js:
* inspector/formatting/resources/javascript-tests/unary-binary-expressions-expected.js:
* inspector/formatting/resources/javascript-tests/unary-binary-expressions.js:
Test formatting of new JavaScript language features.

* inspector/formatting/formatting-css-expected.txt:
* inspector/formatting/formatting-javascript-expected.txt:
* inspector/formatting/formatting-javascript.html:
* inspector/formatting/resources/utilities.js:
(TestPage.registerInitializer.async.runFormattingTest):
(TestPage.registerInitializer.window.addFormattingTests):
(TestPage.registerInitializer):
Cleaner output and better handling for debugging failures.

* inspector/model/parse-script-syntax-tree.html:
Test new AST permutations.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@248760 268f45cc-cd09-0410-ab3c-d52691b4dbfc
@jogibear9988
Copy link

I've created a pull for this in my fork: node-projects/esprima-next#12

@famgy
Copy link

famgy commented Dec 14, 2021

"dependencies": {
"esprima": "^4.0.1",
}
In my pakage.json,I use esprima-version-4.0.1 , but it's error when parsing bigint code, such as "var x = 0x123n".
How to use the new Feature about ES2020:BigInt?

@jogibear9988
Copy link

@famgy I've created a fork: esprima-next wich has support. https://github.com/node-projects/esprima-next

@famgy
Copy link

famgy commented Dec 15, 2021

@famgy I've created a fork: esprima-next wich has support. https://github.com/node-projects/esprima-next
"dependencies": {
"@babel/core": "^7.16.5",
"@babel/preset-env": "^7.16.5",
"esprima-next": "^5.7.0"
}

usage:
var BABEL = require("@babel/core"),
ESPRIMA = require("esprima-next")
var esCode = BABEL.transform('var x = 0x123n', {
presets: ["@babel/preset-env"]
}).code

var astCode = ESPRIMA.parseScript(esCode)

But, It's Error :

Error: Line 3: Unexpected token ILLEGAL
at e.constructError (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:20546)
at e.createError (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:20765)
at e.throwError (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:20888)
at e.throwUnexpectedToken (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:122742)
at e.scanHexLiteral (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:131016)
at e.scanNumericLiteral (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:133188)
at e.lex (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:139302)
at e.nextToken (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:55026)
at e.parseVariableDeclaration (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:91452)
at e.parseVariableDeclarationList (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:91724) {
index: 28,

@lahma
Copy link
Contributor

lahma commented Dec 15, 2021

I've been fixing issues with parsing on .NET side: sebastienros/esprima-dotnet#214 , currently I haven't found any new problems with the current WIP version while integrating Jint with it.

@jogibear9988
Copy link

@famgy
my fork is not an ES5 lib and more, so it should be loaded via "import".

@famgy
Copy link

famgy commented Dec 15, 2021

After clone esprima-next, and run test:
var ESPRIMA = require('.');

It's OK ,such as :
var astCode = ESPRIMA.parseScript('var x = 123n', { tolerant: true })

It's Error, such as:
var astCode = ESPRIMA.parseScript('var x = 0x123n', { tolerant: true })

Is it the result that "123n" is valid, but "0x123n" is invalid ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants