@@ -14,7 +14,7 @@ const assert = require('assert')
14
14
// Helpers
15
15
// ------------------------------------------------------------------------------
16
16
17
- const KNOWN_NODES = new Set ( [ 'ArrayExpression' , 'ArrayPattern' , 'ArrowFunctionExpression' , 'AssignmentExpression' , 'AssignmentPattern' , 'AwaitExpression' , 'BinaryExpression' , 'BlockStatement' , 'BreakStatement' , 'CallExpression' , 'CatchClause' , 'ClassBody' , 'ClassDeclaration' , 'ClassExpression' , 'ConditionalExpression' , 'ContinueStatement' , 'DebuggerStatement' , 'DoWhileStatement' , 'EmptyStatement' , 'ExperimentalRestProperty' , 'ExperimentalSpreadProperty' , 'ExportAllDeclaration' , 'ExportDefaultDeclaration' , 'ExportNamedDeclaration' , 'ExportSpecifier' , 'ExpressionStatement' , 'ForInStatement' , 'ForOfStatement' , 'ForStatement' , 'FunctionDeclaration' , 'FunctionExpression' , 'Identifier' , 'IfStatement' , 'ImportDeclaration' , 'ImportDefaultSpecifier' , 'ImportNamespaceSpecifier' , 'ImportSpecifier' , 'LabeledStatement' , 'Literal' , 'LogicalExpression' , 'MemberExpression' , 'MetaProperty' , 'MethodDefinition' , 'NewExpression' , 'ObjectExpression' , 'ObjectPattern' , 'Program' , 'Property' , 'RestElement' , 'ReturnStatement' , 'SequenceExpression' , 'SpreadElement' , 'Super' , 'SwitchCase' , 'SwitchStatement' , 'TaggedTemplateExpression' , 'TemplateElement' , 'TemplateLiteral' , 'ThisExpression' , 'ThrowStatement' , 'TryStatement' , 'UnaryExpression' , 'UpdateExpression' , 'VariableDeclaration' , 'VariableDeclarator' , 'WhileStatement' , 'WithStatement' , 'YieldExpression' , 'VAttribute' , 'VDirectiveKey' , 'VDocumentFragment' , 'VElement' , 'VEndTag' , 'VExpressionContainer' , 'VFilter' , 'VFilterSequenceExpression' , 'VForExpression' , 'VIdentifier' , 'VLiteral' , 'VOnExpression' , 'VSlotScopeExpression' , 'VStartTag' , 'VText' ] )
17
+ const KNOWN_NODES = new Set ( [ 'ArrayExpression' , 'ArrayPattern' , 'ArrowFunctionExpression' , 'AssignmentExpression' , 'AssignmentPattern' , 'AwaitExpression' , 'BinaryExpression' , 'BlockStatement' , 'BreakStatement' , 'CallExpression' , 'CatchClause' , 'ClassBody' , 'ClassDeclaration' , 'ClassExpression' , 'ConditionalExpression' , 'ContinueStatement' , 'DebuggerStatement' , 'DoWhileStatement' , 'EmptyStatement' , 'ExperimentalRestProperty' , 'ExperimentalSpreadProperty' , 'ExportAllDeclaration' , 'ExportDefaultDeclaration' , 'ExportDefaultSpecifier' , 'ExportNamedDeclaration' , 'ExportNamespaceSpecifier' , 'ExportSpecifier' , 'ExpressionStatement' , 'ForInStatement' , 'ForOfStatement' , 'ForStatement' , 'FunctionDeclaration' , 'FunctionExpression' , 'Identifier' , 'IfStatement' , 'ImportDeclaration' , 'ImportDefaultSpecifier' , 'ImportExpression' , 'ImportNamespaceSpecifier' , 'ImportSpecifier' , 'LabeledStatement' , 'Literal' , 'LogicalExpression' , 'MemberExpression' , 'MetaProperty' , 'MethodDefinition' , 'NewExpression' , 'ObjectExpression' , 'ObjectPattern' , 'OptionalCallExpression' , 'OptionalMemberExpression' , 'Program' , 'Property' , 'RestElement' , 'ReturnStatement' , 'SequenceExpression' , 'SpreadElement' , 'Super' , 'SwitchCase' , 'SwitchStatement' , 'TaggedTemplateExpression' , 'TemplateElement' , 'TemplateLiteral' , 'ThisExpression' , 'ThrowStatement' , 'TryStatement' , 'UnaryExpression' , 'UpdateExpression' , 'VariableDeclaration' , 'VariableDeclarator' , 'WhileStatement' , 'WithStatement' , 'YieldExpression' , 'VAttribute' , 'VDirectiveKey' , 'VDocumentFragment' , 'VElement' , 'VEndTag' , 'VExpressionContainer' , 'VFilter' , 'VFilterSequenceExpression' , 'VForExpression' , 'VIdentifier' , 'VLiteral' , 'VOnExpression' , 'VSlotScopeExpression' , 'VStartTag' , 'VText' ] )
18
18
const LT_CHAR = / [ \r \n \u2028 \u2029 ] /
19
19
const LINES = / [ ^ \r \n \u2028 \u2029 ] + (?: $ | \r \n | [ \r \n \u2028 \u2029 ] ) / g
20
20
const BLOCK_COMMENT_PREFIX = / ^ \s * \* /
@@ -552,7 +552,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
552
552
}
553
553
return true
554
554
}
555
- if ( t === 'CallExpression' || t === 'NewExpression' ) {
555
+ if ( t === 'CallExpression' || t === 'NewExpression' || t === 'OptionalCallExpression' ) {
556
556
const openParen = tokenStore . getTokenAfter ( parent . callee , isNotRightParen )
557
557
return parent . arguments . some ( param =>
558
558
getFirstAndLastTokens ( param , openParen . range [ 1 ] ) . firstToken . range [ 0 ] === token . range [ 0 ]
@@ -1065,7 +1065,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
1065
1065
}
1066
1066
} ,
1067
1067
1068
- CallExpression ( node ) {
1068
+ ' CallExpression, OptionalCallExpression' ( node ) {
1069
1069
const firstToken = tokenStore . getFirstToken ( node )
1070
1070
const rightToken = tokenStore . getLastToken ( node )
1071
1071
const leftToken = tokenStore . getTokenAfter ( node . callee , isLeftParen )
@@ -1074,6 +1074,15 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
1074
1074
processNodeList ( node . arguments , leftToken , rightToken , 1 )
1075
1075
} ,
1076
1076
1077
+ ImportExpression ( node ) {
1078
+ const firstToken = tokenStore . getFirstToken ( node )
1079
+ const rightToken = tokenStore . getLastToken ( node )
1080
+ const leftToken = tokenStore . getTokenAfter ( firstToken , isLeftParen )
1081
+
1082
+ setOffset ( leftToken , 1 , firstToken )
1083
+ processNodeList ( [ node . source ] , leftToken , rightToken , 1 )
1084
+ } ,
1085
+
1077
1086
CatchClause ( node ) {
1078
1087
const firstToken = tokenStore . getFirstToken ( node )
1079
1088
const bodyToken = tokenStore . getFirstToken ( node . body )
@@ -1145,7 +1154,18 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
1145
1154
if ( isSemicolon ( last ( tokens ) ) ) {
1146
1155
tokens . pop ( )
1147
1156
}
1148
- setOffset ( tokens , 1 , firstToken )
1157
+ if ( ! node . exported ) {
1158
+ setOffset ( tokens , 1 , firstToken )
1159
+ } else {
1160
+ // export * as foo from "mod"
1161
+ const asToken = tokenStore . getTokenBefore ( node . exported )
1162
+ const exportedTokens = tokenStore . getTokensBetween ( asToken , node . exported , {
1163
+ includeComments : true
1164
+ } )
1165
+ const oneIndentTokens = tokens . filter ( t => ! exportedTokens . includes ( t ) )
1166
+ setOffset ( oneIndentTokens , 1 , firstToken )
1167
+ setOffset ( exportedTokens , 1 , tokenStore . getTokenBefore ( asToken ) )
1168
+ }
1149
1169
} ,
1150
1170
1151
1171
ExportDefaultDeclaration ( node ) {
@@ -1162,17 +1182,65 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
1162
1182
const declarationToken = tokenStore . getFirstToken ( node , 1 )
1163
1183
setOffset ( declarationToken , 1 , exportToken )
1164
1184
} else {
1165
- // export {foo, bar}; or export {foo, bar} from "mod";
1166
- const leftParenToken = tokenStore . getFirstToken ( node , 1 )
1167
- const rightParenToken = tokenStore . getLastToken ( node , isRightBrace )
1168
- setOffset ( leftParenToken , 0 , exportToken )
1169
- processNodeList ( node . specifiers , leftParenToken , rightParenToken , 1 )
1170
-
1171
- const maybeFromToken = tokenStore . getTokenAfter ( rightParenToken )
1172
- if ( maybeFromToken != null && sourceCode . getText ( maybeFromToken ) === 'from' ) {
1173
- const fromToken = maybeFromToken
1174
- const nameToken = tokenStore . getTokenAfter ( fromToken )
1175
- setOffset ( [ fromToken , nameToken ] , 1 , exportToken )
1185
+ const firstSpecifier = node . specifiers [ 0 ]
1186
+ const secondSpecifier = node . specifiers [ 1 ]
1187
+ if ( ! firstSpecifier || firstSpecifier . type === 'ExportSpecifier' ) {
1188
+ // export {foo, bar}; or export {foo, bar} from "mod";
1189
+ const leftParenToken = tokenStore . getFirstToken ( node , 1 )
1190
+ const rightParenToken = tokenStore . getLastToken ( node , isRightBrace )
1191
+ setOffset ( leftParenToken , 0 , exportToken )
1192
+ processNodeList ( node . specifiers , leftParenToken , rightParenToken , 1 )
1193
+
1194
+ const maybeFromToken = tokenStore . getTokenAfter ( rightParenToken )
1195
+ if ( maybeFromToken != null && sourceCode . getText ( maybeFromToken ) === 'from' ) {
1196
+ const fromToken = maybeFromToken
1197
+ const nameToken = tokenStore . getTokenAfter ( fromToken )
1198
+ setOffset ( [ fromToken , nameToken ] , 1 , exportToken )
1199
+ }
1200
+ } else if ( firstSpecifier . type === 'ExportDefaultSpecifier' ) {
1201
+ // for babel-eslint
1202
+ if ( secondSpecifier && secondSpecifier . type === 'ExportNamespaceSpecifier' ) {
1203
+ // There is a pattern:
1204
+ // export Foo, * as foo from "foo"
1205
+ const idToken = tokenStore . getFirstToken ( firstSpecifier ) // Foo
1206
+ const commaToken = tokenStore . getTokenAfter ( firstSpecifier ) // comma
1207
+ const astaToken = tokenStore . getFirstToken ( secondSpecifier ) // *
1208
+ const fromToken = tokenStore . getTokenAfter ( secondSpecifier ) // from
1209
+ const modToken = tokenStore . getTokenAfter ( fromToken ) // "foo"
1210
+ setOffset ( [ idToken , commaToken , astaToken , fromToken , modToken ] , 1 , exportToken )
1211
+ } else {
1212
+ // There are 3 patterns:
1213
+ // export Foo from "foo"
1214
+ // export Foo, {} from "foo"
1215
+ // export Foo, {a} from "foo"
1216
+ const idToken = tokenStore . getFirstToken ( firstSpecifier )
1217
+ const nextToken = tokenStore . getTokenAfter ( firstSpecifier )
1218
+ if ( isComma ( nextToken ) ) {
1219
+ const leftBrace = tokenStore . getTokenAfter ( nextToken )
1220
+ const rightBrace = tokenStore . getLastToken ( node , isRightBrace )
1221
+ setOffset ( [ idToken , nextToken ] , 1 , exportToken )
1222
+ setOffset ( leftBrace , 0 , idToken )
1223
+ processNodeList ( node . specifiers . slice ( 1 ) , leftBrace , rightBrace , 1 )
1224
+ const fromToken = tokenStore . getTokenAfter ( rightBrace ) // from
1225
+ const modToken = tokenStore . getTokenAfter ( fromToken ) // "foo"
1226
+ setOffset ( [ fromToken , modToken ] , 1 , exportToken )
1227
+ } else {
1228
+ const modToken = tokenStore . getTokenAfter ( nextToken ) // "foo"
1229
+ setOffset ( [
1230
+ idToken ,
1231
+ nextToken , // from
1232
+ modToken
1233
+ ] , 1 , exportToken )
1234
+ }
1235
+ }
1236
+ } else if ( firstSpecifier . type === 'ExportNamespaceSpecifier' ) {
1237
+ // for babel-eslint
1238
+ // There is a pattern:
1239
+ // export * as foo from "foo"
1240
+ const astaToken = tokenStore . getFirstToken ( firstSpecifier )
1241
+ const fromToken = tokenStore . getTokenAfter ( firstSpecifier )
1242
+ const modToken = tokenStore . getTokenAfter ( fromToken )
1243
+ setOffset ( [ astaToken , fromToken , modToken ] , 1 , exportToken )
1176
1244
}
1177
1245
}
1178
1246
} ,
@@ -1185,12 +1253,16 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
1185
1253
1186
1254
'ForInStatement, ForOfStatement' ( node ) {
1187
1255
const forToken = tokenStore . getFirstToken ( node )
1188
- const leftParenToken = tokenStore . getTokenAfter ( forToken )
1256
+ const awaitToken = ( node . await && tokenStore . getTokenAfter ( forToken ) ) || null
1257
+ const leftParenToken = tokenStore . getTokenAfter ( awaitToken || forToken )
1189
1258
const leftToken = tokenStore . getTokenAfter ( leftParenToken )
1190
1259
const inToken = tokenStore . getTokenAfter ( leftToken , isNotRightParen )
1191
1260
const rightToken = tokenStore . getTokenAfter ( inToken )
1192
1261
const rightParenToken = tokenStore . getTokenBefore ( node . body , isNotLeftParen )
1193
1262
1263
+ if ( awaitToken != null ) {
1264
+ setOffset ( awaitToken , 0 , forToken )
1265
+ }
1194
1266
setOffset ( leftParenToken , 1 , forToken )
1195
1267
setOffset ( leftToken , 1 , leftParenToken )
1196
1268
setOffset ( inToken , 1 , leftToken )
@@ -1353,7 +1425,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
1353
1425
}
1354
1426
} ,
1355
1427
1356
- ImportNamespaceSpecifier ( node ) {
1428
+ ' ImportNamespaceSpecifier, ExportNamespaceSpecifier' ( node ) {
1357
1429
const tokens = tokenStore . getTokens ( node )
1358
1430
const firstToken = tokens . shift ( )
1359
1431
setOffset ( tokens , 1 , firstToken )
@@ -1367,7 +1439,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
1367
1439
setOffset ( [ colonToken , bodyToken ] , 1 , labelToken )
1368
1440
} ,
1369
1441
1370
- 'MemberExpression, MetaProperty' ( node ) {
1442
+ 'MemberExpression, MetaProperty, OptionalMemberExpression ' ( node ) {
1371
1443
const objectToken = tokenStore . getFirstToken ( node )
1372
1444
if ( node . computed ) {
1373
1445
const leftBracketToken = tokenStore . getTokenBefore ( node . property , isLeftBracket )
0 commit comments