Skip to content

Commit 45763eb

Browse files
authored
Merge pull request #1159 from ahoppen/ahoppen/reducer-progress
Fix a couple of bugs with progress reporting in the source reducer
2 parents 479e87b + d79e77d commit 45763eb

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

Sources/Diagnose/SourceReducer.swift

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,10 @@ fileprivate class SourceReducer {
196196

197197
/// Replace the first `import` declaration in the source file by the contents of the Swift interface.
198198
private func inlineFirstImport(_ requestInfo: RequestInfo) async throws -> RequestInfo? {
199-
let reductionResult = try await runReductionStep(requestInfo: requestInfo) { tree in
199+
// Don't report progress after inlining an import because it might increase the file size before we have a chance
200+
// to increase `fileSizeAfterLastImportInline`. Progress will get updated again on the next successful reduction
201+
// step.
202+
let reductionResult = try await runReductionStep(requestInfo: requestInfo, reportProgress: false) { tree in
200203
let edits = await Diagnose.inlineFirstImport(
201204
in: tree,
202205
executor: sourcekitdExecutor,
@@ -216,15 +219,22 @@ fileprivate class SourceReducer {
216219
// MARK: Primitives to run reduction steps
217220

218221
private func logSuccessfulReduction(_ requestInfo: RequestInfo, tree: SourceFileSyntax) {
219-
let numberOfImports = tree.numberOfImports
222+
// The number of imports can grow if inlining a single module adds more than 1 new import.
223+
// To keep progress between 0 and 1, clamp the number of imports to the initial import count.
224+
let numberOfImports = min(tree.numberOfImports, initialImportCount)
220225
let fileSize = requestInfo.fileContents.utf8.count
221226

222227
let progressPerRemovedImport = Double(1) / Double(initialImportCount + 1)
223228
let removeImportProgress = Double(initialImportCount - numberOfImports) * progressPerRemovedImport
224229
let fileReductionProgress =
225230
(1 - Double(fileSize) / Double(fileSizeAfterLastImportInline)) * progressPerRemovedImport
226-
let progress = removeImportProgress + fileReductionProgress
227-
precondition(progress >= 0 && progress <= 1)
231+
var progress = removeImportProgress + fileReductionProgress
232+
if progress < 0 || progress > 1 {
233+
logger.fault(
234+
"Trying to report progress \(progress) from remove import progress \(removeImportProgress) and file reduction progress \(fileReductionProgress)"
235+
)
236+
progress = max(min(progress, 1), 0)
237+
}
228238
progressUpdate(progress, "Reduced to \(numberOfImports) imports and \(fileSize) bytes")
229239
}
230240

@@ -234,6 +244,7 @@ fileprivate class SourceReducer {
234244
/// Otherwise, return `nil`
235245
private func runReductionStep(
236246
requestInfo: RequestInfo,
247+
reportProgress: Bool = true,
237248
reduce: (_ tree: SourceFileSyntax) async throws -> ReducerResult
238249
) async throws -> ReductionStepResult {
239250
let tree = Parser.parse(source: requestInfo.fileContents)
@@ -263,7 +274,9 @@ fileprivate class SourceReducer {
263274
let result = try await sourcekitdExecutor.run(request: reducedRequestInfo)
264275
if case .reproducesIssue = result {
265276
logger.debug("Reduction successful")
266-
logSuccessfulReduction(reducedRequestInfo, tree: tree)
277+
if reportProgress {
278+
logSuccessfulReduction(reducedRequestInfo, tree: tree)
279+
}
267280
return .reduced(reducedRequestInfo)
268281
} else {
269282
logger.debug("Reduction did not reproduce the issue")

0 commit comments

Comments
 (0)