@@ -17,7 +17,6 @@ const cjsSourceMapCache = new WeakMap();
17
17
// on filenames.
18
18
const esmSourceMapCache = new Map ( ) ;
19
19
const { fileURLToPath, URL } = require ( 'url' ) ;
20
- const { overrideStackTrace } = require ( 'internal/errors' ) ;
21
20
22
21
let experimentalSourceMaps ;
23
22
function maybeCacheSourceMap ( filename , content , cjsModuleInstance ) {
@@ -38,18 +37,22 @@ function maybeCacheSourceMap(filename, content, cjsModuleInstance) {
38
37
39
38
const match = content . match ( / \/ [ * / ] # \s + s o u r c e M a p p i n g U R L = (?< sourceMappingURL > [ ^ \s ] + ) / ) ;
40
39
if ( match ) {
40
+ const data = dataFromUrl ( basePath , match . groups . sourceMappingURL ) ;
41
+ const url = data ? null : match . groups . sourceMappingURL ;
41
42
if ( cjsModuleInstance ) {
42
43
cjsSourceMapCache . set ( cjsModuleInstance , {
43
44
filename,
44
- url : match . groups . sourceMappingURL ,
45
- data : dataFromUrl ( basePath , match . groups . sourceMappingURL )
45
+ lineLengths : lineLengths ( content ) ,
46
+ data,
47
+ url
46
48
} ) ;
47
49
} else {
48
50
// If there is no cjsModuleInstance assume we are in a
49
51
// "modules/esm" context.
50
52
esmSourceMapCache . set ( filename , {
51
- url : match . groups . sourceMappingURL ,
52
- data : dataFromUrl ( basePath , match . groups . sourceMappingURL )
53
+ lineLengths : lineLengths ( content ) ,
54
+ data,
55
+ url
53
56
} ) ;
54
57
}
55
58
}
@@ -73,6 +76,18 @@ function dataFromUrl(basePath, sourceMappingURL) {
73
76
}
74
77
}
75
78
79
+ // Cache the length of each line in the file that a source map was extracted
80
+ // from. This allows translation from byte offset V8 coverage reports,
81
+ // to line/column offset Source Map V3.
82
+ function lineLengths ( content ) {
83
+ // We purposefully keep \r as part of the line-length calculation, in
84
+ // cases where there is a \r\n separator, so that this can be taken into
85
+ // account in coverage calculations.
86
+ return content . split ( / \n | \u2028 | \u2029 / ) . map ( ( line ) => {
87
+ return line . length ;
88
+ } ) ;
89
+ }
90
+
76
91
function sourceMapFromFile ( sourceMapFile ) {
77
92
try {
78
93
const content = fs . readFileSync ( sourceMapFile , 'utf8' ) ;
@@ -161,56 +176,14 @@ function appendCJSCache(obj) {
161
176
const value = cjsSourceMapCache . get ( Module . _cache [ key ] ) ;
162
177
if ( value ) {
163
178
obj [ `file://${ key } ` ] = {
164
- url : value . url ,
165
- data : value . data
179
+ lineLengths : value . lineLengths ,
180
+ data : value . data ,
181
+ url : value . url
166
182
} ;
167
183
}
168
184
} ) ;
169
185
}
170
186
171
- // Create a prettified stacktrace, inserting context from source maps
172
- // if possible.
173
- const ErrorToString = Error . prototype . toString ; // Capture original toString.
174
- const prepareStackTrace = ( globalThis , error , trace ) => {
175
- // API for node internals to override error stack formatting
176
- // without interfering with userland code.
177
- // TODO(bcoe): add support for source-maps to repl.
178
- if ( overrideStackTrace . has ( error ) ) {
179
- const f = overrideStackTrace . get ( error ) ;
180
- overrideStackTrace . delete ( error ) ;
181
- return f ( error , trace ) ;
182
- }
183
-
184
- const { SourceMap } = require ( 'internal/source_map/source_map' ) ;
185
- const errorString = ErrorToString . call ( error ) ;
186
-
187
- if ( trace . length === 0 ) {
188
- return errorString ;
189
- }
190
- const preparedTrace = trace . map ( ( t , i ) => {
191
- let str = i !== 0 ? '\n at ' : '' ;
192
- str = `${ str } ${ t } ` ;
193
- try {
194
- const sourceMap = findSourceMap ( t . getFileName ( ) , error ) ;
195
- if ( sourceMap && sourceMap . data ) {
196
- const sm = new SourceMap ( sourceMap . data ) ;
197
- // Source Map V3 lines/columns use zero-based offsets whereas, in
198
- // stack traces, they start at 1/1.
199
- const [ , , url , line , col ] =
200
- sm . findEntry ( t . getLineNumber ( ) - 1 , t . getColumnNumber ( ) - 1 ) ;
201
- if ( url && line !== undefined && col !== undefined ) {
202
- str +=
203
- `\n -> ${ url . replace ( 'file://' , '' ) } :${ line + 1 } :${ col + 1 } ` ;
204
- }
205
- }
206
- } catch ( err ) {
207
- debug ( err . stack ) ;
208
- }
209
- return str ;
210
- } ) ;
211
- return `${ errorString } \n at ${ preparedTrace . join ( '' ) } ` ;
212
- } ;
213
-
214
187
// Attempt to lookup a source map, which is either attached to a file URI, or
215
188
// keyed on an error instance.
216
189
function findSourceMap ( uri , error ) {
@@ -230,8 +203,8 @@ function findSourceMap(uri, error) {
230
203
}
231
204
232
205
module . exports = {
206
+ findSourceMap,
233
207
maybeCacheSourceMap,
234
- prepareStackTrace,
235
208
rekeySourceMap,
236
209
sourceMapCacheToObject,
237
210
} ;
0 commit comments