UNPKG

3.07 kBJavaScriptView Raw
1/**
2 * @fileoverview `Map` to load rules lazily.
3 * @author Toru Nagashima <https://github.com/mysticatea>
4 */
5"use strict";
6
7const debug = require("debug")("eslint:rules");
8
9/** @typedef {import("./types").Rule} Rule */
10
11/**
12 * The `Map` object that loads each rule when it's accessed.
13 * @example
14 * const rules = new LazyLoadingRuleMap([
15 * ["eqeqeq", () => require("eqeqeq")],
16 * ["semi", () => require("semi")],
17 * ["no-unused-vars", () => require("no-unused-vars")],
18 * ])
19 *
20 * rules.get("semi") // call `() => require("semi")` here.
21 *
22 * @extends {Map<string, () => Rule>}
23 */
24class LazyLoadingRuleMap extends Map {
25
26 /**
27 * Initialize this map.
28 * @param {Array<[string, function(): Rule]>} loaders The rule loaders.
29 */
30 constructor(loaders) {
31 let remaining = loaders.length;
32
33 super(
34 debug.enabled
35 ? loaders.map(([ruleId, load]) => {
36 let cache = null;
37
38 return [
39 ruleId,
40 () => {
41 if (!cache) {
42 debug("Loading rule %o (remaining=%d)", ruleId, --remaining);
43 cache = load();
44 }
45 return cache;
46 }
47 ];
48 })
49 : loaders
50 );
51
52 // `super(...iterable)` uses `this.set()`, so disable it here.
53 Object.defineProperty(LazyLoadingRuleMap.prototype, "set", {
54 configurable: true,
55 value: void 0
56 });
57 }
58
59 /**
60 * Get a rule.
61 * Each rule will be loaded on the first access.
62 * @param {string} ruleId The rule ID to get.
63 * @returns {Rule|undefined} The rule.
64 */
65 get(ruleId) {
66 const load = super.get(ruleId);
67
68 return load && load();
69 }
70
71 /**
72 * Iterate rules.
73 * @returns {IterableIterator<Rule>} Rules.
74 */
75 *values() {
76 for (const load of super.values()) {
77 yield load();
78 }
79 }
80
81 /**
82 * Iterate rules.
83 * @returns {IterableIterator<[string, Rule]>} Rules.
84 */
85 *entries() {
86 for (const [ruleId, load] of super.entries()) {
87 yield [ruleId, load()];
88 }
89 }
90
91 /**
92 * Call a function with each rule.
93 * @param {Function} callbackFn The callback function.
94 * @param {any} [thisArg] The object to pass to `this` of the callback function.
95 * @returns {void}
96 */
97 forEach(callbackFn, thisArg) {
98 for (const [ruleId, load] of super.entries()) {
99 callbackFn.call(thisArg, load(), ruleId, this);
100 }
101 }
102}
103
104// Forbid mutation.
105Object.defineProperties(LazyLoadingRuleMap.prototype, {
106 clear: { configurable: true, value: void 0 },
107 delete: { configurable: true, value: void 0 },
108 [Symbol.iterator]: {
109 configurable: true,
110 writable: true,
111 value: LazyLoadingRuleMap.prototype.entries
112 }
113});
114
115module.exports = { LazyLoadingRuleMap };