@@ -315,60 +315,85 @@ namespace ts.formatting {
315
315
return false ;
316
316
}
317
317
318
+ function getListIfVisualStartEndIsInListRange ( list : NodeArray < Node > | undefined , start : number , end : number , node : Node ) {
319
+ return list && rangeContainsVisualStartEnd ( list ) ? list : undefined ;
320
+
321
+ // Assumes a list is wrapped by list tokens
322
+ function rangeContainsVisualStartEnd ( textRange : TextRange ) : boolean {
323
+ const children = node . getChildren ( ) ;
324
+ for ( let i = 1 ; i < children . length - 1 ; i ++ ) {
325
+ if ( children [ i ] . pos === textRange . pos && children [ i ] . end === textRange . end ) {
326
+ return rangeContainsStartEnd ( { pos : children [ i - 1 ] . end , end : children [ i + 1 ] . end - children [ i + 1 ] . getWidth ( ) } , start , end ) ;
327
+ }
328
+ }
329
+ return rangeContainsStartEnd ( textRange , start , end ) ;
330
+ }
331
+ }
332
+
318
333
function getListIfStartEndIsInListRange ( list : NodeArray < Node > | undefined , start : number , end : number ) {
319
334
return list && rangeContainsStartEnd ( list , start , end ) ? list : undefined ;
320
335
}
321
336
322
337
export function getContainingList ( node : Node , sourceFile : SourceFile ) : NodeArray < Node > | undefined {
323
338
if ( node . parent ) {
324
- const { end } = node ;
325
- switch ( node . parent . kind ) {
326
- case SyntaxKind . TypeReference :
327
- return getListIfStartEndIsInListRange ( ( < TypeReferenceNode > node . parent ) . typeArguments , node . getStart ( sourceFile ) , end ) ;
328
- case SyntaxKind . ObjectLiteralExpression :
329
- return ( < ObjectLiteralExpression > node . parent ) . properties ;
330
- case SyntaxKind . ArrayLiteralExpression :
331
- return ( < ArrayLiteralExpression > node . parent ) . elements ;
332
- case SyntaxKind . FunctionDeclaration :
333
- case SyntaxKind . FunctionExpression :
334
- case SyntaxKind . ArrowFunction :
335
- case SyntaxKind . MethodDeclaration :
336
- case SyntaxKind . MethodSignature :
337
- case SyntaxKind . CallSignature :
338
- case SyntaxKind . Constructor :
339
- case SyntaxKind . ConstructorType :
340
- case SyntaxKind . ConstructSignature : {
341
- const start = node . getStart ( sourceFile ) ;
342
- return getListIfStartEndIsInListRange ( ( < SignatureDeclaration > node . parent ) . typeParameters , start , end ) ||
343
- getListIfStartEndIsInListRange ( ( < SignatureDeclaration > node . parent ) . parameters , start , end ) ;
344
- }
345
- case SyntaxKind . ClassDeclaration :
346
- case SyntaxKind . ClassExpression :
347
- case SyntaxKind . InterfaceDeclaration :
348
- case SyntaxKind . TypeAliasDeclaration :
349
- case SyntaxKind . JSDocTemplateTag : {
350
- const { typeParameters } = < ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag > node . parent ;
351
- return getListIfStartEndIsInListRange ( typeParameters , node . getStart ( sourceFile ) , end ) ;
352
- }
353
- case SyntaxKind . NewExpression :
354
- case SyntaxKind . CallExpression : {
355
- const start = node . getStart ( sourceFile ) ;
356
- return getListIfStartEndIsInListRange ( ( < CallExpression | NewExpression > node . parent ) . typeArguments , start , end ) ||
357
- getListIfStartEndIsInListRange ( ( < CallExpression | NewExpression > node . parent ) . arguments , start , end ) ;
358
- }
359
- case SyntaxKind . VariableDeclarationList :
360
- return getListIfStartEndIsInListRange ( ( < VariableDeclarationList > node . parent ) . declarations , node . getStart ( sourceFile ) , end ) ;
361
- case SyntaxKind . NamedImports :
362
- case SyntaxKind . NamedExports :
363
- return getListIfStartEndIsInListRange ( ( < NamedImportsOrExports > node . parent ) . elements , node . getStart ( sourceFile ) , end ) ;
364
- case SyntaxKind . ObjectBindingPattern :
365
- case SyntaxKind . ArrayBindingPattern :
366
- return getListIfStartEndIsInListRange ( ( < ObjectBindingPattern | ArrayBindingPattern > node . parent ) . elements , node . getStart ( sourceFile ) , end ) ;
367
- }
339
+ return getListByRange ( node . getStart ( sourceFile ) , node . getEnd ( ) , node . parent ) ;
368
340
}
369
341
return undefined ;
370
342
}
371
343
344
+ function getListByPosition ( pos : number , node : Node ) : NodeArray < Node > | undefined {
345
+ if ( ! node ) {
346
+ return ;
347
+ }
348
+ return getListByRange ( pos , pos , node ) ;
349
+ }
350
+
351
+ function getListByRange ( start : number , end : number , node : Node ) : NodeArray < Node > | undefined {
352
+ switch ( node . kind ) {
353
+ case SyntaxKind . TypeReference :
354
+ return getListIfVisualStartEndIsInListRange ( ( < TypeReferenceNode > node ) . typeArguments , start , end , node ) ;
355
+ case SyntaxKind . ObjectLiteralExpression :
356
+ return getListIfVisualStartEndIsInListRange ( ( < ObjectLiteralExpression > node ) . properties , start , end , node ) ;
357
+ case SyntaxKind . ArrayLiteralExpression :
358
+ return getListIfVisualStartEndIsInListRange ( ( < ArrayLiteralExpression > node ) . elements , start , end , node ) ;
359
+ case SyntaxKind . TypeLiteral :
360
+ return getListIfVisualStartEndIsInListRange ( ( < TypeLiteralNode > node ) . members , start , end , node ) ;
361
+ case SyntaxKind . FunctionDeclaration :
362
+ case SyntaxKind . FunctionExpression :
363
+ case SyntaxKind . ArrowFunction :
364
+ case SyntaxKind . MethodDeclaration :
365
+ case SyntaxKind . MethodSignature :
366
+ case SyntaxKind . CallSignature :
367
+ case SyntaxKind . Constructor :
368
+ case SyntaxKind . ConstructorType :
369
+ case SyntaxKind . ConstructSignature : {
370
+ return getListIfVisualStartEndIsInListRange ( ( < SignatureDeclaration > node ) . typeParameters , start , end , node ) ||
371
+ getListIfVisualStartEndIsInListRange ( ( < SignatureDeclaration > node ) . parameters , start , end , node ) ;
372
+ }
373
+ case SyntaxKind . ClassDeclaration :
374
+ case SyntaxKind . ClassExpression :
375
+ case SyntaxKind . InterfaceDeclaration :
376
+ case SyntaxKind . TypeAliasDeclaration :
377
+ case SyntaxKind . JSDocTemplateTag : {
378
+ const { typeParameters } = < ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag > node ;
379
+ return getListIfStartEndIsInListRange ( typeParameters , start , end ) ;
380
+ }
381
+ case SyntaxKind . NewExpression :
382
+ case SyntaxKind . CallExpression : {
383
+ return getListIfVisualStartEndIsInListRange ( ( < CallExpression > node ) . typeArguments , start , end , node ) ||
384
+ getListIfVisualStartEndIsInListRange ( ( < CallExpression > node ) . arguments , start , end , node ) ;
385
+ }
386
+ case SyntaxKind . VariableDeclarationList :
387
+ return getListIfStartEndIsInListRange ( ( < VariableDeclarationList > node ) . declarations , start , end ) ;
388
+ case SyntaxKind . NamedImports :
389
+ case SyntaxKind . NamedExports :
390
+ return getListIfVisualStartEndIsInListRange ( ( < NamedImportsOrExports > node ) . elements , start , end , node ) ;
391
+ case SyntaxKind . ObjectBindingPattern :
392
+ case SyntaxKind . ArrayBindingPattern :
393
+ return getListIfVisualStartEndIsInListRange ( ( < ObjectBindingPattern | ArrayBindingPattern > node ) . elements , start , end , node ) ;
394
+ }
395
+ }
396
+
372
397
function getActualIndentationForListItem ( node : Node , sourceFile : SourceFile , options : EditorSettings ) : number {
373
398
const containingList = getContainingList ( node , sourceFile ) ;
374
399
if ( containingList ) {
0 commit comments