66 canHaveSymbol ,
77 CheckFlags ,
88 contains ,
9- countWhere ,
109 createPrinterWithRemoveComments ,
1110 createTextSpan ,
1211 createTextSpanFromBounds ,
@@ -60,7 +59,6 @@ import {
6059 JsxTagNameExpression ,
6160 last ,
6261 lastOrUndefined ,
63- length ,
6462 ListFormat ,
6563 map ,
6664 mapToDisplayParts ,
@@ -288,7 +286,7 @@ function getArgumentOrParameterListInfo(node: Node, position: number, sourceFile
288286 if ( ! info ) return undefined ;
289287 const { list, argumentIndex } = info ;
290288
291- const argumentCount = getArgumentCount ( list , /*ignoreTrailingComma*/ isInString ( sourceFile , position , node ) , checker ) ;
289+ const argumentCount = getArgumentCount ( checker , list ) ;
292290 if ( argumentIndex !== 0 ) {
293291 Debug . assertLessThan ( argumentIndex , argumentCount ) ;
294292 }
@@ -309,7 +307,7 @@ function getArgumentOrParameterListAndIndex(node: Node, sourceFile: SourceFile,
309307 // - On the target of the call (parent.func)
310308 // - On the 'new' keyword in a 'new' expression
311309 const list = findContainingList ( node ) ;
312- return list && { list, argumentIndex : getArgumentIndex ( list , node , checker ) } ;
310+ return list && { list, argumentIndex : getArgumentIndex ( checker , list , node ) } ;
313311 }
314312}
315313
@@ -481,37 +479,6 @@ function chooseBetterSymbol(s: Symbol): Symbol {
481479 : s ;
482480}
483481
484- function getArgumentIndex ( argumentsList : Node , node : Node , checker : TypeChecker ) {
485- // The list we got back can include commas. In the presence of errors it may
486- // also just have nodes without commas. For example "Foo(a b c)" will have 3
487- // args without commas. We want to find what index we're at. So we count
488- // forward until we hit ourselves, only incrementing the index if it isn't a
489- // comma.
490- //
491- // Note: the subtlety around trailing commas (in getArgumentCount) does not apply
492- // here. That's because we're only walking forward until we hit the node we're
493- // on. In that case, even if we're after the trailing comma, we'll still see
494- // that trailing comma in the list, and we'll have generated the appropriate
495- // arg index.
496- const args = argumentsList . getChildren ( ) ;
497- let argumentIndex = 0 ;
498- for ( let pos = 0 ; pos < length ( args ) ; pos ++ ) {
499- const child = args [ pos ] ;
500- if ( child === node ) {
501- break ;
502- }
503- if ( isSpreadElement ( child ) ) {
504- argumentIndex = argumentIndex + getSpreadElementCount ( child , checker ) + ( pos > 0 ? pos : 0 ) ;
505- }
506- else {
507- if ( child . kind !== SyntaxKind . CommaToken ) {
508- argumentIndex ++ ;
509- }
510- }
511- }
512- return argumentIndex ;
513- }
514-
515482function getSpreadElementCount ( node : SpreadElement , checker : TypeChecker ) {
516483 const spreadType = checker . getTypeAtLocation ( node . expression ) ;
517484 if ( checker . isTupleType ( spreadType ) ) {
@@ -525,32 +492,54 @@ function getSpreadElementCount(node: SpreadElement, checker: TypeChecker) {
525492 return 0 ;
526493}
527494
528- function getArgumentCount ( argumentsList : Node , ignoreTrailingComma : boolean , checker : TypeChecker ) {
529- // The argument count for a list is normally the number of non-comma children it has.
530- // For example, if you have "Foo(a,b)" then there will be three children of the arg
531- // list 'a' '<comma>' 'b'. So, in this case the arg count will be 2. However, there
532- // is a small subtlety. If you have "Foo(a,)", then the child list will just have
533- // 'a' '<comma>'. So, in the case where the last child is a comma, we increase the
534- // arg count by one to compensate.
535- //
536- // Note: this subtlety only applies to the last comma. If you had "Foo(a,," then
537- // we'll have: 'a' '<comma>' '<missing>'
538- // That will give us 2 non-commas. We then add one for the last comma, giving us an
539- // arg count of 3.
540- const listChildren = argumentsList . getChildren ( ) ;
541-
542- let argumentCount = 0 ;
543- for ( const child of listChildren ) {
495+ function getArgumentIndex ( checker : TypeChecker , argumentsList : Node , node : Node ) {
496+ return getArgumentIndexOrCount ( checker , argumentsList , node ) ;
497+ }
498+
499+ function getArgumentCount ( checker : TypeChecker , argumentsList : Node ) {
500+ return getArgumentIndexOrCount ( checker , argumentsList , /*node*/ undefined ) ;
501+ }
502+
503+ function getArgumentIndexOrCount ( checker : TypeChecker , argumentsList : Node , node : Node | undefined ) {
504+ // The list we got back can include commas. In the presence of errors it may
505+ // also just have nodes without commas. For example "Foo(a b c)" will have 3
506+ // args without commas.
507+ const args = argumentsList . getChildren ( ) ;
508+ let argumentIndex = 0 ;
509+ let skipComma = false ;
510+ for ( const child of args ) {
511+ if ( node && child === node ) {
512+ if ( ! skipComma && child . kind === SyntaxKind . CommaToken ) {
513+ argumentIndex ++ ;
514+ }
515+ return argumentIndex ;
516+ }
544517 if ( isSpreadElement ( child ) ) {
545- argumentCount = argumentCount + getSpreadElementCount ( child , checker ) ;
518+ argumentIndex += getSpreadElementCount ( child , checker ) ;
519+ skipComma = true ;
520+ continue ;
521+ }
522+ if ( child . kind !== SyntaxKind . CommaToken ) {
523+ argumentIndex ++ ;
524+ skipComma = true ;
525+ continue ;
526+ }
527+ if ( skipComma ) {
528+ skipComma = false ;
529+ continue ;
546530 }
531+ argumentIndex ++ ;
547532 }
548-
549- argumentCount = argumentCount + countWhere ( listChildren , arg => arg . kind !== SyntaxKind . CommaToken ) ;
550- if ( ! ignoreTrailingComma && listChildren . length > 0 && last ( listChildren ) . kind === SyntaxKind . CommaToken ) {
551- argumentCount ++ ;
533+ if ( node ) {
534+ return argumentIndex ;
552535 }
553- return argumentCount ;
536+ // The argument count for a list is normally the number of non-comma children it has.
537+ // For example, if you have "Foo(a,b)" then there will be three children of the arg
538+ // list 'a' '<comma>' 'b'. So, in this case the arg count will be 2. However, there
539+ // is a small subtlety. If you have "Foo(a,)", then the child list will just have
540+ // 'a' '<comma>'. So, in the case where the last child is a comma, we increase the
541+ // arg count by one to compensate.
542+ return args . length && last ( args ) . kind === SyntaxKind . CommaToken ? argumentIndex + 1 : argumentIndex ;
554543}
555544
556545// spanIndex is either the index for a given template span.
0 commit comments