/** * @fileoverview `Map` to load rules lazily. * @author Toru Nagashima */ "use strict"; const debug = require("debug")("eslint:rules"); /** @typedef {import("./types").Rule} Rule */ /** * The `Map` object that loads each rule when it's accessed. * * @example * const rules = new LazyLoadingRuleMap([ * ["eqeqeq", () => require("eqeqeq")], * ["semi", () => require("semi")], * ["no-unused-vars", () => require("no-unused-vars")], * ]) * * rules.get("semi") // call `() => require("semi")` here. * * @extends {Map Rule>} */ class LazyLoadingRuleMap extends Map { /** * Initialize this map. * @param {Array<[string, function(): Rule]>} loaders The rule loaders. */ constructor(loaders) { let remaining = loaders.length; super( debug.enabled ? loaders.map(([ruleId, load]) => { let cache = null; return [ ruleId, () => { if (!cache) { debug("Loading rule %o (remaining=%d)", ruleId, --remaining); cache = load(); } return cache; } ]; }) : loaders ); // `super(...iterable)` uses `this.set()`, so disable it here. Object.defineProperty(LazyLoadingRuleMap.prototype, "set", { configurable: true, value: void 0 }); } /** * Get a rule. * Each rule will be loaded on the first access. * @param {string} ruleId The rule ID to get. * @returns {Rule|undefined} The rule. */ get(ruleId) { const load = super.get(ruleId); return load && load(); } /** * Iterate rules. * @returns {IterableIterator} Rules. */ *values() { for (const load of super.values()) { yield load(); } } /** * Iterate rules. * @returns {IterableIterator<[string, Rule]>} Rules. */ *entries() { for (const [ruleId, load] of super.entries()) { yield [ruleId, load()]; } } /** * Call a function with each rule. * @param {Function} callbackFn The callback function. * @param {any} [thisArg] The object to pass to `this` of the callback function. * @returns {void} */ forEach(callbackFn, thisArg) { for (const [ruleId, load] of super.entries()) { callbackFn.call(thisArg, load(), ruleId, this); } } } // Forbid mutation. Object.defineProperties(LazyLoadingRuleMap.prototype, { clear: { configurable: true, value: void 0 }, delete: { configurable: true, value: void 0 }, [Symbol.iterator]: { configurable: true, writable: true, value: LazyLoadingRuleMap.prototype.entries } }); module.exports = { LazyLoadingRuleMap };