refactor getInitFraments to take TemplateContext

add a hack to include the current module as property in source
later we will refactor DependencyTemplate.apply to take a TemplateContext too
This commit is contained in:
Tobias Koppers 2018-07-30 21:39:17 +02:00
parent 72cdb84967
commit d6f8e49c3a
12 changed files with 84 additions and 75 deletions

View File

@ -9,8 +9,16 @@
/** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
/** @typedef {import("./InitFragment")} InitFragment */
/** @typedef {import("./Module")} Module */
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
/**
* @typedef {Object} TemplateContext
* @property {RuntimeTemplate} runtimeTemplate the runtime template
* @property {DependencyTemplates} dependencyTemplates the dependency templates
* @property {Module} module current module
*/
class DependencyTemplate {
/**
* @abstract
@ -26,11 +34,10 @@ class DependencyTemplate {
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {TemplateContext} templateContext the template context
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, runtimeTemplate, dependencyTemplates) {
getInitFragments(dependency, templateContext) {
return null;
}
}

View File

@ -52,6 +52,9 @@ class JavascriptGenerator {
}
const source = new ReplaceSource(originalSource);
// TODO: remove this hack
const sourceAsAny = /** @type {any} */ (source);
sourceAsAny.module = module;
const initFragments = [];
this.sourceBlock(
@ -107,6 +110,7 @@ class JavascriptGenerator {
) {
for (const dependency of block.dependencies) {
this.sourceDependency(
module,
dependency,
dependencyTemplates,
initFragments,
@ -128,6 +132,7 @@ class JavascriptGenerator {
}
/**
* @param {Module} module the current module
* @param {TODO} dependency the dependency to generate
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {InitFragment[]} initFragments mutable list of init fragments
@ -136,6 +141,7 @@ class JavascriptGenerator {
* @returns {void}
*/
sourceDependency(
module,
dependency,
dependencyTemplates,
initFragments,
@ -151,11 +157,11 @@ class JavascriptGenerator {
template.apply(dependency, source, runtimeTemplate, dependencyTemplates);
const fragments = template.getInitFragments(
dependency,
const fragments = template.getInitFragments(dependency, {
runtimeTemplate,
dependencyTemplates
);
dependencyTemplates,
module
});
if (fragments) {
for (const fragment of fragments) {

View File

@ -11,6 +11,7 @@ const NullDependency = require("./NullDependency");
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../DependencyTemplate").TemplateContext} TemplateContext */
/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("../util/createHash").Hash} Hash */
@ -55,11 +56,10 @@ CachedConstDependency.Template = class CachedConstDependencyTemplate extends Dep
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {TemplateContext} templateContext the template context
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, runtimeTemplate, dependencyTemplates) {
getInitFragments(dependency, { runtimeTemplate, dependencyTemplates }) {
const dep = /** @type {CachedConstDependency} */ (dependency);
return [
new InitFragment(

View File

@ -36,9 +36,14 @@ HarmonyAcceptDependency.Template = class HarmonyAcceptDependencyTemplate extends
*/
apply(dependency, source, runtimeTemplate, dependencyTemplates) {
const dep = /** @type {HarmonyAcceptDependency} */ (dependency);
// TODO: remove this hack
const sourceAsAny = /** @type {any} */ (source);
const content = dep.dependencies
.filter(dependency =>
HarmonyImportDependency.Template.isImportEmitted(dependency, source)
HarmonyImportDependency.Template.isImportEmitted(
dependency,
sourceAsAny.module
)
)
.map(dependency => dependency.getImportStatement(true, runtimeTemplate))
.join("");

View File

@ -10,6 +10,7 @@ const NullDependency = require("./NullDependency");
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../DependencyTemplate").TemplateContext} TemplateContext */
/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
@ -38,11 +39,10 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {TemplateContext} templateContext the template context
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, runtimeTemplate, dependencyTemplates) {
getInitFragments(dependency, { runtimeTemplate, dependencyTemplates }) {
const dep = /** @type {HarmonyCompatibilityDependency} */ (dependency);
const usedExports = dep.originModule.usedExports;
if (usedExports !== false && !Array.isArray(usedExports)) {

View File

@ -14,6 +14,7 @@ const HarmonyImportDependency = require("./HarmonyImportDependency");
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
/** @typedef {import("../DependencyTemplate").TemplateContext} TemplateContext */
/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
@ -439,18 +440,13 @@ module.exports = HarmonyExportImportedSpecifierDependency;
HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedSpecifierDependencyTemplate extends HarmonyImportDependency.Template {
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {TemplateContext} templateContext the template context
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, runtimeTemplate, dependencyTemplates) {
getInitFragments(dependency, templateContext) {
const dep = /** @type {HarmonyExportImportedSpecifierDependency} */ (dependency);
if (this.isUsed(dep)) {
const importFragments = super.getInitFragments(
dep,
runtimeTemplate,
dependencyTemplates
);
const importFragments = super.getInitFragments(dep, templateContext);
const exportFragment = new InitFragment(
this.getContent(dep),
InitFragment.STAGE_HARMONY_IMPORTS,

View File

@ -11,6 +11,7 @@ const NullDependency = require("./NullDependency");
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
/** @typedef {import("../DependencyTemplate").TemplateContext} TemplateContext */
/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
@ -52,11 +53,10 @@ HarmonyExportSpecifierDependency.Template = class HarmonyExportSpecifierDependen
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {TemplateContext} templateContext the template context
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, runtimeTemplate, dependencyTemplates) {
getInitFragments(dependency, { runtimeTemplate, dependencyTemplates }) {
return [
new InitFragment(
this.getContent(dependency),

View File

@ -12,7 +12,9 @@ const ModuleDependency = require("./ModuleDependency");
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../DependencyTemplate").TemplateContext} TemplateContext */
/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("../util/createHash").Hash} Hash */
@ -107,25 +109,37 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
// no-op
}
static isImportEmitted(dep, source) {
let sourceInfo = importEmittedMap.get(source);
if (!sourceInfo) return false;
const key = dep._module || dep.request;
return key && sourceInfo.emittedImports.get(key);
/**
*
* @param {Dependency} dep the dependency
* @param {Module} module the module
* @returns {boolean} true, when for this dependency and module a import init fragment was created
*/
static isImportEmitted(dep, module) {
const emittedModules = importEmittedMap.get(dep);
return emittedModules !== undefined && emittedModules.has(module);
}
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {TemplateContext} templateContext the template context
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, runtimeTemplate, dependencyTemplates) {
getInitFragments(dependency, { runtimeTemplate, module }) {
const dep = /** @type {HarmonyImportDependency} */ (dependency);
const moduleKey = dep._module ? dep._module.identifier() : dep.request;
const key = `harmony import ${moduleKey}`;
if (module) {
let emittedModules = importEmittedMap.get(dep);
if (emittedModules === undefined) {
emittedModules = new WeakSet();
importEmittedMap.set(dep, emittedModules);
}
emittedModules.add(module);
}
return [
new InitFragment(
dep.getImportStatement(false, runtimeTemplate),

View File

@ -8,6 +8,7 @@
const HarmonyImportDependency = require("./HarmonyImportDependency");
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../DependencyTemplate").TemplateContext} TemplateContext */
/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
/** @typedef {import("../InitFragment")} InitFragment */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
@ -38,16 +39,15 @@ class HarmonyImportSideEffectDependency extends HarmonyImportDependency {
HarmonyImportSideEffectDependency.Template = class HarmonyImportSideEffectDependencyTemplate extends HarmonyImportDependency.Template {
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {TemplateContext} templateContext the template context
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, runtimeTemplate, dependencyTemplates) {
getInitFragments(dependency, templateContext) {
const dep = /** @type {HarmonyImportSideEffectDependency} */ (dependency);
if (dep._module && dep._module.factoryMeta.sideEffectFree) {
return null;
} else {
return super.getInitFragments(dep, runtimeTemplate, dependencyTemplates);
return super.getInitFragments(dep, templateContext);
}
}
};

View File

@ -10,6 +10,7 @@ const ModuleDependency = require("./ModuleDependency");
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../DependencyTemplate").TemplateContext} TemplateContext */
/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("../util/createHash").Hash} Hash */
@ -43,11 +44,10 @@ ModuleDecoratorDependency.Template = class ModuleDecoratorDependencyTemplate ext
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {TemplateContext} templateContext the template context
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, runtimeTemplate, dependencyTemplates) {
getInitFragments(dependency, { runtimeTemplate, dependencyTemplates }) {
const dep = /** @type {ModuleDecoratorDependency} */ (dependency);
return [
new InitFragment(

View File

@ -10,6 +10,7 @@ const ModuleDependency = require("./ModuleDependency");
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../DependencyTemplate").TemplateContext} TemplateContext */
/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("../util/createHash").Hash} Hash */
@ -58,11 +59,10 @@ class ProvidedDependencyTemplate extends ModuleDependency.Template {
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {TemplateContext} templateContext the template context
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, runtimeTemplate, dependencyTemplates) {
getInitFragments(dependency, { runtimeTemplate, dependencyTemplates }) {
const dep = /** @type {ProvidedDependency} */ (dependency);
return [
new InitFragment(

View File

@ -24,6 +24,7 @@ const createHash = require("../util/createHash");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../DependencyTemplate").TemplateContext} TemplateContext */
/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
/** @typedef {import("../InitFragment")} InitFragment */
/** @typedef {import("../RequestShortener")} RequestShortener */
@ -1232,20 +1233,15 @@ class HarmonyImportSpecifierDependencyConcatenatedTemplate extends DependencyTem
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {TemplateContext} templateContext the template context
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, runtimeTemplate, dependencyTemplates) {
getInitFragments(dependency, templateContext) {
const dep = /** @type {HarmonyImportSpecifierDependency} */ (dependency);
const module = dep._module;
const info = this.modulesMap.get(module);
if (!info) {
return this.originalTemplate.getInitFragments(
dep,
runtimeTemplate,
dependencyTemplates
);
return this.originalTemplate.getInitFragments(dep, templateContext);
} else {
return null;
}
@ -1304,20 +1300,15 @@ class HarmonyImportSideEffectDependencyConcatenatedTemplate extends DependencyTe
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {TemplateContext} templateContext the template context
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, runtimeTemplate, dependencyTemplates) {
getInitFragments(dependency, templateContext) {
const dep = /** @type {HarmonyImportSideEffectDependency} */ (dependency);
const module = dep._module;
const info = this.modulesMap.get(module);
if (!info) {
return this.originalTemplate.getInitFragments(
dep,
runtimeTemplate,
dependencyTemplates
);
return this.originalTemplate.getInitFragments(dep, templateContext);
} else {
return null;
}
@ -1355,18 +1346,13 @@ class HarmonyExportSpecifierDependencyConcatenatedTemplate extends DependencyTem
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {TemplateContext} templateContext the template context
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, runtimeTemplate, dependencyTemplates) {
getInitFragments(dependency, templateContext) {
const dep = /** @type {HarmonyExportSpecifierDependency} */ (dependency);
if (dep.originModule === this.rootModule) {
return this.originalTemplate.getInitFragments(
dep,
runtimeTemplate,
dependencyTemplates
);
return this.originalTemplate.getInitFragments(dep, templateContext);
} else {
return null;
}
@ -1472,20 +1458,15 @@ class HarmonyExportImportedSpecifierDependencyConcatenatedTemplate extends Depen
/**
* @param {Dependency} dependency the dependency for which the template should be applied
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {DependencyTemplates} dependencyTemplates the dependency templates
* @param {TemplateContext} templateContext the template context
* @returns {InitFragment[]|null} the init fragments
*/
getInitFragments(dependency, runtimeTemplate, dependencyTemplates) {
getInitFragments(dependency, templateContext) {
const dep = /** @type {HarmonyExportImportedSpecifierDependency} */ (dependency);
const module = dep._module;
const info = this.modulesMap.get(module);
if (!info) {
return this.originalTemplate.getInitFragments(
dep,
runtimeTemplate,
dependencyTemplates
);
return this.originalTemplate.getInitFragments(dep, templateContext);
} else {
return null;
}