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,12 @@ 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
+ 'OptionalCallExpression' ,
105
+ 'OptionalMemberExpression'
106
+ ] )
100
107
const LT_CHAR = / [ \r \n \u2028 \u2029 ] /
101
108
const LINES = / [ ^ \r \n \u2028 \u2029 ] + (?: $ | \r \n | [ \r \n \u2028 \u2029 ] ) / g
102
109
const BLOCK_COMMENT_PREFIX = / ^ \s * \* /
@@ -300,6 +307,14 @@ function isSemicolon(token) {
300
307
function isComma ( token ) {
301
308
return token != null && token . type === 'Punctuator' && token . value === ','
302
309
}
310
+ /**
311
+ * Check whether the given token is a wildcard.
312
+ * @param {Token } token The token to check.
313
+ * @returns {boolean } `true` if the token is a wildcard.
314
+ */
315
+ function isWildcard ( token ) {
316
+ return token != null && token . type === 'Punctuator' && token . value === '*'
317
+ }
303
318
304
319
/**
305
320
* Check whether the given token is a whitespace.
@@ -321,7 +336,9 @@ function isComment(token) {
321
336
( token . type === 'Block' ||
322
337
token . type === 'Line' ||
323
338
token . type === 'Shebang' ||
324
- token . type . endsWith ( 'Comment' ) )
339
+ ( typeof token . type ===
340
+ 'string' /* Although acorn supports new tokens, espree may not yet support new tokens.*/ &&
341
+ token . type . endsWith ( 'Comment' ) ) )
325
342
)
326
343
}
327
344
@@ -336,7 +353,11 @@ function isNotComment(token) {
336
353
token . type !== 'Block' &&
337
354
token . type !== 'Line' &&
338
355
token . type !== 'Shebang' &&
339
- ! token . type . endsWith ( 'Comment' )
356
+ ! (
357
+ typeof token . type ===
358
+ 'string' /* Although acorn supports new tokens, espree may not yet support new tokens.*/ &&
359
+ token . type . endsWith ( 'Comment' )
360
+ )
340
361
)
341
362
}
342
363
@@ -1330,6 +1351,15 @@ module.exports.defineVisitor = function create(
1330
1351
setOffset ( leftToken , 1 , firstToken )
1331
1352
processNodeList ( node . arguments , leftToken , rightToken , 1 )
1332
1353
} ,
1354
+ /** @param {ImportExpression } node */
1355
+ ImportExpression ( node ) {
1356
+ const firstToken = tokenStore . getFirstToken ( node )
1357
+ const rightToken = tokenStore . getLastToken ( node )
1358
+ const leftToken = tokenStore . getTokenAfter ( firstToken , isLeftParen )
1359
+
1360
+ setOffset ( leftToken , 1 , firstToken )
1361
+ processNodeList ( [ node . source ] , leftToken , rightToken , 1 )
1362
+ } ,
1333
1363
/** @param {CatchClause } node */
1334
1364
CatchClause ( node ) {
1335
1365
const firstToken = tokenStore . getFirstToken ( node )
@@ -1417,7 +1447,20 @@ module.exports.defineVisitor = function create(
1417
1447
if ( isSemicolon ( last ( tokens ) ) ) {
1418
1448
tokens . pop ( )
1419
1449
}
1420
- setOffset ( tokens , 1 , firstToken )
1450
+ if ( ! node . exported ) {
1451
+ setOffset ( tokens , 1 , firstToken )
1452
+ } else {
1453
+ // export * as foo from "mod"
1454
+ const starToken = /** @type {Token } */ ( tokens . find ( isWildcard ) )
1455
+ const asToken = tokenStore . getTokenAfter ( starToken )
1456
+ const exportedToken = tokenStore . getTokenAfter ( asToken )
1457
+ const afterTokens = tokens . slice ( tokens . indexOf ( exportedToken ) + 1 )
1458
+
1459
+ setOffset ( starToken , 1 , firstToken )
1460
+ setOffset ( asToken , 1 , starToken )
1461
+ setOffset ( exportedToken , 1 , starToken )
1462
+ setOffset ( afterTokens , 1 , firstToken )
1463
+ }
1421
1464
} ,
1422
1465
/** @param {ExportDefaultDeclaration } node */
1423
1466
ExportDefaultDeclaration ( node ) {
@@ -1435,23 +1478,28 @@ module.exports.defineVisitor = function create(
1435
1478
const declarationToken = tokenStore . getFirstToken ( node , 1 )
1436
1479
setOffset ( declarationToken , 1 , exportToken )
1437
1480
} 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 )
1481
+ const firstSpecifier = node . specifiers [ 0 ]
1482
+ if ( ! firstSpecifier || firstSpecifier . type === 'ExportSpecifier' ) {
1483
+ // export {foo, bar}; or export {foo, bar} from "mod";
1484
+ const leftParenToken = tokenStore . getFirstToken ( node , 1 )
1485
+ const rightParenToken = /** @type {Token } */ ( tokenStore . getLastToken (
1486
+ node ,
1487
+ isRightBrace
1488
+ ) )
1489
+ setOffset ( leftParenToken , 0 , exportToken )
1490
+ processNodeList ( node . specifiers , leftParenToken , rightParenToken , 1 )
1491
+
1492
+ const maybeFromToken = tokenStore . getTokenAfter ( rightParenToken )
1493
+ if (
1494
+ maybeFromToken != null &&
1495
+ sourceCode . getText ( maybeFromToken ) === 'from'
1496
+ ) {
1497
+ const fromToken = maybeFromToken
1498
+ const nameToken = tokenStore . getTokenAfter ( fromToken )
1499
+ setOffset ( [ fromToken , nameToken ] , 1 , exportToken )
1500
+ }
1501
+ } else {
1502
+ // maybe babel-eslint
1455
1503
}
1456
1504
}
1457
1505
} ,
@@ -1464,7 +1512,12 @@ module.exports.defineVisitor = function create(
1464
1512
/** @param {ForInStatement | ForOfStatement } node */
1465
1513
'ForInStatement, ForOfStatement' ( node ) {
1466
1514
const forToken = tokenStore . getFirstToken ( node )
1467
- const leftParenToken = tokenStore . getTokenAfter ( forToken )
1515
+ const awaitToken =
1516
+ ( node . type === 'ForOfStatement' &&
1517
+ node . await &&
1518
+ tokenStore . getTokenAfter ( forToken ) ) ||
1519
+ null
1520
+ const leftParenToken = tokenStore . getTokenAfter ( awaitToken || forToken )
1468
1521
const leftToken = tokenStore . getTokenAfter ( leftParenToken )
1469
1522
const inToken = /** @type {Token } */ ( tokenStore . getTokenAfter (
1470
1523
leftToken ,
@@ -1476,6 +1529,9 @@ module.exports.defineVisitor = function create(
1476
1529
isNotLeftParen
1477
1530
)
1478
1531
1532
+ if ( awaitToken != null ) {
1533
+ setOffset ( awaitToken , 0 , forToken )
1534
+ }
1479
1535
setOffset ( leftParenToken , 1 , forToken )
1480
1536
setOffset ( leftToken , 1 , leftParenToken )
1481
1537
setOffset ( inToken , 1 , leftToken )
@@ -1958,7 +2014,10 @@ module.exports.defineVisitor = function create(
1958
2014
/** @param {ASTNode } node */
1959
2015
// Ignore tokens of unknown nodes.
1960
2016
'*:exit' ( node ) {
1961
- if ( ! KNOWN_NODES . has ( node . type ) ) {
2017
+ if (
2018
+ ! KNOWN_NODES . has ( node . type ) &&
2019
+ ! NON_STANDARD_KNOWN_NODES . has ( node . type )
2020
+ ) {
1962
2021
ignore ( node )
1963
2022
}
1964
2023
} ,
0 commit comments