diff options
Diffstat (limited to 'node_modules/webpack/lib/ModuleGraphConnection.js')
| -rw-r--r-- | node_modules/webpack/lib/ModuleGraphConnection.js | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/ModuleGraphConnection.js b/node_modules/webpack/lib/ModuleGraphConnection.js new file mode 100644 index 00000000..515d2c9d --- /dev/null +++ b/node_modules/webpack/lib/ModuleGraphConnection.js @@ -0,0 +1,204 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +/** @typedef {import("./Dependency")} Dependency */ +/** @typedef {import("./Module")} Module */ +/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ + +/** + * Module itself is not connected, but transitive modules are connected transitively. + */ +const TRANSITIVE_ONLY = Symbol("transitive only"); + +/** + * While determining the active state, this flag is used to signal a circular connection. + */ +const CIRCULAR_CONNECTION = Symbol("circular connection"); + +/** @typedef {boolean | typeof TRANSITIVE_ONLY | typeof CIRCULAR_CONNECTION} ConnectionState */ + +/** + * @param {ConnectionState} a first + * @param {ConnectionState} b second + * @returns {ConnectionState} merged + */ +const addConnectionStates = (a, b) => { + if (a === true || b === true) return true; + if (a === false) return b; + if (b === false) return a; + if (a === TRANSITIVE_ONLY) return b; + if (b === TRANSITIVE_ONLY) return a; + return a; +}; + +/** + * @param {ConnectionState} a first + * @param {ConnectionState} b second + * @returns {ConnectionState} intersected + */ +const intersectConnectionStates = (a, b) => { + if (a === false || b === false) return false; + if (a === true) return b; + if (b === true) return a; + if (a === CIRCULAR_CONNECTION) return b; + if (b === CIRCULAR_CONNECTION) return a; + return a; +}; + +class ModuleGraphConnection { + /** + * @param {Module|null} originModule the referencing module + * @param {Dependency|null} dependency the referencing dependency + * @param {Module} module the referenced module + * @param {string=} explanation some extra detail + * @param {boolean=} weak the reference is weak + * @param {false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState=} condition condition for the connection + */ + constructor( + originModule, + dependency, + module, + explanation, + weak = false, + condition = undefined + ) { + this.originModule = originModule; + this.resolvedOriginModule = originModule; + this.dependency = dependency; + this.resolvedModule = module; + this.module = module; + this.weak = weak; + this.conditional = !!condition; + this._active = condition !== false; + /** @type {(function(ModuleGraphConnection, RuntimeSpec): ConnectionState) | undefined} */ + this.condition = condition || undefined; + /** @type {Set<string> | undefined} */ + this.explanations = undefined; + if (explanation) { + this.explanations = new Set(); + this.explanations.add(explanation); + } + } + + clone() { + const clone = new ModuleGraphConnection( + this.resolvedOriginModule, + this.dependency, + this.resolvedModule, + undefined, + this.weak, + this.condition + ); + clone.originModule = this.originModule; + clone.module = this.module; + clone.conditional = this.conditional; + clone._active = this._active; + if (this.explanations) clone.explanations = new Set(this.explanations); + return clone; + } + + /** + * @param {function(ModuleGraphConnection, RuntimeSpec): ConnectionState} condition condition for the connection + * @returns {void} + */ + addCondition(condition) { + if (this.conditional) { + const old = + /** @type {(function(ModuleGraphConnection, RuntimeSpec): ConnectionState)} */ + (this.condition); + this.condition = (c, r) => + intersectConnectionStates(old(c, r), condition(c, r)); + } else if (this._active) { + this.conditional = true; + this.condition = condition; + } + } + + /** + * @param {string} explanation the explanation to add + * @returns {void} + */ + addExplanation(explanation) { + if (this.explanations === undefined) { + this.explanations = new Set(); + } + this.explanations.add(explanation); + } + + get explanation() { + if (this.explanations === undefined) return ""; + return Array.from(this.explanations).join(" "); + } + + // TODO webpack 5 remove + get active() { + throw new Error("Use getActiveState instead"); + } + + /** + * @param {RuntimeSpec} runtime the runtime + * @returns {boolean} true, if the connection is active + */ + isActive(runtime) { + if (!this.conditional) return this._active; + + return ( + /** @type {(function(ModuleGraphConnection, RuntimeSpec): ConnectionState)} */ ( + this.condition + )(this, runtime) !== false + ); + } + + /** + * @param {RuntimeSpec} runtime the runtime + * @returns {boolean} true, if the connection is active + */ + isTargetActive(runtime) { + if (!this.conditional) return this._active; + return ( + /** @type {(function(ModuleGraphConnection, RuntimeSpec): ConnectionState)} */ ( + this.condition + )(this, runtime) === true + ); + } + + /** + * @param {RuntimeSpec} runtime the runtime + * @returns {ConnectionState} true: fully active, false: inactive, TRANSITIVE: direct module inactive, but transitive connection maybe active + */ + getActiveState(runtime) { + if (!this.conditional) return this._active; + return /** @type {(function(ModuleGraphConnection, RuntimeSpec): ConnectionState)} */ ( + this.condition + )(this, runtime); + } + + /** + * @param {boolean} value active or not + * @returns {void} + */ + setActive(value) { + this.conditional = false; + this._active = value; + } + + set active(value) { + throw new Error("Use setActive instead"); + } +} + +/** @typedef {typeof TRANSITIVE_ONLY} TRANSITIVE_ONLY */ +/** @typedef {typeof CIRCULAR_CONNECTION} CIRCULAR_CONNECTION */ + +module.exports = ModuleGraphConnection; +module.exports.addConnectionStates = addConnectionStates; +module.exports.TRANSITIVE_ONLY = /** @type {typeof TRANSITIVE_ONLY} */ ( + TRANSITIVE_ONLY +); +module.exports.CIRCULAR_CONNECTION = /** @type {typeof CIRCULAR_CONNECTION} */ ( + CIRCULAR_CONNECTION +); |
