Merge pull request #10661 from vankop/bug-10623

Fix InnerGraph
This commit is contained in:
Tobias Koppers 2020-04-08 23:12:34 +02:00 committed by GitHub
commit 5971dee506
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 98 additions and 35 deletions

View File

@ -103,7 +103,7 @@ HarmonyExportExpressionDependency.Template = class HarmonyExportDependencyTempla
dep.range[0] - 1,
content + "(" + dep.prefix
);
source.replace(dep.range[1], dep.rangeStatement[1] - 1, ");");
source.replace(dep.range[1], dep.rangeStatement[1] - 0.5, ");");
return;
}

View File

@ -1865,7 +1865,7 @@ class HarmonyExportExpressionDependencyConcatenatedTemplate extends DependencyTe
dep.range[0] - 1,
content + "(" + dep.prefix
);
source.replace(dep.range[1], dep.rangeStatement[1] - 1, ");");
source.replace(dep.range[1], dep.rangeStatement[1] - 0.5, ");");
return;
}

View File

@ -11,6 +11,7 @@ const {
const PureExpressionDependency = require("../dependencies/PureExpressionDependency");
const InnerGraph = require("./InnerGraph");
/** @typedef {import("estree").Node} Node */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */
@ -34,6 +35,7 @@ const isPure = (expr, parser, commentsStartPos) => {
parser.getTagData(expr.name, harmonySpecifierTag)
);
case "ClassDeclaration":
case "ClassExpression":
if (expr.body.type !== "ClassBody") return false;
if (expr.superClass && !isPure(expr.superClass, parser, expr.range[0])) {
@ -50,6 +52,7 @@ const isPure = (expr, parser, commentsStartPos) => {
return true;
});
case "FunctionDeclaration":
case "FunctionExpression":
case "ArrowFunctionExpression":
case "Literal":
@ -124,8 +127,11 @@ class InnerGraphPlugin {
InnerGraph.inferDependencyUsage(parser.state);
logger.timeAggregate("infer dependency usage");
});
/** @type {WeakMap<{}, TopLevelSymbol>} */
/** @type {WeakMap<Node, TopLevelSymbol>} */
const statementWithTopLevelSymbol = new WeakMap();
/** @type {WeakMap<Node, Node>} */
const statementPurePart = new WeakMap();
parser.hooks.preStatement.tap("InnerGraphPlugin", statement => {
if (!InnerGraph.isEnabled(parser.state)) return;
@ -150,22 +156,25 @@ class InnerGraphPlugin {
}
if (statement.type === "ExportDefaultDeclaration") {
const decl = statement.declaration;
if (
decl.type === "FunctionExpression" ||
decl.type === "ArrowFunctionExpression" ||
decl.type === "ClassExpression" ||
decl.type === "Identifier"
) {
if (isPure(decl, parser, decl.range[1])) {
const name = "*default*";
const fn = InnerGraph.tagTopLevelSymbol(parser, name);
statementWithTopLevelSymbol.set(statement, fn);
if (
!decl.type.endsWith("FunctionExpression") &&
!decl.type.endsWith("Declaration") &&
decl.type !== "Literal"
) {
statementPurePart.set(statement, decl);
}
}
}
}
});
/** @type {WeakMap<{}, TopLevelSymbol>} */
/** @type {WeakMap<Node, TopLevelSymbol>} */
const declWithTopLevelSymbol = new WeakMap();
const pureDeclarators = new WeakSet();
parser.hooks.preDeclarator.tap(
"InnerGraphPlugin",
(decl, statement) => {
@ -175,21 +184,16 @@ class InnerGraphPlugin {
decl.init &&
decl.id.type === "Identifier"
) {
if (
decl.init.type === "FunctionExpression" ||
decl.init.type === "ArrowFunctionExpression" ||
decl.init.type === "ClassExpression"
) {
const name = decl.id.name;
const fn = InnerGraph.tagTopLevelSymbol(parser, name);
declWithTopLevelSymbol.set(decl, fn);
return true;
}
if (isPure(decl.init, parser, decl.id.range[1])) {
const name = decl.id.name;
const fn = InnerGraph.tagTopLevelSymbol(parser, name);
declWithTopLevelSymbol.set(decl, fn);
pureDeclarators.add(decl);
if (
!decl.init.type.endsWith("FunctionExpression") &&
decl.init.type !== "Literal"
) {
pureDeclarators.add(decl);
}
return true;
}
}
@ -202,12 +206,32 @@ class InnerGraphPlugin {
const fn = statementWithTopLevelSymbol.get(statement);
if (fn) {
InnerGraph.setTopLevelSymbol(parser.state, fn);
const purePart = statementPurePart.get(statement);
if (purePart) {
InnerGraph.onUsage(parser.state, usedByExports => {
switch (usedByExports) {
case undefined:
case true:
return;
default: {
const dep = new PureExpressionDependency(
purePart.range
);
dep.loc = statement.loc;
dep.usedByExports = usedByExports;
parser.state.module.addDependency(dep);
break;
}
}
});
}
}
}
});
parser.hooks.declarator.tap("InnerGraphPlugin", (decl, statement) => {
if (!InnerGraph.isEnabled(parser.state)) return;
const fn = declWithTopLevelSymbol.get(decl);
if (fn) {
InnerGraph.setTopLevelSymbol(parser.state, fn);
if (pureDeclarators.has(decl)) {

View File

@ -641,26 +641,26 @@ Entrypoint entry-1 = vendor-1.js entry-1.js
`;
exports[`StatsTestCases should print correct stats for commons-plugin-issue-4980 1`] = `
"Hash: 97b9c00d6fc61229e73bd32d88a9cafb3cfa08af
"Hash: f2652f529f967f7f2bec5cac904b0fb414d6d93f
Child
Hash: 97b9c00d6fc61229e73b
Hash: f2652f529f967f7f2bec
Time: X ms
Built at: 1970-04-20 12:42:42
Asset Size
app.73e459ccd7f12100fa78-1.js 6.13 KiB [emitted] [immutable] [name: app]
vendor.611fd9bad8fe7de29fe7-1.js 615 bytes [emitted] [immutable] [name: vendor] [id hint: vendor]
Entrypoint app = vendor.611fd9bad8fe7de29fe7-1.js app.73e459ccd7f12100fa78-1.js
vendor.f0527072691801f43979-1.js 615 bytes [emitted] [immutable] [name: vendor] [id hint: vendor]
Entrypoint app = vendor.f0527072691801f43979-1.js app.73e459ccd7f12100fa78-1.js
./entry-1.js + 2 modules 190 bytes [built]
./constants.js 87 bytes [built]
+ 3 hidden modules
Child
Hash: d32d88a9cafb3cfa08af
Hash: 5cac904b0fb414d6d93f
Time: X ms
Built at: 1970-04-20 12:42:42
Asset Size
app.1db34ba9ee5e51d1e813-2.js 6.14 KiB [emitted] [immutable] [name: app]
vendor.611fd9bad8fe7de29fe7-2.js 615 bytes [emitted] [immutable] [name: vendor] [id hint: vendor]
Entrypoint app = vendor.611fd9bad8fe7de29fe7-2.js app.1db34ba9ee5e51d1e813-2.js
vendor.f0527072691801f43979-2.js 615 bytes [emitted] [immutable] [name: vendor] [id hint: vendor]
Entrypoint app = vendor.f0527072691801f43979-2.js app.1db34ba9ee5e51d1e813-2.js
./entry-2.js + 2 modules 197 bytes [built]
./constants.js 87 bytes [built]
+ 3 hidden modules"
@ -1190,7 +1190,7 @@ exports[`StatsTestCases should print correct stats for immutable 1`] = `
`;
exports[`StatsTestCases should print correct stats for import-context-filter 1`] = `
"Hash: 5e1865f3f46f484bbbaf
"Hash: 781698f35c52fda3a34c
Time: X ms
Built at: 1970-04-20 12:42:42
Asset Size
@ -1612,11 +1612,11 @@ If you don't want to include a polyfill, you can use an empty module like this:
`;
exports[`StatsTestCases should print correct stats for module-reasons 1`] = `
"Hash: 7ad27c2fa358483a7fdd
"Hash: 6e6b4ee402334fe8ace1
Time: X ms
Built at: 1970-04-20 12:42:42
Asset Size
main.js 1.4 KiB [emitted] [name: main]
Asset Size
main.js 1.32 KiB [emitted] [name: main]
Entrypoint main = main.js
./index.js + 2 modules 102 bytes [built]
entry ./index main
@ -2733,7 +2733,7 @@ Entrypoint main = main.js
`;
exports[`StatsTestCases should print correct stats for side-effects-simple-unused 1`] = `
"Hash: bba4214f926bfb74bb29
"Hash: 4205efc704387d48d033
Time: X ms
Built at: 1970-04-20 12:42:42
Asset Size
@ -3784,11 +3784,11 @@ chunk default/async-a.js (async-a) 134 bytes <{179}> [rendered]
`;
exports[`StatsTestCases should print correct stats for tree-shaking 1`] = `
"Hash: 06b3690c160b35374c1d
"Hash: 4abb9dd9f28d864fe0ca
Time: X ms
Built at: 1970-04-20 12:42:42
Asset Size
bundle.js 7.17 KiB [emitted] [name: main]
bundle.js 7.09 KiB [emitted] [name: main]
Entrypoint main = bundle.js
./index.js 316 bytes [built] [1 warning]
[no exports]

View File

@ -0,0 +1,16 @@
import {exportDefaultUsed as export1} from "./package1/script";
import {exportDefaultUsed as export2} from "./package1/script2";
import {exportDefaultUsed as export3} from "./package2/script";
it("should load module correctly", () => {
require('./module');
});
it("default export should be unused", () => {
expect(export1).toBe(false);
expect(export2).toBe(false);
});
it("default export should be used", () => {
expect(export3).toBe(true);
});

View File

@ -0,0 +1,4 @@
import * as script from "./package1/script"
import script1 from "./package2/script";
export const mod = script1;

View File

@ -0,0 +1,5 @@
import mod from "./script1";
export default mod;
export * from "./script1";
export const exportDefaultUsed = __webpack_exports_info__.default.used;

View File

@ -0,0 +1,2 @@
export * from "./script2"
export default 1

View File

@ -0,0 +1,5 @@
import mod from "./script3";
export default function () { return mod };
export * from "./script3";
export const exportDefaultUsed = __webpack_exports_info__.default.used;

View File

@ -0,0 +1 @@
export default 1

View File

@ -0,0 +1,5 @@
import mod from "./script1";
export default mod;
export * from "./script1";
export const exportDefaultUsed = __webpack_exports_info__.default.used;

View File

@ -0,0 +1 @@
export default 1