@@ -168,7 +168,8 @@ const inspectDefaultOptions = ObjectSeal({
168
168
breakLength : 80 ,
169
169
compact : 3 ,
170
170
sorted : false ,
171
- getters : false
171
+ getters : false ,
172
+ numericSeparator : false ,
172
173
} ) ;
173
174
174
175
const kObjectType = 0 ;
@@ -244,6 +245,7 @@ function getUserOptions(ctx, isCrossContext) {
244
245
compact : ctx . compact ,
245
246
sorted : ctx . sorted ,
246
247
getters : ctx . getters ,
248
+ numericSeparator : ctx . numericSeparator ,
247
249
...ctx . userOptions
248
250
} ;
249
251
@@ -301,7 +303,8 @@ function inspect(value, opts) {
301
303
breakLength : inspectDefaultOptions . breakLength ,
302
304
compact : inspectDefaultOptions . compact ,
303
305
sorted : inspectDefaultOptions . sorted ,
304
- getters : inspectDefaultOptions . getters
306
+ getters : inspectDefaultOptions . getters ,
307
+ numericSeparator : inspectDefaultOptions . numericSeparator ,
305
308
} ;
306
309
if ( arguments . length > 1 ) {
307
310
// Legacy...
@@ -949,7 +952,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
949
952
formatter = formatArrayBuffer ;
950
953
} else if ( keys . length === 0 && protoProps === undefined ) {
951
954
return prefix +
952
- `{ byteLength: ${ formatNumber ( ctx . stylize , value . byteLength ) } }` ;
955
+ `{ byteLength: ${ formatNumber ( ctx . stylize , value . byteLength , false ) } }` ;
953
956
}
954
957
braces [ 0 ] = `${ prefix } {` ;
955
958
ArrayPrototypeUnshift ( keys , 'byteLength' ) ;
@@ -1370,13 +1373,61 @@ function handleMaxCallStackSize(ctx, err, constructorName, indentationLvl) {
1370
1373
assert . fail ( err . stack ) ;
1371
1374
}
1372
1375
1373
- function formatNumber ( fn , value ) {
1374
- // Format -0 as '-0'. Checking `value === -0` won't distinguish 0 from -0.
1375
- return fn ( ObjectIs ( value , - 0 ) ? '-0' : `${ value } ` , 'number' ) ;
1376
+ function addNumericSeparator ( integerString ) {
1377
+ let result = '' ;
1378
+ let i = integerString . length ;
1379
+ const start = integerString . startsWith ( '-' ) ? 1 : 0 ;
1380
+ for ( ; i >= start + 4 ; i -= 3 ) {
1381
+ result = `_${ integerString . slice ( i - 3 , i ) } ${ result } ` ;
1382
+ }
1383
+ return i === integerString . length ?
1384
+ integerString :
1385
+ `${ integerString . slice ( 0 , i ) } ${ result } ` ;
1386
+ }
1387
+
1388
+ function addNumericSeparatorEnd ( integerString ) {
1389
+ let result = '' ;
1390
+ let i = 0 ;
1391
+ for ( ; i < integerString . length - 3 ; i += 3 ) {
1392
+ result += `${ integerString . slice ( i , i + 3 ) } _` ;
1393
+ }
1394
+ return i === 0 ?
1395
+ integerString :
1396
+ `${ result } ${ integerString . slice ( i ) } ` ;
1397
+ }
1398
+
1399
+ function formatNumber ( fn , number , numericSeparator ) {
1400
+ if ( ! numericSeparator ) {
1401
+ // Format -0 as '-0'. Checking `number === -0` won't distinguish 0 from -0.
1402
+ if ( ObjectIs ( number , - 0 ) ) {
1403
+ return fn ( '-0' , 'number' ) ;
1404
+ }
1405
+ return fn ( `${ number } ` , 'number' ) ;
1406
+ }
1407
+ const integer = Math . trunc ( number ) ;
1408
+ const string = String ( integer ) ;
1409
+ if ( integer === number ) {
1410
+ if ( ! isFinite ( number ) || string . includes ( 'e' ) ) {
1411
+ return fn ( string , 'number' ) ;
1412
+ }
1413
+ return fn ( `${ addNumericSeparator ( string ) } ` , 'number' ) ;
1414
+ }
1415
+ if ( NumberIsNaN ( number ) ) {
1416
+ return fn ( string , 'number' ) ;
1417
+ }
1418
+ return fn ( `${
1419
+ addNumericSeparator ( string )
1420
+ } .${
1421
+ addNumericSeparatorEnd ( String ( number ) . slice ( string . length + 1 ) )
1422
+ } `, 'number' ) ;
1376
1423
}
1377
1424
1378
- function formatBigInt ( fn , value ) {
1379
- return fn ( `${ value } n` , 'bigint' ) ;
1425
+ function formatBigInt ( fn , bigint , numericSeparator ) {
1426
+ const string = String ( bigint ) ;
1427
+ if ( ! numericSeparator ) {
1428
+ return fn ( `${ string } n` , 'bigint' ) ;
1429
+ }
1430
+ return fn ( `${ addNumericSeparator ( string ) } n` , 'bigint' ) ;
1380
1431
}
1381
1432
1382
1433
function formatPrimitive ( fn , value , ctx ) {
@@ -1400,9 +1451,9 @@ function formatPrimitive(fn, value, ctx) {
1400
1451
return fn ( strEscape ( value ) , 'string' ) + trailer ;
1401
1452
}
1402
1453
if ( typeof value === 'number' )
1403
- return formatNumber ( fn , value ) ;
1454
+ return formatNumber ( fn , value , ctx . numericSeparator ) ;
1404
1455
if ( typeof value === 'bigint' )
1405
- return formatBigInt ( fn , value ) ;
1456
+ return formatBigInt ( fn , value , ctx . numericSeparator ) ;
1406
1457
if ( typeof value === 'boolean' )
1407
1458
return fn ( `${ value } ` , 'boolean' ) ;
1408
1459
if ( typeof value === 'undefined' )
@@ -1519,8 +1570,9 @@ function formatTypedArray(value, length, ctx, ignored, recurseTimes) {
1519
1570
const elementFormatter = value . length > 0 && typeof value [ 0 ] === 'number' ?
1520
1571
formatNumber :
1521
1572
formatBigInt ;
1522
- for ( let i = 0 ; i < maxLength ; ++ i )
1523
- output [ i ] = elementFormatter ( ctx . stylize , value [ i ] ) ;
1573
+ for ( let i = 0 ; i < maxLength ; ++ i ) {
1574
+ output [ i ] = elementFormatter ( ctx . stylize , value [ i ] , ctx . numericSeparator ) ;
1575
+ }
1524
1576
if ( remaining > 0 ) {
1525
1577
output [ maxLength ] = `... ${ remaining } more item${ remaining > 1 ? 's' : '' } ` ;
1526
1578
}
@@ -1864,8 +1916,8 @@ function tryStringify(arg) {
1864
1916
if ( ! CIRCULAR_ERROR_MESSAGE ) {
1865
1917
try {
1866
1918
const a = { } ; a . a = a ; JSONStringify ( a ) ;
1867
- } catch ( err ) {
1868
- CIRCULAR_ERROR_MESSAGE = firstErrorLine ( err ) ;
1919
+ } catch ( circularError ) {
1920
+ CIRCULAR_ERROR_MESSAGE = firstErrorLine ( circularError ) ;
1869
1921
}
1870
1922
}
1871
1923
if ( err . name === 'TypeError' &&
@@ -1888,6 +1940,22 @@ function formatWithOptions(inspectOptions, ...args) {
1888
1940
return formatWithOptionsInternal ( inspectOptions , args ) ;
1889
1941
}
1890
1942
1943
+ function formatNumberNoColor ( number , options ) {
1944
+ return formatNumber (
1945
+ stylizeNoColor ,
1946
+ number ,
1947
+ options ?. numericSeparator ?? inspectDefaultOptions . numericSeparator
1948
+ )
1949
+ }
1950
+
1951
+ function formatBigIntNoColor ( bigint , options ) {
1952
+ return formatBigInt (
1953
+ stylizeNoColor ,
1954
+ bigint ,
1955
+ options ?. numericSeparator ?? inspectDefaultOptions . numericSeparator
1956
+ )
1957
+ }
1958
+
1891
1959
function formatWithOptionsInternal ( inspectOptions , args ) {
1892
1960
const first = args [ 0 ] ;
1893
1961
let a = 0 ;
@@ -1909,9 +1977,9 @@ function formatWithOptionsInternal(inspectOptions, args) {
1909
1977
case 115 : // 's'
1910
1978
const tempArg = args [ ++ a ] ;
1911
1979
if ( typeof tempArg === 'number' ) {
1912
- tempStr = formatNumber ( stylizeNoColor , tempArg ) ;
1980
+ tempStr = formatNumberNoColor ( tempArg , inspectOptions ) ;
1913
1981
} else if ( typeof tempArg === 'bigint' ) {
1914
- tempStr = ` ${ tempArg } n` ;
1982
+ tempStr = formatBigIntNoColor ( tempArg , inspectOptions ) ;
1915
1983
} else if ( typeof tempArg !== 'object' ||
1916
1984
tempArg === null ||
1917
1985
! hasBuiltInToString ( tempArg ) ) {
@@ -1931,11 +1999,11 @@ function formatWithOptionsInternal(inspectOptions, args) {
1931
1999
case 100 : // 'd'
1932
2000
const tempNum = args [ ++ a ] ;
1933
2001
if ( typeof tempNum === 'bigint' ) {
1934
- tempStr = ` ${ tempNum } n` ;
2002
+ tempStr = formatBigIntNoColor ( tempNum , inspectOptions ) ;
1935
2003
} else if ( typeof tempNum === 'symbol' ) {
1936
2004
tempStr = 'NaN' ;
1937
2005
} else {
1938
- tempStr = formatNumber ( stylizeNoColor , Number ( tempNum ) ) ;
2006
+ tempStr = formatNumberNoColor ( Number ( tempNum ) , inspectOptions ) ;
1939
2007
}
1940
2008
break ;
1941
2009
case 79 : // 'O'
@@ -1952,21 +2020,19 @@ function formatWithOptionsInternal(inspectOptions, args) {
1952
2020
case 105 : // 'i'
1953
2021
const tempInteger = args [ ++ a ] ;
1954
2022
if ( typeof tempInteger === 'bigint' ) {
1955
- tempStr = ` ${ tempInteger } n` ;
2023
+ tempStr = formatBigIntNoColor ( tempInteger , inspectOptions ) ;
1956
2024
} else if ( typeof tempInteger === 'symbol' ) {
1957
2025
tempStr = 'NaN' ;
1958
2026
} else {
1959
- tempStr = formatNumber ( stylizeNoColor ,
1960
- NumberParseInt ( tempInteger ) ) ;
2027
+ tempStr = formatNumberNoColor ( NumberParseInt ( tempInteger ) , inspectOptions ) ;
1961
2028
}
1962
2029
break ;
1963
2030
case 102 : // 'f'
1964
2031
const tempFloat = args [ ++ a ] ;
1965
2032
if ( typeof tempFloat === 'symbol' ) {
1966
2033
tempStr = 'NaN' ;
1967
2034
} else {
1968
- tempStr = formatNumber ( stylizeNoColor ,
1969
- NumberParseFloat ( tempFloat ) ) ;
2035
+ tempStr = formatNumberNoColor ( NumberParseFloat ( tempFloat ) , inspectOptions ) ;
1970
2036
}
1971
2037
break ;
1972
2038
case 99 : // 'c'
0 commit comments