cleanup, generalization

This commit is contained in:
Tobias Koppers 2020-04-08 21:40:13 +02:00
parent 3b769f4ff8
commit 7044757751
5 changed files with 43 additions and 60 deletions

View File

@ -38,23 +38,10 @@ class DependenciesBlock {
/**
* @param {Dependency} dependency dependency being tied to block.
* This is an "edge" pointing to another "node" on module graph.
* @param {number=} i index to insert
* @returns {void}
*/
addDependency(dependency, i = this.dependencies.length) {
addDependency(dependency) {
this.dependencies.push(dependency);
if (i < this.dependencies.length - 1) {
let tmp1 = this.dependencies[i];
this.dependencies[i] = dependency;
let j = i;
while (++j < this.dependencies.length) {
let tmp2 = this.dependencies[j];
this.dependencies[j] = tmp1;
tmp1 = tmp2;
}
}
}
/**

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,9 +127,10 @@ class InnerGraphPlugin {
InnerGraph.inferDependencyUsage(parser.state);
logger.timeAggregate("infer dependency usage");
});
/** @type {WeakMap<{}, TopLevelSymbol>} */
/** @type {WeakMap<Node, TopLevelSymbol>} */
const statementWithTopLevelSymbol = new WeakMap();
const pureExpressions = new WeakSet();
/** @type {WeakMap<Node, Node>} */
const statementPurePart = new WeakMap();
parser.hooks.preStatement.tap("InnerGraphPlugin", statement => {
if (!InnerGraph.isEnabled(parser.state)) return;
@ -152,24 +156,22 @@ 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 (isPure(decl, parser, decl.range[1])) {
pureExpressions.add(decl);
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();
@ -182,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;
}
}
@ -209,21 +206,20 @@ class InnerGraphPlugin {
const fn = statementWithTopLevelSymbol.get(statement);
if (fn) {
InnerGraph.setTopLevelSymbol(parser.state, fn);
if (
statement.type === "ExportDefaultDeclaration" &&
pureExpressions.has(statement.declaration)
) {
const purePart = statementPurePart.get(statement);
if (purePart) {
InnerGraph.onUsage(parser.state, usedByExports => {
switch (usedByExports) {
case undefined:
case true:
return;
default: {
const decl = statement.declaration;
const dep = new PureExpressionDependency(decl.range);
const dep = new PureExpressionDependency(
purePart.range
);
dep.loc = statement.loc;
dep.usedByExports = usedByExports;
parser.state.module.addDependency(dep, 0);
parser.state.module.addDependency(dep);
break;
}
}

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: 929ca56c76e036db72a4
"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]