Skip to content

Commit ad1ff7c

Browse files
authored
Use iterator for line starts during emit (microsoft#407)
1 parent 4090bab commit ad1ff7c

File tree

2 files changed

+43
-27
lines changed

2 files changed

+43
-27
lines changed

internal/core/core.go

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -314,33 +314,42 @@ func Coalesce[T *U, U any](a T, b T) T {
314314

315315
func ComputeLineStarts(text string) []TextPos {
316316
result := make([]TextPos, 0, strings.Count(text, "\n")+1)
317-
pos := 0
318-
lineStart := 0
319-
for pos < len(text) {
320-
b := text[pos]
321-
if b < 0x7F {
322-
pos++
323-
switch b {
324-
case '\r':
325-
if pos < len(text) && text[pos] == '\n' {
326-
pos++
317+
return slices.AppendSeq(result, ComputeLineStartsSeq(text))
318+
}
319+
320+
func ComputeLineStartsSeq(text string) iter.Seq[TextPos] {
321+
return func(yield func(TextPos) bool) {
322+
pos := 0
323+
lineStart := 0
324+
for pos < len(text) {
325+
b := text[pos]
326+
if b < 0x7F {
327+
pos++
328+
switch b {
329+
case '\r':
330+
if pos < len(text) && text[pos] == '\n' {
331+
pos++
332+
}
333+
fallthrough
334+
case '\n':
335+
if !yield(TextPos(lineStart)) {
336+
return
337+
}
338+
lineStart = pos
339+
}
340+
} else {
341+
ch, size := utf8.DecodeRuneInString(text[pos:])
342+
pos += size
343+
if stringutil.IsLineBreak(ch) {
344+
if !yield(TextPos(lineStart)) {
345+
return
346+
}
347+
lineStart = pos
327348
}
328-
fallthrough
329-
case '\n':
330-
result = append(result, TextPos(lineStart))
331-
lineStart = pos
332-
}
333-
} else {
334-
ch, size := utf8.DecodeRuneInString(text[pos:])
335-
pos += size
336-
if stringutil.IsLineBreak(ch) {
337-
result = append(result, TextPos(lineStart))
338-
lineStart = pos
339349
}
340350
}
351+
yield(TextPos(lineStart))
341352
}
342-
result = append(result, TextPos(lineStart))
343-
return result
344353
}
345354

346355
func PositionToLineAndCharacter(position int, lineStarts []TextPos) (line int, character int) {

internal/printer/textwriter.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,18 @@ func (w *textWriter) RawWrite(s string) {
8686
}
8787

8888
func (w *textWriter) updateLineCountAndPosFor(s string) {
89-
lineStartsOfS := core.ComputeLineStarts(s)
90-
if len(lineStartsOfS) > 1 {
91-
w.lineCount += len(lineStartsOfS) - 1
89+
var count int
90+
var lastLineStart core.TextPos
91+
92+
for lineStart := range core.ComputeLineStartsSeq(s) {
93+
count++
94+
lastLineStart = lineStart
95+
}
96+
97+
if count > 1 {
98+
w.lineCount += count - 1
9299
curLen := w.builder.Len()
93-
w.linePos = curLen - len(s) + int(lineStartsOfS[len(lineStartsOfS)-1])
100+
w.linePos = curLen - len(s) + int(lastLineStart)
94101
w.lineStart = (w.linePos - curLen) == 0
95102
return
96103
}

0 commit comments

Comments
 (0)