mirror of https://github.com/webpack/webpack.git
Merge pull request #12007 from webpack/bugfix/11990
fix: check statements in path for asi safe
This commit is contained in:
commit
612f28a780
|
|
@ -1551,6 +1551,18 @@ class JavascriptParser extends Parser {
|
|||
this.prevStatement = this.statementPath.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks a statements that is nested within a parent statement
|
||||
* and can potentially be a non-block statement.
|
||||
* This enforces the nested statement to never be in ASI position.
|
||||
* @param {StatementNode} statement the nested statement
|
||||
* @returns {void}
|
||||
*/
|
||||
walkNestedStatement(statement) {
|
||||
this.prevStatement = undefined;
|
||||
this.walkStatement(statement);
|
||||
}
|
||||
|
||||
// Real Statements
|
||||
preWalkBlockStatement(statement) {
|
||||
this.preWalkStatements(statement.body);
|
||||
|
|
@ -1581,15 +1593,15 @@ class JavascriptParser extends Parser {
|
|||
const result = this.hooks.statementIf.call(statement);
|
||||
if (result === undefined) {
|
||||
this.walkExpression(statement.test);
|
||||
this.walkStatement(statement.consequent);
|
||||
this.walkNestedStatement(statement.consequent);
|
||||
if (statement.alternate) {
|
||||
this.walkStatement(statement.alternate);
|
||||
this.walkNestedStatement(statement.alternate);
|
||||
}
|
||||
} else {
|
||||
if (result) {
|
||||
this.walkStatement(statement.consequent);
|
||||
this.walkNestedStatement(statement.consequent);
|
||||
} else if (statement.alternate) {
|
||||
this.walkStatement(statement.alternate);
|
||||
this.walkNestedStatement(statement.alternate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1604,7 +1616,7 @@ class JavascriptParser extends Parser {
|
|||
const result = hook.call(statement);
|
||||
if (result === true) return;
|
||||
}
|
||||
this.walkStatement(statement.body);
|
||||
this.walkNestedStatement(statement.body);
|
||||
}
|
||||
|
||||
preWalkWithStatement(statement) {
|
||||
|
|
@ -1613,7 +1625,7 @@ class JavascriptParser extends Parser {
|
|||
|
||||
walkWithStatement(statement) {
|
||||
this.walkExpression(statement.object);
|
||||
this.walkStatement(statement.body);
|
||||
this.walkNestedStatement(statement.body);
|
||||
}
|
||||
|
||||
preWalkSwitchStatement(statement) {
|
||||
|
|
@ -1661,7 +1673,7 @@ class JavascriptParser extends Parser {
|
|||
|
||||
walkWhileStatement(statement) {
|
||||
this.walkExpression(statement.test);
|
||||
this.walkStatement(statement.body);
|
||||
this.walkNestedStatement(statement.body);
|
||||
}
|
||||
|
||||
preWalkDoWhileStatement(statement) {
|
||||
|
|
@ -1669,7 +1681,7 @@ class JavascriptParser extends Parser {
|
|||
}
|
||||
|
||||
walkDoWhileStatement(statement) {
|
||||
this.walkStatement(statement.body);
|
||||
this.walkNestedStatement(statement.body);
|
||||
this.walkExpression(statement.test);
|
||||
}
|
||||
|
||||
|
|
@ -1687,6 +1699,7 @@ class JavascriptParser extends Parser {
|
|||
if (statement.init) {
|
||||
if (statement.init.type === "VariableDeclaration") {
|
||||
this.blockPreWalkVariableDeclaration(statement.init);
|
||||
this.prevStatement = undefined;
|
||||
this.walkStatement(statement.init);
|
||||
} else {
|
||||
this.walkExpression(statement.init);
|
||||
|
|
@ -1706,7 +1719,7 @@ class JavascriptParser extends Parser {
|
|||
this.prevStatement = prev;
|
||||
this.walkStatements(body.body);
|
||||
} else {
|
||||
this.walkStatement(body);
|
||||
this.walkNestedStatement(body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -1735,7 +1748,7 @@ class JavascriptParser extends Parser {
|
|||
this.prevStatement = prev;
|
||||
this.walkStatements(body.body);
|
||||
} else {
|
||||
this.walkStatement(body);
|
||||
this.walkNestedStatement(body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -1767,7 +1780,7 @@ class JavascriptParser extends Parser {
|
|||
this.prevStatement = prev;
|
||||
this.walkStatements(body.body);
|
||||
} else {
|
||||
this.walkStatement(body);
|
||||
this.walkNestedStatement(body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -3376,9 +3389,14 @@ class JavascriptParser extends Parser {
|
|||
const currentStatement = this.statementPath[this.statementPath.length - 1];
|
||||
if (currentStatement === undefined) throw new Error("Not in statement");
|
||||
return (
|
||||
// Either asking directly for the end position of the current statement
|
||||
(currentStatement.range[1] === pos && this.semicolons.has(pos)) ||
|
||||
// Or asking for the start position of the current statement,
|
||||
// here we have to check multiple things
|
||||
(currentStatement.range[0] === pos &&
|
||||
// is there a previous statement which might be relevant?
|
||||
this.prevStatement !== undefined &&
|
||||
// is the end position of the previous statement an ASI position?
|
||||
this.semicolons.has(this.prevStatement.range[1]))
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,11 @@
|
|||
export function a() {}
|
||||
|
||||
let count = 0;
|
||||
|
||||
export function callme() {
|
||||
count++;
|
||||
}
|
||||
|
||||
export function getCount() {
|
||||
return count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import {a as b} from "./a";
|
||||
import {a as b, callme, getCount} from "./a";
|
||||
import * as c from "./b";
|
||||
|
||||
function donotcallme() {
|
||||
|
|
@ -12,4 +12,34 @@ it("should respect asi flag", () => {
|
|||
b();
|
||||
(donotcallme)
|
||||
c;
|
||||
|
||||
var i = 0
|
||||
for (;i < 10;i++) callme()
|
||||
var i = 0
|
||||
for (;i < 10;(function() {
|
||||
i++
|
||||
})()) callme()
|
||||
var i = 0
|
||||
for (;i < 2;i++) {
|
||||
(donotcallme)
|
||||
b();
|
||||
}
|
||||
var i = 0
|
||||
if (i++) callme()
|
||||
var i = 1
|
||||
if (i)
|
||||
(donotcallme)
|
||||
else
|
||||
callme()
|
||||
var i = 0
|
||||
while (i++ < 4) callme()
|
||||
do (donotcallme)
|
||||
while (i++ < 4) callme()
|
||||
var i = 0
|
||||
while (i++ < 4) (function () {
|
||||
var i = 4
|
||||
return callme()
|
||||
})()
|
||||
|
||||
expect(getCount()).toBe(29)
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4162,6 +4162,13 @@ declare class JavascriptParser extends Parser {
|
|||
preWalkStatement(statement?: any): void;
|
||||
blockPreWalkStatement(statement?: any): void;
|
||||
walkStatement(statement?: any): void;
|
||||
|
||||
/**
|
||||
* Walks a statements that is nested within a parent statement
|
||||
* and can potentially be a non-block statement.
|
||||
* This enforces the nested statement to never be in ASI position.
|
||||
*/
|
||||
walkNestedStatement(statement: Statement): void;
|
||||
preWalkBlockStatement(statement?: any): void;
|
||||
walkBlockStatement(statement?: any): void;
|
||||
walkExpressionStatement(statement?: any): void;
|
||||
|
|
|
|||
Loading…
Reference in New Issue