Skip to content

Commit 78ace71

Browse files
committed
Flush Foundation.Date Out of the Driver
Now that the relevant file system utilities have been migrated, there are no more dependencies on Foundation.Date left in the library.
1 parent 1fbd99d commit 78ace71

17 files changed

+114
-144
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import TSCBasic
1313
import SwiftOptions
1414

15-
import struct Foundation.Date
1615
import class Dispatch.DispatchQueue
1716

1817
import enum TSCUtility.Diagnostics
@@ -179,7 +178,7 @@ public struct Driver {
179178
@_spi(Testing) public let inputFiles: [TypedVirtualPath]
180179

181180
/// The last time each input file was modified, recorded at the start of the build.
182-
@_spi(Testing) public let recordedInputModificationDates: [TypedVirtualPath: Date]
181+
@_spi(Testing) public let recordedInputModificationDates: [TypedVirtualPath: TimePoint]
183182

184183
/// The mapping from input files to output files for each kind.
185184
let outputFileMap: OutputFileMap?

Sources/SwiftDriver/Execution/DriverExecutor.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import TSCBasic
14-
import struct Foundation.Date
1514
import struct Foundation.Data
1615
import class Foundation.JSONDecoder
1716
import var Foundation.EXIT_SUCCESS
@@ -25,23 +24,23 @@ public protocol DriverExecutor {
2524
@discardableResult
2625
func execute(job: Job,
2726
forceResponseFiles: Bool,
28-
recordedInputModificationDates: [TypedVirtualPath: Date]) throws -> ProcessResult
27+
recordedInputModificationDates: [TypedVirtualPath: TimePoint]) throws -> ProcessResult
2928

3029
/// Execute multiple jobs, tracking job status using the provided execution delegate.
3130
/// Pass in the `IncrementalCompilationState` to allow for incremental compilation.
3231
func execute(workload: DriverExecutorWorkload,
3332
delegate: JobExecutionDelegate,
3433
numParallelJobs: Int,
3534
forceResponseFiles: Bool,
36-
recordedInputModificationDates: [TypedVirtualPath: Date]
35+
recordedInputModificationDates: [TypedVirtualPath: TimePoint]
3736
) throws
3837

3938
/// Execute multiple jobs, tracking job status using the provided execution delegate.
4039
func execute(jobs: [Job],
4140
delegate: JobExecutionDelegate,
4241
numParallelJobs: Int,
4342
forceResponseFiles: Bool,
44-
recordedInputModificationDates: [TypedVirtualPath: Date]
43+
recordedInputModificationDates: [TypedVirtualPath: TimePoint]
4544
) throws
4645

4746
/// Launch a process with the given command line and report the result.
@@ -86,7 +85,7 @@ extension DriverExecutor {
8685
func execute<T: Decodable>(job: Job,
8786
capturingJSONOutputAs outputType: T.Type,
8887
forceResponseFiles: Bool,
89-
recordedInputModificationDates: [TypedVirtualPath: Date]) throws -> T {
88+
recordedInputModificationDates: [TypedVirtualPath: TimePoint]) throws -> T {
9089
let result = try execute(job: job,
9190
forceResponseFiles: forceResponseFiles,
9291
recordedInputModificationDates: recordedInputModificationDates)
@@ -111,7 +110,7 @@ extension DriverExecutor {
111110
delegate: JobExecutionDelegate,
112111
numParallelJobs: Int,
113112
forceResponseFiles: Bool,
114-
recordedInputModificationDates: [TypedVirtualPath: Date]
113+
recordedInputModificationDates: [TypedVirtualPath: TimePoint]
115114
) throws {
116115
try execute(
117116
workload: .all(jobs),

Sources/SwiftDriver/IncrementalCompilation/BuildRecord.swift

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
1313
@_implementationOnly import Yams
14-
import struct Foundation.Date
1514

1615
/// Holds the info about inputs needed to plan incremenal compilation
1716
/// A.k.a. BuildRecord was the legacy name
@@ -20,16 +19,16 @@ public struct BuildRecord {
2019
/// When testing, the argsHash may be missing from the build record
2120
public let argsHash: String?
2221
/// Next compile, will compare an input mod time against the start time of the previous build
23-
public let buildStartTime: Date
22+
public let buildStartTime: TimePoint
2423
/// Next compile, will compare an output mod time against the end time of the previous build
25-
public let buildEndTime: Date
24+
public let buildEndTime: TimePoint
2625
/// The date is the modification time of the main input file the last time the driver ran
2726
public let inputInfos: [VirtualPath: InputInfo]
2827

2928
public init(argsHash: String?,
3029
swiftVersion: String,
31-
buildStartTime: Date,
32-
buildEndTime: Date,
30+
buildStartTime: TimePoint,
31+
buildEndTime: TimePoint,
3332
inputInfos: [VirtualPath: InputInfo]) {
3433
self.argsHash = argsHash
3534
self.swiftVersion = swiftVersion
@@ -67,8 +66,8 @@ public extension BuildRecord {
6766
var argsHash: String?
6867
var swiftVersion: String?
6968
// Legacy driver does not disable incremental if no buildTime field.
70-
var buildStartTime: Date = .distantPast
71-
var buildEndTime: Date = .distantFuture
69+
var buildStartTime: TimePoint = .distantPast
70+
var buildEndTime: TimePoint = .distantFuture
7271
var inputInfos: [VirtualPath: InputInfo]?
7372
for (key, value) in sections {
7473
guard let k = key.string else {
@@ -138,7 +137,7 @@ public extension BuildRecord {
138137
_ node: Yams.Node,
139138
forInputInfo: Bool,
140139
_ failedToReadOutOfDateMap: (String) -> Void
141-
) -> Date? {
140+
) -> TimePoint? {
142141
guard let vals = node.sequence else {
143142
failedToReadOutOfDateMap(
144143
forInputInfo
@@ -153,7 +152,7 @@ public extension BuildRecord {
153152
failedToReadOutOfDateMap("could not read time value in build record")
154153
return nil
155154
}
156-
return Date(legacyDriverSecs: secs, nanos: ns)
155+
return TimePoint(seconds: UInt64(secs), nanoseconds: UInt32(ns))
157156
}
158157

159158
private static func decodeInputInfos(
@@ -197,11 +196,11 @@ extension BuildRecord {
197196
init(jobs: [Job],
198197
finishedJobResults: [BuildRecordInfo.JobResult],
199198
skippedInputs: Set<TypedVirtualPath>?,
200-
compilationInputModificationDates: [TypedVirtualPath: Date],
199+
compilationInputModificationDates: [TypedVirtualPath: TimePoint],
201200
actualSwiftVersion: String,
202201
argsHash: String!,
203-
timeBeforeFirstJob: Date,
204-
timeAfterLastJob: Date
202+
timeBeforeFirstJob: TimePoint,
203+
timeAfterLastJob: TimePoint
205204
) {
206205
let jobResultsByInput = Dictionary(uniqueKeysWithValues:
207206
finishedJobResults.flatMap { entry in
@@ -256,10 +255,9 @@ extension BuildRecord {
256255
}
257256
}
258257

259-
private static func encode(_ date: Date, tag tagString: String? = nil) -> Yams.Node {
260-
let secsAndNanos = date.legacyDriverSecsAndNanos
258+
private static func encode(_ date: TimePoint, tag tagString: String? = nil) -> Yams.Node {
261259
return Yams.Node(
262-
secsAndNanos.map {Yams.Node(String($0))},
260+
[ Yams.Node(String(date.seconds)), Yams.Node(String(date.nanoseconds)) ],
263261
tagString.map {Yams.Tag(Yams.Tag.Name(rawValue: $0))} ?? .implicit,
264262
.flow)
265263
}

Sources/SwiftDriver/IncrementalCompilation/BuildRecordInfo.swift

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
import TSCBasic
1414
import SwiftOptions
15-
import struct Foundation.Date
1615
import class Dispatch.DispatchQueue
1716

1817
/// Holds information required to read and write the build record (aka
@@ -38,9 +37,9 @@ import class Dispatch.DispatchQueue
3837
let fileSystem: FileSystem
3938
let currentArgsHash: String
4039
@_spi(Testing) public let actualSwiftVersion: String
41-
@_spi(Testing) public let timeBeforeFirstJob: Date
40+
@_spi(Testing) public let timeBeforeFirstJob: TimePoint
4241
let diagnosticEngine: DiagnosticsEngine
43-
let compilationInputModificationDates: [TypedVirtualPath: Date]
42+
let compilationInputModificationDates: [TypedVirtualPath: TimePoint]
4443

4544
private var finishedJobResults = [JobResult]()
4645
// A confinement queue that protects concurrent access to the
@@ -53,9 +52,9 @@ import class Dispatch.DispatchQueue
5352
fileSystem: FileSystem,
5453
currentArgsHash: String,
5554
actualSwiftVersion: String,
56-
timeBeforeFirstJob: Date,
55+
timeBeforeFirstJob: TimePoint,
5756
diagnosticEngine: DiagnosticsEngine,
58-
compilationInputModificationDates: [TypedVirtualPath: Date])
57+
compilationInputModificationDates: [TypedVirtualPath: TimePoint])
5958
{
6059
self.buildRecordPath = buildRecordPath
6160
self.fileSystem = fileSystem
@@ -77,7 +76,7 @@ import class Dispatch.DispatchQueue
7776
outputFileMap: OutputFileMap?,
7877
incremental: Bool,
7978
parsedOptions: ParsedOptions,
80-
recordedInputModificationDates: [TypedVirtualPath: Date]
79+
recordedInputModificationDates: [TypedVirtualPath: TimePoint]
8180
) {
8281
// Cannot write a buildRecord without a path.
8382
guard let buildRecordPath = Self.computeBuildRecordPath(
@@ -100,7 +99,7 @@ import class Dispatch.DispatchQueue
10099
fileSystem: fileSystem,
101100
currentArgsHash: currentArgsHash,
102101
actualSwiftVersion: actualSwiftVersion,
103-
timeBeforeFirstJob: Date(),
102+
timeBeforeFirstJob: .now(),
104103
diagnosticEngine: diagnosticEngine,
105104
compilationInputModificationDates: compilationInputModificationDates)
106105
}
@@ -165,7 +164,7 @@ import class Dispatch.DispatchQueue
165164
actualSwiftVersion: actualSwiftVersion,
166165
argsHash: currentArgsHash,
167166
timeBeforeFirstJob: timeBeforeFirstJob,
168-
timeAfterLastJob: Date())
167+
timeAfterLastJob: .now())
169168
}
170169

171170
guard let contents = buildRecord.encode(currentArgsHash: currentArgsHash,

Sources/SwiftDriver/IncrementalCompilation/FirstWaveComputer.swift

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import TSCBasic
14-
import struct Foundation.Date
1514
import class Dispatch.DispatchQueue
1615

1716
extension IncrementalCompilationState {
@@ -257,21 +256,13 @@ extension IncrementalCompilationState.FirstWaveComputer {
257256
) -> [ChangedInput] {
258257
jobsInPhases.compileGroups.compactMap { group in
259258
let input = group.primaryInput
260-
let modDate = buildRecordInfo.compilationInputModificationDates[input]
261-
?? Date.distantFuture
259+
let modDate = buildRecordInfo.compilationInputModificationDates[input] ?? .distantFuture
262260
let inputInfo = outOfDateBuildRecord.inputInfos[input.file]
263261
let previousCompilationStatus = inputInfo?.status ?? .newlyAdded
264262
let previousModTime = inputInfo?.previousModTime
265263

266-
// Because legacy driver reads/writes dates wrt 1970,
267-
// and because converting time intervals to/from Dates from 1970
268-
// exceeds Double precision, must not compare dates directly
269-
var datesMatch: Bool {
270-
modDate.timeIntervalSince1970 == previousModTime?.timeIntervalSince1970
271-
}
272-
273264
switch previousCompilationStatus {
274-
case .upToDate where datesMatch:
265+
case .upToDate where modDate == previousModTime:
275266
reporter?.report("May skip current input:", input)
276267
return nil
277268

@@ -286,7 +277,7 @@ extension IncrementalCompilationState.FirstWaveComputer {
286277
}
287278
return ChangedInput(typedFile: input,
288279
status: previousCompilationStatus,
289-
datesMatch: datesMatch)
280+
datesMatch: modDate == previousModTime)
290281
}
291282
}
292283

Sources/SwiftDriver/IncrementalCompilation/IncrementalCompilationState+Extensions.swift

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
1313
import SwiftOptions
14-
import struct Foundation.Date
1514
import protocol Foundation.LocalizedError
1615

1716
/// In a separate file to ensure that ``IncrementalCompilationState/protectedState``
@@ -50,9 +49,9 @@ extension IncrementalCompilationState {
5049
/// Compiler options related to incremental builds.
5150
let incrementalOptions: IncrementalCompilationState.Options
5251
/// The last time this compilation was started. Used to compare against e.g. input file mod dates.
53-
let buildStartTime: Date
52+
let buildStartTime: TimePoint
5453
/// The last time this compilation finished. Used to compare against output file mod dates
55-
let buildEndTime: Date
54+
let buildEndTime: TimePoint
5655
}
5756
}
5857

@@ -175,8 +174,7 @@ extension IncrementalCompilationState {
175174
report(skipping: false, "No outputs")
176175
return false
177176
}
178-
guard .distantPast < oldestOutputModTime
179-
else {
177+
guard .distantPast < oldestOutputModTime else {
180178
report(skipping: false, "Missing output", oldestOutput)
181179
return false
182180
}
@@ -189,29 +187,29 @@ extension IncrementalCompilationState {
189187
return true
190188
}
191189

192-
private func findOldestOutputForSkipping(postCompileJob: Job) -> (TypedVirtualPath, Date)? {
193-
var oldestOutputAndModTime: (TypedVirtualPath, Date)? = nil
190+
private func findOldestOutputForSkipping(postCompileJob: Job) -> (TypedVirtualPath, TimePoint)? {
191+
var oldestOutputAndModTime: (TypedVirtualPath, TimePoint)? = nil
194192
for output in postCompileJob.outputs {
195-
guard let outputModTime = modTime(output)
196-
else {
197-
oldestOutputAndModTime = (output, .distantPast)
198-
break
193+
guard let outputModTime = try? self.fileSystem.lastModificationTime(for: output.file) else {
194+
return (output, .distantPast)
199195
}
200-
oldestOutputAndModTime = oldestOutputAndModTime.map {
201-
$0.1 < outputModTime ? $0 : (output, outputModTime)
196+
197+
if let candidate = oldestOutputAndModTime {
198+
oldestOutputAndModTime = candidate.1 < outputModTime ? candidate : (output, outputModTime)
199+
} else {
200+
oldestOutputAndModTime = (output, outputModTime)
202201
}
203-
?? (output, outputModTime)
204202
}
205203
return oldestOutputAndModTime
206204
}
207-
private func findAnInputOf( postCompileJob: Job, newerThan outputModTime: Date) -> TypedVirtualPath? {
205+
private func findAnInputOf( postCompileJob: Job, newerThan outputModTime: TimePoint) -> TypedVirtualPath? {
208206
postCompileJob.inputs.first { input in
209-
outputModTime < (modTime(input) ?? .distantFuture)
207+
guard let modTime = try? self.fileSystem.lastModificationTime(for: input.file) else {
208+
return false
209+
}
210+
return outputModTime < modTime
210211
}
211212
}
212-
private func modTime(_ path: TypedVirtualPath) -> Date? {
213-
try? fileSystem.lastModificationTime(for: path.file)
214-
}
215213
}
216214

217215

Sources/SwiftDriver/IncrementalCompilation/IncrementalDependencyAndInputSetup.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
import TSCBasic
1414
import SwiftOptions
15-
import struct Foundation.Date
1615
import class Dispatch.DispatchQueue
1716

1817
// Initial incremental state computation
@@ -121,8 +120,8 @@ extension IncrementalCompilationState {
121120
@_spi(Testing) public let dependencyDotFilesIncludeExternals: Bool = true
122121
@_spi(Testing) public let dependencyDotFilesIncludeAPINotes: Bool = false
123122

124-
@_spi(Testing) public let buildStartTime: Date
125-
@_spi(Testing) public let buildEndTime: Date
123+
@_spi(Testing) public let buildStartTime: TimePoint
124+
@_spi(Testing) public let buildEndTime: TimePoint
126125

127126
// Do not try to reuse a graph from a different compilation, so check
128127
// the build record.
@@ -249,11 +248,10 @@ extension IncrementalCompilationState.IncrementalDependencyAndInputSetup {
249248
graphIfPresent = nil
250249
}
251250
catch let ModuleDependencyGraph.ReadError.timeTravellingPriors(priorsModTime: priorsModTime,
252-
buildStartTime: buildStartTime,
253-
priorsTimeIntervalSinceStart: priorsTimeIntervalSinceStart) {
251+
buildStartTime: buildStartTime) {
254252
diagnosticEngine.emit(
255253
warning: "Will not do cross-module incremental builds, priors saved at \(priorsModTime)), " +
256-
"but the previous build started at \(buildStartTime) [priorsTimeIntervalSinceStart: \(priorsTimeIntervalSinceStart)], at '\(dependencyGraphPath)'")
254+
"but the previous build started at \(buildStartTime), at '\(dependencyGraphPath)'")
257255
graphIfPresent = nil
258256
}
259257
catch {

Sources/SwiftDriver/IncrementalCompilation/InputInfo.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import TSCBasic
14-
import struct Foundation.Date
1514

1615
/// Contains information about the current status of an input to the incremental
1716
/// build.
@@ -24,9 +23,9 @@ import struct Foundation.Date
2423
/// The current status of the input file.
2524
/*@_spi(Testing)*/ public let status: Status
2625
/// The last known modification time of this input.
27-
/*@_spi(Testing)*/ public let previousModTime: Date
26+
/*@_spi(Testing)*/ public let previousModTime: TimePoint
2827

29-
/*@_spi(Testing)*/ public init(status: Status, previousModTime: Date) {
28+
/*@_spi(Testing)*/ public init(status: Status, previousModTime: TimePoint) {
3029
self.status = status
3130
self.previousModTime = previousModTime
3231
}
@@ -119,7 +118,7 @@ fileprivate extension ProcessResult {
119118

120119
// MARK: - reading
121120
public extension InputInfo {
122-
init?(tag: String, previousModTime: Date,
121+
init?(tag: String, previousModTime: TimePoint,
123122
failedToReadOutOfDateMap: (String) -> Void
124123
) {
125124
guard let status = Status(identifier: tag) else {

0 commit comments

Comments
 (0)