source: imaps-frontend/node_modules/webpack/lib/util/runtime.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 4 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 15.8 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const SortableSet = require("./SortableSet");
9
10/** @typedef {import("../Compilation")} Compilation */
11/** @typedef {import("../Entrypoint").EntryOptions} EntryOptions */
12
13/** @typedef {string | SortableSet<string> | undefined} RuntimeSpec */
14/** @typedef {RuntimeSpec | boolean} RuntimeCondition */
15
16/**
17 * @param {Compilation} compilation the compilation
18 * @param {string} name name of the entry
19 * @param {EntryOptions=} options optionally already received entry options
20 * @returns {RuntimeSpec} runtime
21 */
22module.exports.getEntryRuntime = (compilation, name, options) => {
23 let dependOn;
24 let runtime;
25 if (options) {
26 ({ dependOn, runtime } = options);
27 } else {
28 const entry = compilation.entries.get(name);
29 if (!entry) return name;
30 ({ dependOn, runtime } = entry.options);
31 }
32 if (dependOn) {
33 /** @type {RuntimeSpec} */
34 let result;
35 const queue = new Set(dependOn);
36 for (const name of queue) {
37 const dep = compilation.entries.get(name);
38 if (!dep) continue;
39 const { dependOn, runtime } = dep.options;
40 if (dependOn) {
41 for (const name of dependOn) {
42 queue.add(name);
43 }
44 } else {
45 result = mergeRuntimeOwned(result, runtime || name);
46 }
47 }
48 return result || name;
49 }
50 return runtime || name;
51};
52
53/**
54 * @param {RuntimeSpec} runtime runtime
55 * @param {function(string | undefined): void} fn functor
56 * @param {boolean} deterministicOrder enforce a deterministic order
57 * @returns {void}
58 */
59const forEachRuntime = (runtime, fn, deterministicOrder = false) => {
60 if (runtime === undefined) {
61 fn(undefined);
62 } else if (typeof runtime === "string") {
63 fn(runtime);
64 } else {
65 if (deterministicOrder) runtime.sort();
66 for (const r of runtime) {
67 fn(r);
68 }
69 }
70};
71module.exports.forEachRuntime = forEachRuntime;
72
73/**
74 * @template T
75 * @param {SortableSet<T>} set set
76 * @returns {string} runtime key
77 */
78const getRuntimesKey = set => {
79 set.sort();
80 return Array.from(set).join("\n");
81};
82
83/**
84 * @param {RuntimeSpec} runtime runtime(s)
85 * @returns {string} key of runtimes
86 */
87const getRuntimeKey = runtime => {
88 if (runtime === undefined) return "*";
89 if (typeof runtime === "string") return runtime;
90 return runtime.getFromUnorderedCache(getRuntimesKey);
91};
92module.exports.getRuntimeKey = getRuntimeKey;
93
94/**
95 * @param {string} key key of runtimes
96 * @returns {RuntimeSpec} runtime(s)
97 */
98const keyToRuntime = key => {
99 if (key === "*") return;
100 const items = key.split("\n");
101 if (items.length === 1) return items[0];
102 return new SortableSet(items);
103};
104module.exports.keyToRuntime = keyToRuntime;
105
106/**
107 * @template T
108 * @param {SortableSet<T>} set set
109 * @returns {string} runtime string
110 */
111const getRuntimesString = set => {
112 set.sort();
113 return Array.from(set).join("+");
114};
115
116/**
117 * @param {RuntimeSpec} runtime runtime(s)
118 * @returns {string} readable version
119 */
120const runtimeToString = runtime => {
121 if (runtime === undefined) return "*";
122 if (typeof runtime === "string") return runtime;
123 return runtime.getFromUnorderedCache(getRuntimesString);
124};
125module.exports.runtimeToString = runtimeToString;
126
127/**
128 * @param {RuntimeCondition} runtimeCondition runtime condition
129 * @returns {string} readable version
130 */
131module.exports.runtimeConditionToString = runtimeCondition => {
132 if (runtimeCondition === true) return "true";
133 if (runtimeCondition === false) return "false";
134 return runtimeToString(runtimeCondition);
135};
136
137/**
138 * @param {RuntimeSpec} a first
139 * @param {RuntimeSpec} b second
140 * @returns {boolean} true, when they are equal
141 */
142const runtimeEqual = (a, b) => {
143 if (a === b) {
144 return true;
145 } else if (
146 a === undefined ||
147 b === undefined ||
148 typeof a === "string" ||
149 typeof b === "string"
150 ) {
151 return false;
152 } else if (a.size !== b.size) {
153 return false;
154 }
155 a.sort();
156 b.sort();
157 const aIt = a[Symbol.iterator]();
158 const bIt = b[Symbol.iterator]();
159 for (;;) {
160 const aV = aIt.next();
161 if (aV.done) return true;
162 const bV = bIt.next();
163 if (aV.value !== bV.value) return false;
164 }
165};
166module.exports.runtimeEqual = runtimeEqual;
167
168/**
169 * @param {RuntimeSpec} a first
170 * @param {RuntimeSpec} b second
171 * @returns {-1|0|1} compare
172 */
173module.exports.compareRuntime = (a, b) => {
174 if (a === b) {
175 return 0;
176 } else if (a === undefined) {
177 return -1;
178 } else if (b === undefined) {
179 return 1;
180 }
181 const aKey = getRuntimeKey(a);
182 const bKey = getRuntimeKey(b);
183 if (aKey < bKey) return -1;
184 if (aKey > bKey) return 1;
185 return 0;
186};
187
188/**
189 * @param {RuntimeSpec} a first
190 * @param {RuntimeSpec} b second
191 * @returns {RuntimeSpec} merged
192 */
193const mergeRuntime = (a, b) => {
194 if (a === undefined) {
195 return b;
196 } else if (b === undefined) {
197 return a;
198 } else if (a === b) {
199 return a;
200 } else if (typeof a === "string") {
201 if (typeof b === "string") {
202 const set = new SortableSet();
203 set.add(a);
204 set.add(b);
205 return set;
206 } else if (b.has(a)) {
207 return b;
208 }
209 const set = new SortableSet(b);
210 set.add(a);
211 return set;
212 }
213 if (typeof b === "string") {
214 if (a.has(b)) return a;
215 const set = new SortableSet(a);
216 set.add(b);
217 return set;
218 }
219 const set = new SortableSet(a);
220 for (const item of b) set.add(item);
221 if (set.size === a.size) return a;
222 return set;
223};
224module.exports.mergeRuntime = mergeRuntime;
225
226/**
227 * @param {RuntimeCondition} a first
228 * @param {RuntimeCondition} b second
229 * @param {RuntimeSpec} runtime full runtime
230 * @returns {RuntimeCondition} result
231 */
232module.exports.mergeRuntimeCondition = (a, b, runtime) => {
233 if (a === false) return b;
234 if (b === false) return a;
235 if (a === true || b === true) return true;
236 const merged = mergeRuntime(a, b);
237 if (merged === undefined) return;
238 if (typeof merged === "string") {
239 if (typeof runtime === "string" && merged === runtime) return true;
240 return merged;
241 }
242 if (typeof runtime === "string" || runtime === undefined) return merged;
243 if (merged.size === runtime.size) return true;
244 return merged;
245};
246
247/**
248 * @param {RuntimeSpec | true} a first
249 * @param {RuntimeSpec | true} b second
250 * @param {RuntimeSpec} runtime full runtime
251 * @returns {RuntimeSpec | true} result
252 */
253module.exports.mergeRuntimeConditionNonFalse = (a, b, runtime) => {
254 if (a === true || b === true) return true;
255 const merged = mergeRuntime(a, b);
256 if (merged === undefined) return;
257 if (typeof merged === "string") {
258 if (typeof runtime === "string" && merged === runtime) return true;
259 return merged;
260 }
261 if (typeof runtime === "string" || runtime === undefined) return merged;
262 if (merged.size === runtime.size) return true;
263 return merged;
264};
265
266/**
267 * @param {RuntimeSpec} a first (may be modified)
268 * @param {RuntimeSpec} b second
269 * @returns {RuntimeSpec} merged
270 */
271const mergeRuntimeOwned = (a, b) => {
272 if (b === undefined) {
273 return a;
274 } else if (a === b) {
275 return a;
276 } else if (a === undefined) {
277 if (typeof b === "string") {
278 return b;
279 }
280 return new SortableSet(b);
281 } else if (typeof a === "string") {
282 if (typeof b === "string") {
283 const set = new SortableSet();
284 set.add(a);
285 set.add(b);
286 return set;
287 }
288 const set = new SortableSet(b);
289 set.add(a);
290 return set;
291 }
292 if (typeof b === "string") {
293 a.add(b);
294 return a;
295 }
296 for (const item of b) a.add(item);
297 return a;
298};
299module.exports.mergeRuntimeOwned = mergeRuntimeOwned;
300
301/**
302 * @param {RuntimeSpec} a first
303 * @param {RuntimeSpec} b second
304 * @returns {RuntimeSpec} merged
305 */
306module.exports.intersectRuntime = (a, b) => {
307 if (a === undefined) {
308 return b;
309 } else if (b === undefined) {
310 return a;
311 } else if (a === b) {
312 return a;
313 } else if (typeof a === "string") {
314 if (typeof b === "string") {
315 return;
316 } else if (b.has(a)) {
317 return a;
318 }
319 return;
320 }
321 if (typeof b === "string") {
322 if (a.has(b)) return b;
323 return;
324 }
325 const set = new SortableSet();
326 for (const item of b) {
327 if (a.has(item)) set.add(item);
328 }
329 if (set.size === 0) return;
330 if (set.size === 1) {
331 const [item] = set;
332 return item;
333 }
334 return set;
335};
336
337/**
338 * @param {RuntimeSpec} a first
339 * @param {RuntimeSpec} b second
340 * @returns {RuntimeSpec} result
341 */
342const subtractRuntime = (a, b) => {
343 if (a === undefined) {
344 return;
345 } else if (b === undefined) {
346 return a;
347 } else if (a === b) {
348 return;
349 } else if (typeof a === "string") {
350 if (typeof b === "string") {
351 return a;
352 } else if (b.has(a)) {
353 return;
354 }
355 return a;
356 }
357 if (typeof b === "string") {
358 if (!a.has(b)) return a;
359 if (a.size === 2) {
360 for (const item of a) {
361 if (item !== b) return item;
362 }
363 }
364 const set = new SortableSet(a);
365 set.delete(b);
366 return set;
367 }
368 const set = new SortableSet();
369 for (const item of a) {
370 if (!b.has(item)) set.add(item);
371 }
372 if (set.size === 0) return;
373 if (set.size === 1) {
374 const [item] = set;
375 return item;
376 }
377 return set;
378};
379module.exports.subtractRuntime = subtractRuntime;
380
381/**
382 * @param {RuntimeCondition} a first
383 * @param {RuntimeCondition} b second
384 * @param {RuntimeSpec} runtime runtime
385 * @returns {RuntimeCondition} result
386 */
387module.exports.subtractRuntimeCondition = (a, b, runtime) => {
388 if (b === true) return false;
389 if (b === false) return a;
390 if (a === false) return false;
391 const result = subtractRuntime(a === true ? runtime : a, b);
392 return result === undefined ? false : result;
393};
394
395/**
396 * @param {RuntimeSpec} runtime runtime
397 * @param {function(RuntimeSpec=): boolean} filter filter function
398 * @returns {boolean | RuntimeSpec} true/false if filter is constant for all runtimes, otherwise runtimes that are active
399 */
400module.exports.filterRuntime = (runtime, filter) => {
401 if (runtime === undefined) return filter();
402 if (typeof runtime === "string") return filter(runtime);
403 let some = false;
404 let every = true;
405 let result;
406 for (const r of runtime) {
407 const v = filter(r);
408 if (v) {
409 some = true;
410 result = mergeRuntimeOwned(result, r);
411 } else {
412 every = false;
413 }
414 }
415 if (!some) return false;
416 if (every) return true;
417 return result;
418};
419
420/**
421 * @template T
422 * @typedef {Map<string, T>} RuntimeSpecMapInnerMap
423 */
424
425/**
426 * @template T
427 */
428class RuntimeSpecMap {
429 /**
430 * @param {RuntimeSpecMap<T>=} clone copy form this
431 */
432 constructor(clone) {
433 this._mode = clone ? clone._mode : 0; // 0 = empty, 1 = single entry, 2 = map
434 /** @type {RuntimeSpec} */
435 this._singleRuntime = clone ? clone._singleRuntime : undefined;
436 /** @type {T | undefined} */
437 this._singleValue = clone ? clone._singleValue : undefined;
438 /** @type {RuntimeSpecMapInnerMap<T> | undefined} */
439 this._map = clone && clone._map ? new Map(clone._map) : undefined;
440 }
441
442 /**
443 * @param {RuntimeSpec} runtime the runtimes
444 * @returns {T | undefined} value
445 */
446 get(runtime) {
447 switch (this._mode) {
448 case 0:
449 return;
450 case 1:
451 return runtimeEqual(this._singleRuntime, runtime)
452 ? this._singleValue
453 : undefined;
454 default:
455 return /** @type {RuntimeSpecMapInnerMap<T>} */ (this._map).get(
456 getRuntimeKey(runtime)
457 );
458 }
459 }
460
461 /**
462 * @param {RuntimeSpec} runtime the runtimes
463 * @returns {boolean} true, when the runtime is stored
464 */
465 has(runtime) {
466 switch (this._mode) {
467 case 0:
468 return false;
469 case 1:
470 return runtimeEqual(this._singleRuntime, runtime);
471 default:
472 return /** @type {RuntimeSpecMapInnerMap<T>} */ (this._map).has(
473 getRuntimeKey(runtime)
474 );
475 }
476 }
477
478 /**
479 * @param {RuntimeSpec} runtime the runtimes
480 * @param {T} value the value
481 */
482 set(runtime, value) {
483 switch (this._mode) {
484 case 0:
485 this._mode = 1;
486 this._singleRuntime = runtime;
487 this._singleValue = value;
488 break;
489 case 1:
490 if (runtimeEqual(this._singleRuntime, runtime)) {
491 this._singleValue = value;
492 break;
493 }
494 this._mode = 2;
495 this._map = new Map();
496 this._map.set(
497 getRuntimeKey(this._singleRuntime),
498 /** @type {T} */ (this._singleValue)
499 );
500 this._singleRuntime = undefined;
501 this._singleValue = undefined;
502 /* falls through */
503 default:
504 /** @type {RuntimeSpecMapInnerMap<T>} */
505 (this._map).set(getRuntimeKey(runtime), value);
506 }
507 }
508
509 /**
510 * @param {RuntimeSpec} runtime the runtimes
511 * @param {() => TODO} computer function to compute the value
512 * @returns {TODO} true, when the runtime was deleted
513 */
514 provide(runtime, computer) {
515 switch (this._mode) {
516 case 0:
517 this._mode = 1;
518 this._singleRuntime = runtime;
519 return (this._singleValue = computer());
520 case 1: {
521 if (runtimeEqual(this._singleRuntime, runtime)) {
522 return /** @type {T} */ (this._singleValue);
523 }
524 this._mode = 2;
525 this._map = new Map();
526 this._map.set(
527 getRuntimeKey(this._singleRuntime),
528 /** @type {T} */ (this._singleValue)
529 );
530 this._singleRuntime = undefined;
531 this._singleValue = undefined;
532 const newValue = computer();
533 this._map.set(getRuntimeKey(runtime), newValue);
534 return newValue;
535 }
536 default: {
537 const key = getRuntimeKey(runtime);
538 const value = /** @type {Map<string, T>} */ (this._map).get(key);
539 if (value !== undefined) return value;
540 const newValue = computer();
541 /** @type {Map<string, T>} */
542 (this._map).set(key, newValue);
543 return newValue;
544 }
545 }
546 }
547
548 /**
549 * @param {RuntimeSpec} runtime the runtimes
550 */
551 delete(runtime) {
552 switch (this._mode) {
553 case 0:
554 return;
555 case 1:
556 if (runtimeEqual(this._singleRuntime, runtime)) {
557 this._mode = 0;
558 this._singleRuntime = undefined;
559 this._singleValue = undefined;
560 }
561 return;
562 default:
563 /** @type {RuntimeSpecMapInnerMap<T>} */
564 (this._map).delete(getRuntimeKey(runtime));
565 }
566 }
567
568 /**
569 * @param {RuntimeSpec} runtime the runtimes
570 * @param {function(T | undefined): T} fn function to update the value
571 */
572 update(runtime, fn) {
573 switch (this._mode) {
574 case 0:
575 throw new Error("runtime passed to update must exist");
576 case 1: {
577 if (runtimeEqual(this._singleRuntime, runtime)) {
578 this._singleValue = fn(this._singleValue);
579 break;
580 }
581 const newValue = fn(undefined);
582 if (newValue !== undefined) {
583 this._mode = 2;
584 this._map = new Map();
585 this._map.set(
586 getRuntimeKey(this._singleRuntime),
587 /** @type {T} */ (this._singleValue)
588 );
589 this._singleRuntime = undefined;
590 this._singleValue = undefined;
591 this._map.set(getRuntimeKey(runtime), newValue);
592 }
593 break;
594 }
595 default: {
596 const key = getRuntimeKey(runtime);
597 const oldValue = /** @type {Map<string, T>} */ (this._map).get(key);
598 const newValue = fn(oldValue);
599 if (newValue !== oldValue)
600 /** @type {RuntimeSpecMapInnerMap<T>} */
601 (this._map).set(key, newValue);
602 }
603 }
604 }
605
606 keys() {
607 switch (this._mode) {
608 case 0:
609 return [];
610 case 1:
611 return [this._singleRuntime];
612 default:
613 return Array.from(
614 /** @type {RuntimeSpecMapInnerMap<T>} */
615 (this._map).keys(),
616 keyToRuntime
617 );
618 }
619 }
620
621 /**
622 * @returns {IterableIterator<T>} values
623 */
624 values() {
625 switch (this._mode) {
626 case 0:
627 return [][Symbol.iterator]();
628 case 1:
629 return [/** @type {T} */ (this._singleValue)][Symbol.iterator]();
630 default:
631 return /** @type {Map<string, T>} */ (this._map).values();
632 }
633 }
634
635 get size() {
636 if (/** @type {number} */ (this._mode) <= 1) {
637 return /** @type {number} */ (this._mode);
638 }
639
640 return /** @type {Map<string, T>} */ (this._map).size;
641 }
642}
643
644module.exports.RuntimeSpecMap = RuntimeSpecMap;
645
646class RuntimeSpecSet {
647 /**
648 * @param {Iterable<RuntimeSpec>=} iterable iterable
649 */
650 constructor(iterable) {
651 /** @type {Map<string, RuntimeSpec>} */
652 this._map = new Map();
653 if (iterable) {
654 for (const item of iterable) {
655 this.add(item);
656 }
657 }
658 }
659
660 /**
661 * @param {RuntimeSpec} runtime runtime
662 */
663 add(runtime) {
664 this._map.set(getRuntimeKey(runtime), runtime);
665 }
666
667 /**
668 * @param {RuntimeSpec} runtime runtime
669 * @returns {boolean} true, when the runtime exists
670 */
671 has(runtime) {
672 return this._map.has(getRuntimeKey(runtime));
673 }
674
675 /**
676 * @returns {IterableIterator<RuntimeSpec>} iterable iterator
677 */
678 [Symbol.iterator]() {
679 return this._map.values();
680 }
681
682 get size() {
683 return this._map.size;
684 }
685}
686
687module.exports.RuntimeSpecSet = RuntimeSpecSet;
Note: See TracBrowser for help on using the repository browser.