Skip to content

Commit 41bc4c4

Browse files
authored
Avoid a few possible unnecessary copies in low level implementation details (#1296)
* Declare a few private types as non-copyable to avoid unintentional copies of data in low level implementation details * Avoid potential unnecessary copies when highlighting tutorial code steps
1 parent 5ed689d commit 41bc4c4

File tree

5 files changed

+24
-35
lines changed

5 files changed

+24
-35
lines changed

Sources/SwiftDocC/Infrastructure/Link Resolution/PathHierarchy+PathComponent.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ extension PathHierarchy.PathParser {
210210
}
211211
}
212212

213-
private struct PathComponentScanner {
213+
private struct PathComponentScanner: ~Copyable {
214214
private var remaining: Substring
215215

216216
static let separator: Character = "/"

Sources/SwiftDocC/Infrastructure/Link Resolution/PathHierarchy+TypeSignature.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ extension PathHierarchy {
230230
}
231231

232232
/// A small helper type that tracks the scope of nested brackets; `()`, `[]`, or `<>`.
233-
private struct SwiftBracketsStack {
233+
private struct SwiftBracketsStack: ~Copyable {
234234
enum Bracket {
235235
case angle // <>
236236
case square // []
@@ -522,7 +522,7 @@ extension PathHierarchy.PathParser {
522522

523523
// MARK: Scanning a substring
524524

525-
private struct StringScanner {
525+
private struct StringScanner: ~Copyable {
526526
private var remaining: Substring
527527

528528
init(_ original: Substring) {

Sources/SwiftDocC/Infrastructure/Link Resolution/PathHierarchy+TypeSignatureDisambiguation.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ extension PathHierarchy.DisambiguationContainer {
6363
}
6464
}
6565

66-
private static func _minimalSuggestedDisambiguationForFewParameters(typeNames: Table<String>) -> [[String]?] {
66+
private static func _minimalSuggestedDisambiguationForFewParameters(typeNames: consuming Table<String>) -> [[String]?] {
6767
typealias IntSet = _TinySmallValueIntSet
6868
// We find the minimal suggested type-signature disambiguation in two steps.
6969
//
@@ -216,7 +216,7 @@ extension PathHierarchy.DisambiguationContainer {
216216
}
217217
}
218218

219-
private static func _minimalSuggestedDisambiguationForManyParameters(typeNames: Table<String>) -> [[String]?] {
219+
private static func _minimalSuggestedDisambiguationForManyParameters(typeNames: consuming Table<String>) -> [[String]?] {
220220
// If there are more than 64 parameters or more than 64 overloads we only try to disambiguate by a single type name.
221221
//
222222
// In practice, the number of parameters goes down rather quickly.
@@ -418,7 +418,7 @@ extension _TinySmallValueIntSet {
418418
// MARK: Table
419419

420420
/// A fixed-size grid of elements.
421-
private struct Table<Element> {
421+
private struct Table<Element>: ~Copyable {
422422
typealias Size = (width: Int, height: Int)
423423
@usableFromInline
424424
let size: Size

Sources/SwiftDocC/Model/Rendering/Tutorial/LineHighlighter.swift

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021-2023 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2025 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -30,23 +30,6 @@ import Foundation
3030
```
3131
*/
3232
public struct LineHighlighter {
33-
/**
34-
A local utility type to hold incremental results.
35-
*/
36-
private struct IncrementalResult {
37-
/// The previous ``Code`` element to compare.
38-
/// If this is the first ``Step``'s ``Code``, this will be `nil`.
39-
let previousCode: Code?
40-
41-
/// The highlight results accumulated so far.
42-
let results: [Result]
43-
44-
init(previousCode: Code? = nil, results: [Result] = []) {
45-
self.previousCode = previousCode
46-
self.results = results
47-
}
48-
}
49-
5033
/**
5134
The final resulting highlights for a given file.
5235
*/
@@ -100,7 +83,7 @@ public struct LineHighlighter {
10083
}
10184

10285
/// The lines in the `resource` file.
103-
private func lines(of resource: ResourceReference) -> [String]? {
86+
private func lines(of resource: borrowing ResourceReference) -> [String]? {
10487
let fileContent: String?
10588
// Check if the file is a local asset that can be read directly from the context
10689
if let fileData = try? context.resource(with: resource) {
@@ -118,7 +101,7 @@ public struct LineHighlighter {
118101
}
119102

120103
/// Returns the line highlights between two files.
121-
private func lineHighlights(old: ResourceReference, new: ResourceReference) -> Result {
104+
private func lineHighlights(old: borrowing ResourceReference, new: ResourceReference) -> Result {
122105
// Retrieve the contents of the current file and the file we're comparing against.
123106
guard let oldLines = lines(of: old), let newLines = lines(of: new) else {
124107
return Result(file: new, highlights: [])
@@ -138,7 +121,7 @@ public struct LineHighlighter {
138121
}
139122

140123
/// Returns the line highlights between two ``Code`` elements.
141-
private func lineHighlights(old: Code?, new: Code) -> Result {
124+
private func lineHighlights(old: consuming Code?, new: borrowing Code) -> Result {
142125
if let previousFileOverride = new.previousFileReference {
143126
guard !new.shouldResetDiff else {
144127
return Result(file: new.fileReference, highlights: [])
@@ -157,11 +140,17 @@ public struct LineHighlighter {
157140

158141
/// The highlights to apply for the given ``TutorialSection``.
159142
var highlights: [Result] {
160-
return tutorialSection.stepsContent?.steps
161-
.compactMap { $0.code }
162-
.reduce(IncrementalResult(), { (incrementalResult, newCode) -> IncrementalResult in
163-
let result = lineHighlights(old: incrementalResult.previousCode, new: newCode)
164-
return IncrementalResult(previousCode: newCode, results: incrementalResult.results + [result])
165-
}).results ?? []
143+
guard let steps = tutorialSection.stepsContent?.steps else { return [] }
144+
145+
var previousCode: Code? = nil
146+
var results: [Result] = []
147+
148+
for step in steps {
149+
guard let newCode = step.code else { continue }
150+
results.append(lineHighlights(old: previousCode, new: newCode))
151+
previousCode = newCode
152+
}
153+
154+
return results
166155
}
167156
}

Sources/SwiftDocC/Utility/CollectionChanges.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2022 Apple Inc. and the Swift project authors
4+
Copyright (c) 2022-2025 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -65,7 +65,7 @@ struct CollectionChanges {
6565
///
6666
/// - Important:
6767
/// Removals need to be applied in reverse order. All removals need to be applied before applying any insertions. Insertions need to be applied in order.
68-
private struct ChangeSegmentBuilder {
68+
private struct ChangeSegmentBuilder: ~Copyable {
6969
typealias Segment = CollectionChanges.Segment
7070

7171
private(set) var segments: [Segment]

0 commit comments

Comments
 (0)