@@ -16,66 +16,75 @@ const MAX_RECURSIVE_DEPTH = 2;
16
16
* Used to print values in error messages.
17
17
*/
18
18
export default function inspect ( value : mixed ) : string {
19
- return formatValue ( value , 0 ) ;
19
+ return formatValue ( value , [ ] ) ;
20
20
}
21
21
22
- function formatValue ( value , recurseTimes ) {
22
+ function formatValue ( value , seenValues ) {
23
23
switch ( typeof value ) {
24
24
case 'string' :
25
25
return JSON . stringify ( value ) ;
26
26
case 'function' :
27
27
return value . name ? `[function ${ value . name } ]` : '[function]' ;
28
28
case 'object' :
29
- if ( value ) {
30
- const customInspectFn = getCustomFn ( value ) ;
31
-
32
- if ( customInspectFn ) {
33
- // $FlowFixMe(>=0.90.0)
34
- const customValue = customInspectFn . call ( value ) ;
35
-
36
- // check for infinite recursion
37
- if ( customValue !== value ) {
38
- return typeof customValue === 'string'
39
- ? customValue
40
- : formatValue ( customValue , recurseTimes ) ;
41
- }
42
- } else if ( Array . isArray ( value ) ) {
43
- return formatArray ( value , recurseTimes ) ;
44
- }
45
-
46
- return formatObject ( value , recurseTimes ) ;
47
- }
48
-
49
- return String ( value ) ;
29
+ return formatObjectValue ( value , seenValues ) ;
50
30
default :
51
31
return String ( value ) ;
52
32
}
53
33
}
54
34
55
- function formatObject ( object , recurseTimes ) {
35
+ function formatObjectValue ( value , previouslySeenValues ) {
36
+ if ( previouslySeenValues . indexOf ( value ) !== - 1 ) {
37
+ return '[Circular]' ;
38
+ }
39
+ const seenValues = [ ...previouslySeenValues , value ] ;
40
+
41
+ if ( value ) {
42
+ const customInspectFn = getCustomFn ( value ) ;
43
+
44
+ if ( customInspectFn ) {
45
+ // $FlowFixMe(>=0.90.0)
46
+ const customValue = customInspectFn . call ( value ) ;
47
+
48
+ // check for infinite recursion
49
+ if ( customValue !== value ) {
50
+ return typeof customValue === 'string'
51
+ ? customValue
52
+ : formatValue ( customValue , seenValues ) ;
53
+ }
54
+ } else if ( Array . isArray ( value ) ) {
55
+ return formatArray ( value , seenValues ) ;
56
+ }
57
+
58
+ return formatObject ( value , seenValues ) ;
59
+ }
60
+
61
+ return String ( value ) ;
62
+ }
63
+
64
+ function formatObject ( object , seenValues ) {
56
65
const keys = Object . keys ( object ) ;
57
66
if ( keys . length === 0 ) {
58
67
return '{}' ;
59
68
}
60
69
61
- if ( recurseTimes === MAX_RECURSIVE_DEPTH ) {
70
+ if ( seenValues . length > MAX_RECURSIVE_DEPTH ) {
62
71
return '[' + getObjectTag ( object ) + ']' ;
63
72
}
64
73
65
74
const properties = keys . map ( key => {
66
- const value = formatValue ( object [ key ] , recurseTimes + 1 ) ;
75
+ const value = formatValue ( object [ key ] , seenValues ) ;
67
76
return key + ': ' + value ;
68
77
} ) ;
69
78
70
79
return '{ ' + properties . join ( ', ' ) + ' }' ;
71
80
}
72
81
73
- function formatArray ( array , recurseTimes ) {
82
+ function formatArray ( array , seenValues ) {
74
83
if ( array . length === 0 ) {
75
84
return '[]' ;
76
85
}
77
86
78
- if ( recurseTimes === MAX_RECURSIVE_DEPTH ) {
87
+ if ( seenValues . length > MAX_RECURSIVE_DEPTH ) {
79
88
return '[Array]' ;
80
89
}
81
90
@@ -84,7 +93,7 @@ function formatArray(array, recurseTimes) {
84
93
const items = [ ] ;
85
94
86
95
for ( let i = 0 ; i < len ; ++ i ) {
87
- items . push ( formatValue ( array [ i ] , recurseTimes + 1 ) ) ;
96
+ items . push ( formatValue ( array [ i ] , seenValues ) ) ;
88
97
}
89
98
90
99
if ( remaining === 1 ) {
0 commit comments