Skip to content

Commit 725fff2

Browse files
authored
Merge pull request webpack#6071 from ooflorent/parser_eval
Add static analysis for bitwise operations and exponential operator
2 parents e03a227 + da08376 commit 725fff2

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

lib/Parser.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,15 @@ class Parser extends Tapable {
174174
res.setNumber(left.number / right.number);
175175
res.setRange(expr.range);
176176
return res;
177+
} else if(expr.operator === "**") {
178+
left = this.evaluateExpression(expr.left);
179+
right = this.evaluateExpression(expr.right);
180+
if(!left || !right) return;
181+
if(!left.isNumber() || !right.isNumber()) return;
182+
res = new BasicEvaluatedExpression();
183+
res.setNumber(Math.pow(left.number, right.number));
184+
res.setRange(expr.range);
185+
return res;
177186
} else if(expr.operator === "==" || expr.operator === "===") {
178187
left = this.evaluateExpression(expr.left);
179188
right = this.evaluateExpression(expr.right);
@@ -200,6 +209,60 @@ class Parser extends Tapable {
200209
} else if(left.isBoolean() && right.isBoolean()) {
201210
return res.setBoolean(left.bool !== right.bool);
202211
}
212+
} else if(expr.operator === "&") {
213+
left = this.evaluateExpression(expr.left);
214+
right = this.evaluateExpression(expr.right);
215+
if(!left || !right) return;
216+
if(!left.isNumber() || !right.isNumber()) return;
217+
res = new BasicEvaluatedExpression();
218+
res.setNumber(left.number & right.number);
219+
res.setRange(expr.range);
220+
return res;
221+
} else if(expr.operator === "|") {
222+
left = this.evaluateExpression(expr.left);
223+
right = this.evaluateExpression(expr.right);
224+
if(!left || !right) return;
225+
if(!left.isNumber() || !right.isNumber()) return;
226+
res = new BasicEvaluatedExpression();
227+
res.setNumber(left.number | right.number);
228+
res.setRange(expr.range);
229+
return res;
230+
} else if(expr.operator === "^") {
231+
left = this.evaluateExpression(expr.left);
232+
right = this.evaluateExpression(expr.right);
233+
if(!left || !right) return;
234+
if(!left.isNumber() || !right.isNumber()) return;
235+
res = new BasicEvaluatedExpression();
236+
res.setNumber(left.number ^ right.number);
237+
res.setRange(expr.range);
238+
return res;
239+
} else if(expr.operator === ">>>") {
240+
left = this.evaluateExpression(expr.left);
241+
right = this.evaluateExpression(expr.right);
242+
if(!left || !right) return;
243+
if(!left.isNumber() || !right.isNumber()) return;
244+
res = new BasicEvaluatedExpression();
245+
res.setNumber(left.number >>> right.number);
246+
res.setRange(expr.range);
247+
return res;
248+
} else if(expr.operator === ">>") {
249+
left = this.evaluateExpression(expr.left);
250+
right = this.evaluateExpression(expr.right);
251+
if(!left || !right) return;
252+
if(!left.isNumber() || !right.isNumber()) return;
253+
res = new BasicEvaluatedExpression();
254+
res.setNumber(left.number >> right.number);
255+
res.setRange(expr.range);
256+
return res;
257+
} else if(expr.operator === "<<") {
258+
left = this.evaluateExpression(expr.left);
259+
right = this.evaluateExpression(expr.right);
260+
if(!left || !right) return;
261+
if(!left.isNumber() || !right.isNumber()) return;
262+
res = new BasicEvaluatedExpression();
263+
res.setNumber(left.number << right.number);
264+
res.setRange(expr.range);
265+
return res;
203266
}
204267
});
205268
this.plugin("evaluate UnaryExpression", function(expr) {
@@ -242,6 +305,14 @@ class Parser extends Tapable {
242305
} else if(argument.isNumber()) {
243306
return new BasicEvaluatedExpression().setBoolean(!argument.number).setRange(expr.range);
244307
}
308+
} else if(expr.operator === "~") {
309+
const argument = this.evaluateExpression(expr.argument);
310+
if(!argument) return;
311+
if(!argument.isNumber()) return;
312+
const res = new BasicEvaluatedExpression();
313+
res.setNumber(~argument.number);
314+
res.setRange(expr.range);
315+
return res;
245316
}
246317
});
247318
this.plugin("evaluate typeof undefined", function(expr) {

test/Parser.unittest.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,16 @@ describe("Parser", () => {
305305
"1": "number=1",
306306
"1 + 3": "number=4",
307307
"3 - 1": "number=2",
308+
"2 * 3": "number=6",
309+
"8 / 2": "number=4",
310+
"2 ** 3": "number=8",
311+
"12 & 5": "number=4",
312+
"12 | 5": "number=13",
313+
"12 ^ 5": "number=9",
314+
"9 >>> 2": "number=2",
315+
"9 >> 2": "number=2",
316+
"9 << 2": "number=36",
317+
"~3": "number=-4",
308318
"1 == 1": "bool=true",
309319
"1 === 1": "bool=true",
310320
"3 != 1": "bool=true",

0 commit comments

Comments
 (0)