move methods from Module into ModuleGraph

This commit is contained in:
Tobias Koppers 2018-08-16 13:55:41 +02:00
parent c21d59f783
commit 3bb5263bfd
14 changed files with 145 additions and 130 deletions

View File

@ -791,7 +791,7 @@ class Compilation {
dependentModule.profile = currentProfile;
}
dependentModule.setIssuer(this.moduleGraph, module);
this.moduleGraph.setIssuer(dependentModule, module);
} else {
if (this.profile) {
if (module.profile) {

View File

@ -51,14 +51,14 @@ class FlagDependencyUsagePlugin {
* @returns {void}
*/
const processModule = (module, usedExports) => {
let ue = module.getUsedExports(moduleGraph);
let ue = moduleGraph.getUsedExports(module);
if (ue === true) return;
if (usedExports === true) {
module.setUsedExports(moduleGraph, (ue = true));
moduleGraph.setUsedExports(module, (ue = true));
} else if (Array.isArray(usedExports)) {
if (!ue) {
module.setUsedExports(
moduleGraph,
moduleGraph.setUsedExports(
module,
(ue = new SortableSet(usedExports))
);
} else {
@ -72,7 +72,7 @@ class FlagDependencyUsagePlugin {
}
} else {
if (ue !== false) return;
module.setUsedExports(moduleGraph, (ue = new SortableSet()));
moduleGraph.setUsedExports(module, (ue = new SortableSet()));
}
// for a module without side effects we stop tracking usage here when no export is used
@ -109,7 +109,7 @@ class FlagDependencyUsagePlugin {
if (!reference) return;
const referenceModule = reference.module;
const importedNames = reference.importedNames;
const oldUsedExports = referenceModule.getUsedExports(moduleGraph);
const oldUsedExports = moduleGraph.getUsedExports(referenceModule);
if (
!oldUsedExports ||
!isContained(oldUsedExports, importedNames)
@ -119,7 +119,7 @@ class FlagDependencyUsagePlugin {
};
for (const module of modules) {
module.setUsedExports(moduleGraph, false);
moduleGraph.setUsedExports(module, false);
}
/** @type {[Module, DependenciesBlock, UsedExports][]} */

View File

@ -30,7 +30,7 @@ class FlagInitialModulesAsUsedPlugin {
return;
}
for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
module.setUsedExports(moduleGraph, true);
moduleGraph.setUsedExports(module, true);
moduleGraph.addExtraReason(module, this.explanation);
}
}

View File

@ -75,7 +75,7 @@ class FunctionModuleTemplatePlugin {
} else if (module.buildMeta.providedExports) {
source.add(Template.toComment("no static exports found") + "\n");
}
const usedExports = module.getUsedExports(moduleGraph);
const usedExports = moduleGraph.getUsedExports(module);
if (usedExports === true) {
source.add(Template.toComment("all exports used") + "\n");
} else if (usedExports === false) {
@ -91,8 +91,8 @@ class FunctionModuleTemplatePlugin {
);
}
}
const optimizationBailout = module.getOptimizationBailout(
this.moduleGraph
const optimizationBailout = this.moduleGraph.getOptimizationBailout(
module
);
if (optimizationBailout) {
for (const text of optimizationBailout) {

View File

@ -45,9 +45,6 @@ const Template = require("./Template");
/** @typedef {KnownBuildMeta & Record<string, any>} BuildMeta */
const EMPTY_RESOLVE_OPTIONS = {};
const optimizationBailoutSymbol = Symbol("optimization bailout");
const usedExportsSymbol = Symbol("used exports");
const issuerSymbol = Symbol("issuer");
let debugId = 1000;
@ -138,61 +135,6 @@ class Module extends DependenciesBlock {
return (this.buildInfo && this.buildInfo.moduleArgument) || "module";
}
/**
* @param {ModuleGraph} moduleGraph the module graph
* @returns {Module | null} the issuer module
*/
getIssuer(moduleGraph) {
const meta = moduleGraph.getMeta(this);
return meta[issuerSymbol];
}
/**
* @param {ModuleGraph} moduleGraph the module graph
* @param {Module | null} issuer the issuer module
* @returns {void}
*/
setIssuer(moduleGraph, issuer) {
const meta = moduleGraph.getMeta(this);
meta[issuerSymbol] = issuer;
}
/**
* @param {ModuleGraph} moduleGraph the module graph
* @returns {(string | OptimizationBailoutFunction)[]} optimization bailouts
*/
getOptimizationBailout(moduleGraph) {
const meta = moduleGraph.getMeta(this);
const list = meta[optimizationBailoutSymbol];
if (list === undefined) {
return (meta[optimizationBailoutSymbol] = []);
}
return list;
}
/**
* @param {ModuleGraph} moduleGraph the module graph
* @returns {false | true | SortableSet<string> | null} the used exports
* false: module is not used at all.
* true: the module namespace/object export is used.
* SortableSet<string>: these export names are used.
* empty SortableSet<string>: module is used but no export.
* null: unknown, worst case should be assumed.
*/
getUsedExports(moduleGraph) {
const value = moduleGraph.getMeta(this)[usedExportsSymbol];
return value === undefined ? null : value;
}
/**
* @param {ModuleGraph} moduleGraph the module graph
* @param {false | true | SortableSet<string>} usedExports the used exports
* @returns {void}
*/
setUsedExports(moduleGraph, usedExports) {
moduleGraph.getMeta(this)[usedExportsSymbol] = usedExports;
}
/**
* disconnect the module from the graph
* @returns {void}
@ -309,7 +251,7 @@ class Module extends DependenciesBlock {
* @returns {boolean} true, if the module is used
*/
isModuleUsed(moduleGraph) {
return this.getUsedExports(moduleGraph) !== false;
return moduleGraph.getUsedExports(this) !== false;
}
/**
@ -318,7 +260,7 @@ class Module extends DependenciesBlock {
* @returns {boolean} true, if the export is used
*/
isExportUsed(moduleGraph, exportName) {
const usedExports = this.getUsedExports(moduleGraph);
const usedExports = moduleGraph.getUsedExports(this);
if (usedExports === null || usedExports === true) return true;
if (usedExports === false) return false;
return usedExports.has(exportName);
@ -331,7 +273,7 @@ class Module extends DependenciesBlock {
* string, the mangled export name when used.
*/
getUsedName(moduleGraph, exportName) {
const usedExports = this.getUsedExports(moduleGraph);
const usedExports = moduleGraph.getUsedExports(this);
if (usedExports === null || usedExports === true) return exportName;
if (usedExports === false) return false;
if (!usedExports.has(exportName)) return false;
@ -391,7 +333,7 @@ class Module extends DependenciesBlock {
*/
updateHash(hash, compilation) {
hash.update(`${this.id}`);
const usedExports = this.getUsedExports(compilation.moduleGraph);
const usedExports = compilation.moduleGraph.getUsedExports(this);
if (typeof usedExports === "boolean") {
hash.update(JSON.stringify(usedExports));
} else if (!usedExports) {
@ -522,22 +464,26 @@ Object.defineProperty(Module.prototype, "isUsed", {
Object.defineProperty(Module.prototype, "used", {
get() {
throw new Error("Module.used was refactored (use getUsedExports instead)");
throw new Error(
"Module.used was refactored (use ModuleGraph.getUsedExports instead)"
);
},
set(value) {
throw new Error("Module.used was refactored (use setUsedExports instead)");
throw new Error(
"Module.used was refactored (use ModuleGraph.setUsedExports instead)"
);
}
});
Object.defineProperty(Module.prototype, "usedExports", {
get() {
throw new Error(
"Module.usedExports was refactored (use getUsedExports instead)"
"Module.usedExports was refactored (use ModuleGraph.getUsedExports instead)"
);
},
set(value) {
throw new Error(
"Module.usedExports was refactored (use setUsedExports instead)"
"Module.usedExports was refactored (use ModuleGraph.setUsedExports instead)"
);
}
});

View File

@ -10,12 +10,31 @@ const ModuleGraphConnection = require("./ModuleGraphConnection");
/** @typedef {import("./DependenciesBlock")} DependenciesBlock */
/** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./Module")} Module */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @template T @typedef {import("./util/SortableSet")<T>} SortableSet<T> */
/** @typedef {(requestShortener: RequestShortener) => string} OptimizationBailoutFunction */
class ModuleGraphModule {
constructor() {
/** @type {Set<ModuleGraphConnection>} */
this.incomingConnections = new Set();
/** @type {Set<ModuleGraphConnection>} */
this.outgoingConnections = new Set();
/** @type {Module | null} */
this.issuer = null;
/** @type {(string | OptimizationBailoutFunction)[]} */
this.optimizationBailout = [];
/** @type {false | true | SortableSet<string> | null} */
this.usedExports = null;
}
}
class ModuleGraph {
constructor() {
/** @type {Map<Dependency, ModuleGraphConnection>} */
this._dependencyMap = new Map();
/** @type {Map<Module, Set<ModuleGraphConnection>>} */
/** @type {Map<Module, ModuleGraphModule>} */
this._moduleMap = new Map();
/** @type {Map<Module, Set<ModuleGraphConnection>>} */
this._originMap = new Map();
@ -25,22 +44,17 @@ class ModuleGraph {
this._parentsMap = new Map();
}
_getModuleSet(module) {
let connections = this._moduleMap.get(module);
if (connections === undefined) {
connections = new Set();
this._moduleMap.set(module, connections);
/**
* @param {Module} module the module
* @returns {ModuleGraphModule} the internal module
*/
_getModuleGraphModule(module) {
let mgm = this._moduleMap.get(module);
if (mgm === undefined) {
mgm = new ModuleGraphModule();
this._moduleMap.set(module, mgm);
}
return connections;
}
_getOriginSet(module) {
let connections = this._originMap.get(module);
if (connections === undefined) {
connections = new Set();
this._originMap.set(module, connections);
}
return connections;
return mgm;
}
/**
@ -84,9 +98,10 @@ class ModuleGraph {
module
);
this._dependencyMap.set(dependency, connection);
const connections = this._getModuleSet(module);
const connections = this._getModuleGraphModule(module).incomingConnections;
connections.add(connection);
const originConnections = this._getOriginSet(originModule);
const originConnections = this._getModuleGraphModule(originModule)
.outgoingConnections;
originConnections.add(connection);
}
@ -98,11 +113,11 @@ class ModuleGraph {
updateModule(dependency, module) {
const connection = this._dependencyMap.get(dependency);
if (connection.module === module) return;
const oldSet = this._moduleMap.get(connection.module);
oldSet.delete(connection);
const oldMgm = this._getModuleGraphModule(connection.module);
oldMgm.incomingConnections.delete(connection);
connection.module = module;
const newSet = this._moduleMap.get(module);
newSet.add(connection);
const newMgm = this._getModuleGraphModule(module);
newMgm.incomingConnections.add(connection);
}
/**
@ -123,8 +138,10 @@ class ModuleGraph {
*/
replaceModule(oldModule, newModule, filterConnection) {
if (oldModule === newModule) return;
const oldConnections = this._getOriginSet(oldModule);
const newConnections = this._getOriginSet(newModule);
const oldMgm = this._getModuleGraphModule(oldModule);
const newMgm = this._getModuleGraphModule(newModule);
const oldConnections = oldMgm.outgoingConnections;
const newConnections = newMgm.outgoingConnections;
for (const connection of oldConnections) {
if (filterConnection(connection)) {
connection.originModule = newModule;
@ -132,8 +149,8 @@ class ModuleGraph {
oldConnections.delete(connection);
}
}
const oldConnections2 = this._getModuleSet(oldModule);
const newConnections2 = this._getModuleSet(newModule);
const oldConnections2 = oldMgm.incomingConnections;
const newConnections2 = newMgm.incomingConnections;
for (const connection of oldConnections2) {
if (filterConnection(connection)) {
connection.module = newModule;
@ -149,7 +166,7 @@ class ModuleGraph {
* @returns {void}
*/
addExtraReason(module, explanation) {
const connections = this._getModuleSet(module);
const connections = this._getModuleGraphModule(module).incomingConnections;
connections.add(new ModuleGraphConnection(null, null, module, explanation));
}
@ -203,7 +220,7 @@ class ModuleGraph {
* @returns {ModuleGraphConnection[]} reasons why a module is included
*/
getIncomingConnections(module) {
const connections = this._getModuleSet(module);
const connections = this._getModuleGraphModule(module).incomingConnections;
return Array.from(connections);
}
@ -212,10 +229,62 @@ class ModuleGraph {
* @returns {ModuleGraphConnection[]} list of outgoing connections
*/
getOutgoingConnection(module) {
const connections = this._getOriginSet(module);
const connections = this._getModuleGraphModule(module).outgoingConnections;
return Array.from(connections);
}
/**
* @param {Module} module the module
* @returns {Module | null} the issuer module
*/
getIssuer(module) {
const mgm = this._getModuleGraphModule(module);
return mgm.issuer;
}
/**
* @param {Module} module the module
* @param {Module | null} issuer the issuer module
* @returns {void}
*/
setIssuer(module, issuer) {
const mgm = this._getModuleGraphModule(module);
mgm.issuer = issuer;
}
/**
* @param {Module} module the module
* @returns {(string | OptimizationBailoutFunction)[]} optimization bailouts
*/
getOptimizationBailout(module) {
const mgm = this._getModuleGraphModule(module);
return mgm.optimizationBailout;
}
/**
* @param {Module} module the module
* @returns {false | true | SortableSet<string> | null} the used exports
* false: module is not used at all.
* true: the module namespace/object export is used.
* SortableSet<string>: these export names are used.
* empty SortableSet<string>: module is used but no export.
* null: unknown, worst case should be assumed.
*/
getUsedExports(module) {
const mgm = this._getModuleGraphModule(module);
return mgm.usedExports;
}
/**
* @param {Module} module the module
* @param {false | true | SortableSet<string>} usedExports the used exports
* @returns {void}
*/
setUsedExports(module, usedExports) {
const mgm = this._getModuleGraphModule(module);
mgm.usedExports = usedExports;
}
/**
* @param {any} thing any thing
* @returns {Object} metadata

View File

@ -324,7 +324,7 @@ class Stats {
if (showErrorDetails && e.missing) {
text += e.missing.map(item => `\n[${item}]`).join("");
}
const origin = e.origin || (e.module && e.module.getIssuer(moduleGraph));
const origin = e.origin || (e.module && moduleGraph.getIssuer(e.module));
if (showModuleTrace && origin) {
text += `\n @ ${this.formatFilePath(
origin.readableIdentifier(requestShortener)
@ -342,10 +342,10 @@ class Stats {
text += ` ${locInfo}`;
}
}
let current = origin.getIssuer(moduleGraph);
let current = moduleGraph.getIssuer(origin);
while (current) {
text += `\n @ ${current.readableIdentifier(requestShortener)}`;
current = current.getIssuer(moduleGraph);
current = moduleGraph.getIssuer(current);
}
}
return text;
@ -507,11 +507,11 @@ class Stats {
const fnModule = (module, nested) => {
const path = [];
const issuer = module.getIssuer(moduleGraph);
const issuer = moduleGraph.getIssuer(module);
let current = issuer;
while (current) {
path.push(current);
current = current.getIssuer(moduleGraph);
current = moduleGraph.getIssuer(current);
}
path.reverse();
const obj = {
@ -601,7 +601,7 @@ class Stats {
});
}
if (showUsedExports) {
const usedExports = module.getUsedExports(moduleGraph);
const usedExports = moduleGraph.getUsedExports(module);
if (usedExports === null) {
obj.usedExports = null;
} else if (typeof usedExports === "boolean") {
@ -616,8 +616,8 @@ class Stats {
: null;
}
if (showOptimizationBailout) {
obj.optimizationBailout = module
.getOptimizationBailout(moduleGraph)
obj.optimizationBailout = moduleGraph
.getOptimizationBailout(module)
.map(item => {
if (typeof item === "function") return item(requestShortener);
return item;

View File

@ -36,7 +36,7 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, { module, runtimeTemplate, moduleGraph }) {
const usedExports = module.getUsedExports(moduleGraph);
const usedExports = moduleGraph.getUsedExports(module);
if (usedExports === true || usedExports === null) {
const content = runtimeTemplate.defineEsModuleFlagStatement({
exportsArgument: module.exportsArgument

View File

@ -35,7 +35,7 @@ const getHashValue = (moduleGraph, importedModule) => {
return "";
}
const usedExports = importedModule.getUsedExports(moduleGraph);
const usedExports = moduleGraph.getUsedExports(importedModule);
const stringifiedUsedExports = JSON.stringify(usedExports);
const stringifiedProvidedExports = JSON.stringify(
importedModule.buildMeta.providedExports
@ -96,7 +96,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
const id = this.id;
const parentModule = moduleGraph.getParentModule(this);
const used = parentModule.getUsedName(moduleGraph, name);
const usedExports = parentModule.getUsedExports(moduleGraph);
const usedExports = moduleGraph.getUsedExports(parentModule);
const importedModule = moduleGraph.getModule(this);
if (!importedModule) {
@ -495,7 +495,7 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
const activeFromOtherStarExports = dep._discoverActiveExportsFromOtherStartExports(
moduleGraph
);
const usedExports = module.getUsedExports(moduleGraph);
const usedExports = moduleGraph.getUsedExports(module);
if (usedExports && usedExports !== true) {
// we know which exports are used

View File

@ -173,7 +173,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
""
);
if (importedModule) {
const usedExports = importedModule.getUsedExports(moduleGraph);
const usedExports = moduleGraph.getUsedExports(importedModule);
const stringifyUsedExports = JSON.stringify(usedExports);
hash.update(stringifyUsedExports);
}

View File

@ -326,7 +326,7 @@ class ConcatenatedModule extends Module {
this.depth = rootModule.depth;
// Info from Optimization
this.setUsedExports(moduleGraph, rootModule.getUsedExports(moduleGraph));
moduleGraph.setUsedExports(this, moduleGraph.getUsedExports(rootModule));
const modulesArray = Array.from(modules);
@ -1145,7 +1145,7 @@ class ConcatenatedModule extends Module {
const result = new ConcatSource();
// add harmony compatibility flag (must be first because of possible circular dependencies)
const usedExports = this.rootModule.getUsedExports(moduleGraph);
const usedExports = moduleGraph.getUsedExports(this.rootModule);
if (usedExports === true) {
result.add(
runtimeTemplate.defineEsModuleFlagStatement({

View File

@ -58,8 +58,8 @@ class ModuleConcatenationPlugin {
const setBailoutReason = (module, reason) => {
setInnerBailoutReason(module, reason);
module
.getOptimizationBailout(moduleGraph)
moduleGraph
.getOptimizationBailout(module)
.push(
typeof reason === "function"
? rs => formatBailoutReason(reason(rs))
@ -308,8 +308,8 @@ class ModuleConcatenationPlugin {
}
} else {
for (const warning of currentConfiguration.getWarningsSorted()) {
currentRoot
.getOptimizationBailout(moduleGraph)
moduleGraph
.getOptimizationBailout(currentRoot)
.push(formatBailoutWarning(warning[0], warning[1]));
}
}
@ -332,8 +332,8 @@ class ModuleConcatenationPlugin {
compilation
);
for (const warning of concatConfiguration.getWarningsSorted()) {
newModule
.getOptimizationBailout(moduleGraph)
moduleGraph
.getOptimizationBailout(newModule)
.push(formatBailoutWarning(warning[0], warning[1]));
}
for (const m of modules) {

View File

@ -400,7 +400,7 @@ class WebAssemblyGenerator extends Generator {
let bin = /** @type {ArrayBuffer} */ (sourceAsAny);
bin = preprocess(bin);
const usedExports = module.getUsedExports(moduleGraph);
const usedExports = moduleGraph.getUsedExports(module);
const initFuncId = t.identifier(
usedExports && usedExports !== true
? Template.numberToIdentifer(usedExports.size)

View File

@ -24,7 +24,7 @@ class WebAssemblyJavascriptGenerator extends Generator {
* @returns {Source} generated code
*/
generate(module, { runtimeTemplate, moduleGraph }) {
const usedExports = module.getUsedExports(moduleGraph);
const usedExports = moduleGraph.getUsedExports(module);
const initIdentifer =
usedExports && usedExports !== true
? Template.numberToIdentifer(usedExports.size)