fix: types

This commit is contained in:
alexander.akait 2024-10-24 06:02:20 +03:00
parent 5ac0434184
commit e10dcf597e
20 changed files with 558 additions and 287 deletions

1
declarations.d.ts vendored
View File

@ -407,6 +407,7 @@ interface ImportAttributeNode {
}
type TODO = any;
type EXPECTED_ANY = any;
type RecursiveArrayOrRecord<T> =
| { [index: string]: RecursiveArrayOrRecord<T> }

View File

@ -97,7 +97,9 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
* @returns {Source} a source
*/
getSource(module, runtime, sourceType) {
return this.get(module, runtime).sources.get(sourceType);
return /** @type {Source} */ (
this.get(module, runtime).sources.get(sourceType)
);
}
/**

View File

@ -127,25 +127,25 @@ class CssModule extends NormalModule {
static deserialize(context) {
const obj = new CssModule({
// will be deserialized by Module
layer: null,
layer: /** @type {EXPECTED_ANY} */ (null),
type: "",
// will be filled by updateCacheModule
resource: "",
context: "",
request: null,
userRequest: null,
rawRequest: null,
loaders: null,
matchResource: null,
parser: null,
parserOptions: null,
generator: null,
generatorOptions: null,
resolveOptions: null,
cssLayer: null,
supports: null,
media: null,
inheritance: null
request: /** @type {EXPECTED_ANY} */ (null),
userRequest: /** @type {EXPECTED_ANY} */ (null),
rawRequest: /** @type {EXPECTED_ANY} */ (null),
loaders: /** @type {EXPECTED_ANY} */ (null),
matchResource: /** @type {EXPECTED_ANY} */ (null),
parser: /** @type {EXPECTED_ANY} */ (null),
parserOptions: /** @type {EXPECTED_ANY} */ (null),
generator: /** @type {EXPECTED_ANY} */ (null),
generatorOptions: /** @type {EXPECTED_ANY} */ (null),
resolveOptions: /** @type {EXPECTED_ANY} */ (null),
cssLayer: /** @type {EXPECTED_ANY} */ (null),
supports: /** @type {EXPECTED_ANY} */ (null),
media: /** @type {EXPECTED_ANY} */ (null),
inheritance: /** @type {EXPECTED_ANY} */ (null)
});
obj.deserialize(context);
return obj;
@ -153,6 +153,7 @@ class CssModule extends NormalModule {
/**
* @param {ObjectDeserializerContext} context context
* @returns {TODO} Module
*/
deserialize(context) {
const { read } = context;

View File

@ -165,7 +165,7 @@ class DllModule extends Module {
*/
cleanupForCache() {
super.cleanupForCache();
this.dependencies = undefined;
this.dependencies = /** @type {EXPECTED_ANY} */ (undefined);
}
}

View File

@ -14,6 +14,7 @@ const HarmonyImportDependency = require("./dependencies/HarmonyImportDependency"
const ImportDependency = require("./dependencies/ImportDependency");
const { resolveByProperty, cachedSetProperty } = require("./util/cleverMerge");
/** @typedef {import("../declarations/WebpackOptions").ExternalItemFunctionData} ExternalItemFunctionData */
/** @typedef {import("../declarations/WebpackOptions").Externals} Externals */
/** @typedef {import("./Compilation").DepConstructor} DepConstructor */
/** @typedef {import("./ExternalModule").DependencyMeta} DependencyMeta */
@ -25,6 +26,12 @@ const EMPTY_RESOLVE_OPTIONS = {};
// TODO webpack 6 remove this
const callDeprecatedExternals = util.deprecate(
/**
* @param {TODO} externalsFunction externals function
* @param {string} context context
* @param {string} request request
* @param {(err: Error | null | undefined, value: ExternalValue | undefined, ty: ExternalType | undefined) => void} cb cb
*/
(externalsFunction, context, request, cb) => {
// eslint-disable-next-line no-useless-call
externalsFunction.call(null, context, request, cb);
@ -36,15 +43,16 @@ const callDeprecatedExternals = util.deprecate(
const cache = new WeakMap();
/**
* @param {object} obj obj
* @template {object} T
* @param {T} obj obj
* @param {TODO} layer layer
* @returns {object} result
* @returns {Omit<T, "byLayer">} result
*/
const resolveLayer = (obj, layer) => {
let map = cache.get(obj);
let map = cache.get(/** @type {object} */ (obj));
if (map === undefined) {
map = new Map();
cache.set(obj, map);
cache.set(/** @type {object} */ (obj), map);
} else {
const cacheEntry = map.get(layer);
if (cacheEntry !== undefined) return cacheEntry;
@ -54,8 +62,8 @@ const resolveLayer = (obj, layer) => {
return result;
};
/** @typedef {string|string[]|boolean|Record<string, string|string[]>} ExternalValue */
/** @typedef {string|undefined} ExternalType */
/** @typedef {string | string[] | boolean | Record<string, string | string[]>} ExternalValue */
/** @typedef {string | undefined} ExternalType */
class ExternalModuleFactoryPlugin {
/**
@ -213,6 +221,12 @@ class ExternalModuleFactoryPlugin {
return handleExternal(dependency.request, undefined, callback);
}
} else if (typeof externals === "function") {
/**
* @param {Error | null | undefined} err err
* @param {ExternalValue=} value value
* @param {ExternalType=} type type
* @returns {void}
*/
const cb = (err, value, type) => {
if (err) return callback(err);
if (value !== undefined) {
@ -259,7 +273,8 @@ class ExternalModuleFactoryPlugin {
context,
request,
resolveContext,
callback
/** @type {TODO} */
(callback)
);
} else {
return new Promise((resolve, reject) => {

View File

@ -69,7 +69,9 @@ class LoaderOptionsPlugin {
if (key === "include" || key === "exclude" || key === "test") {
continue;
}
context[key] = options[key];
/** @type {any} */
(context)[key] = options[key];
}
}
}

View File

@ -1607,24 +1607,28 @@ class NormalModule extends Module {
super.serialize(context);
}
/**
* @param {ObjectDeserializerContext} context context
* @returns {TODO} Module
*/
static deserialize(context) {
const obj = new NormalModule({
// will be deserialized by Module
layer: null,
layer: /** @type {EXPECTED_ANY} */ (null),
type: "",
// will be filled by updateCacheModule
resource: "",
context: "",
request: null,
userRequest: null,
rawRequest: null,
loaders: null,
matchResource: null,
parser: null,
parserOptions: null,
generator: null,
generatorOptions: null,
resolveOptions: null
request: /** @type {EXPECTED_ANY} */ (null),
userRequest: /** @type {EXPECTED_ANY} */ (null),
rawRequest: /** @type {EXPECTED_ANY} */ (null),
loaders: /** @type {EXPECTED_ANY} */ (null),
matchResource: /** @type {EXPECTED_ANY} */ (null),
parser: /** @type {EXPECTED_ANY} */ (null),
parserOptions: /** @type {EXPECTED_ANY} */ (null),
generator: /** @type {EXPECTED_ANY} */ (null),
generatorOptions: /** @type {EXPECTED_ANY} */ (null),
resolveOptions: /** @type {EXPECTED_ANY} */ (null)
});
obj.deserialize(context);
return obj;

View File

@ -5,7 +5,18 @@
"use strict";
/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
/** @typedef {import("./Compiler")} Compiler */
class OptionsApply {
process(options, compiler) {}
/**
* @param {WebpackOptions} options options object
* @param {Compiler} compiler compiler object
* @returns {WebpackOptions} options object
*/
process(options, compiler) {
return options;
}
}
module.exports = OptionsApply;

View File

@ -8,23 +8,45 @@
const LazySet = require("../util/LazySet");
const makeSerializable = require("../util/makeSerializable");
/** @typedef {import("enhanced-resolve").ResolveContext} ResolveContext */
/** @typedef {import("enhanced-resolve").ResolveOptions} ResolveOptions */
/** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */
/** @typedef {import("enhanced-resolve").Resolver} Resolver */
/** @typedef {import("../CacheFacade").ItemCacheFacade} ItemCacheFacade */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../FileSystemInfo")} FileSystemInfo */
/** @typedef {import("../FileSystemInfo").Snapshot} Snapshot */
/** @typedef {import("../FileSystemInfo").SnapshotOptions} SnapshotOptions */
/** @typedef {import("../ResolverFactory").ResolveOptionsWithDependencyType} ResolveOptionsWithDependencyType */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/**
* @template T
* @typedef {import("tapable").SyncHook<T>} SyncHook
*/
class CacheEntry {
/**
* @param {ResolveRequest} result result
* @param {Snapshot} snapshot snapshot
*/
constructor(result, snapshot) {
this.result = result;
this.snapshot = snapshot;
}
/**
* @param {ObjectSerializerContext} context context
*/
serialize({ write }) {
write(this.result);
write(this.snapshot);
}
/**
* @param {ObjectDeserializerContext} context context
*/
deserialize({ read }) {
this.result = read();
this.snapshot = read();
@ -36,7 +58,7 @@ makeSerializable(CacheEntry, "webpack/lib/cache/ResolverCachePlugin");
/**
* @template T
* @param {Set<T> | LazySet<T>} set set to add items to
* @param {Set<T> | LazySet<T>} otherSet set to add items from
* @param {Set<T> | LazySet<T> | Iterable<T>} otherSet set to add items from
* @returns {void}
*/
const addAllToSet = (set, otherSet) => {
@ -50,7 +72,8 @@ const addAllToSet = (set, otherSet) => {
};
/**
* @param {object} object an object
* @template {object} T
* @param {T} object an object
* @param {boolean} excludeContext if true, context is not included in string
* @returns {string} stringified version
*/
@ -77,6 +100,7 @@ class ResolverCachePlugin {
const cache = compiler.getCache("ResolverCachePlugin");
/** @type {FileSystemInfo} */
let fileSystemInfo;
/** @type {SnapshotOptions | undefined} */
let snapshotOptions;
let realResolves = 0;
let cachedResolves = 0;
@ -100,12 +124,16 @@ class ResolverCachePlugin {
}
});
});
/** @typedef {function((Error | null)=, ResolveRequest=): void} Callback */
/** @typedef {ResolveRequest & { _ResolverCachePluginCacheMiss: true }} ResolveRequestWithCacheMiss */
/**
* @param {ItemCacheFacade} itemCache cache
* @param {Resolver} resolver the resolver
* @param {object} resolveContext context for resolving meta info
* @param {object} request the request info object
* @param {function((Error | null)=, object=): void} callback callback function
* @param {ResolveContext} resolveContext context for resolving meta info
* @param {ResolveRequest} request the request info object
* @param {Callback} callback callback function
* @returns {void}
*/
const doRealResolve = (
@ -116,10 +144,13 @@ class ResolverCachePlugin {
callback
) => {
realResolves++;
const newRequest = {
_ResolverCachePluginCacheMiss: true,
...request
};
const newRequest =
/** @type {ResolveRequestWithCacheMiss} */
({
_ResolverCachePluginCacheMiss: true,
...request
});
/** @type {ResolveContext} */
const newResolveContext = {
...resolveContext,
stack: new Set(),
@ -130,16 +161,25 @@ class ResolverCachePlugin {
/** @type {LazySet<string>} */
contextDependencies: new LazySet()
};
/** @type {ResolveRequest[] | undefined} */
let yieldResult;
let withYield = false;
if (typeof newResolveContext.yield === "function") {
yieldResult = [];
withYield = true;
newResolveContext.yield = obj => yieldResult.push(obj);
newResolveContext.yield = obj =>
/** @type {ResolveRequest[]} */
(yieldResult).push(obj);
}
/**
* @param {"fileDependencies" | "contextDependencies" | "missingDependencies"} key key
*/
const propagate = key => {
if (resolveContext[key]) {
addAllToSet(resolveContext[key], newResolveContext[key]);
addAllToSet(
/** @type {Set<string>} */ (resolveContext[key]),
/** @type {Set<string>} */ (newResolveContext[key])
);
}
};
const resolveTime = Date.now();
@ -158,25 +198,43 @@ class ResolverCachePlugin {
const missingDependencies = newResolveContext.missingDependencies;
fileSystemInfo.createSnapshot(
resolveTime,
fileDependencies,
contextDependencies,
missingDependencies,
/** @type {Set<string>} */
(fileDependencies),
/** @type {Set<string>} */
(contextDependencies),
/** @type {Set<string>} */
(missingDependencies),
snapshotOptions,
(err, snapshot) => {
if (err) return callback(err);
const resolveResult = withYield ? yieldResult : result;
// since we intercept resolve hook
// we still can get result in callback
if (withYield && result) yieldResult.push(result);
if (withYield && result)
/** @type {ResolveRequest[]} */ (yieldResult).push(result);
if (!snapshot) {
if (resolveResult) return callback(null, resolveResult);
if (resolveResult)
return callback(
null,
/** @type {ResolveRequest} */
(resolveResult)
);
return callback();
}
itemCache.store(
new CacheEntry(resolveResult, snapshot),
new CacheEntry(
/** @type {ResolveRequest} */
(resolveResult),
snapshot
),
storeErr => {
if (storeErr) return callback(storeErr);
if (resolveResult) return callback(null, resolveResult);
if (resolveResult)
return callback(
null,
/** @type {ResolveRequest} */
(resolveResult)
);
callback();
}
);
@ -187,175 +245,192 @@ class ResolverCachePlugin {
};
compiler.resolverFactory.hooks.resolver.intercept({
factory(type, hook) {
/** @type {Map<string, (function(Error=, object=): void)[]>} */
/** @type {Map<string, (function(Error=, ResolveRequest=): void)[]>} */
const activeRequests = new Map();
/** @type {Map<string, [function(Error=, object=): void, function(Error=, object=): void][]>} */
/** @type {Map<string, [function(Error=, ResolveRequest=): void, NonNullable<ResolveContext["yield"]>][]>} */
const activeRequestsWithYield = new Map();
hook.tap(
"ResolverCachePlugin",
/**
* @param {Resolver} resolver the resolver
* @param {object} options resolve options
* @param {object} userOptions resolve options passed by the user
* @returns {void}
*/
(resolver, options, userOptions) => {
if (options.cache !== true) return;
const optionsIdent = objectToString(userOptions, false);
const cacheWithContext =
options.cacheWithContext !== undefined
? options.cacheWithContext
: false;
resolver.hooks.resolve.tapAsync(
{
name: "ResolverCachePlugin",
stage: -100
},
(request, resolveContext, callback) => {
if (
/** @type {TODO} */ (request)._ResolverCachePluginCacheMiss ||
!fileSystemInfo
) {
return callback();
}
const withYield = typeof resolveContext.yield === "function";
const identifier = `${type}${
withYield ? "|yield" : "|default"
}${optionsIdent}${objectToString(request, !cacheWithContext)}`;
/** @type {SyncHook<[Resolver, ResolveOptions, ResolveOptionsWithDependencyType]>} */
(hook).tap("ResolverCachePlugin", (resolver, options, userOptions) => {
if (/** @type {TODO} */ (options).cache !== true) return;
const optionsIdent = objectToString(userOptions, false);
const cacheWithContext =
options.cacheWithContext !== undefined
? options.cacheWithContext
: false;
resolver.hooks.resolve.tapAsync(
{
name: "ResolverCachePlugin",
stage: -100
},
(request, resolveContext, callback) => {
if (
/** @type {ResolveRequestWithCacheMiss} */
(request)._ResolverCachePluginCacheMiss ||
!fileSystemInfo
) {
return callback();
}
const withYield = typeof resolveContext.yield === "function";
const identifier = `${type}${
withYield ? "|yield" : "|default"
}${optionsIdent}${objectToString(request, !cacheWithContext)}`;
if (withYield) {
const activeRequest = activeRequestsWithYield.get(identifier);
if (activeRequest) {
activeRequest[0].push(callback);
activeRequest[1].push(
/** @type {TODO} */ (resolveContext.yield)
);
return;
}
} else {
const activeRequest = activeRequests.get(identifier);
if (activeRequest) {
activeRequest.push(callback);
return;
}
}
const itemCache = cache.getItemCache(identifier, null);
let callbacks;
let yields;
const done = withYield
? (err, result) => {
if (callbacks === undefined) {
if (err) {
callback(err);
} else {
if (result)
for (const r of result) resolveContext.yield(r);
callback(null, null);
}
yields = undefined;
callbacks = false;
} else {
if (err) {
for (const cb of callbacks) cb(err);
} else {
for (let i = 0; i < callbacks.length; i++) {
const cb = callbacks[i];
const yield_ = yields[i];
if (result) for (const r of result) yield_(r);
cb(null, null);
}
}
activeRequestsWithYield.delete(identifier);
yields = undefined;
callbacks = false;
}
}
: (err, result) => {
if (callbacks === undefined) {
callback(err, result);
callbacks = false;
} else {
for (const callback of callbacks) {
callback(err, result);
}
activeRequests.delete(identifier);
callbacks = false;
}
};
/**
* @param {Error=} err error if any
* @param {CacheEntry=} cacheEntry cache entry
* @returns {void}
*/
const processCacheResult = (err, cacheEntry) => {
if (err) return done(err);
if (cacheEntry) {
const { snapshot, result } = cacheEntry;
fileSystemInfo.checkSnapshotValid(
snapshot,
(err, valid) => {
if (err || !valid) {
cacheInvalidResolves++;
return doRealResolve(
itemCache,
resolver,
resolveContext,
request,
done
);
}
cachedResolves++;
if (resolveContext.missingDependencies) {
addAllToSet(
/** @type {LazySet<string>} */
(resolveContext.missingDependencies),
snapshot.getMissingIterable()
);
}
if (resolveContext.fileDependencies) {
addAllToSet(
/** @type {LazySet<string>} */
(resolveContext.fileDependencies),
snapshot.getFileIterable()
);
}
if (resolveContext.contextDependencies) {
addAllToSet(
/** @type {LazySet<string>} */
(resolveContext.contextDependencies),
snapshot.getContextIterable()
);
}
done(null, result);
}
);
} else {
doRealResolve(
itemCache,
resolver,
resolveContext,
request,
done
);
}
};
itemCache.get(processCacheResult);
if (withYield && callbacks === undefined) {
callbacks = [callback];
yields = [resolveContext.yield];
activeRequestsWithYield.set(
identifier,
/** @type {[any, any]} */ ([callbacks, yields])
if (withYield) {
const activeRequest = activeRequestsWithYield.get(identifier);
if (activeRequest) {
activeRequest[0].push(callback);
activeRequest[1].push(
/** @type {NonNullable<ResolveContext["yield"]>} */
(resolveContext.yield)
);
} else if (callbacks === undefined) {
callbacks = [callback];
activeRequests.set(identifier, callbacks);
return;
}
} else {
const activeRequest = activeRequests.get(identifier);
if (activeRequest) {
activeRequest.push(callback);
return;
}
}
);
}
);
const itemCache = cache.getItemCache(identifier, null);
/** @type {Callback[] | false | undefined} */
let callbacks;
/** @type {NonNullable<ResolveContext["yield"]>[] | undefined} */
let yields;
/**
* @type {function((Error | null)=, ResolveRequest | ResolveRequest[]=): void}
*/
const done = withYield
? (err, result) => {
if (callbacks === undefined) {
if (err) {
callback(err);
} else {
if (result)
for (const r of /** @type {ResolveRequest[]} */ (
result
)) {
/** @type {NonNullable<ResolveContext["yield"]>} */
(resolveContext.yield)(r);
}
callback(null, null);
}
yields = undefined;
callbacks = false;
} else {
const definedCallbacks =
/** @type {Callback[]} */
(callbacks);
if (err) {
for (const cb of definedCallbacks) cb(err);
} else {
for (let i = 0; i < definedCallbacks.length; i++) {
const cb = definedCallbacks[i];
const yield_ =
/** @type {NonNullable<ResolveContext["yield"]>[]} */
(yields)[i];
if (result)
for (const r of /** @type {ResolveRequest[]} */ (
result
))
yield_(r);
cb(null, null);
}
}
activeRequestsWithYield.delete(identifier);
yields = undefined;
callbacks = false;
}
}
: (err, result) => {
if (callbacks === undefined) {
callback(err, /** @type {ResolveRequest} */ (result));
callbacks = false;
} else {
for (const callback of /** @type {Callback[]} */ (
callbacks
)) {
callback(err, /** @type {ResolveRequest} */ (result));
}
activeRequests.delete(identifier);
callbacks = false;
}
};
/**
* @param {(Error | null)=} err error if any
* @param {(CacheEntry | null)=} cacheEntry cache entry
* @returns {void}
*/
const processCacheResult = (err, cacheEntry) => {
if (err) return done(err);
if (cacheEntry) {
const { snapshot, result } = cacheEntry;
fileSystemInfo.checkSnapshotValid(snapshot, (err, valid) => {
if (err || !valid) {
cacheInvalidResolves++;
return doRealResolve(
itemCache,
resolver,
resolveContext,
request,
done
);
}
cachedResolves++;
if (resolveContext.missingDependencies) {
addAllToSet(
/** @type {Set<string>} */
(resolveContext.missingDependencies),
snapshot.getMissingIterable()
);
}
if (resolveContext.fileDependencies) {
addAllToSet(
/** @type {Set<string>} */
(resolveContext.fileDependencies),
snapshot.getFileIterable()
);
}
if (resolveContext.contextDependencies) {
addAllToSet(
/** @type {Set<string>} */
(resolveContext.contextDependencies),
snapshot.getContextIterable()
);
}
done(null, result);
});
} else {
doRealResolve(
itemCache,
resolver,
resolveContext,
request,
done
);
}
};
itemCache.get(processCacheResult);
if (withYield && callbacks === undefined) {
callbacks = [callback];
yields = [
/** @type {NonNullable<ResolveContext["yield"]>} */
(resolveContext.yield)
];
activeRequestsWithYield.set(
identifier,
/** @type {[any, any]} */ ([callbacks, yields])
);
} else if (callbacks === undefined) {
callbacks = [callback];
activeRequests.set(identifier, callbacks);
}
}
);
});
return hook;
}
});

View File

@ -347,8 +347,6 @@ class CssModulesPlugin {
parent.supports,
parent.media
]);
console.log(inheritance);
}
if (parent.inheritance) {
@ -573,7 +571,6 @@ class CssModulesPlugin {
// Get ordered list of modules per chunk group
// Lists are in reverse order to allow to use Array.pop()
const modulesByChunkGroup = Array.from(chunk.groupsIterable, chunkGroup => {
const sortedModules = modulesList
.map(module => ({
@ -593,6 +590,11 @@ class CssModulesPlugin {
if (modulesByChunkGroup.length === 1)
return modulesByChunkGroup[0].list.reverse();
/**
* @param {{ list: Module[] }} a a
* @param {{ list: Module[] }} b b
* @returns {-1 | 0 | 1} result
*/
const compareModuleLists = ({ list: a }, { list: b }) => {
if (a.length === 0) {
return b.length === 0 ? 0 : 1;

View File

@ -70,7 +70,13 @@ const memoize = require("./util/memoize");
*/
const lazyFunction = factory => {
const fac = memoize(factory);
const f = /** @type {any} */ ((...args) => fac()(...args));
const f = /** @type {any} */ (
/**
* @param {...any} args args
* @returns {T} result
*/
(...args) => fac()(...args)
);
return /** @type {T} */ (f);
};
@ -113,13 +119,21 @@ module.exports = mergeExports(fn, {
get webpack() {
return require("./webpack");
},
/**
* @returns {function(Configuration): void} validate fn
*/
get validate() {
const webpackOptionsSchemaCheck = require("../schemas/WebpackOptions.check.js");
const getRealValidate = memoize(() => {
const validateSchema = require("./validateSchema");
const webpackOptionsSchema = require("../schemas/WebpackOptions.json");
return options => validateSchema(webpackOptionsSchema, options);
});
const getRealValidate = memoize(
/**
* @returns {function(Configuration): void} validate fn
*/
() => {
const validateSchema = require("./validateSchema");
const webpackOptionsSchema = require("../schemas/WebpackOptions.json");
return options => validateSchema(webpackOptionsSchema, options);
}
);
return options => {
if (!webpackOptionsSchemaCheck(options)) getRealValidate()(options);
};

View File

@ -1888,11 +1888,11 @@ ${defineGetters}`
*/
static deserialize(context) {
const obj = new ConcatenatedModule({
identifier: undefined,
rootModule: undefined,
modules: undefined,
identifier: /** @type {EXPECTED_ANY} */ (undefined),
rootModule: /** @type {EXPECTED_ANY} */ (undefined),
modules: /** @type {EXPECTED_ANY} */ (undefined),
runtime: undefined,
compilation: undefined
compilation: /** @type {EXPECTED_ANY} */ (undefined)
});
obj.deserialize(context);
return obj;

View File

@ -135,6 +135,8 @@ const identifyBigInt = n => {
return 2;
};
/** @typedef {TODO} Context */
/**
* @typedef {PrimitiveSerializableType[]} DeserializedType
* @typedef {BufferSerializableType[]} SerializedType
@ -152,7 +154,7 @@ class BinaryMiddleware extends SerializerMiddleware {
/**
* @param {function(): Promise<any> | any} fn lazy function
* @param {object} context serialize function
* @param {TODO} context serialize function
* @returns {function(): Promise<any> | any} new lazy
*/
_serializeLazy(fn, context) {
@ -163,7 +165,7 @@ class BinaryMiddleware extends SerializerMiddleware {
/**
* @param {DeserializedType} data data
* @param {object} context context object
* @param {TODO} context context object
* @param {{ leftOverBuffer: Buffer | null, allocationSize: number, increaseCounter: number }} allocationScope allocation scope
* @returns {SerializedType} serialized data
*/
@ -634,9 +636,9 @@ class BinaryMiddleware extends SerializerMiddleware {
// avoid leaking memory
currentBuffer = null;
leftOverBuffer = null;
allocationScope = undefined;
allocationScope = /** @type {EXPECTED_ANY} */ (undefined);
const _buffers = buffers;
buffers = undefined;
buffers = /** @type {EXPECTED_ANY} */ (undefined);
return _buffers;
}
@ -666,19 +668,21 @@ class BinaryMiddleware extends SerializerMiddleware {
/**
* @param {SerializedType} data data
* @param {object} context context object
* @param {TODO} context context object
* @returns {DeserializedType} deserialized data
*/
_deserialize(data, context) {
let currentDataItem = 0;
/** @type {BufferSerializableType | null} */
let currentBuffer = data[0];
let currentIsBuffer = Buffer.isBuffer(currentBuffer);
let currentPosition = 0;
/** @type {(x: Buffer) => Buffer} */
const retainedBuffer = context.retainedBuffer || (x => x);
const checkOverflow = () => {
if (currentPosition >= currentBuffer.length) {
if (currentPosition >= /** @type {Buffer} */ (currentBuffer).length) {
currentPosition = 0;
currentDataItem++;
currentBuffer =
@ -691,7 +695,8 @@ class BinaryMiddleware extends SerializerMiddleware {
* @returns {boolean} true when in current buffer, otherwise false
*/
const isInCurrentBuffer = n =>
currentIsBuffer && n + currentPosition <= currentBuffer.length;
currentIsBuffer &&
n + currentPosition <= /** @type {Buffer} */ (currentBuffer).length;
const ensureBuffer = () => {
if (!currentIsBuffer) {
throw new Error(
@ -708,12 +713,13 @@ class BinaryMiddleware extends SerializerMiddleware {
*/
const read = n => {
ensureBuffer();
const rem = currentBuffer.length - currentPosition;
const rem =
/** @type {Buffer} */ (currentBuffer).length - currentPosition;
if (rem < n) {
const buffers = [read(rem)];
n -= rem;
ensureBuffer();
while (currentBuffer.length < n) {
while (/** @type {Buffer} */ (currentBuffer).length < n) {
const b = /** @type {Buffer} */ (currentBuffer);
buffers.push(b);
n -= b.length;
@ -739,7 +745,9 @@ class BinaryMiddleware extends SerializerMiddleware {
*/
const readUpTo = n => {
ensureBuffer();
const rem = currentBuffer.length - currentPosition;
const rem =
/** @type {Buffer} */
(currentBuffer).length - currentPosition;
if (rem < n) {
n = rem;
}
@ -901,7 +909,8 @@ class BinaryMiddleware extends SerializerMiddleware {
const len = readU32();
if (isInCurrentBuffer(len) && currentPosition + len < 0x7fffffff) {
result.push(
currentBuffer.toString(
/** @type {Buffer} */
(currentBuffer).toString(
undefined,
currentPosition,
currentPosition + len
@ -919,7 +928,8 @@ class BinaryMiddleware extends SerializerMiddleware {
return () => {
if (currentIsBuffer && currentPosition < 0x7ffffffe) {
result.push(
currentBuffer.toString(
/** @type {Buffer} */
(currentBuffer).toString(
"latin1",
currentPosition,
currentPosition + 1
@ -992,11 +1002,13 @@ class BinaryMiddleware extends SerializerMiddleware {
return () => {
const len = readU32();
if (isInCurrentBuffer(len) && currentPosition + len < 0x7fffffff) {
const value = currentBuffer.toString(
undefined,
currentPosition,
currentPosition + len
);
const value =
/** @type {Buffer} */
(currentBuffer).toString(
undefined,
currentPosition,
currentPosition + len
);
result.push(BigInt(value));
currentPosition += len;
@ -1018,7 +1030,8 @@ class BinaryMiddleware extends SerializerMiddleware {
currentPosition + len < 0x7fffffff
) {
result.push(
currentBuffer.toString(
/** @type {Buffer} */
(currentBuffer).toString(
"latin1",
currentPosition,
currentPosition + len
@ -1118,7 +1131,7 @@ class BinaryMiddleware extends SerializerMiddleware {
// avoid leaking memory in context
// eslint-disable-next-line prefer-const
let _result = result;
result = undefined;
result = /** @type {EXPECTED_ANY} */ (undefined);
return _result;
}
}

View File

@ -304,6 +304,10 @@ class ObjectMiddleware extends SerializerMiddleware {
referenceable.set(item, currentPos++);
};
let bufferDedupeMap = new Map();
/**
* @param {Buffer} buf buffer
* @returns {Buffer} deduped buffer
*/
const dedupeBuffer = buf => {
const len = buf.length;
const entry = bufferDedupeMap.get(len);
@ -422,9 +426,10 @@ class ObjectMiddleware extends SerializerMiddleware {
if (err !== NOT_SERIALIZABLE) {
if (hasDebugInfoAttached === undefined)
hasDebugInfoAttached = new WeakSet();
if (!hasDebugInfoAttached.has(err)) {
err.message += `\nwhile serializing ${stackToString(value)}`;
hasDebugInfoAttached.add(err);
if (!hasDebugInfoAttached.has(/** @type {Error} */ (err))) {
/** @type {Error} */
(err).message += `\nwhile serializing ${stackToString(value)}`;
hasDebugInfoAttached.add(/** @type {Error} */ (err));
}
}
throw err;
@ -587,7 +592,8 @@ class ObjectMiddleware extends SerializerMiddleware {
bufferDedupeMap =
objectTypeLookup =
ctx =
undefined;
/** @type {EXPECTED_ANY} */
(undefined);
}
}
@ -722,7 +728,8 @@ class ObjectMiddleware extends SerializerMiddleware {
: serializerEntry[1].name
? `${serializerEntry[1].request} ${serializerEntry[1].name}`
: serializerEntry[1].request;
err.message += `\n(during deserialization of ${name})`;
/** @type {Error} */
(err).message += `\n(during deserialization of ${name})`;
throw err;
}
}
@ -756,7 +763,13 @@ class ObjectMiddleware extends SerializerMiddleware {
// This happens because the optimized code v8 generates
// is optimized for our "ctx.read" method so it will reference
// it from e. g. Dependency.prototype.deserialize -(IC)-> ctx.read
result = referenceable = data = objectTypeLookup = ctx = undefined;
result =
referenceable =
data =
objectTypeLookup =
ctx =
/** @type {EXPECTED_ANY} */
(undefined);
}
}
}

View File

@ -112,9 +112,10 @@ class SerializerMiddleware {
}
/**
* @template T
* @param {function(): Promise<any> | any} lazy lazy function
* @param {function(any): Promise<any> | any} deserialize deserialize function
* @returns {function(): Promise<any> | any} new lazy
* @param {function(T): Promise<T> | T} deserialize deserialize function
* @returns {function(): Promise<T> | T} new lazy
*/
static deserializeLazy(lazy, deserialize) {
const fn = memoize(() => {

View File

@ -6,8 +6,8 @@
/** @typedef {undefined | null | number | string | boolean | Buffer | object | (() => ComplexSerializableType[] | Promise<ComplexSerializableType[]>)} ComplexSerializableType */
/** @typedef {undefined|null|number|bigint|string|boolean|Buffer|(() => PrimitiveSerializableType[] | Promise<PrimitiveSerializableType[]>)} PrimitiveSerializableType */
/** @typedef {undefined | null | number | bigint | string | boolean | Buffer | (() => PrimitiveSerializableType[] | Promise<PrimitiveSerializableType[]>)} PrimitiveSerializableType */
/** @typedef {Buffer|(() => BufferSerializableType[] | Promise<BufferSerializableType[]>)} BufferSerializableType */
/** @typedef {Buffer | (() => BufferSerializableType[] | Promise<BufferSerializableType[]>)} BufferSerializableType */
module.exports = {};

View File

@ -633,7 +633,10 @@ class RuntimeSpecMap {
}
get size() {
if (/** @type {number} */ (this._mode) <= 1) return this._mode;
if (/** @type {number} */ (this._mode) <= 1) {
return /** @type {number} */ (this._mode);
}
return /** @type {Map<string, T>} */ (this._map).size;
}
}

View File

@ -6,30 +6,42 @@
"use strict";
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/** @typedef {(string|number|undefined|[])[]} SemVerRange */
/** @typedef {string | number | undefined} SemVerRangeItem */
/** @typedef {(SemVerRangeItem | SemVerRangeItem[])[]} SemVerRange */
/**
* @param {string} str version string
* @returns {(string|number|undefined|[])[]} parsed version
* @returns {SemVerRange} parsed version
*/
const parseVersion = str => {
/**
* @param {str} str str
* @returns {(string | number)[]} result
*/
var splitAndConvert = function (str) {
return str.split(".").map(function (item) {
// eslint-disable-next-line eqeqeq
return +item == item ? +item : item;
return +item == /** @type {EXPECTED_ANY} */ (item) ? +item : item;
});
};
var match = /^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(str);
/** @type {(string|number|undefined|[])[]} */
var match =
/** @type {RegExpExecArray} */
(/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(str));
/** @type {(string | number | undefined | [])[]} */
var ver = match[1] ? splitAndConvert(match[1]) : [];
if (match[2]) {
ver.length++;
ver.push.apply(ver, splitAndConvert(match[2]));
}
if (match[3]) {
ver.push([]);
ver.push.apply(ver, splitAndConvert(match[3]));
}
return ver;
};
module.exports.parseVersion = parseVersion;
@ -89,16 +101,28 @@ module.exports.versionLt = versionLt;
* @returns {SemVerRange} parsed range
*/
module.exports.parseRange = str => {
/**
* @param {string} str str
* @returns {(string | number)[]} result
*/
const splitAndConvert = str => {
return str
.split(".")
.map(item => (item !== "NaN" && `${+item}` === item ? +item : item));
};
// see https://docs.npmjs.com/misc/semver#range-grammar for grammar
/**
* @param {string} str str
* @returns {SemVerRangeItem[]}
*/
const parsePartial = str => {
const match = /^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(str);
/** @type {(string|number|undefined|[])[]} */
const match =
/** @type {RegExpExecArray} */
(/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(str));
/** @type {SemVerRangeItem[]} */
const ver = match[1] ? [0, ...splitAndConvert(match[1])] : [0];
if (match[2]) {
ver.length++;
ver.push.apply(ver, splitAndConvert(match[2]));
@ -116,6 +140,12 @@ module.exports.parseRange = str => {
return ver;
};
/**
*
* @param {SemVerRangeItem[]} range range
* @returns {SemVerRangeItem[]}
*/
const toFixed = range => {
if (range.length === 1) {
// Special case for "*" is "x.x.x" instead of "="
@ -130,9 +160,20 @@ module.exports.parseRange = str => {
return [range.length, ...range.slice(1)];
};
/**
*
* @param {SemVerRangeItem[]} range
* @returns {SemVerRangeItem[]} result
*/
const negate = range => {
return [-range[0] - 1, ...range.slice(1)];
return [-(/** @type { [number]} */ (range)[0]) - 1, ...range.slice(1)];
};
/**
* @param {string} str str
* @returns {SemVerRange}
*/
const parseSimple = str => {
// simple ::= primitive | partial | tilde | caret
// primitive ::= ( '<' | '>' | '>=' | '<=' | '=' | '!' ) ( ' ' ) * partial
@ -143,6 +184,7 @@ module.exports.parseRange = str => {
const remainder = parsePartial(
start.length ? str.slice(start.length).trim() : str.trim()
);
switch (start) {
case "^":
if (remainder.length > 1 && remainder[1] === 0) {
@ -185,6 +227,13 @@ module.exports.parseRange = str => {
throw new Error("Unexpected start value");
}
};
/**
*
* @param {SemVerRangeItem[][]} items items
* @param {number} fn fn
* @returns {SemVerRange} result
*/
const combine = (items, fn) => {
if (items.length === 1) return items[0];
const arr = [];
@ -195,38 +244,64 @@ module.exports.parseRange = str => {
arr.push(...item.slice(1));
}
}
// eslint-disable-next-line no-sparse-arrays
return [, ...arr, ...items.slice(1).map(() => fn)];
};
/**
* @param {string} str str
* @returns {SemVerRange}
*/
const parseRange = str => {
// range ::= hyphen | simple ( ' ' ( ' ' ) * simple ) * | ''
// hyphen ::= partial ( ' ' ) * ' - ' ( ' ' ) * partial
const items = str.split(/\s+-\s+/);
if (items.length === 1) {
const items = str
.trim()
.split(/(?<=[-0-9A-Za-z])\s+/g)
.map(parseSimple);
const items =
/** @type {SemVerRangeItem[][]} */
(
str
.trim()
.split(/(?<=[-0-9A-Za-z])\s+/g)
.map(parseSimple)
);
return combine(items, 2);
}
const a = parsePartial(items[0]);
const b = parsePartial(items[1]);
// >=a <=b => and( >=a, or( <b, =b ) ) => >=a, <b, =b, or, and
// eslint-disable-next-line no-sparse-arrays
return [, toFixed(b), negate(b), 1, a, 2];
};
/**
* @param {string} str str
* @returns {SemVerRange}
*/
const parseLogicalOr = str => {
// range-set ::= range ( logical-or range ) *
// logical-or ::= ( ' ' ) * '||' ( ' ' ) *
const items = str.split(/\s*\|\|\s*/).map(parseRange);
const items =
/** @type {SemVerRangeItem[][]} */
(str.split(/\s*\|\|\s*/).map(parseRange));
return combine(items, 1);
};
return parseLogicalOr(str);
};
/* eslint-disable eqeqeq */
/**
* @param {SemVerRange} range
* @returns {string}
*/
const rangeToString = range => {
var fixCount = range[0];
var fixCount = /** @type {number} */ (range[0]);
var str = "";
if (range.length === 1) {
return "*";
@ -270,7 +345,7 @@ const rangeToString = range => {
? "(" + pop() + " || " + pop() + ")"
: item === 2
? stack.pop() + " " + stack.pop()
: rangeToString(item)
: rangeToString(/** @type {SemVerRange} */ (item))
);
}
return pop();
@ -279,10 +354,9 @@ const rangeToString = range => {
return /** @type {string} */ (stack.pop()).replace(/^\((.+)\)$/, "$1");
}
};
/* eslint-enable eqeqeq */
module.exports.rangeToString = rangeToString;
/* eslint-disable eqeqeq */
/**
* @param {SemVerRange} range version range
* @param {string} version the version
@ -341,16 +415,22 @@ const satisfy = (range, version) => {
// big-cmp: when negated => return false, else => next-nequ
// small-cmp: when negated => next-nequ, else => return false
var rangeType = j < range.length ? (typeof range[j])[0] : "";
var rangeType =
/** @type {"s" | "n" | "u" | ""} */
(j < range.length ? (typeof range[j])[0] : "");
/** @type {number | string | undefined} */
var versionValue;
/** @type {"n" | "s" | "u" | "o" | undefined} */
var versionType;
// Handles first column in both tables (end of version or object)
if (
i >= version.length ||
((versionValue = version[i]),
(versionType = (typeof versionValue)[0]) == "o")
(versionType = /** @type {"n" | "s" | "u" | "o"} */ (
(typeof versionValue)[0]
)) == "o")
) {
// Handles nequal
if (!isEqual) return true;
@ -378,7 +458,11 @@ const satisfy = (range, version) => {
}
} else {
// Handles "cmp" cases
if (negated ? versionValue > range[j] : versionValue < range[j]) {
if (
negated
? versionValue > /** @type {(number | string)[]} */ (range)[j]
: versionValue < /** @type {(number | string)[]} */ (range)[j]
) {
return false;
}
if (versionValue != range[j]) isEqual = false;
@ -410,17 +494,20 @@ const satisfy = (range, version) => {
}
}
}
/** @type {(boolean | number)[]} */
var stack = [];
var p = stack.pop.bind(stack);
// eslint-disable-next-line no-redeclare
for (var i = 1; i < range.length; i++) {
var item = /** @type {SemVerRange | 0 | 1 | 2} */ (range[i]);
var item = /** @type {SemVerRangeItem[] | 0 | 1 | 2} */ (range[i]);
stack.push(
item == 1
? p() | p()
? /** @type {() => number} */ (p)() | /** @type {() => number} */ (p)()
: item == 2
? p() & p()
? /** @type {() => number} */ (p)() &
/** @type {() => number} */ (p)()
: item
? satisfy(item, version)
: !p()
@ -431,6 +518,10 @@ const satisfy = (range, version) => {
/* eslint-enable eqeqeq */
module.exports.satisfy = satisfy;
/**
* @param {SemVerRange | string | number | false | undefined} json
* @returns {string}
*/
module.exports.stringifyHoley = json => {
switch (typeof json) {
case "undefined":
@ -453,6 +544,10 @@ module.exports.stringifyHoley = json => {
};
//#region runtime code: parseVersion
/**
* @param {RuntimeTemplate} runtimeTemplate
* @returns {string}
*/
exports.parseVersionRuntimeCode = runtimeTemplate =>
`var parseVersion = ${runtimeTemplate.basicFunction("str", [
"// see webpack/lib/util/semver.js for original code",
@ -461,6 +556,10 @@ exports.parseVersionRuntimeCode = runtimeTemplate =>
//#endregion
//#region runtime code: versionLt
/**
* @param {RuntimeTemplate} runtimeTemplate
* @returns {string}
*/
exports.versionLtRuntimeCode = runtimeTemplate =>
`var versionLt = ${runtimeTemplate.basicFunction("a, b", [
"// see webpack/lib/util/semver.js for original code",
@ -469,6 +568,10 @@ exports.versionLtRuntimeCode = runtimeTemplate =>
//#endregion
//#region runtime code: rangeToString
/**
* @param {RuntimeTemplate} runtimeTemplate
* @returns {string}
*/
exports.rangeToStringRuntimeCode = runtimeTemplate =>
`var rangeToString = ${runtimeTemplate.basicFunction("range", [
"// see webpack/lib/util/semver.js for original code",
@ -477,6 +580,10 @@ exports.rangeToStringRuntimeCode = runtimeTemplate =>
//#endregion
//#region runtime code: satisfy
/**
* @param {RuntimeTemplate} runtimeTemplate
* @returns {string}
*/
exports.satisfyRuntimeCode = runtimeTemplate =>
`var satisfy = ${runtimeTemplate.basicFunction("range, version", [
"// see webpack/lib/util/semver.js for original code",

View File

@ -66,6 +66,10 @@ const files = ["lib/util/semver.js"];
fullMatch,
`
//#region runtime code: ${name}
/**
* @param {RuntimeTemplate} runtimeTemplate
* @returns {string}
*/
exports.${name}RuntimeCode = runtimeTemplate => \`var ${name} = \${runtimeTemplate.basicFunction("${args}", [
"// see webpack/${file} for original code",
${templateLiteral ? `\`${code}\`` : `'${code}'`}

9
types.d.ts vendored
View File

@ -9266,7 +9266,7 @@ declare class NormalModule extends Module {
static getCompilationHooks(
compilation: Compilation
): NormalModuleCompilationHooks;
static deserialize(context?: any): NormalModule;
static deserialize(context: ObjectDeserializerContext): any;
}
declare interface NormalModuleCompilationHooks {
loader: SyncHook<[LoaderContextNormalModule<any>, NormalModule]>;
@ -10081,7 +10081,10 @@ declare interface Options {
associatedObjectForCache?: object;
}
declare abstract class OptionsApply {
process(options?: any, compiler?: any): void;
process(
options: WebpackOptionsNormalized,
compiler: Compiler
): WebpackOptionsNormalized;
}
declare interface OriginRecord {
module: null | Module;
@ -15390,7 +15393,7 @@ declare namespace exports {
callback?: CallbackWebpack<MultiStats>
): MultiCompiler;
};
export const validate: (options?: any) => void;
export const validate: (arg0: Configuration) => void;
export const validateSchema: (
schema: Parameters<typeof validateFunction>[0],
options: Parameters<typeof validateFunction>[1],