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

@babel/eslint-parser: fix BigIntLiteral node to match ESTree spec #10827

Merged
merged 6 commits into from Dec 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions eslint/babel-eslint-parser/package.json
Expand Up @@ -34,6 +34,7 @@
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
"@babel/plugin-syntax-bigint": "^7.7.4",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-export-default-from": "^7.0.0",
"@babel/plugin-syntax-export-namespace-from": "^7.0.0",
Expand Down
Expand Up @@ -70,7 +70,6 @@ const astTransformVisitor = {
}

// modules

if (path.isImportDeclaration()) {
delete node.isType;
}
Expand Down
Expand Up @@ -77,6 +77,9 @@ export default function(token, tt, source) {
flags: value.flags,
};
token.value = `/${value.pattern}/${value.flags}`;
} else if (type === tt.bigint) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Muuuuuch better 😄

token.type = "Numeric";
token.value = `${token.value}n`;
}

return token;
Expand Down
8 changes: 7 additions & 1 deletion eslint/babel-eslint-parser/test/babel-eslint-parser.js
Expand Up @@ -27,7 +27,7 @@ function parseAndAssertSame(code) {
loc: true,
range: true,
comment: true,
ecmaVersion: 2018,
ecmaVersion: 2020,
sourceType: "module",
});
const babylonAST = parseForESLint(code, {
Expand Down Expand Up @@ -518,5 +518,11 @@ describe("babylon-to-espree", () => {
}
`);
});

it("BigInt", () => {
parseAndAssertSame(`
const a = 1n;
`);
});
});
});
Expand Up @@ -17,5 +17,6 @@ module.exports = {
"@babel/plugin-syntax-export-namespace-from",
["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: false }],
["@babel/plugin-proposal-pipeline-operator", { proposal: "minimal" }],
"@babel/plugin-syntax-bigint",
],
};
21 changes: 18 additions & 3 deletions packages/babel-parser/src/plugins/estree.js
@@ -1,5 +1,7 @@
// @flow

/* global BigInt */

import { types as tt, TokenType } from "../tokenizer/types";
import type Parser from "../parser";
import * as N from "../types";
Expand Down Expand Up @@ -31,6 +33,16 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return node;
}

estreeParseBigIntLiteral(value: any): N.Node {
// https://github.com/estree/estree/blob/master/es2020.md#bigintliteral
// $FlowIgnore
const bigInt = typeof BigInt !== "undefined" ? BigInt(value) : null;
Copy link
Contributor

Choose a reason for hiding this comment

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

We should add a test case to show that the parsed result is different on node.js 6 and 8, which does not have BigInt support.

https://github.com/estree/estree/blob/master/es2020.md#bigintliteral

In environments that don't support BigInt values, value property will be null as the BigInt value can't be represented natively.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, are we not testing in older Node versions at the moment? I tested it locally with older Node versions and assumed this was already being done in CI?

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, right - sorry, I was thinking of the @babel/eslint-parser tests. Yes, we should add a test for this in @babel/parser.

const node = this.estreeParseLiteral(bigInt);
node.bigint = String(node.value || value);

return node;
}

estreeParseLiteral(value: any): N.Node {
return this.parseLiteral(value, "Literal");
}
Expand Down Expand Up @@ -244,13 +256,16 @@ export default (superClass: Class<Parser>): Class<Parser> =>

parseExprAtom(refShorthandDefaultPos?: ?Pos): N.Expression {
switch (this.state.type) {
case tt.regexp:
return this.estreeParseRegExpLiteral(this.state.value);

case tt.num:
case tt.string:
return this.estreeParseLiteral(this.state.value);

case tt.regexp:
return this.estreeParseRegExpLiteral(this.state.value);

case tt.bigint:
return this.estreeParseBigIntLiteral(this.state.value);

case tt._null:
return this.estreeParseLiteral(null);

Expand Down
3 changes: 2 additions & 1 deletion packages/babel-parser/src/types.js
Expand Up @@ -96,7 +96,8 @@ export type Literal =
| NullLiteral
| StringLiteral
| BooleanLiteral
| NumericLiteral;
| NumericLiteral
| BigIntLiteral;

export type RegExpLiteral = NodeBase & {
type: "RegExpLiteral",
Expand Down
@@ -0,0 +1 @@
const a = 1n;
102 changes: 102 additions & 0 deletions packages/babel-parser/test/fixtures/estree/bigInt/basic/output.json
@@ -0,0 +1,102 @@
{
"type": "File",
"start": 0,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 13
}
},
"program": {
"type": "Program",
"start": 0,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 13
}
},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 13
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 12
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "a"
},
"name": "a"
},
"init": {
"type": "Literal",
"start": 10,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 1,
"column": 12
}
},
"value": "1",
Copy link
Member Author

Choose a reason for hiding this comment

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

This isn't the actual correct value in the AST (it's the BigInt.prototype.toString() representation since BigInts can't be serialized to JSON), but it should be fine for testing purposes.

"raw": "1n",
"bigint": "1"
}
}
],
"kind": "const"
}
]
}
}
@@ -0,0 +1,6 @@
{
"plugins": [
"estree",
"bigInt"
]
}
@@ -1,3 +1,6 @@
{
"plugins": ["classProperties", ["decorators", { "decoratorsBeforeExport": false }]]
"plugins": [
"classProperties",
["decorators", { "decoratorsBeforeExport": false }]
]
}