feat: `bigint` for the `DefinePlugin` plugin
This commit is contained in:
parent
b9dbc095f8
commit
1308ae7e8e
|
@ -86,6 +86,9 @@ const toCode = (code, parser) => {
|
|||
if (typeof code === "object") {
|
||||
return stringifyObj(code, parser);
|
||||
}
|
||||
if (typeof code === "bigint") {
|
||||
return `${code}n`;
|
||||
}
|
||||
return code + "";
|
||||
};
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ const TypeConstArray = 8;
|
|||
const TypeIdentifier = 9;
|
||||
const TypeWrapped = 10;
|
||||
const TypeTemplateString = 11;
|
||||
const TypeBigInt = 12;
|
||||
|
||||
class BasicEvaluatedExpression {
|
||||
constructor() {
|
||||
|
@ -26,6 +27,7 @@ class BasicEvaluatedExpression {
|
|||
this.truthy = false;
|
||||
this.bool = undefined;
|
||||
this.number = undefined;
|
||||
this.bigint = undefined;
|
||||
this.regExp = undefined;
|
||||
this.string = undefined;
|
||||
this.quasis = undefined;
|
||||
|
@ -54,6 +56,10 @@ class BasicEvaluatedExpression {
|
|||
return this.type === TypeNumber;
|
||||
}
|
||||
|
||||
isBigInt() {
|
||||
return this.type === TypeBigInt;
|
||||
}
|
||||
|
||||
isBoolean() {
|
||||
return this.type === TypeBoolean;
|
||||
}
|
||||
|
@ -101,6 +107,7 @@ class BasicEvaluatedExpression {
|
|||
if (this.isNull()) return false;
|
||||
if (this.isString()) return this.string !== "";
|
||||
if (this.isNumber()) return this.number !== 0;
|
||||
if (this.isBigInt()) return this.bigint !== BigInt(0);
|
||||
if (this.isRegExp()) return true;
|
||||
if (this.isArray()) return true;
|
||||
if (this.isConstArray()) return true;
|
||||
|
@ -122,6 +129,7 @@ class BasicEvaluatedExpression {
|
|||
if (this.isNull()) return "null";
|
||||
if (this.isString()) return this.string;
|
||||
if (this.isNumber()) return `${this.number}`;
|
||||
if (this.isBigInt()) return `${this.bigint}n`;
|
||||
if (this.isRegExp()) return `${this.regExp}`;
|
||||
if (this.isArray()) {
|
||||
let array = [];
|
||||
|
@ -162,6 +170,12 @@ class BasicEvaluatedExpression {
|
|||
return this;
|
||||
}
|
||||
|
||||
setBigInt(bigint) {
|
||||
this.type = TypeBigInt;
|
||||
this.bigint = bigint;
|
||||
return this;
|
||||
}
|
||||
|
||||
setBoolean(bool) {
|
||||
this.type = TypeBoolean;
|
||||
this.bool = bool;
|
||||
|
|
|
@ -289,6 +289,15 @@ class JavascriptParser extends Parser {
|
|||
return new BasicEvaluatedExpression()
|
||||
.setNumber(expr.value)
|
||||
.setRange(expr.range);
|
||||
case "bigint":
|
||||
return new BasicEvaluatedExpression()
|
||||
.setBigInt(
|
||||
BigInt(
|
||||
// @ts-ignore The `bigint` property doesn't exists
|
||||
expr.bigint
|
||||
)
|
||||
)
|
||||
.setRange(expr.range);
|
||||
case "string":
|
||||
return new BasicEvaluatedExpression()
|
||||
.setString(expr.value)
|
||||
|
@ -384,6 +393,10 @@ class JavascriptParser extends Parser {
|
|||
} else {
|
||||
return;
|
||||
}
|
||||
} else if (left.isBigInt()) {
|
||||
if (right.isBigInt()) {
|
||||
res.setBigInt(left.bigint + right.bigint);
|
||||
}
|
||||
} else if (left.isWrapped()) {
|
||||
if (left.postfix && left.postfix.isString() && right.isString()) {
|
||||
// ("prefix" + inner + "postfix") + "right"
|
||||
|
@ -474,38 +487,63 @@ class JavascriptParser extends Parser {
|
|||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (!left.isNumber() || !right.isNumber()) return;
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number - right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number - right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint - right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
} else if (expr.operator === "*") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (!left.isNumber() || !right.isNumber()) return;
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number * right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number * right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint * right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
} else if (expr.operator === "/") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (!left.isNumber() || !right.isNumber()) return;
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number / right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number / right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint / right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
} else if (expr.operator === "**") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (!left.isNumber() || !right.isNumber()) return;
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(Math.pow(left.number, right.number));
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number ** right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint ** right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
} else if (expr.operator === "==" || expr.operator === "===") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
|
@ -516,8 +554,12 @@ class JavascriptParser extends Parser {
|
|||
return res.setBoolean(left.string === right.string);
|
||||
} else if (left.isNumber() && right.isNumber()) {
|
||||
return res.setBoolean(left.number === right.number);
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
return res.setBoolean(left.bigint === right.bigint);
|
||||
} else if (left.isBoolean() && right.isBoolean()) {
|
||||
return res.setBoolean(left.bool === right.bool);
|
||||
} else if (left.isNull() && right.isNull()) {
|
||||
return res.setBoolean(true);
|
||||
}
|
||||
} else if (expr.operator === "!=" || expr.operator === "!==") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
|
@ -529,36 +571,58 @@ class JavascriptParser extends Parser {
|
|||
return res.setBoolean(left.string !== right.string);
|
||||
} else if (left.isNumber() && right.isNumber()) {
|
||||
return res.setBoolean(left.number !== right.number);
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
return res.setBoolean(left.bigint !== right.bigint);
|
||||
} else if (left.isBoolean() && right.isBoolean()) {
|
||||
return res.setBoolean(left.bool !== right.bool);
|
||||
} else if (left.isNull() && right.isNull()) {
|
||||
return res.setBoolean(false);
|
||||
}
|
||||
} else if (expr.operator === "&") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (!left.isNumber() || !right.isNumber()) return;
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number & right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number & right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint & right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
} else if (expr.operator === "|") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (!left.isNumber() || !right.isNumber()) return;
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number | right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number | right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint | right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
} else if (expr.operator === "^") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (!left.isNumber() || !right.isNumber()) return;
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number ^ right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number ^ right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint ^ right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
} else if (expr.operator === ">>>") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
|
@ -572,20 +636,32 @@ class JavascriptParser extends Parser {
|
|||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (!left.isNumber() || !right.isNumber()) return;
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number >> right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number >> right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint >> right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
} else if (expr.operator === "<<") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (!left.isNumber() || !right.isNumber()) return;
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number << right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number << right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint << right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.hooks.evaluate
|
||||
|
@ -621,11 +697,21 @@ class JavascriptParser extends Parser {
|
|||
.setString("string")
|
||||
.setRange(expr.range);
|
||||
}
|
||||
if (arg.isNull()) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setString("object")
|
||||
.setRange(expr.range);
|
||||
}
|
||||
if (arg.isNumber()) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setString("number")
|
||||
.setRange(expr.range);
|
||||
}
|
||||
if (arg.isBigInt()) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setString("bigint")
|
||||
.setRange(expr.range);
|
||||
}
|
||||
if (arg.isBoolean()) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setString("boolean")
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.2",
|
||||
"@types/estree": "0.0.39",
|
||||
"@types/estree": "0.0.42",
|
||||
"@types/node": "^12.6.9",
|
||||
"@yarnpkg/lockfile": "^1.1.0",
|
||||
"babel-loader": "^8.0.6",
|
||||
|
|
|
@ -414,6 +414,27 @@ describe("JavascriptParser", () => {
|
|||
"!0": "bool=true",
|
||||
"!-0": "bool=true",
|
||||
"!+0": "bool=true",
|
||||
"20n": "bigint=20",
|
||||
"10n + 10n": "bigint=20",
|
||||
"10n - 5n": "bigint=5",
|
||||
"10n * 5n": "bigint=50",
|
||||
"10n / 5n": "bigint=2",
|
||||
"5n ** 2n": "bigint=25",
|
||||
"5n == 5n": "bool=true",
|
||||
"5n === 5n": "bool=true",
|
||||
"5n != 5n": "bool=false",
|
||||
"5n !== 5n": "bool=false",
|
||||
"5n != 1n": "bool=true",
|
||||
"5n !== 1n": "bool=true",
|
||||
"5n & 3n": "bigint=1",
|
||||
"5n | 2n": "bigint=7",
|
||||
"5n ^ 2n": "bigint=7",
|
||||
"5n >> 2n": "bigint=1",
|
||||
"5n << 2n": "bigint=20",
|
||||
"null == null": "bool=true",
|
||||
"null === null": "bool=true",
|
||||
"null != null": "bool=false",
|
||||
"null !== null": "bool=false",
|
||||
"true === false": "bool=false",
|
||||
"false !== false": "bool=false",
|
||||
"true == true": "bool=true",
|
||||
|
@ -448,6 +469,10 @@ describe("JavascriptParser", () => {
|
|||
"typeof b.Number": "string=number",
|
||||
"typeof b['Number']": "string=number",
|
||||
"typeof b[Number]": "",
|
||||
"typeof true": "string=boolean",
|
||||
"typeof null": "string=object",
|
||||
"typeof 1": "string=number",
|
||||
"typeof 1n": "string=bigint",
|
||||
"b.Number": "number=123",
|
||||
"b['Number']": "number=123",
|
||||
"b[Number]": "",
|
||||
|
@ -532,6 +557,7 @@ describe("JavascriptParser", () => {
|
|||
const result = [];
|
||||
if (evalExpr.isString()) result.push("string=" + evalExpr.string);
|
||||
if (evalExpr.isNumber()) result.push("number=" + evalExpr.number);
|
||||
if (evalExpr.isBigInt()) result.push("bigint=" + evalExpr.bigint);
|
||||
if (evalExpr.isBoolean()) result.push("bool=" + evalExpr.bool);
|
||||
if (evalExpr.isRegExp()) result.push("regExp=" + evalExpr.regExp);
|
||||
if (evalExpr.isConditional())
|
||||
|
|
|
@ -17,10 +17,41 @@ it("should define FUNCTION", function() {
|
|||
expect((typeof FUNCTION)).toBe("function");
|
||||
if(typeof FUNCTION !== "function") require("fail");
|
||||
});
|
||||
it("should define NULL", function() {
|
||||
expect(NULL).toBeNull();
|
||||
if(NULL) require("fail");
|
||||
if(NULL !== null) require("fail");
|
||||
if(typeof NULL !== "object") require("fail");
|
||||
});
|
||||
it("should define UNDEFINED", function() {
|
||||
expect((typeof UNDEFINED)).toBe("undefined");
|
||||
if(typeof UNDEFINED !== "undefined") require("fail");
|
||||
});
|
||||
it("should define NUMBER", function() {
|
||||
expect(NUMBER).toBe(100.05);
|
||||
expect((typeof NUMBER)).toBe("number");
|
||||
if(NUMBER !== 100.05) require("fail");
|
||||
if(typeof NUMBER !== "number") require("fail");
|
||||
});
|
||||
it("should define ZERO", function() {
|
||||
expect(ZERO).toBe(0);
|
||||
expect((typeof ZERO)).toBe("number");
|
||||
if(ZERO !== 0) require("fail");
|
||||
if(typeof ZERO !== "number") require("fail");
|
||||
});
|
||||
it("should define ONE", function() {
|
||||
expect(ONE).toBe(1);
|
||||
expect((typeof ONE)).toBe("number");
|
||||
expect(42 / ONE).toBe(42);
|
||||
if(ONE !== 1) require("fail");
|
||||
if(typeof ONE !== "number") require("fail");
|
||||
});
|
||||
it("should define BIGINT", function() {
|
||||
expect(BIGINT).toBe(9007199254740991n);
|
||||
expect((typeof BIGINT)).toBe("bigint");
|
||||
if(BIGINT !== 9007199254740991n) require("fail");
|
||||
if(typeof BIGINT !== "bigint") require("fail");
|
||||
});
|
||||
it("should define POSITIVE_ZERO", function() {
|
||||
expect(POSITIVE_ZERO).toBe(+0);
|
||||
expect(POSITIVE_ZERO).toBe(0);
|
||||
|
|
|
@ -5,7 +5,12 @@ module.exports = {
|
|||
new DefinePlugin({
|
||||
TRUE: true,
|
||||
FALSE: false,
|
||||
NULL: null,
|
||||
UNDEFINED: undefined,
|
||||
NUMBER: 100.05,
|
||||
ZERO: 0,
|
||||
ONE: 1,
|
||||
BIGINT: 9007199254740991n,
|
||||
POSITIVE_ZERO: +0,
|
||||
NEGATIVE_ZER0: -0,
|
||||
NEGATIVE_NUMBER: -100.25,
|
||||
|
|
|
@ -410,10 +410,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
||||
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
|
||||
|
||||
"@types/estree@0.0.39":
|
||||
version "0.0.39"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
|
||||
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
|
||||
"@types/estree@0.0.42":
|
||||
version "0.0.42"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.42.tgz#8d0c1f480339efedb3e46070e22dd63e0430dd11"
|
||||
integrity sha512-K1DPVvnBCPxzD+G51/cxVIoc2X8uUVl1zpJeE6iKcgHMj4+tbat5Xu4TjV7v2QSDbIeAfLi2hIk+u2+s0MlpUQ==
|
||||
|
||||
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
|
||||
version "2.0.1"
|
||||
|
|
Loading…
Reference in New Issue