1
1
'use strict' ;
2
2
3
3
const uv = process . binding ( 'uv' ) ;
4
+ const Debug = require ( 'vm' ) . runInDebugContext ( 'Debug' ) ;
4
5
5
6
const formatRegExp = / % [ s d j % ] / g;
6
7
exports . format = function ( f ) {
@@ -192,6 +193,14 @@ function arrayToHash(array) {
192
193
}
193
194
194
195
196
+ function inspectPromise ( p ) {
197
+ var mirror = Debug . MakeMirror ( p , true ) ;
198
+ if ( ! mirror . isPromise ( ) )
199
+ return null ;
200
+ return { status : mirror . status ( ) , value : mirror . promiseValue ( ) . value_ } ;
201
+ }
202
+
203
+
195
204
function formatValue ( ctx , value , recurseTimes ) {
196
205
// Provide a hook for user-specified inspect functions.
197
206
// Check that value is an object with an inspect function on it
@@ -276,14 +285,43 @@ function formatValue(ctx, value, recurseTimes) {
276
285
}
277
286
}
278
287
279
- var base = '' , array = false , braces = [ '{' , '}' ] ;
288
+ var base = '' , empty = false , braces , formatter ;
280
289
281
- // Make Array say that they are Array
282
290
if ( Array . isArray ( value ) ) {
283
- array = true ;
284
291
braces = [ '[' , ']' ] ;
292
+ empty = value . length === 0 ;
293
+ formatter = formatArray ;
294
+ } else if ( value instanceof Set ) {
295
+ braces = [ 'Set {' , '}' ] ;
296
+ // With `showHidden`, `length` will display as a hidden property for
297
+ // arrays. For consistency's sake, do the same for `size`, even though this
298
+ // property isn't selected by Object.getOwnPropertyNames().
299
+ if ( ctx . showHidden )
300
+ keys . unshift ( 'size' ) ;
301
+ empty = value . size === 0 ;
302
+ formatter = formatSet ;
303
+ } else if ( value instanceof Map ) {
304
+ braces = [ 'Map {' , '}' ] ;
305
+ // Ditto.
306
+ if ( ctx . showHidden )
307
+ keys . unshift ( 'size' ) ;
308
+ empty = value . size === 0 ;
309
+ formatter = formatMap ;
310
+ } else {
311
+ // Only create a mirror if the object superficially looks like a Promise.
312
+ var promiseInternals = value instanceof Promise && inspectPromise ( value ) ;
313
+ if ( promiseInternals ) {
314
+ braces = [ 'Promise {' , '}' ] ;
315
+ formatter = formatPromise ;
316
+ } else {
317
+ braces = [ '{' , '}' ] ;
318
+ empty = true ; // No other data than keys.
319
+ formatter = formatObject ;
320
+ }
285
321
}
286
322
323
+ empty = empty === true && keys . length === 0 ;
324
+
287
325
// Make functions say that they are functions
288
326
if ( typeof value === 'function' ) {
289
327
var n = value . name ? ': ' + value . name : '' ;
@@ -323,7 +361,7 @@ function formatValue(ctx, value, recurseTimes) {
323
361
base = ' ' + '[Boolean: ' + formatted + ']' ;
324
362
}
325
363
326
- if ( keys . length === 0 && ( ! array || value . length === 0 ) ) {
364
+ if ( empty === true ) {
327
365
return braces [ 0 ] + base + braces [ 1 ] ;
328
366
}
329
367
@@ -337,14 +375,7 @@ function formatValue(ctx, value, recurseTimes) {
337
375
338
376
ctx . seen . push ( value ) ;
339
377
340
- var output ;
341
- if ( array ) {
342
- output = formatArray ( ctx , value , recurseTimes , visibleKeys , keys ) ;
343
- } else {
344
- output = keys . map ( function ( key ) {
345
- return formatProperty ( ctx , value , recurseTimes , visibleKeys , key , array ) ;
346
- } ) ;
347
- }
378
+ var output = formatter ( ctx , value , recurseTimes , visibleKeys , keys ) ;
348
379
349
380
ctx . seen . pop ( ) ;
350
381
@@ -397,6 +428,13 @@ function formatError(value) {
397
428
}
398
429
399
430
431
+ function formatObject ( ctx , value , recurseTimes , visibleKeys , keys ) {
432
+ return keys . map ( function ( key ) {
433
+ return formatProperty ( ctx , value , recurseTimes , visibleKeys , key , false ) ;
434
+ } ) ;
435
+ }
436
+
437
+
400
438
function formatArray ( ctx , value , recurseTimes , visibleKeys , keys ) {
401
439
var output = [ ] ;
402
440
for ( var i = 0 , l = value . length ; i < l ; ++ i ) {
@@ -417,6 +455,59 @@ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
417
455
}
418
456
419
457
458
+ function formatSet ( ctx , value , recurseTimes , visibleKeys , keys ) {
459
+ var output = [ ] ;
460
+ value . forEach ( function ( v ) {
461
+ var nextRecurseTimes = recurseTimes === null ? null : recurseTimes - 1 ;
462
+ var str = formatValue ( ctx , v , nextRecurseTimes ) ;
463
+ output . push ( str ) ;
464
+ } ) ;
465
+ keys . forEach ( function ( key ) {
466
+ output . push ( formatProperty ( ctx , value , recurseTimes , visibleKeys ,
467
+ key , false ) ) ;
468
+ } ) ;
469
+ return output ;
470
+ }
471
+
472
+
473
+ function formatMap ( ctx , value , recurseTimes , visibleKeys , keys ) {
474
+ var output = [ ] ;
475
+ value . forEach ( function ( v , k ) {
476
+ var nextRecurseTimes = recurseTimes === null ? null : recurseTimes - 1 ;
477
+ var str = formatValue ( ctx , k , nextRecurseTimes ) ;
478
+ str += ' => ' ;
479
+ str += formatValue ( ctx , v , nextRecurseTimes ) ;
480
+ output . push ( str ) ;
481
+ } ) ;
482
+ keys . forEach ( function ( key ) {
483
+ output . push ( formatProperty ( ctx , value , recurseTimes , visibleKeys ,
484
+ key , false ) ) ;
485
+ } ) ;
486
+ return output ;
487
+ }
488
+
489
+ function formatPromise ( ctx , value , recurseTimes , visibleKeys , keys ) {
490
+ var output = [ ] ;
491
+ var internals = inspectPromise ( value ) ;
492
+ if ( internals . status === 'pending' ) {
493
+ output . push ( '<pending>' ) ;
494
+ } else {
495
+ var nextRecurseTimes = recurseTimes === null ? null : recurseTimes - 1 ;
496
+ var str = formatValue ( ctx , internals . value , nextRecurseTimes ) ;
497
+ if ( internals . status === 'rejected' ) {
498
+ output . push ( '<rejected> ' + str ) ;
499
+ } else {
500
+ output . push ( str ) ;
501
+ }
502
+ }
503
+ keys . forEach ( function ( key ) {
504
+ output . push ( formatProperty ( ctx , value , recurseTimes , visibleKeys ,
505
+ key , false ) ) ;
506
+ } ) ;
507
+ return output ;
508
+ }
509
+
510
+
420
511
function formatProperty ( ctx , value , recurseTimes , visibleKeys , key , array ) {
421
512
var name , str , desc ;
422
513
desc = Object . getOwnPropertyDescriptor ( value , key ) || { value : value [ key ] } ;
@@ -488,7 +579,10 @@ function reduceToSingleString(output, base, braces) {
488
579
489
580
if ( length > 60 ) {
490
581
return braces [ 0 ] +
491
- ( base === '' ? '' : base + '\n ' ) +
582
+ // If the opening "brace" is too large, like in the case of "Set {",
583
+ // we need to force the first item to be on the next line or the
584
+ // items will not line up correctly.
585
+ ( base === '' && braces [ 0 ] . length === 1 ? '' : base + '\n ' ) +
492
586
' ' +
493
587
output . join ( ',\n ' ) +
494
588
' ' +
0 commit comments