Skip to content

Commit

Permalink
Merge pull request #11904 from webpack/bugfix/11897
Browse files Browse the repository at this point in the history
improve handling of ASI in concatenated modules and with imports
  • Loading branch information
sokra committed Nov 3, 2020
2 parents 2267924 + 48150a0 commit a76c9be
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 83 deletions.
6 changes: 5 additions & 1 deletion lib/dependencies/HarmonyImportDependencyParserPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,13 @@ module.exports = class HarmonyImportDependencyParserPlugin {
(statement, source) => {
parser.state.lastHarmonyImportOrder =
(parser.state.lastHarmonyImportOrder || 0) + 1;
const clearDep = new ConstDependency("", statement.range);
const clearDep = new ConstDependency(
parser.isAsiPosition(statement.range[0]) ? ";" : "",
statement.range
);
clearDep.loc = statement.loc;
parser.state.module.addPresentationalDependency(clearDep);
parser.unsetAsiPosition(statement.range[1]);
const sideEffectDep = new HarmonyImportSideEffectDependency(
source,
parser.state.lastHarmonyImportOrder
Expand Down
56 changes: 51 additions & 5 deletions lib/javascript/JavascriptParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -1405,7 +1405,11 @@ class JavascriptParser extends Parser {
}

preWalkStatement(statement) {
if (this.hooks.preStatement.call(statement)) return;
this.statementPath.push(statement);
if (this.hooks.preStatement.call(statement)) {
this.prevStatement = this.statementPath.pop();
return;
}
switch (statement.type) {
case "BlockStatement":
this.preWalkBlockStatement(statement);
Expand Down Expand Up @@ -1447,10 +1451,15 @@ class JavascriptParser extends Parser {
this.preWalkWithStatement(statement);
break;
}
this.prevStatement = this.statementPath.pop();
}

blockPreWalkStatement(statement) {
if (this.hooks.blockPreStatement.call(statement)) return;
this.statementPath.push(statement);
if (this.hooks.blockPreStatement.call(statement)) {
this.prevStatement = this.statementPath.pop();
return;
}
switch (statement.type) {
case "ImportDeclaration":
this.blockPreWalkImportDeclaration(statement);
Expand All @@ -1471,6 +1480,7 @@ class JavascriptParser extends Parser {
this.blockPreWalkClassDeclaration(statement);
break;
}
this.prevStatement = this.statementPath.pop();
}

walkStatement(statement) {
Expand Down Expand Up @@ -1549,7 +1559,9 @@ class JavascriptParser extends Parser {
walkBlockStatement(statement) {
this.inBlockScope(() => {
const body = statement.body;
const prev = this.prevStatement;
this.blockPreWalkStatements(body);
this.prevStatement = prev;
this.walkStatements(body);
});
}
Expand Down Expand Up @@ -1689,7 +1701,9 @@ class JavascriptParser extends Parser {
const body = statement.body;
if (body.type === "BlockStatement") {
// no need to add additional scope
const prev = this.prevStatement;
this.blockPreWalkStatements(body.body);
this.prevStatement = prev;
this.walkStatements(body.body);
} else {
this.walkStatement(body);
Expand All @@ -1716,7 +1730,9 @@ class JavascriptParser extends Parser {
const body = statement.body;
if (body.type === "BlockStatement") {
// no need to add additional scope
const prev = this.prevStatement;
this.blockPreWalkStatements(body.body);
this.prevStatement = prev;
this.walkStatements(body.body);
} else {
this.walkStatement(body);
Expand Down Expand Up @@ -1746,7 +1762,9 @@ class JavascriptParser extends Parser {
const body = statement.body;
if (body.type === "BlockStatement") {
// no need to add additional scope
const prev = this.prevStatement;
this.blockPreWalkStatements(body.body);
this.prevStatement = prev;
this.walkStatements(body.body);
} else {
this.walkStatement(body);
Expand All @@ -1770,7 +1788,9 @@ class JavascriptParser extends Parser {
}
if (statement.body.type === "BlockStatement") {
this.detectMode(statement.body.body);
const prev = this.prevStatement;
this.preWalkStatement(statement.body);
this.prevStatement = prev;
this.walkStatement(statement.body);
} else {
this.walkExpression(statement.body);
Expand Down Expand Up @@ -1848,7 +1868,9 @@ class JavascriptParser extends Parser {
if (
!this.hooks.exportDeclaration.call(statement, statement.declaration)
) {
const prev = this.prevStatement;
this.preWalkStatement(statement.declaration);
this.prevStatement = prev;
this.blockPreWalkStatement(statement.declaration);
let index = 0;
this.enterDeclaration(statement.declaration, def => {
Expand Down Expand Up @@ -1896,7 +1918,9 @@ class JavascriptParser extends Parser {
}

blockPreWalkExportDefaultDeclaration(statement) {
const prev = this.prevStatement;
this.preWalkStatement(statement.declaration);
this.prevStatement = prev;
this.blockPreWalkStatement(statement.declaration);
if (
statement.declaration.id &&
Expand Down Expand Up @@ -2049,7 +2073,9 @@ class JavascriptParser extends Parser {
const switchCase = switchCases[index];

if (switchCase.consequent.length > 0) {
const prev = this.prevStatement;
this.blockPreWalkStatements(switchCase.consequent);
this.prevStatement = prev;
}
}

Expand Down Expand Up @@ -2079,7 +2105,9 @@ class JavascriptParser extends Parser {
});
this.walkPattern(catchClause.param);
}
const prev = this.prevStatement;
this.blockPreWalkStatement(catchClause.body);
this.prevStatement = prev;
this.walkStatement(catchClause.body);
});
}
Expand Down Expand Up @@ -2276,7 +2304,9 @@ class JavascriptParser extends Parser {
}
if (expression.body.type === "BlockStatement") {
this.detectMode(expression.body.body);
const prev = this.prevStatement;
this.preWalkStatement(expression.body);
this.prevStatement = prev;
this.walkStatement(expression.body);
} else {
this.walkExpression(expression.body);
Expand All @@ -2294,7 +2324,9 @@ class JavascriptParser extends Parser {
}
if (expression.body.type === "BlockStatement") {
this.detectMode(expression.body.body);
const prev = this.prevStatement;
this.preWalkStatement(expression.body);
this.prevStatement = prev;
this.walkStatement(expression.body);
} else {
this.walkExpression(expression.body);
Expand Down Expand Up @@ -2561,7 +2593,9 @@ class JavascriptParser extends Parser {
}
if (functionExpression.body.type === "BlockStatement") {
this.detectMode(functionExpression.body.body);
const prev = this.prevStatement;
this.preWalkStatement(functionExpression.body);
this.prevStatement = prev;
this.walkStatement(functionExpression.body);
} else {
this.walkExpression(functionExpression.body);
Expand Down Expand Up @@ -3224,7 +3258,9 @@ class JavascriptParser extends Parser {
if (this.hooks.program.call(ast, comments) === undefined) {
this.detectMode(ast.body);
this.preWalkStatements(ast.body);
this.prevStatement = undefined;
this.blockPreWalkStatements(ast.body);
this.prevStatement = undefined;
this.walkStatements(ast.body);
}
this.hooks.finish.call(ast, comments);
Expand Down Expand Up @@ -3337,14 +3373,24 @@ class JavascriptParser extends Parser {
* @returns {boolean} true when a semicolon has been inserted before this position, false if not
*/
isAsiPosition(pos) {
if (this.prevStatement === undefined) return false;
const currentStatement = this.statementPath[this.statementPath.length - 1];
if (currentStatement === undefined) return true;
return (
currentStatement.range[0] === pos &&
this.semicolons.has(this.prevStatement.range[1])
(currentStatement.range[1] === pos && this.semicolons.has(pos)) ||
(currentStatement.range[0] === pos &&
(this.prevStatement === undefined ||
this.semicolons.has(this.prevStatement.range[1])))
);
}

/**
* @param {number} pos source code position
* @returns {void}
*/
unsetAsiPosition(pos) {
this.semicolons.delete(pos);
}

isStatementLevelExpression(expr) {
const currentStatement = this.statementPath[this.statementPath.length - 1];
return (
Expand Down

0 comments on commit a76c9be

Please sign in to comment.