@depup/webpack-sources 3.3.4-depup.0 → 3.6.0-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/changes.json +1 -1
- package/lib/CachedSource.js +257 -63
- package/lib/CompatSource.js +42 -1
- package/lib/ConcatSource.js +100 -28
- package/lib/OriginalSource.js +111 -45
- package/lib/PrefixSource.js +60 -11
- package/lib/RawSource.js +85 -29
- package/lib/ReplaceSource.js +269 -73
- package/lib/SizeOnlySource.js +10 -1
- package/lib/Source.js +39 -0
- package/lib/SourceMapSource.js +92 -10
- package/lib/helpers/createMappingsSerializer.js +307 -54
- package/lib/helpers/getFromStreamChunks.js +165 -73
- package/lib/helpers/getGeneratedSourceInfo.js +7 -4
- package/lib/helpers/readMappings.js +6 -3
- package/lib/helpers/scopes.js +438 -0
- package/lib/helpers/splitIntoLines.js +10 -9
- package/lib/helpers/splitIntoPotentialTokens.js +99 -26
- package/lib/helpers/streamAndGetSourceAndMap.js +61 -22
- package/lib/helpers/streamChunks.js +3 -2
- package/lib/helpers/streamChunksOfCombinedSourceMap.js +7 -3
- package/lib/helpers/streamChunksOfRawSource.js +23 -15
- package/lib/helpers/streamChunksOfSourceMap.js +50 -42
- package/lib/index.js +3 -0
- package/package.json +34 -23
- package/types/CachedSource.d.ts +192 -0
- package/types/CompatSource.d.ts +87 -0
- package/types/ConcatSource.d.ts +75 -0
- package/types/OriginalSource.d.ts +87 -0
- package/types/PrefixSource.d.ts +59 -0
- package/types/RawSource.d.ts +75 -0
- package/types/ReplaceSource.d.ts +107 -0
- package/types/SizeOnlySource.d.ts +24 -0
- package/types/Source.d.ts +189 -0
- package/types/SourceMapSource.d.ts +136 -0
- package/types/helpers/createMappingsSerializer.d.ts +60 -0
- package/types/helpers/getFromStreamChunks.d.ts +16 -0
- package/types/helpers/getGeneratedSourceInfo.d.ts +31 -0
- package/types/helpers/getName.d.ts +15 -0
- package/types/helpers/getSource.d.ts +15 -0
- package/types/helpers/readMappings.d.ts +19 -0
- package/types/helpers/scopes.d.ts +119 -0
- package/types/helpers/splitIntoLines.d.ts +6 -0
- package/types/helpers/splitIntoPotentialTokens.d.ts +37 -0
- package/types/helpers/streamAndGetSourceAndMap.d.ts +39 -0
- package/types/helpers/streamChunks.d.ts +56 -0
- package/types/helpers/streamChunksOfCombinedSourceMap.d.ts +42 -0
- package/types/helpers/streamChunksOfRawSource.d.ts +16 -0
- package/types/helpers/streamChunksOfSourceMap.d.ts +19 -0
- package/types/helpers/stringBufferUtils.d.ts +55 -0
- package/types/index.d.ts +50 -0
- package/types.d.ts +42 -439
package/lib/ConcatSource.js
CHANGED
|
@@ -11,6 +11,7 @@ const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks");
|
|
|
11
11
|
const streamChunks = require("./helpers/streamChunks");
|
|
12
12
|
|
|
13
13
|
/** @typedef {import("./CompatSource").SourceLike} SourceLike */
|
|
14
|
+
/** @typedef {import("./Source").ClearCacheOptions} ClearCacheOptions */
|
|
14
15
|
/** @typedef {import("./Source").HashLike} HashLike */
|
|
15
16
|
/** @typedef {import("./Source").MapOptions} MapOptions */
|
|
16
17
|
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */
|
|
@@ -33,15 +34,19 @@ class ConcatSource extends Source {
|
|
|
33
34
|
constructor(...args) {
|
|
34
35
|
super();
|
|
35
36
|
/**
|
|
36
|
-
* @private
|
|
37
37
|
* @type {Child[]}
|
|
38
38
|
*/
|
|
39
39
|
this._children = [];
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
// Indexed loops avoid the iterator-protocol overhead `for...of`
|
|
42
|
+
// pays per element. Hot during webpack's emit when many
|
|
43
|
+
// ConcatSources are constructed/flattened.
|
|
44
|
+
for (let i = 0, l = args.length; i < l; i++) {
|
|
45
|
+
const item = args[i];
|
|
42
46
|
if (item instanceof ConcatSource) {
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
const children = item._children;
|
|
48
|
+
for (let j = 0, jl = children.length; j < jl; j++) {
|
|
49
|
+
this._children.push(children[j]);
|
|
45
50
|
}
|
|
46
51
|
} else {
|
|
47
52
|
this._children.push(item);
|
|
@@ -49,7 +54,6 @@ class ConcatSource extends Source {
|
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
/**
|
|
52
|
-
* @private
|
|
53
57
|
* @type {boolean}
|
|
54
58
|
*/
|
|
55
59
|
this._isOptimized = args.length === 0;
|
|
@@ -69,8 +73,9 @@ class ConcatSource extends Source {
|
|
|
69
73
|
*/
|
|
70
74
|
add(item) {
|
|
71
75
|
if (item instanceof ConcatSource) {
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
const children = item._children;
|
|
77
|
+
for (let i = 0, l = children.length; i < l; i++) {
|
|
78
|
+
this._children.push(children[i]);
|
|
74
79
|
}
|
|
75
80
|
} else {
|
|
76
81
|
this._children.push(item);
|
|
@@ -83,17 +88,38 @@ class ConcatSource extends Source {
|
|
|
83
88
|
* @returns {void}
|
|
84
89
|
*/
|
|
85
90
|
addAllSkipOptimizing(items) {
|
|
86
|
-
for (
|
|
87
|
-
this._children.push(
|
|
91
|
+
for (let i = 0, l = items.length; i < l; i++) {
|
|
92
|
+
this._children.push(items[i]);
|
|
88
93
|
}
|
|
89
94
|
}
|
|
90
95
|
|
|
96
|
+
/**
|
|
97
|
+
* @returns {Buffer} buffer
|
|
98
|
+
*/
|
|
91
99
|
buffer() {
|
|
100
|
+
return Buffer.concat(this.buffers());
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @returns {Buffer[]} buffers
|
|
105
|
+
*/
|
|
106
|
+
buffers() {
|
|
92
107
|
if (!this._isOptimized) this._optimize();
|
|
108
|
+
const children = /** @type {SourceLike[]} */ (this._children);
|
|
109
|
+
const childCount = children.length;
|
|
93
110
|
/** @type {Buffer[]} */
|
|
94
111
|
const buffers = [];
|
|
95
|
-
|
|
96
|
-
|
|
112
|
+
// Indexed loop + manual splat avoids the iterator allocation per
|
|
113
|
+
// child and the inner for-of allocation per child.buffers() call.
|
|
114
|
+
// Hot path during webpack's emit on deeply-nested ConcatSources.
|
|
115
|
+
for (let ci = 0; ci < childCount; ci++) {
|
|
116
|
+
const child = children[ci];
|
|
117
|
+
if (typeof child.buffers === "function") {
|
|
118
|
+
const childBuffers = child.buffers();
|
|
119
|
+
for (let bi = 0, blen = childBuffers.length; bi < blen; bi++) {
|
|
120
|
+
buffers.push(childBuffers[bi]);
|
|
121
|
+
}
|
|
122
|
+
} else if (typeof child.buffer === "function") {
|
|
97
123
|
buffers.push(child.buffer());
|
|
98
124
|
} else {
|
|
99
125
|
const bufferOrString = child.source();
|
|
@@ -105,7 +131,7 @@ class ConcatSource extends Source {
|
|
|
105
131
|
}
|
|
106
132
|
}
|
|
107
133
|
}
|
|
108
|
-
return
|
|
134
|
+
return buffers;
|
|
109
135
|
}
|
|
110
136
|
|
|
111
137
|
/**
|
|
@@ -113,18 +139,25 @@ class ConcatSource extends Source {
|
|
|
113
139
|
*/
|
|
114
140
|
source() {
|
|
115
141
|
if (!this._isOptimized) this._optimize();
|
|
142
|
+
const children = /** @type {Source[]} */ (this._children);
|
|
143
|
+
const childCount = children.length;
|
|
116
144
|
let source = "";
|
|
117
|
-
for (
|
|
118
|
-
source +=
|
|
145
|
+
for (let ci = 0; ci < childCount; ci++) {
|
|
146
|
+
source += children[ci].source();
|
|
119
147
|
}
|
|
120
148
|
return source;
|
|
121
149
|
}
|
|
122
150
|
|
|
151
|
+
/**
|
|
152
|
+
* @returns {number} size
|
|
153
|
+
*/
|
|
123
154
|
size() {
|
|
124
155
|
if (!this._isOptimized) this._optimize();
|
|
156
|
+
const children = /** @type {Source[]} */ (this._children);
|
|
157
|
+
const childCount = children.length;
|
|
125
158
|
let size = 0;
|
|
126
|
-
for (
|
|
127
|
-
size +=
|
|
159
|
+
for (let ci = 0; ci < childCount; ci++) {
|
|
160
|
+
size += children[ci].size();
|
|
128
161
|
}
|
|
129
162
|
return size;
|
|
130
163
|
}
|
|
@@ -169,7 +202,10 @@ class ConcatSource extends Source {
|
|
|
169
202
|
const finalSource = Boolean(options && options.finalSource);
|
|
170
203
|
let code = "";
|
|
171
204
|
let needToCloseMapping = false;
|
|
172
|
-
|
|
205
|
+
const children = /** @type {Source[]} */ (this._children);
|
|
206
|
+
const childCount = children.length;
|
|
207
|
+
for (let ci = 0; ci < childCount; ci++) {
|
|
208
|
+
const item = children[ci];
|
|
173
209
|
/** @type {number[]} */
|
|
174
210
|
const sourceIndexMapping = [];
|
|
175
211
|
/** @type {number[]} */
|
|
@@ -211,11 +247,6 @@ class ConcatSource extends Source {
|
|
|
211
247
|
sourceIndex < 0 || sourceIndex >= sourceIndexMapping.length
|
|
212
248
|
? -1
|
|
213
249
|
: sourceIndexMapping[sourceIndex];
|
|
214
|
-
const resultNameIndex =
|
|
215
|
-
nameIndex < 0 || nameIndex >= nameIndexMapping.length
|
|
216
|
-
? -1
|
|
217
|
-
: nameIndexMapping[nameIndex];
|
|
218
|
-
lastMappingLine = resultSourceIndex < 0 ? 0 : generatedLine;
|
|
219
250
|
let _chunk;
|
|
220
251
|
// When using finalSource, we process the entire source code at once at the end, rather than chunk by chunk
|
|
221
252
|
if (finalSource) {
|
|
@@ -224,8 +255,17 @@ class ConcatSource extends Source {
|
|
|
224
255
|
_chunk = chunk;
|
|
225
256
|
}
|
|
226
257
|
if (resultSourceIndex < 0) {
|
|
258
|
+
lastMappingLine = 0;
|
|
227
259
|
onChunk(_chunk, line, column, -1, -1, -1, -1);
|
|
228
260
|
} else {
|
|
261
|
+
// Only compute the remapped name index when the chunk
|
|
262
|
+
// actually carries a source mapping; otherwise it is
|
|
263
|
+
// unused.
|
|
264
|
+
const resultNameIndex =
|
|
265
|
+
nameIndex < 0 || nameIndex >= nameIndexMapping.length
|
|
266
|
+
? -1
|
|
267
|
+
: nameIndexMapping[nameIndex];
|
|
268
|
+
lastMappingLine = generatedLine;
|
|
229
269
|
onChunk(
|
|
230
270
|
_chunk,
|
|
231
271
|
line,
|
|
@@ -237,11 +277,11 @@ class ConcatSource extends Source {
|
|
|
237
277
|
);
|
|
238
278
|
}
|
|
239
279
|
},
|
|
240
|
-
(i, source, sourceContent) => {
|
|
280
|
+
(i, source, sourceContent, scopeBindings) => {
|
|
241
281
|
let globalIndex = sourceMapping.get(source);
|
|
242
282
|
if (globalIndex === undefined) {
|
|
243
283
|
sourceMapping.set(source, (globalIndex = sourceMapping.size));
|
|
244
|
-
onSource(globalIndex, source, sourceContent);
|
|
284
|
+
onSource(globalIndex, source, sourceContent, scopeBindings);
|
|
245
285
|
}
|
|
246
286
|
sourceIndexMapping[i] = globalIndex;
|
|
247
287
|
},
|
|
@@ -287,16 +327,46 @@ class ConcatSource extends Source {
|
|
|
287
327
|
};
|
|
288
328
|
}
|
|
289
329
|
|
|
330
|
+
/**
|
|
331
|
+
* Release cached data held by this source. clearCache is a memory
|
|
332
|
+
* hint: it never affects correctness or output, only how expensive
|
|
333
|
+
* the next read is. Subclasses override; the base is a no-op so
|
|
334
|
+
* every Source supports the call. Composite sources always recurse
|
|
335
|
+
* into wrapped sources. When the same child is reachable via several
|
|
336
|
+
* parents (e.g. modules shared across webpack chunks), pass a shared
|
|
337
|
+
* `visited` WeakSet so each subtree is walked at most once.
|
|
338
|
+
* Not safe to call concurrently with source/map/sourceAndMap/
|
|
339
|
+
* streamChunks/updateHash on the same instance.
|
|
340
|
+
* @param {ClearCacheOptions=} options selectors
|
|
341
|
+
* @param {WeakSet<Source>=} visited de-duplication set shared across calls
|
|
342
|
+
* @returns {void}
|
|
343
|
+
*/
|
|
344
|
+
clearCache(options, visited) {
|
|
345
|
+
if (visited !== undefined && visited.has(this)) return;
|
|
346
|
+
const children = this._children;
|
|
347
|
+
const { length } = children;
|
|
348
|
+
let v = visited;
|
|
349
|
+
if (v === undefined && length > 0) v = new WeakSet();
|
|
350
|
+
if (v !== undefined) v.add(this);
|
|
351
|
+
for (let i = 0; i < length; i++) {
|
|
352
|
+
const child = children[i];
|
|
353
|
+
if (typeof child !== "string" && typeof child.clearCache === "function") {
|
|
354
|
+
child.clearCache(options, v);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
290
359
|
/**
|
|
291
360
|
* @param {HashLike} hash hash
|
|
292
361
|
* @returns {void}
|
|
293
362
|
*/
|
|
294
363
|
updateHash(hash) {
|
|
295
364
|
if (!this._isOptimized) this._optimize();
|
|
365
|
+
const children = /** @type {Source[]} */ (this._children);
|
|
366
|
+
const childCount = children.length;
|
|
296
367
|
hash.update("ConcatSource");
|
|
297
|
-
for (
|
|
298
|
-
|
|
299
|
-
(item).updateHash(hash);
|
|
368
|
+
for (let ci = 0; ci < childCount; ci++) {
|
|
369
|
+
children[ci].updateHash(hash);
|
|
300
370
|
}
|
|
301
371
|
}
|
|
302
372
|
|
|
@@ -358,7 +428,9 @@ class ConcatSource extends Source {
|
|
|
358
428
|
newChildren.push(currentRawSources);
|
|
359
429
|
}
|
|
360
430
|
};
|
|
361
|
-
|
|
431
|
+
const children = this._children;
|
|
432
|
+
for (let ci = 0, cl = children.length; ci < cl; ci++) {
|
|
433
|
+
const child = children[ci];
|
|
362
434
|
if (typeof child === "string") {
|
|
363
435
|
if (currentString === undefined) {
|
|
364
436
|
currentString = child;
|
package/lib/OriginalSource.js
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
const Source = require("./Source");
|
|
9
9
|
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks");
|
|
10
10
|
const getGeneratedSourceInfo = require("./helpers/getGeneratedSourceInfo");
|
|
11
|
-
const
|
|
12
|
-
const splitIntoPotentialTokens = require("./helpers/splitIntoPotentialTokens");
|
|
11
|
+
const { eachPotentialToken } = require("./helpers/splitIntoPotentialTokens");
|
|
13
12
|
const {
|
|
14
13
|
isDualStringBufferCachingEnabled,
|
|
15
14
|
} = require("./helpers/stringBufferUtils");
|
|
16
15
|
|
|
16
|
+
/** @typedef {import("./Source").ClearCacheOptions} ClearCacheOptions */
|
|
17
17
|
/** @typedef {import("./Source").HashLike} HashLike */
|
|
18
18
|
/** @typedef {import("./Source").MapOptions} MapOptions */
|
|
19
19
|
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */
|
|
@@ -24,32 +24,36 @@ const {
|
|
|
24
24
|
/** @typedef {import("./helpers/streamChunks").OnName} OnName */
|
|
25
25
|
/** @typedef {import("./helpers/streamChunks").OnSource} OnSource */
|
|
26
26
|
/** @typedef {import("./helpers/streamChunks").Options} Options */
|
|
27
|
+
/** @typedef {import("./helpers/streamChunks").ScopeBindings} ScopeBindings */
|
|
27
28
|
|
|
28
29
|
class OriginalSource extends Source {
|
|
29
30
|
/**
|
|
30
31
|
* @param {string | Buffer} value value
|
|
31
32
|
* @param {string} name name
|
|
33
|
+
* @param {ScopeBindings=} scopeBindings what each name this source declares
|
|
34
|
+
* evaluates to in the generated code, for the map's `scopes` field
|
|
32
35
|
*/
|
|
33
|
-
constructor(value, name) {
|
|
36
|
+
constructor(value, name, scopeBindings) {
|
|
34
37
|
super();
|
|
35
38
|
|
|
36
39
|
const isBuffer = Buffer.isBuffer(value);
|
|
37
40
|
|
|
38
41
|
/**
|
|
39
|
-
* @private
|
|
40
42
|
* @type {undefined | string}
|
|
41
43
|
*/
|
|
42
44
|
this._value = isBuffer ? undefined : value;
|
|
43
45
|
/**
|
|
44
|
-
* @private
|
|
45
46
|
* @type {undefined | Buffer}
|
|
46
47
|
*/
|
|
47
48
|
this._valueAsBuffer = isBuffer ? value : undefined;
|
|
48
49
|
/**
|
|
49
|
-
* @private
|
|
50
50
|
* @type {string}
|
|
51
51
|
*/
|
|
52
52
|
this._name = name;
|
|
53
|
+
/**
|
|
54
|
+
* @type {undefined | ScopeBindings}
|
|
55
|
+
*/
|
|
56
|
+
this._scopeBindings = scopeBindings;
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
getName() {
|
|
@@ -72,6 +76,9 @@ class OriginalSource extends Source {
|
|
|
72
76
|
return this._value;
|
|
73
77
|
}
|
|
74
78
|
|
|
79
|
+
/**
|
|
80
|
+
* @returns {Buffer} buffer
|
|
81
|
+
*/
|
|
75
82
|
buffer() {
|
|
76
83
|
if (this._valueAsBuffer === undefined) {
|
|
77
84
|
const value = Buffer.from(/** @type {string} */ (this._value), "utf8");
|
|
@@ -83,6 +90,20 @@ class OriginalSource extends Source {
|
|
|
83
90
|
return this._valueAsBuffer;
|
|
84
91
|
}
|
|
85
92
|
|
|
93
|
+
/**
|
|
94
|
+
* @returns {number} size
|
|
95
|
+
*/
|
|
96
|
+
size() {
|
|
97
|
+
if (this._cachedSize !== undefined) return this._cachedSize;
|
|
98
|
+
if (this._valueAsBuffer !== undefined) {
|
|
99
|
+
return (this._cachedSize = this._valueAsBuffer.length);
|
|
100
|
+
}
|
|
101
|
+
return (this._cachedSize = Buffer.byteLength(
|
|
102
|
+
/** @type {string} */ (this._value),
|
|
103
|
+
"utf8",
|
|
104
|
+
));
|
|
105
|
+
}
|
|
106
|
+
|
|
86
107
|
/**
|
|
87
108
|
* @param {MapOptions=} options map options
|
|
88
109
|
* @returns {RawSourceMap | null} map
|
|
@@ -112,34 +133,36 @@ class OriginalSource extends Source {
|
|
|
112
133
|
/** @type {Buffer} */
|
|
113
134
|
(this._valueAsBuffer).toString("utf8");
|
|
114
135
|
}
|
|
115
|
-
onSource(0, this._name, this._value);
|
|
136
|
+
onSource(0, this._name, this._value, this._scopeBindings);
|
|
116
137
|
const finalSource = Boolean(options && options.finalSource);
|
|
117
138
|
if (!options || options.columns !== false) {
|
|
118
|
-
// With column info we need to
|
|
119
|
-
|
|
139
|
+
// With column info we need to walk every potential token. The
|
|
140
|
+
// scan is streamed by offset (see `eachPotentialToken`) so we
|
|
141
|
+
// only allocate a chunk substring when one is actually emitted —
|
|
142
|
+
// and `map()` / `sourceAndMap()` set `finalSource`, in which case
|
|
143
|
+
// the chunk is dropped and no substring is allocated at all.
|
|
144
|
+
const value = this._value;
|
|
120
145
|
let line = 1;
|
|
121
146
|
let column = 0;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
onChunk(chunk, line, column, 0, line, column, -1);
|
|
130
|
-
}
|
|
131
|
-
if (isEndOfLine) {
|
|
132
|
-
line++;
|
|
133
|
-
column = 0;
|
|
134
|
-
} else {
|
|
135
|
-
column += match.length;
|
|
136
|
-
}
|
|
147
|
+
eachPotentialToken(value, (start, end, newline) => {
|
|
148
|
+
const length = end - start;
|
|
149
|
+
if (newline && length === 1) {
|
|
150
|
+
if (!finalSource) onChunk("\n", line, column, -1, -1, -1, -1);
|
|
151
|
+
} else {
|
|
152
|
+
const chunk = finalSource ? undefined : value.slice(start, end);
|
|
153
|
+
onChunk(chunk, line, column, 0, line, column, -1);
|
|
137
154
|
}
|
|
138
|
-
|
|
155
|
+
if (newline) {
|
|
156
|
+
line++;
|
|
157
|
+
column = 0;
|
|
158
|
+
} else {
|
|
159
|
+
column += length;
|
|
160
|
+
}
|
|
161
|
+
});
|
|
139
162
|
return {
|
|
140
163
|
generatedLine: line,
|
|
141
164
|
generatedColumn: column,
|
|
142
|
-
source: finalSource ?
|
|
165
|
+
source: finalSource ? value : undefined,
|
|
143
166
|
};
|
|
144
167
|
} else if (finalSource) {
|
|
145
168
|
// Without column info and with final source we only
|
|
@@ -165,27 +188,64 @@ class OriginalSource extends Source {
|
|
|
165
188
|
}
|
|
166
189
|
return result;
|
|
167
190
|
}
|
|
168
|
-
// Without column info, but also without final source
|
|
169
|
-
//
|
|
191
|
+
// Without column info, but also without final source.
|
|
192
|
+
// We only get here when (options.columns === false && !finalSource),
|
|
193
|
+
// so the source field is always undefined and the chunk arg is always
|
|
194
|
+
// the line text. Single-pass scan over newlines avoids the
|
|
195
|
+
// splitIntoLines array allocation.
|
|
196
|
+
const value = this._value;
|
|
197
|
+
const len = value.length;
|
|
198
|
+
if (len === 0) {
|
|
199
|
+
return { generatedLine: 1, generatedColumn: 0, source: undefined };
|
|
200
|
+
}
|
|
170
201
|
let line = 1;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
202
|
+
let i = 0;
|
|
203
|
+
while (i < len) {
|
|
204
|
+
const n = value.indexOf("\n", i);
|
|
205
|
+
if (n === -1) {
|
|
206
|
+
const lastLine = i === 0 ? value : value.slice(i);
|
|
207
|
+
onChunk(lastLine, line, 0, 0, line, 0, -1);
|
|
208
|
+
return {
|
|
209
|
+
generatedLine: line,
|
|
210
|
+
generatedColumn: lastLine.length,
|
|
211
|
+
source: undefined,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const chunk = n === i ? "\n" : value.slice(i, n + 1);
|
|
215
|
+
onChunk(chunk, line, 0, 0, line, 0, -1);
|
|
176
216
|
line++;
|
|
217
|
+
i = n + 1;
|
|
218
|
+
}
|
|
219
|
+
// Source ended with a newline.
|
|
220
|
+
return { generatedLine: line, generatedColumn: 0, source: undefined };
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Release cached data held by this source. clearCache is a memory
|
|
225
|
+
* hint: it never affects correctness or output, only how expensive
|
|
226
|
+
* the next read is. Subclasses override; the base is a no-op so
|
|
227
|
+
* every Source supports the call. Composite sources always recurse
|
|
228
|
+
* into wrapped sources. When the same child is reachable via several
|
|
229
|
+
* parents (e.g. modules shared across webpack chunks), pass a shared
|
|
230
|
+
* `visited` WeakSet so each subtree is walked at most once.
|
|
231
|
+
* Not safe to call concurrently with source/map/sourceAndMap/
|
|
232
|
+
* streamChunks/updateHash on the same instance.
|
|
233
|
+
* @param {ClearCacheOptions=} options selectors
|
|
234
|
+
* @param {WeakSet<Source>=} visited de-duplication set shared across calls
|
|
235
|
+
* @returns {void}
|
|
236
|
+
*/
|
|
237
|
+
clearCache(options, visited) {
|
|
238
|
+
if (visited !== undefined) {
|
|
239
|
+
if (visited.has(this)) return;
|
|
240
|
+
visited.add(this);
|
|
241
|
+
}
|
|
242
|
+
if (options !== undefined && options.source === false) return;
|
|
243
|
+
if (this._value !== undefined && this._valueAsBuffer !== undefined) {
|
|
244
|
+
// When both forms are cached, drop the string (UTF-16 in V8 is
|
|
245
|
+
// ~2 bytes/char) and keep the more compact buffer. source() will
|
|
246
|
+
// rehydrate the string on demand.
|
|
247
|
+
this._value = undefined;
|
|
177
248
|
}
|
|
178
|
-
return matches.length === 0 || /** @type {string} */ (match).endsWith("\n")
|
|
179
|
-
? {
|
|
180
|
-
generatedLine: matches.length + 1,
|
|
181
|
-
generatedColumn: 0,
|
|
182
|
-
source: finalSource ? this._value : undefined,
|
|
183
|
-
}
|
|
184
|
-
: {
|
|
185
|
-
generatedLine: matches.length,
|
|
186
|
-
generatedColumn: /** @type {string} */ (match).length,
|
|
187
|
-
source: finalSource ? this._value : undefined,
|
|
188
|
-
};
|
|
189
249
|
}
|
|
190
250
|
|
|
191
251
|
/**
|
|
@@ -194,7 +254,13 @@ class OriginalSource extends Source {
|
|
|
194
254
|
*/
|
|
195
255
|
updateHash(hash) {
|
|
196
256
|
hash.update("OriginalSource");
|
|
197
|
-
|
|
257
|
+
// Same as RawSource: utf8 is what `buffer()` would have encoded to,
|
|
258
|
+
// and one of the two forms is always set.
|
|
259
|
+
if (this._valueAsBuffer === undefined) {
|
|
260
|
+
hash.update(/** @type {string} */ (this._value));
|
|
261
|
+
} else {
|
|
262
|
+
hash.update(this._valueAsBuffer);
|
|
263
|
+
}
|
|
198
264
|
hash.update(this._name || "");
|
|
199
265
|
}
|
|
200
266
|
}
|
package/lib/PrefixSource.js
CHANGED
|
@@ -10,6 +10,7 @@ const Source = require("./Source");
|
|
|
10
10
|
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks");
|
|
11
11
|
const streamChunks = require("./helpers/streamChunks");
|
|
12
12
|
|
|
13
|
+
/** @typedef {import("./Source").ClearCacheOptions} ClearCacheOptions */
|
|
13
14
|
/** @typedef {import("./Source").HashLike} HashLike */
|
|
14
15
|
/** @typedef {import("./Source").MapOptions} MapOptions */
|
|
15
16
|
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */
|
|
@@ -21,7 +22,31 @@ const streamChunks = require("./helpers/streamChunks");
|
|
|
21
22
|
/** @typedef {import("./helpers/streamChunks").OnSource} OnSource */
|
|
22
23
|
/** @typedef {import("./helpers/streamChunks").Options} Options */
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
// `/\n/g` (no lookahead) lets V8's regex compiler take its
|
|
26
|
+
// literal-character fast path; the previous `/\n(?=.|\s)/g` form
|
|
27
|
+
// disabled it. Output stays identical because `buildPrefixed` strips
|
|
28
|
+
// the spurious trailing prefix when the input ended with a newline.
|
|
29
|
+
const NEWLINE_REGEX = /\n/g;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Prepend `prefix` and insert `prefix` after every newline that has
|
|
33
|
+
* content following — the original `/\n(?=.|\s)/g` semantics, but
|
|
34
|
+
* implemented as a fast-path regex + tail-strip.
|
|
35
|
+
* @param {string} prefix prefix
|
|
36
|
+
* @param {string} node underlying source string
|
|
37
|
+
* @returns {string} prefixed string
|
|
38
|
+
*/
|
|
39
|
+
const buildPrefixed = (prefix, node) => {
|
|
40
|
+
if (prefix.length === 0) return node;
|
|
41
|
+
const replaced = node.replace(NEWLINE_REGEX, `\n${prefix}`);
|
|
42
|
+
const len = node.length;
|
|
43
|
+
// `/\n/g` matches the trailing newline too, so the replace appended
|
|
44
|
+
// a spurious prefix at the end. Trim it.
|
|
45
|
+
if (len > 0 && node.charCodeAt(len - 1) === 10) {
|
|
46
|
+
return prefix + replaced.slice(0, replaced.length - prefix.length);
|
|
47
|
+
}
|
|
48
|
+
return prefix + replaced;
|
|
49
|
+
};
|
|
25
50
|
|
|
26
51
|
class PrefixSource extends Source {
|
|
27
52
|
/**
|
|
@@ -31,12 +56,10 @@ class PrefixSource extends Source {
|
|
|
31
56
|
constructor(prefix, source) {
|
|
32
57
|
super();
|
|
33
58
|
/**
|
|
34
|
-
* @private
|
|
35
59
|
* @type {string}
|
|
36
60
|
*/
|
|
37
61
|
this._prefix = prefix;
|
|
38
62
|
/**
|
|
39
|
-
* @private
|
|
40
63
|
* @type {Source}
|
|
41
64
|
*/
|
|
42
65
|
this._source =
|
|
@@ -57,12 +80,19 @@ class PrefixSource extends Source {
|
|
|
57
80
|
* @returns {SourceValue} source
|
|
58
81
|
*/
|
|
59
82
|
source() {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
83
|
+
return buildPrefixed(
|
|
84
|
+
this._prefix,
|
|
85
|
+
/** @type {string} */ (this._source.source()),
|
|
86
|
+
);
|
|
63
87
|
}
|
|
64
88
|
|
|
65
|
-
//
|
|
89
|
+
// buffer() / buffers() / size() inherit from Source.prototype.
|
|
90
|
+
// Source.buffer() does Buffer.from(this.source(), "utf8") — cheaper
|
|
91
|
+
// in CodSpeed instruction count than any safe override we tried
|
|
92
|
+
// (caching is unsafe with mutable child; a JS-side splice loop
|
|
93
|
+
// regressed ~5x in instruction count). Speeding up source() via the
|
|
94
|
+
// simpler regex above lifts buffer(), buffers(), size(), and any
|
|
95
|
+
// other `this.source()`-using path with no override needed.
|
|
66
96
|
|
|
67
97
|
/**
|
|
68
98
|
* @param {MapOptions=} options map options
|
|
@@ -141,10 +171,7 @@ class PrefixSource extends Source {
|
|
|
141
171
|
generatedColumn === 0
|
|
142
172
|
? 0
|
|
143
173
|
: prefixOffset + /** @type {number} */ (generatedColumn),
|
|
144
|
-
source:
|
|
145
|
-
source !== undefined
|
|
146
|
-
? prefix + source.replace(REPLACE_REGEX, `\n${prefix}`)
|
|
147
|
-
: undefined,
|
|
174
|
+
source: source !== undefined ? buildPrefixed(prefix, source) : undefined,
|
|
148
175
|
};
|
|
149
176
|
}
|
|
150
177
|
|
|
@@ -157,6 +184,28 @@ class PrefixSource extends Source {
|
|
|
157
184
|
this._source.updateHash(hash);
|
|
158
185
|
hash.update(this._prefix);
|
|
159
186
|
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Release cached data held by this source. clearCache is a memory
|
|
190
|
+
* hint: it never affects correctness or output, only how expensive
|
|
191
|
+
* the next read is. Subclasses override; the base is a no-op so
|
|
192
|
+
* every Source supports the call. Composite sources always recurse
|
|
193
|
+
* into wrapped sources. When the same child is reachable via several
|
|
194
|
+
* parents (e.g. modules shared across webpack chunks), pass a shared
|
|
195
|
+
* `visited` WeakSet so each subtree is walked at most once.
|
|
196
|
+
* Not safe to call concurrently with source/map/sourceAndMap/
|
|
197
|
+
* streamChunks/updateHash on the same instance.
|
|
198
|
+
* @param {ClearCacheOptions=} options selectors
|
|
199
|
+
* @param {WeakSet<Source>=} visited de-duplication set shared across calls
|
|
200
|
+
* @returns {void}
|
|
201
|
+
*/
|
|
202
|
+
clearCache(options, visited) {
|
|
203
|
+
if (visited !== undefined && visited.has(this)) return;
|
|
204
|
+
let v = visited;
|
|
205
|
+
if (v === undefined) v = new WeakSet();
|
|
206
|
+
v.add(this);
|
|
207
|
+
this._source.clearCache(options, v);
|
|
208
|
+
}
|
|
160
209
|
}
|
|
161
210
|
|
|
162
211
|
module.exports = PrefixSource;
|