| /** |
| * @fileoverview `Map` to load rules lazily. |
| * @author Toru Nagashima <https://github.com/mysticatea> |
| */ |
| "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<string, () => 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<Rule>} 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 }; |