adding some random types

This commit is contained in:
Tobias Koppers 2019-07-17 23:35:05 +02:00
parent cac462cba8
commit e2b1ab3258
4 changed files with 116 additions and 8 deletions

View File

@ -7,6 +7,9 @@
const AsyncQueue = require("./util/AsyncQueue");
/** @typedef {import("./WebpackError")} WebpackError */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
let FS_ACCURACY = 2000;
/**
@ -15,6 +18,14 @@ let FS_ACCURACY = 2000;
* @property {number} timestamp
*/
/**
* @typedef {Object} Snapshot
* @property {number} startTime
* @property {Map<string, FileSystemInfoEntry | "error">} fileTimestamps
* @property {Map<string, FileSystemInfoEntry | "error">} contextTimestamps
* @property {Map<string, FileSystemInfoEntry | "error">} missingTimestamps
*/
/* istanbul ignore next */
const applyMtime = mtime => {
if (FS_ACCURACY > 1 && mtime % 2 !== 0) FS_ACCURACY = 1;
@ -24,6 +35,9 @@ const applyMtime = mtime => {
};
class FileSystemInfo {
/**
* @param {InputFileSystem} fs file system
*/
constructor(fs) {
this.fs = fs;
/** @type {Map<string, FileSystemInfoEntry | null>} */
@ -64,7 +78,7 @@ class FileSystemInfo {
/**
* @param {string} path file path
* @param {function(Error=, FileSystemInfoEntry=): void} callback callback function
* @param {function(WebpackError=, FileSystemInfoEntry=): void} callback callback function
* @returns {void}
*/
getFileTimestamp(path, callback) {
@ -75,7 +89,7 @@ class FileSystemInfo {
/**
* @param {string} path context path
* @param {function(Error=, FileSystemInfoEntry=): void} callback callback function
* @param {function(WebpackError=, FileSystemInfoEntry=): void} callback callback function
* @returns {void}
*/
getContextTimestamp(path, callback) {
@ -84,9 +98,22 @@ class FileSystemInfo {
this.contextTimestampQueue.add(path, callback);
}
/**
*
* @param {number} startTime when processing the files has started
* @param {Iterable<string>} files all files
* @param {Iterable<string>} directories all directories
* @param {Iterable<string>} missing all missing files or directories
* @param {Object} options options object (for future extensions)
* @param {function(WebpackError=, Snapshot=): void} callback callback function
* @returns {void}
*/
createSnapshot(startTime, files, directories, missing, options, callback) {
/** @type {Map<string, FileSystemInfoEntry | "error">} */
const fileTimestamps = new Map();
/** @type {Map<string, FileSystemInfoEntry | "error">} */
const contextTimestamps = new Map();
/** @type {Map<string, FileSystemInfoEntry | "error">} */
const missingTimestamps = new Map();
let jobs = 1;
const jobDone = () => {
@ -144,6 +171,11 @@ class FileSystemInfo {
jobDone();
}
/**
* @param {Snapshot} snapshot the snapshot made
* @param {function(WebpackError=, boolean=): void} callback callback function
* @returns {void}
*/
checkSnapshotValid(snapshot, callback) {
const {
startTime,
@ -163,6 +195,11 @@ class FileSystemInfo {
callback(null, false);
}
};
/**
* @param {FileSystemInfoEntry} current current entry
* @param {FileSystemInfoEntry | "error"} snap entry from snapshot
* @returns {boolean} true, if ok
*/
const checkExistance = (current, snap) => {
if (snap === "error") {
// If there was an error while snapshotting (i. e. EBUSY)
@ -171,6 +208,11 @@ class FileSystemInfo {
}
return !current === !snap;
};
/**
* @param {FileSystemInfoEntry} current current entry
* @param {FileSystemInfoEntry | "error"} snap entry from snapshot
* @returns {boolean} true, if ok
*/
const checkFile = (current, snap) => {
if (snap === "error") {
// If there was an error while snapshotting (i. e. EBUSY)

View File

@ -8,7 +8,21 @@
/** @typedef {import("enhanced-resolve/lib/Resolver")} Resolver */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../FileSystemInfo")} FileSystemInfo */
/** @typedef {import("../FileSystemInfo").Snapshot} Snapshot */
/**
* @typedef {Object} CacheEntry
* @property {Object} result
* @property {Set<string>} fileDependencies
* @property {Set<string>} contextDependencies
* @property {Set<string>} missingDependencies
* @property {Snapshot} snapshot
*/
/**
* @param {Object} request a request
* @returns {string} stringified version
*/
const requestToString = request => {
let str = "";
for (const key in request) {
@ -34,6 +48,15 @@ class ResolverCachePlugin {
compiler.hooks.thisCompilation.tap("ResolverCachePlugin", compilation => {
fileSystemInfo = compilation.fileSystemInfo;
});
/**
* @param {string} identifier cache key
* @param {string} type resolver type
* @param {Resolver} resolver the resolver
* @param {Object} resolveContext context for resolving meta info
* @param {Object} request the request info object
* @param {function(Error=, Object=): void} callback callback function
* @returns {void}
*/
const doRealResolve = (
identifier,
type,
@ -89,7 +112,7 @@ class ResolverCachePlugin {
cache.store(
identifier,
null,
{
/** @type {CacheEntry} */ {
result,
fileDependencies: newResolveContext.fileDependencies,
contextDependencies: newResolveContext.contextDependencies,
@ -130,6 +153,11 @@ class ResolverCachePlugin {
const identifier = `/resolve/${type}${requestToString(
request
)}`;
/**
* @param {Error=} err error if any
* @param {CacheEntry=} cacheEntry cache entry
* @returns {void}
*/
const processCacheResult = (err, cacheEntry) => {
if (err) return callback(err);

View File

@ -11,26 +11,39 @@ const DONE_MARKER = 2;
const DONE_MAYBE_ROOT_CYCLE_MARKER = 3;
const DONE_AND_ROOT_MARKER = 4;
/**
* @template T
*/
class Node {
/**
* @param {T} item the value of the node
*/
constructor(item) {
this.item = item;
/** @type {Set<Node<T>>} */
this.dependencies = new Set();
this.marker = NO_MARKER;
/** @type {Cycle<T> | undefined} */
this.cycle = undefined;
this.incoming = 0;
}
}
/**
* @template T
*/
class Cycle {
constructor() {
/** @type {Set<Node<T>>} */
this.nodes = new Set();
}
}
/**
* @template T
* @typedef {Object} StackEntry
* @property {Node} node
* @property {Node[]} openEdges
* @property {Node<T>} node
* @property {Node<T>[]} openEdges
*/
/**
@ -40,6 +53,7 @@ class Cycle {
* @returns {Iterable<T>} graph roots of the items
*/
module.exports = (items, getDependencies) => {
/** @type {Map<T, Node<T>>} */
const itemToNode = new Map();
for (const item of items) {
const node = new Node(item);
@ -61,13 +75,13 @@ module.exports = (items, getDependencies) => {
// Set of current root modules
// items will be removed if a new reference to it has been found
/** @type {Set<Node>} */
/** @type {Set<Node<T>>} */
const roots = new Set();
// Set of current cycles without references to it
// cycles will be removed if a new reference to it has been found
// that is not part of the cycle
/** @type {Set<Cycle>} */
/** @type {Set<Cycle<T>>} */
const rootCycles = new Set();
// For all non-marked nodes
@ -80,7 +94,7 @@ module.exports = (items, getDependencies) => {
selectedNode.marker = IN_PROGRESS_MARKER;
// keep a stack to avoid recursive walk
/** @type {StackEntry[]} */
/** @type {StackEntry<T>[]} */
const stack = [
{
node: selectedNode,
@ -185,6 +199,7 @@ module.exports = (items, getDependencies) => {
// inside of the cycle
for (const cycle of rootCycles) {
let max = 0;
/** @type {Set<Node<T>>} */
const cycleRoots = new Set();
const nodes = cycle.nodes;
for (const node of nodes) {

View File

@ -15,17 +15,40 @@ const projectPaths = [
path.resolve(__dirname, "../declarations.d.ts")
];
/**
* @param {string} file filename
* @returns {boolean} true, when file is part of the project
*/
const isProjectFile = file => {
return projectPaths.some(p =>
file.toLowerCase().startsWith(p.replace(/\\/g, "/").toLowerCase())
);
};
/**
* @typedef {Object} Location
* @property {number} line
* @property {number} column
*/
/**
* @typedef {Object} FileReport
* @property {string} path
* @property {Record<number, { start: Location, end: Location }>} statementMap
* @property {{}} fnMap
* @property {{}} branchMap
* @property {Record<number, number>} s
* @property {{}} f
* @property {{}} b
*/
/** @type {Record<string, FileReport>} */
const coverageReport = Object.create(null);
for (const sourceFile of program.getSourceFiles()) {
let file = sourceFile.fileName;
if (isProjectFile(file)) {
/** @type {FileReport} */
const rep = {
path: path.sep !== "/" ? file.replace(/\//g, path.sep) : file,
statementMap: {},