source: frontend/node_modules/webpack/lib/CodeGenerationResults.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 6.0 KB
RevLine 
[9af201e]1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const { DEFAULTS } = require("./config/defaults");
9const { getOrInsert } = require("./util/MapHelpers");
10const { first } = require("./util/SetHelpers");
11const createHash = require("./util/createHash");
12const { RuntimeSpecMap, runtimeToString } = require("./util/runtime");
13
14/** @typedef {import("webpack-sources").Source} Source */
15/** @typedef {import("./Module")} Module */
16/** @typedef {import("./Module").SourceType} SourceType */
17/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
18/** @typedef {import("./Module").CodeGenerationResultData} CodeGenerationResultData */
19/** @typedef {import("./Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
20/** @typedef {import("./util/Hash").HashFunction} HashFunction */
21/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
22
23/**
24 * Stores code generation results keyed by module and runtime so later stages
25 * can retrieve emitted sources, metadata, and derived hashes.
26 */
27class CodeGenerationResults {
28 /**
29 * Initializes an empty result store and remembers which hash function should
30 * be used when a result hash needs to be derived lazily.
31 * @param {HashFunction} hashFunction the hash function to use
32 */
33 constructor(hashFunction = DEFAULTS.HASH_FUNCTION) {
34 /** @type {Map<Module, RuntimeSpecMap<CodeGenerationResult>>} */
35 this.map = new Map();
36 /** @type {HashFunction} */
37 this._hashFunction = hashFunction;
38 }
39
40 /**
41 * Returns the code generation result for a module/runtime pair, rejecting
42 * ambiguous lookups where no unique runtime-independent result exists.
43 * @param {Module} module the module
44 * @param {RuntimeSpec} runtime runtime(s)
45 * @returns {CodeGenerationResult} the CodeGenerationResult
46 */
47 get(module, runtime) {
48 const entry = this.map.get(module);
49 if (entry === undefined) {
50 throw new Error(
51 `No code generation entry for ${module.identifier()} (existing entries: ${Array.from(
52 this.map.keys(),
53 (m) => m.identifier()
54 ).join(", ")})`
55 );
56 }
57 if (runtime === undefined) {
58 if (entry.size > 1) {
59 const results = new Set(entry.values());
60 if (results.size !== 1) {
61 throw new Error(
62 `No unique code generation entry for unspecified runtime for ${module.identifier()} (existing runtimes: ${Array.from(
63 entry.keys(),
64 (r) => runtimeToString(r)
65 ).join(", ")}).
66Caller might not support runtime-dependent code generation (opt-out via optimization.usedExports: "global").`
67 );
68 }
69 return /** @type {CodeGenerationResult} */ (first(results));
70 }
71 return /** @type {CodeGenerationResult} */ (entry.values().next().value);
72 }
73 const result = entry.get(runtime);
74 if (result === undefined) {
75 throw new Error(
76 `No code generation entry for runtime ${runtimeToString(
77 runtime
78 )} for ${module.identifier()} (existing runtimes: ${Array.from(
79 entry.keys(),
80 (r) => runtimeToString(r)
81 ).join(", ")})`
82 );
83 }
84 return result;
85 }
86
87 /**
88 * Reports whether a module has a stored result for the requested runtime, or
89 * a single unambiguous result when no runtime is specified.
90 * @param {Module} module the module
91 * @param {RuntimeSpec} runtime runtime(s)
92 * @returns {boolean} true, when we have data for this
93 */
94 has(module, runtime) {
95 const entry = this.map.get(module);
96 if (entry === undefined) {
97 return false;
98 }
99 if (runtime !== undefined) {
100 return entry.has(runtime);
101 } else if (entry.size > 1) {
102 const results = new Set(entry.values());
103 return results.size === 1;
104 }
105 return entry.size === 1;
106 }
107
108 /**
109 * Returns a generated source of the requested source type from a stored code
110 * generation result.
111 * @param {Module} module the module
112 * @param {RuntimeSpec} runtime runtime(s)
113 * @param {SourceType} sourceType the source type
114 * @returns {Source} a source
115 */
116 getSource(module, runtime, sourceType) {
117 return /** @type {Source} */ (
118 this.get(module, runtime).sources.get(sourceType)
119 );
120 }
121
122 /**
123 * Returns the runtime requirements captured during code generation for the
124 * requested module/runtime pair.
125 * @param {Module} module the module
126 * @param {RuntimeSpec} runtime runtime(s)
127 * @returns {ReadOnlyRuntimeRequirements | null} runtime requirements
128 */
129 getRuntimeRequirements(module, runtime) {
130 return this.get(module, runtime).runtimeRequirements;
131 }
132
133 /**
134 * Returns an arbitrary metadata entry recorded during code generation.
135 * @param {Module} module the module
136 * @param {RuntimeSpec} runtime runtime(s)
137 * @param {string} key data key
138 * @returns {ReturnType<CodeGenerationResultData["get"]>} data generated by code generation
139 */
140 getData(module, runtime, key) {
141 const data = this.get(module, runtime).data;
142 return data === undefined ? undefined : data.get(key);
143 }
144
145 /**
146 * Returns a stable hash for the generated sources and runtime requirements,
147 * computing and caching it on first access.
148 * @param {Module} module the module
149 * @param {RuntimeSpec} runtime runtime(s)
150 * @returns {string} hash of the code generation
151 */
152 getHash(module, runtime) {
153 const info = this.get(module, runtime);
154 if (info.hash !== undefined) return info.hash;
155 const hash = createHash(this._hashFunction);
156 for (const [type, source] of info.sources) {
157 hash.update(type);
158 source.updateHash(hash);
159 }
160 if (info.runtimeRequirements) {
161 for (const rr of info.runtimeRequirements) hash.update(rr);
162 }
163 return (info.hash = hash.digest("hex"));
164 }
165
166 /**
167 * Stores a code generation result for a module/runtime pair, creating the
168 * per-module runtime map when needed.
169 * @param {Module} module the module
170 * @param {RuntimeSpec} runtime runtime(s)
171 * @param {CodeGenerationResult} result result from module
172 * @returns {void}
173 */
174 add(module, runtime, result) {
175 const map = getOrInsert(
176 this.map,
177 module,
178 () =>
179 /** @type {RuntimeSpecMap<CodeGenerationResult>} */
180 new RuntimeSpecMap()
181 );
182 map.set(runtime, result);
183 }
184}
185
186module.exports = CodeGenerationResults;
Note: See TracBrowser for help on using the repository browser.