2828
2929import java .util .ArrayList ;
3030import java .util .Arrays ;
31- import java .util .stream .IntStream ;
3231
3332import org .apache .commons .lang3 .tuple .Pair ;
3433import org .rascalmpl .vscode .lsp .util .locations .LineColumnOffsetMap ;
@@ -37,13 +36,13 @@ public class ArrayLineOffsetMap implements LineColumnOffsetMap {
3736 private final IntArray lines ;
3837 private final ArrayList <IntArray > wideColumnOffsets ;
3938 private final ArrayList <IntArray > wideColumnOffsetsInverse ;
40- private final IntArray lineLengths ;
39+ private final IntArray lineStartOffsets ;
4140
42- public ArrayLineOffsetMap (IntArray lines , ArrayList <IntArray > wideColumnOffsets , ArrayList <IntArray > wideColumnOffsetsInverse , IntArray lineLengths ) {
41+ public ArrayLineOffsetMap (IntArray lines , ArrayList <IntArray > wideColumnOffsets , ArrayList <IntArray > wideColumnOffsetsInverse , IntArray lineStartOffsets ) {
4342 this .lines = lines ;
4443 this .wideColumnOffsets = wideColumnOffsets ;
4544 this .wideColumnOffsetsInverse = wideColumnOffsetsInverse ;
46- this .lineLengths = lineLengths ;
45+ this .lineStartOffsets = lineStartOffsets ;
4746 }
4847
4948 @ Override
@@ -83,27 +82,8 @@ public int translateInverseColumn(int line, int column, boolean isEnd) {
8382 public Pair <Integer , Integer > calculateInverseOffsetLength (int beginLine , int beginColumn , int endLine , int endColumn ) {
8483 assert beginLine <= endLine : "beginLine cannot be larger than endLine" ;
8584
86- int startOffset = 0 ;
87- int endOffset = 0 ;
88-
89- for (int line = 0 ; line <= endLine ; line ++) {
90- int lineLength = translateInverseColumn (line , lineLengths .data [line ], true );
91- if (line < beginLine ) {
92- startOffset += lineLength ;
93- endOffset += lineLength ;
94- } else if (line == beginLine ) {
95- startOffset += translateInverseColumn (line , beginColumn , false );
96- endOffset += line == endLine
97- ? translateInverseColumn (line , endColumn , true )
98- : lineLength ;
99- } else if (line < endLine ) {
100- // beginLine < line < endLine
101- endOffset += lineLength ;
102- } else {
103- // line == endLine && beginLine != endLine
104- endOffset += translateInverseColumn (line , endColumn , true );
105- }
106- }
85+ int startOffset = lineStartOffsets .get (beginLine ) + translateInverseColumn (beginLine , beginColumn , false );
86+ int endOffset = lineStartOffsets .get (endLine ) + translateInverseColumn (endLine , endColumn , true );
10787
10888 return Pair .of (startOffset , endOffset - startOffset );
10989 }
@@ -113,22 +93,18 @@ public static LineColumnOffsetMap build(String contents) {
11393 int line = 0 ;
11494 int column = 0 ;
11595 char prev = '\0' ;
116- int lineLength = 0 ;
11796 GrowingIntArray linesWithSurrogate = new GrowingIntArray ();
11897 ArrayList <IntArray > linesMap = new ArrayList <>(0 );
11998 ArrayList <IntArray > inverseLinesMap = new ArrayList <>(0 );
12099 GrowingIntArray currentLine = new GrowingIntArray ();
121- GrowingIntArray lineLengths = new GrowingIntArray ();
100+ GrowingIntArray lineStartOffsets = new GrowingIntArray ();
122101
102+ lineStartOffsets .add (0 );
123103 for (int i = 0 , n = contents .length () ; i < n ; i ++) {
124104 char c = contents .charAt (i );
125105 if (c == '\n' || c == '\r' ) {
126106 if (c != prev && (prev == '\r' || prev == '\n' )) {
127- lineLength += 1 ; // 2 for \r\n
128107 continue ; // multichar newline skip it
129- } else {
130- lineLengths .add (lineLength + 1 );
131- lineLength = 0 ;
132108 }
133109 if (!currentLine .isEmpty ()) {
134110 linesWithSurrogate .add (line );
@@ -138,15 +114,14 @@ public static LineColumnOffsetMap build(String contents) {
138114 }
139115 line ++;
140116 column = 0 ;
117+ lineStartOffsets .add (i + 1 );
141118 }
142119 else {
143120 column ++;
144- lineLength ++;
145121 if (Character .isHighSurrogate (c ) && (i + 1 ) < n && Character .isLowSurrogate (contents .charAt (i + 1 ))) {
146122 // full surrogate pair, register it, and skip the next char
147123 currentLine .add (column );
148124 i ++;
149- lineLength ++;
150125 }
151126 }
152127 prev = c ;
@@ -157,14 +132,13 @@ public static LineColumnOffsetMap build(String contents) {
157132 linesMap .add (currentLine .build ());
158133 inverseLinesMap .add (currentLine .buildInverse ());
159134 }
160- lineLengths .add (lineLength );
161135 if (linesMap .isEmpty ()) {
162- return EMPTY_MAP (lineLengths .build ());
136+ return EMPTY_MAP (lineStartOffsets .build ());
163137 }
164- return new ArrayLineOffsetMap (linesWithSurrogate .build (), linesMap , inverseLinesMap , lineLengths .build ());
138+ return new ArrayLineOffsetMap (linesWithSurrogate .build (), linesMap , inverseLinesMap , lineStartOffsets .build ());
165139 }
166140
167- private static LineColumnOffsetMap EMPTY_MAP (IntArray lineLengths ) {
141+ private static LineColumnOffsetMap EMPTY_MAP (IntArray lineStartOffsets ) {
168142 return new LineColumnOffsetMap (){
169143 @ Override
170144 public int translateColumn (int line , int column , boolean atEnd ) {
@@ -176,8 +150,8 @@ public int translateInverseColumn(int line, int column, boolean isEnd) {
176150 }
177151 @ Override
178152 public Pair <Integer , Integer > calculateInverseOffsetLength (int beginLine , int beginColumn , int endLine , int endColumn ) {
179- final int beginOffset = beginColumn + IntStream . of ( lineLengths . data ). limit ( beginLine ). sum ( );
180- final int endOffset = endColumn + IntStream . of ( lineLengths . data ). limit ( endLine ). sum ( );
153+ final int beginOffset = beginColumn + lineStartOffsets . get ( beginLine );
154+ final int endOffset = endColumn + lineStartOffsets . get ( endLine );
181155 return Pair .of (beginOffset , endOffset - beginOffset );
182156 }
183157
@@ -232,6 +206,13 @@ public IntArray(int[] data, int length) {
232206 this .length = length ;
233207 }
234208
209+ public int get (int i ) {
210+ if (i < 0 || i >= length ) {
211+ throw new IndexOutOfBoundsException (String .format ("Cannot get element at %d; IntArray has %d elements" , i , this .length ));
212+ }
213+ return data [i ];
214+ }
215+
235216 /**
236217 * search for key, assume it's sorted data
237218 * @return >= 0 in case of exact match, below 0 is the insert point
0 commit comments