@@ -72,7 +72,6 @@ const {
72
72
customInspectSymbol,
73
73
deprecate,
74
74
getSystemErrorName : internalErrorName ,
75
- getIdentificationOf,
76
75
isError,
77
76
promisify,
78
77
join,
@@ -397,6 +396,35 @@ function stylizeNoColor(str, styleType) {
397
396
return str ;
398
397
}
399
398
399
+ function getConstructorName ( obj ) {
400
+ while ( obj ) {
401
+ const descriptor = Object . getOwnPropertyDescriptor ( obj , 'constructor' ) ;
402
+ if ( descriptor !== undefined &&
403
+ typeof descriptor . value === 'function' &&
404
+ descriptor . value . name !== '' ) {
405
+ return descriptor . value . name ;
406
+ }
407
+
408
+ obj = Object . getPrototypeOf ( obj ) ;
409
+ }
410
+
411
+ return '' ;
412
+ }
413
+
414
+ function getPrefix ( constructor , tag ) {
415
+ if ( constructor !== '' ) {
416
+ if ( tag !== '' && constructor !== tag ) {
417
+ return `${ constructor } [${ tag } ] ` ;
418
+ }
419
+ return `${ constructor } ` ;
420
+ }
421
+
422
+ if ( tag !== '' )
423
+ return `[${ tag } ] ` ;
424
+
425
+ return '' ;
426
+ }
427
+
400
428
function formatValue ( ctx , value , recurseTimes , ln ) {
401
429
// Primitive types cannot have properties
402
430
if ( typeof value !== 'object' && typeof value !== 'function' ) {
@@ -476,15 +504,10 @@ function formatValue(ctx, value, recurseTimes, ln) {
476
504
477
505
const keyLength = keys . length + symbols . length ;
478
506
479
- const { constructor, tag } = getIdentificationOf ( value ) ;
480
- let prefix = '' ;
481
- if ( constructor && tag && constructor !== tag )
482
- prefix = `${ constructor } [${ tag } ] ` ;
483
- else if ( constructor )
484
- prefix = `${ constructor } ` ;
485
- else if ( tag )
486
- prefix = `[${ tag } ] ` ;
487
-
507
+ const constructor = getConstructorName ( value ) ;
508
+ let tag = value [ Symbol . toStringTag ] ;
509
+ if ( typeof tag !== 'string' )
510
+ tag = '' ;
488
511
let base = '' ;
489
512
let formatter = formatObject ;
490
513
let braces ;
@@ -497,22 +520,25 @@ function formatValue(ctx, value, recurseTimes, ln) {
497
520
noIterator = false ;
498
521
if ( Array . isArray ( value ) ) {
499
522
// Only set the constructor for non ordinary ("Array [...]") arrays.
523
+ const prefix = getPrefix ( constructor , tag ) ;
500
524
braces = [ `${ prefix === 'Array ' ? '' : prefix } [` , ']' ] ;
501
525
if ( value . length === 0 && keyLength === 0 )
502
526
return `${ braces [ 0 ] } ]` ;
503
527
formatter = formatArray ;
504
528
} else if ( isSet ( value ) ) {
529
+ const prefix = getPrefix ( constructor , tag ) ;
505
530
if ( value . size === 0 && keyLength === 0 )
506
531
return `${ prefix } {}` ;
507
532
braces = [ `${ prefix } {` , '}' ] ;
508
533
formatter = formatSet ;
509
534
} else if ( isMap ( value ) ) {
535
+ const prefix = getPrefix ( constructor , tag ) ;
510
536
if ( value . size === 0 && keyLength === 0 )
511
537
return `${ prefix } {}` ;
512
538
braces = [ `${ prefix } {` , '}' ] ;
513
539
formatter = formatMap ;
514
540
} else if ( isTypedArray ( value ) ) {
515
- braces = [ `${ prefix } [` , ']' ] ;
541
+ braces = [ `${ getPrefix ( constructor , tag ) } [` , ']' ] ;
516
542
formatter = formatTypedArray ;
517
543
} else if ( isMapIterator ( value ) ) {
518
544
braces = [ `[${ tag } ] {` , '}' ] ;
@@ -544,11 +570,16 @@ function formatValue(ctx, value, recurseTimes, ln) {
544
570
}
545
571
if ( noIterator ) {
546
572
braces = [ '{' , '}' ] ;
547
- if ( prefix === 'Object ' ) {
573
+ if ( constructor === 'Object' ) {
548
574
if ( isArgumentsObject ( value ) ) {
549
575
braces [ 0 ] = '[Arguments] {' ;
550
576
if ( keyLength === 0 )
551
577
return '[Arguments] {}' ;
578
+ } else if ( tag !== '' ) {
579
+ braces [ 0 ] = `${ getPrefix ( constructor , tag ) } {` ;
580
+ if ( keyLength === 0 ) {
581
+ return `${ braces [ 0 ] } }` ;
582
+ }
552
583
} else if ( keyLength === 0 ) {
553
584
return '{}' ;
554
585
}
@@ -580,27 +611,28 @@ function formatValue(ctx, value, recurseTimes, ln) {
580
611
// Fast path for ArrayBuffer and SharedArrayBuffer.
581
612
// Can't do the same for DataView because it has a non-primitive
582
613
// .buffer property that we need to recurse for.
614
+ const prefix = getPrefix ( constructor , tag ) ;
583
615
if ( keyLength === 0 )
584
616
return prefix +
585
617
`{ byteLength: ${ formatNumber ( ctx . stylize , value . byteLength ) } }` ;
586
618
braces [ 0 ] = `${ prefix } {` ;
587
619
keys . unshift ( 'byteLength' ) ;
588
620
} else if ( isDataView ( value ) ) {
589
- braces [ 0 ] = `${ prefix } {` ;
621
+ braces [ 0 ] = `${ getPrefix ( constructor , tag ) } {` ;
590
622
// .buffer goes last, it's not a primitive like the others.
591
623
keys . unshift ( 'byteLength' , 'byteOffset' , 'buffer' ) ;
592
624
} else if ( isPromise ( value ) ) {
593
- braces [ 0 ] = `${ prefix } {` ;
625
+ braces [ 0 ] = `${ getPrefix ( constructor , tag ) } {` ;
594
626
formatter = formatPromise ;
595
627
} else if ( isWeakSet ( value ) ) {
596
- braces [ 0 ] = `${ prefix } {` ;
628
+ braces [ 0 ] = `${ getPrefix ( constructor , tag ) } {` ;
597
629
if ( ctx . showHidden ) {
598
630
formatter = formatWeakSet ;
599
631
} else {
600
632
extra = '[items unknown]' ;
601
633
}
602
634
} else if ( isWeakMap ( value ) ) {
603
- braces [ 0 ] = `${ prefix } {` ;
635
+ braces [ 0 ] = `${ getPrefix ( constructor , tag ) } {` ;
604
636
if ( ctx . showHidden ) {
605
637
formatter = formatWeakMap ;
606
638
} else {
@@ -639,9 +671,9 @@ function formatValue(ctx, value, recurseTimes, ln) {
639
671
} else if ( keyLength === 0 ) {
640
672
if ( isExternal ( value ) )
641
673
return ctx . stylize ( '[External]' , 'special' ) ;
642
- return `${ prefix } {}` ;
674
+ return `${ getPrefix ( constructor , tag ) } {}` ;
643
675
} else {
644
- braces [ 0 ] = `${ prefix } {` ;
676
+ braces [ 0 ] = `${ getPrefix ( constructor , tag ) } {` ;
645
677
}
646
678
}
647
679
}
@@ -676,8 +708,8 @@ function formatNumber(fn, value) {
676
708
function formatPrimitive ( fn , value , ctx ) {
677
709
if ( typeof value === 'string' ) {
678
710
if ( ctx . compact === false &&
679
- value . length > MIN_LINE_LENGTH &&
680
- ctx . indentationLvl + value . length > ctx . breakLength ) {
711
+ ctx . indentationLvl + value . length > ctx . breakLength &&
712
+ value . length > MIN_LINE_LENGTH ) {
681
713
// eslint-disable-next-line max-len
682
714
const minLineLength = Math . max ( ctx . breakLength - ctx . indentationLvl , MIN_LINE_LENGTH ) ;
683
715
// eslint-disable-next-line max-len
@@ -696,9 +728,9 @@ function formatPrimitive(fn, value, ctx) {
696
728
// eslint-disable-next-line max-len, node-core/no-unescaped-regexp-dot
697
729
readableRegExps [ divisor ] = new RegExp ( `(.|\\n){1,${ divisor } }(\\s|$)|(\\n|.)+?(\\s|$)` , 'gm' ) ;
698
730
}
699
- const indent = ' ' . repeat ( ctx . indentationLvl ) ;
700
731
const matches = value . match ( readableRegExps [ divisor ] ) ;
701
732
if ( matches . length > 1 ) {
733
+ const indent = ' ' . repeat ( ctx . indentationLvl ) ;
702
734
res += `${ fn ( strEscape ( matches [ 0 ] ) , 'string' ) } +\n` ;
703
735
for ( var i = 1 ; i < matches . length - 1 ; i ++ ) {
704
736
res += `${ indent } ${ fn ( strEscape ( matches [ i ] ) , 'string' ) } +\n` ;
0 commit comments