12
12
// Helpers
13
13
// ------------------------------------------------------------------------------
14
14
15
+ /** @type {Set<ASTNode['type']> } */
15
16
const KNOWN_NODES = new Set ( [
16
17
'ArrayExpression' ,
17
18
'ArrayPattern' ,
@@ -24,6 +25,7 @@ const KNOWN_NODES = new Set([
24
25
'BreakStatement' ,
25
26
'CallExpression' ,
26
27
'CatchClause' ,
28
+ 'ChainExpression' ,
27
29
'ClassBody' ,
28
30
'ClassDeclaration' ,
29
31
'ClassExpression' ,
@@ -32,8 +34,6 @@ const KNOWN_NODES = new Set([
32
34
'DebuggerStatement' ,
33
35
'DoWhileStatement' ,
34
36
'EmptyStatement' ,
35
- 'ExperimentalRestProperty' ,
36
- 'ExperimentalSpreadProperty' ,
37
37
'ExportAllDeclaration' ,
38
38
'ExportDefaultDeclaration' ,
39
39
'ExportNamedDeclaration' ,
@@ -48,6 +48,7 @@ const KNOWN_NODES = new Set([
48
48
'IfStatement' ,
49
49
'ImportDeclaration' ,
50
50
'ImportDefaultSpecifier' ,
51
+ 'ImportExpression' ,
51
52
'ImportNamespaceSpecifier' ,
52
53
'ImportSpecifier' ,
53
54
'LabeledStatement' ,
@@ -97,6 +98,10 @@ const KNOWN_NODES = new Set([
97
98
'VStartTag' ,
98
99
'VText'
99
100
] )
101
+ const NON_STANDARD_KNOWN_NODES = new Set ( [
102
+ 'ExperimentalRestProperty' ,
103
+ 'ExperimentalSpreadProperty'
104
+ ] )
100
105
const LT_CHAR = / [ \r \n \u2028 \u2029 ] /
101
106
const LINES = / [ ^ \r \n \u2028 \u2029 ] + (?: $ | \r \n | [ \r \n \u2028 \u2029 ] ) / g
102
107
const BLOCK_COMMENT_PREFIX = / ^ \s * \* /
@@ -300,6 +305,14 @@ function isSemicolon(token) {
300
305
function isComma ( token ) {
301
306
return token != null && token . type === 'Punctuator' && token . value === ','
302
307
}
308
+ /**
309
+ * Check whether the given token is a wildcard.
310
+ * @param {Token } token The token to check.
311
+ * @returns {boolean } `true` if the token is a wildcard.
312
+ */
313
+ function isWildcard ( token ) {
314
+ return token != null && token . type === 'Punctuator' && token . value === '*'
315
+ }
303
316
304
317
/**
305
318
* Check whether the given token is a whitespace.
@@ -321,7 +334,9 @@ function isComment(token) {
321
334
( token . type === 'Block' ||
322
335
token . type === 'Line' ||
323
336
token . type === 'Shebang' ||
324
- token . type . endsWith ( 'Comment' ) )
337
+ ( typeof token . type ===
338
+ 'string' /* Although acorn supports new tokens, espree may not yet support new tokens.*/ &&
339
+ token . type . endsWith ( 'Comment' ) ) )
325
340
)
326
341
}
327
342
@@ -336,7 +351,11 @@ function isNotComment(token) {
336
351
token . type !== 'Block' &&
337
352
token . type !== 'Line' &&
338
353
token . type !== 'Shebang' &&
339
- ! token . type . endsWith ( 'Comment' )
354
+ ! (
355
+ typeof token . type ===
356
+ 'string' /* Although acorn supports new tokens, espree may not yet support new tokens.*/ &&
357
+ token . type . endsWith ( 'Comment' )
358
+ )
340
359
)
341
360
}
342
361
@@ -1330,6 +1349,15 @@ module.exports.defineVisitor = function create(
1330
1349
setOffset ( leftToken , 1 , firstToken )
1331
1350
processNodeList ( node . arguments , leftToken , rightToken , 1 )
1332
1351
} ,
1352
+ /** @param {ImportExpression } node */
1353
+ ImportExpression ( node ) {
1354
+ const firstToken = tokenStore . getFirstToken ( node )
1355
+ const rightToken = tokenStore . getLastToken ( node )
1356
+ const leftToken = tokenStore . getTokenAfter ( firstToken , isLeftParen )
1357
+
1358
+ setOffset ( leftToken , 1 , firstToken )
1359
+ processNodeList ( [ node . source ] , leftToken , rightToken , 1 )
1360
+ } ,
1333
1361
/** @param {CatchClause } node */
1334
1362
CatchClause ( node ) {
1335
1363
const firstToken = tokenStore . getFirstToken ( node )
@@ -1417,7 +1445,20 @@ module.exports.defineVisitor = function create(
1417
1445
if ( isSemicolon ( last ( tokens ) ) ) {
1418
1446
tokens . pop ( )
1419
1447
}
1420
- setOffset ( tokens , 1 , firstToken )
1448
+ if ( ! node . exported ) {
1449
+ setOffset ( tokens , 1 , firstToken )
1450
+ } else {
1451
+ // export * as foo from "mod"
1452
+ const starToken = /** @type {Token } */ ( tokens . find ( isWildcard ) )
1453
+ const asToken = tokenStore . getTokenAfter ( starToken )
1454
+ const exportedToken = tokenStore . getTokenAfter ( asToken )
1455
+ const afterTokens = tokens . slice ( tokens . indexOf ( exportedToken ) + 1 )
1456
+
1457
+ setOffset ( starToken , 1 , firstToken )
1458
+ setOffset ( asToken , 1 , starToken )
1459
+ setOffset ( exportedToken , 1 , starToken )
1460
+ setOffset ( afterTokens , 1 , firstToken )
1461
+ }
1421
1462
} ,
1422
1463
/** @param {ExportDefaultDeclaration } node */
1423
1464
ExportDefaultDeclaration ( node ) {
@@ -1435,23 +1476,28 @@ module.exports.defineVisitor = function create(
1435
1476
const declarationToken = tokenStore . getFirstToken ( node , 1 )
1436
1477
setOffset ( declarationToken , 1 , exportToken )
1437
1478
} else {
1438
- // export {foo, bar}; or export {foo, bar} from "mod";
1439
- const leftParenToken = tokenStore . getFirstToken ( node , 1 )
1440
- const rightParenToken = /** @type {Token } */ ( tokenStore . getLastToken (
1441
- node ,
1442
- isRightBrace
1443
- ) )
1444
- setOffset ( leftParenToken , 0 , exportToken )
1445
- processNodeList ( node . specifiers , leftParenToken , rightParenToken , 1 )
1446
-
1447
- const maybeFromToken = tokenStore . getTokenAfter ( rightParenToken )
1448
- if (
1449
- maybeFromToken != null &&
1450
- sourceCode . getText ( maybeFromToken ) === 'from'
1451
- ) {
1452
- const fromToken = maybeFromToken
1453
- const nameToken = tokenStore . getTokenAfter ( fromToken )
1454
- setOffset ( [ fromToken , nameToken ] , 1 , exportToken )
1479
+ const firstSpecifier = node . specifiers [ 0 ]
1480
+ if ( ! firstSpecifier || firstSpecifier . type === 'ExportSpecifier' ) {
1481
+ // export {foo, bar}; or export {foo, bar} from "mod";
1482
+ const leftParenToken = tokenStore . getFirstToken ( node , 1 )
1483
+ const rightParenToken = /** @type {Token } */ ( tokenStore . getLastToken (
1484
+ node ,
1485
+ isRightBrace
1486
+ ) )
1487
+ setOffset ( leftParenToken , 0 , exportToken )
1488
+ processNodeList ( node . specifiers , leftParenToken , rightParenToken , 1 )
1489
+
1490
+ const maybeFromToken = tokenStore . getTokenAfter ( rightParenToken )
1491
+ if (
1492
+ maybeFromToken != null &&
1493
+ sourceCode . getText ( maybeFromToken ) === 'from'
1494
+ ) {
1495
+ const fromToken = maybeFromToken
1496
+ const nameToken = tokenStore . getTokenAfter ( fromToken )
1497
+ setOffset ( [ fromToken , nameToken ] , 1 , exportToken )
1498
+ }
1499
+ } else {
1500
+ // maybe babel-eslint
1455
1501
}
1456
1502
}
1457
1503
} ,
@@ -1464,7 +1510,12 @@ module.exports.defineVisitor = function create(
1464
1510
/** @param {ForInStatement | ForOfStatement } node */
1465
1511
'ForInStatement, ForOfStatement' ( node ) {
1466
1512
const forToken = tokenStore . getFirstToken ( node )
1467
- const leftParenToken = tokenStore . getTokenAfter ( forToken )
1513
+ const awaitToken =
1514
+ ( node . type === 'ForOfStatement' &&
1515
+ node . await &&
1516
+ tokenStore . getTokenAfter ( forToken ) ) ||
1517
+ null
1518
+ const leftParenToken = tokenStore . getTokenAfter ( awaitToken || forToken )
1468
1519
const leftToken = tokenStore . getTokenAfter ( leftParenToken )
1469
1520
const inToken = /** @type {Token } */ ( tokenStore . getTokenAfter (
1470
1521
leftToken ,
@@ -1476,6 +1527,9 @@ module.exports.defineVisitor = function create(
1476
1527
isNotLeftParen
1477
1528
)
1478
1529
1530
+ if ( awaitToken != null ) {
1531
+ setOffset ( awaitToken , 0 , forToken )
1532
+ }
1479
1533
setOffset ( leftParenToken , 1 , forToken )
1480
1534
setOffset ( leftToken , 1 , leftParenToken )
1481
1535
setOffset ( inToken , 1 , leftToken )
@@ -1958,7 +2012,10 @@ module.exports.defineVisitor = function create(
1958
2012
/** @param {ASTNode } node */
1959
2013
// Ignore tokens of unknown nodes.
1960
2014
'*:exit' ( node ) {
1961
- if ( ! KNOWN_NODES . has ( node . type ) ) {
2015
+ if (
2016
+ ! KNOWN_NODES . has ( node . type ) &&
2017
+ ! NON_STANDARD_KNOWN_NODES . has ( node . type )
2018
+ ) {
1962
2019
ignore ( node )
1963
2020
}
1964
2021
} ,
0 commit comments