Skip to content

Commit f6d3ff1

Browse files
committed
FixItApplier: Eliminate quadratic dropFirst
1 parent b953b57 commit f6d3ff1

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

Sources/SwiftIDEUtils/FixItApplier.swift

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,29 +59,41 @@ public enum FixItApplier {
5959
var edits = edits
6060
var source = tree.description
6161

62-
while let edit = edits.first {
63-
edits = Array(edits.dropFirst())
62+
for var editIndex in edits.indices {
63+
let edit = edits[editIndex]
6464

6565
// Empty edits do nothing.
6666
guard !edit.isEmpty else {
6767
continue
6868
}
6969

70-
let startIndex = source.utf8.index(source.utf8.startIndex, offsetBy: edit.startUtf8Offset)
71-
let endIndex = source.utf8.index(source.utf8.startIndex, offsetBy: edit.endUtf8Offset)
70+
do {
71+
let startIndex = source.utf8.index(source.utf8.startIndex, offsetBy: edit.startUtf8Offset)
72+
let endIndex = source.utf8.index(source.utf8.startIndex, offsetBy: edit.endUtf8Offset)
7273

73-
source.replaceSubrange(startIndex..<endIndex, with: edit.replacement)
74+
source.replaceSubrange(startIndex..<endIndex, with: edit.replacement)
75+
}
7476

7577
// Drop any subsequent edits that conflict with one we just applied, and
7678
// adjust the range of the rest.
77-
for i in edits.indices {
78-
let remainingEdit = edits[i]
79+
while true {
80+
editIndex += 1
81+
guard editIndex != edits.endIndex else {
82+
break
83+
}
84+
85+
let remainingEdit = edits[editIndex]
86+
87+
// Empty edits do nothing.
88+
guard !remainingEdit.isEmpty else {
89+
continue
90+
}
7991

8092
guard !remainingEdit.range.overlaps(edit.range) else {
8193
// The edit overlaps with the previous edit. We can't apply both
8294
// without conflicts. Drop this one by swapping it for a no-op
8395
// edit.
84-
edits[i] = SourceEdit()
96+
edits[editIndex] = SourceEdit()
8597
continue
8698
}
8799

@@ -92,7 +104,7 @@ public enum FixItApplier {
92104
let startPosition = AbsolutePosition(utf8Offset: remainingEdit.startUtf8Offset + shift)
93105
let endPosition = AbsolutePosition(utf8Offset: remainingEdit.endUtf8Offset + shift)
94106

95-
edits[i] = SourceEdit(range: startPosition..<endPosition, replacement: remainingEdit.replacement)
107+
edits[editIndex] = SourceEdit(range: startPosition..<endPosition, replacement: remainingEdit.replacement)
96108
}
97109
}
98110
}

0 commit comments

Comments
 (0)