Skip to content

Commit b3270fe

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

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

Sources/SwiftIDEUtils/FixItApplier.swift

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,29 +59,37 @@ 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 utf8 = source.utf8
72+
let startIndex = utf8.index(utf8.startIndex, offsetBy: edit.startUtf8Offset)
73+
let endIndex = utf8.index(utf8.startIndex, offsetBy: edit.endUtf8Offset)
7274

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

7578
// Drop any subsequent edits that conflict with one we just applied, and
7679
// adjust the range of the rest.
77-
for i in edits.indices {
78-
let remainingEdit = edits[i]
80+
while edits.formIndex(after: &editIndex) != edits.endIndex {
81+
let remainingEdit = edits[editIndex]
82+
83+
// Empty edits do nothing.
84+
guard !remainingEdit.isEmpty else {
85+
continue
86+
}
7987

8088
guard !remainingEdit.range.overlaps(edit.range) else {
8189
// The edit overlaps with the previous edit. We can't apply both
8290
// without conflicts. Drop this one by swapping it for a no-op
8391
// edit.
84-
edits[i] = SourceEdit()
92+
edits[editIndex] = SourceEdit()
8593
continue
8694
}
8795

@@ -92,7 +100,7 @@ public enum FixItApplier {
92100
let startPosition = AbsolutePosition(utf8Offset: remainingEdit.startUtf8Offset + shift)
93101
let endPosition = AbsolutePosition(utf8Offset: remainingEdit.endUtf8Offset + shift)
94102

95-
edits[i] = SourceEdit(range: startPosition..<endPosition, replacement: remainingEdit.replacement)
103+
edits[editIndex] = SourceEdit(range: startPosition..<endPosition, replacement: remainingEdit.replacement)
96104
}
97105
}
98106
}
@@ -101,6 +109,13 @@ public enum FixItApplier {
101109
}
102110
}
103111

112+
private extension Collection {
113+
func formIndex(after index: inout Index) -> Index {
114+
self.formIndex(after: &index) as Void
115+
return index
116+
}
117+
}
118+
104119
private extension SourceEdit {
105120
var startUtf8Offset: Int {
106121
return range.lowerBound.utf8Offset

0 commit comments

Comments
 (0)