@@ -344,7 +344,7 @@ namespace ts.formatting {
344344 }
345345
346346 export function formatNodeGivenIndentation ( node : Node , sourceFileLike : SourceFileLike , languageVariant : LanguageVariant , initialIndentation : number , delta : number , formatContext : FormatContext ) : TextChange [ ] {
347- const range = { pos : 0 , end : sourceFileLike . text . length } ;
347+ const range = { pos : node . pos , end : node . end } ;
348348 return getFormattingScanner ( sourceFileLike . text , languageVariant , range . pos , range . end , scanner => formatSpanWorker (
349349 range ,
350350 node ,
@@ -438,6 +438,25 @@ namespace ts.formatting {
438438 }
439439 }
440440
441+ if ( previousRange ! && formattingScanner . getStartPos ( ) >= originalRange . end ) {
442+ const token =
443+ formattingScanner . isOnEOF ( ) ? formattingScanner . readEOFTokenRange ( ) :
444+ formattingScanner . isOnToken ( ) ? formattingScanner . readTokenInfo ( enclosingNode ) . token :
445+ undefined ;
446+
447+ if ( token ) {
448+ processPair (
449+ token ,
450+ sourceFile . getLineAndCharacterOfPosition ( token . pos ) . line ,
451+ enclosingNode ,
452+ previousRange ,
453+ previousRangeStartLine ! ,
454+ previousParent ! ,
455+ enclosingNode ,
456+ /*dynamicIndentation*/ undefined ) ;
457+ }
458+ }
459+
441460 return edits ;
442461
443462 // local functions
@@ -653,29 +672,14 @@ namespace ts.formatting {
653672 } ) ;
654673
655674 // proceed any tokens in the node that are located after child nodes
656- while ( formattingScanner . isOnToken ( ) ) {
675+ while ( formattingScanner . isOnToken ( ) && formattingScanner . getStartPos ( ) < originalRange . end ) {
657676 const tokenInfo = formattingScanner . readTokenInfo ( node ) ;
658- if ( tokenInfo . token . end > node . end ) {
677+ if ( tokenInfo . token . end > Math . min ( node . end , originalRange . end ) ) {
659678 break ;
660679 }
661680 consumeTokenAndAdvanceScanner ( tokenInfo , node , nodeDynamicIndentation , node ) ;
662681 }
663682
664- if ( ! node . parent && formattingScanner . isOnEOF ( ) ) {
665- const token = formattingScanner . readEOFTokenRange ( ) ;
666- if ( token . end <= node . end && previousRange ) {
667- processPair (
668- token ,
669- sourceFile . getLineAndCharacterOfPosition ( token . pos ) . line ,
670- node ,
671- previousRange ,
672- previousRangeStartLine ,
673- previousParent ,
674- contextNode ,
675- nodeDynamicIndentation ) ;
676- }
677- }
678-
679683 function processChildNode (
680684 child : Node ,
681685 inheritedIndentation : number ,
@@ -717,9 +721,12 @@ namespace ts.formatting {
717721 return inheritedIndentation ;
718722 }
719723
720- while ( formattingScanner . isOnToken ( ) ) {
724+ while ( formattingScanner . isOnToken ( ) && formattingScanner . getStartPos ( ) < originalRange . end ) {
721725 // proceed any parent tokens that are located prior to child.getStart()
722726 const tokenInfo = formattingScanner . readTokenInfo ( node ) ;
727+ if ( tokenInfo . token . end > originalRange . end ) {
728+ return inheritedIndentation ;
729+ }
723730 if ( tokenInfo . token . end > childStartPos ) {
724731 if ( tokenInfo . token . pos > childStartPos ) {
725732 formattingScanner . skipToStartOf ( child ) ;
@@ -731,7 +738,7 @@ namespace ts.formatting {
731738 consumeTokenAndAdvanceScanner ( tokenInfo , node , parentDynamicIndentation , node ) ;
732739 }
733740
734- if ( ! formattingScanner . isOnToken ( ) ) {
741+ if ( ! formattingScanner . isOnToken ( ) || formattingScanner . getStartPos ( ) >= originalRange . end ) {
735742 return inheritedIndentation ;
736743 }
737744
@@ -773,7 +780,7 @@ namespace ts.formatting {
773780
774781 if ( listStartToken !== SyntaxKind . Unknown ) {
775782 // introduce a new indentation scope for lists (including list start and end tokens)
776- while ( formattingScanner . isOnToken ( ) ) {
783+ while ( formattingScanner . isOnToken ( ) && formattingScanner . getStartPos ( ) < originalRange . end ) {
777784 const tokenInfo = formattingScanner . readTokenInfo ( parent ) ;
778785 if ( tokenInfo . token . end > nodes . pos ) {
779786 // stop when formatting scanner moves past the beginning of node list
@@ -814,7 +821,7 @@ namespace ts.formatting {
814821 }
815822
816823 const listEndToken = getCloseTokenForOpenToken ( listStartToken ) ;
817- if ( listEndToken !== SyntaxKind . Unknown && formattingScanner . isOnToken ( ) ) {
824+ if ( listEndToken !== SyntaxKind . Unknown && formattingScanner . isOnToken ( ) && formattingScanner . getStartPos ( ) < originalRange . end ) {
818825 let tokenInfo : TokenInfo | undefined = formattingScanner . readTokenInfo ( parent ) ;
819826 if ( tokenInfo . token . kind === SyntaxKind . CommaToken && isCallLikeExpression ( parent ) ) {
820827 const commaTokenLine = sourceFile . getLineAndCharacterOfPosition ( tokenInfo . token . pos ) . line ;
@@ -969,7 +976,7 @@ namespace ts.formatting {
969976 previousStartLine : number ,
970977 previousParent : Node ,
971978 contextNode : Node ,
972- dynamicIndentation : DynamicIndentation ) : LineAction {
979+ dynamicIndentation : DynamicIndentation | undefined ) : LineAction {
973980
974981 formattingContext . updateContext ( previousItem , previousParent , currentItem , currentParent , contextNode ) ;
975982
@@ -982,24 +989,26 @@ namespace ts.formatting {
982989 // win in a conflict with lower priority rules.
983990 forEachRight ( rules , rule => {
984991 lineAction = applyRuleEdits ( rule , previousItem , previousStartLine , currentItem , currentStartLine ) ;
985- switch ( lineAction ) {
986- case LineAction . LineRemoved :
987- // Handle the case where the next line is moved to be the end of this line.
988- // In this case we don't indent the next line in the next pass.
989- if ( currentParent . getStart ( sourceFile ) === currentItem . pos ) {
990- dynamicIndentation . recomputeIndentation ( /*lineAddedByFormatting*/ false , contextNode ) ;
991- }
992- break ;
993- case LineAction . LineAdded :
994- // Handle the case where token2 is moved to the new line.
995- // In this case we indent token2 in the next pass but we set
996- // sameLineIndent flag to notify the indenter that the indentation is within the line.
997- if ( currentParent . getStart ( sourceFile ) === currentItem . pos ) {
998- dynamicIndentation . recomputeIndentation ( /*lineAddedByFormatting*/ true , contextNode ) ;
999- }
1000- break ;
1001- default :
1002- Debug . assert ( lineAction === LineAction . None ) ;
992+ if ( dynamicIndentation ) {
993+ switch ( lineAction ) {
994+ case LineAction . LineRemoved :
995+ // Handle the case where the next line is moved to be the end of this line.
996+ // In this case we don't indent the next line in the next pass.
997+ if ( currentParent . getStart ( sourceFile ) === currentItem . pos ) {
998+ dynamicIndentation . recomputeIndentation ( /*lineAddedByFormatting*/ false , contextNode ) ;
999+ }
1000+ break ;
1001+ case LineAction . LineAdded :
1002+ // Handle the case where token2 is moved to the new line.
1003+ // In this case we indent token2 in the next pass but we set
1004+ // sameLineIndent flag to notify the indenter that the indentation is within the line.
1005+ if ( currentParent . getStart ( sourceFile ) === currentItem . pos ) {
1006+ dynamicIndentation . recomputeIndentation ( /*lineAddedByFormatting*/ true , contextNode ) ;
1007+ }
1008+ break ;
1009+ default :
1010+ Debug . assert ( lineAction === LineAction . None ) ;
1011+ }
10031012 }
10041013
10051014 // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line
0 commit comments