@@ -675,85 +675,49 @@ namespace ts.server {
675
675
// Input position is relative to the start of this node.
676
676
// Output line number is absolute.
677
677
charOffsetToLineInfo ( lineNumberAccumulator : number , relativePosition : number ) : { oneBasedLine : number , zeroBasedColumn : number , lineText : string | undefined } {
678
- const childInfo = this . childFromCharOffset ( lineNumberAccumulator , relativePosition ) ;
679
- if ( ! childInfo . child ) {
680
- return {
681
- oneBasedLine : lineNumberAccumulator ,
682
- zeroBasedColumn : relativePosition ,
683
- lineText : undefined ,
684
- } ;
685
- }
686
- else if ( childInfo . childIndex < this . children . length ) {
687
- if ( childInfo . child . isLeaf ( ) ) {
688
- return {
689
- oneBasedLine : childInfo . lineNumberAccumulator ,
690
- zeroBasedColumn : childInfo . relativePosition ,
691
- lineText : childInfo . child . text ,
692
- } ;
678
+ if ( this . children . length === 0 ) {
679
+ // Root node might have no children if this is an empty document.
680
+ return { oneBasedLine : lineNumberAccumulator , zeroBasedColumn : relativePosition , lineText : undefined } ;
681
+ }
682
+
683
+ for ( const child of this . children ) {
684
+ if ( child . charCount ( ) > relativePosition ) {
685
+ if ( child . isLeaf ( ) ) {
686
+ return { oneBasedLine : lineNumberAccumulator , zeroBasedColumn : relativePosition , lineText : child . text } ;
687
+ }
688
+ else {
689
+ return ( < LineNode > child ) . charOffsetToLineInfo ( lineNumberAccumulator , relativePosition ) ;
690
+ }
693
691
}
694
692
else {
695
- const lineNode = < LineNode > ( childInfo . child ) ;
696
- return lineNode . charOffsetToLineInfo ( childInfo . lineNumberAccumulator , childInfo . relativePosition ) ;
693
+ relativePosition -= child . charCount ( ) ;
694
+ lineNumberAccumulator += child . lineCount ( ) ;
697
695
}
698
696
}
699
- else {
700
- const lineInfo = this . lineNumberToInfo ( this . lineCount ( ) , 0 ) ;
701
- return { oneBasedLine : this . lineCount ( ) , zeroBasedColumn : lineInfo . leaf . charCount ( ) , lineText : undefined } ;
702
- }
703
- }
704
697
705
- lineNumberToInfo ( relativeOneBasedLine : number , positionAccumulator : number ) : { position : number , leaf : LineLeaf | undefined } {
706
- const childInfo = this . childFromLineNumber ( relativeOneBasedLine , positionAccumulator ) ;
707
- if ( ! childInfo . child ) {
708
- return { position : positionAccumulator , leaf : undefined } ;
709
- }
710
- else if ( childInfo . child . isLeaf ( ) ) {
711
- return { position : childInfo . positionAccumulator , leaf : childInfo . child } ;
712
- }
713
- else {
714
- const lineNode = < LineNode > ( childInfo . child ) ;
715
- return lineNode . lineNumberToInfo ( childInfo . relativeOneBasedLine , childInfo . positionAccumulator ) ;
716
- }
698
+ // Skipped all children
699
+ const { leaf } = this . lineNumberToInfo ( this . lineCount ( ) , 0 ) ;
700
+ return { oneBasedLine : this . lineCount ( ) , zeroBasedColumn : leaf . charCount ( ) , lineText : undefined } ;
717
701
}
718
702
719
703
/**
720
704
* Input line number is relative to the start of this node.
721
705
* Output line number is relative to the child.
722
706
* positionAccumulator will be an absolute position once relativeLineNumber reaches 0.
723
707
*/
724
- private childFromLineNumber ( relativeOneBasedLine : number , positionAccumulator : number ) : { child : LineCollection , relativeOneBasedLine : number , positionAccumulator : number } {
725
- let child : LineCollection ;
726
- let i : number ;
727
- for ( i = 0 ; i < this . children . length ; i ++ ) {
728
- child = this . children [ i ] ;
708
+ lineNumberToInfo ( relativeOneBasedLine : number , positionAccumulator : number ) : { position : number , leaf : LineLeaf | undefined } {
709
+ for ( const child of this . children ) {
729
710
const childLineCount = child . lineCount ( ) ;
730
711
if ( childLineCount >= relativeOneBasedLine ) {
731
- break ;
712
+ return child . isLeaf ( ) ? { position : positionAccumulator , leaf : child } : ( < LineNode > child ) . lineNumberToInfo ( relativeOneBasedLine , positionAccumulator ) ;
732
713
}
733
714
else {
734
715
relativeOneBasedLine -= childLineCount ;
735
716
positionAccumulator += child . charCount ( ) ;
736
717
}
737
718
}
738
- return { child, relativeOneBasedLine, positionAccumulator } ;
739
- }
740
719
741
- private childFromCharOffset ( lineNumberAccumulator : number , relativePosition : number
742
- ) : { child : LineCollection , childIndex : number , relativePosition : number , lineNumberAccumulator : number } {
743
- let child : LineCollection ;
744
- let i : number ;
745
- let len : number ;
746
- for ( i = 0 , len = this . children . length ; i < len ; i ++ ) {
747
- child = this . children [ i ] ;
748
- if ( child . charCount ( ) > relativePosition ) {
749
- break ;
750
- }
751
- else {
752
- relativePosition -= child . charCount ( ) ;
753
- lineNumberAccumulator += child . lineCount ( ) ;
754
- }
755
- }
756
- return { child, childIndex : i , relativePosition, lineNumberAccumulator } ;
720
+ return { position : positionAccumulator , leaf : undefined } ;
757
721
}
758
722
759
723
private splitAfter ( childIndex : number ) {
0 commit comments