Skip to content

Commit 1a2b65d

Browse files
brooke-callahanjakepetroules
authored andcommitted
Fix build warnings about obsolete use of await.
rdar://159492437
1 parent 1e9bfe1 commit 1a2b65d

File tree

7 files changed

+87
-7
lines changed

7 files changed

+87
-7
lines changed

Sources/SWBCore/ProjectModel/Workspace.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,14 @@ public final class Workspace: ProjectModelItem, PIFObject, ReferenceLookupContex
262262
return project
263263
}
264264

265+
public static func projectLocation(for target: Target?, workspace: Workspace?) -> Diagnostic.Location {
266+
if let target, let workspace {
267+
let path = workspace.project(for: target).xcodeprojPath
268+
return Diagnostic.Location.path(path, fileLocation: nil)
269+
}
270+
return .unknown
271+
}
272+
265273
/// Find the projects with the given name.
266274
public func projects(named name: String) -> [Project] {
267275
return projectsByName[name] ?? []

Sources/SWBCore/SpecImplementations/CommandLineToolSpec.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1463,7 +1463,7 @@ open class GenericOutputParser : TaskOutputParser {
14631463
public let toolBasenames: Set<String>
14641464

14651465
/// Buffered output that has not yet been parsed (parsing is line-by-line, so we buffer incomplete lines until we receive more output).
1466-
private var unparsedBytes: ArraySlice<UInt8> = []
1466+
internal var unparsedBytes: ArraySlice<UInt8> = []
14671467

14681468
/// The Diagnostic that is being constructed, possibly across multiple lines of input.
14691469
private var inProgressDiagnostic: Diagnostic?

Sources/SWBCore/SpecImplementations/Tools/LinkerTools.swift

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,60 @@ public struct DiscoveredLdLinkerToolSpecInfo: DiscoveredCommandLineToolSpecInfo
176176
/// Maximum number of undefined symbols to emit. Might be configurable in the future.
177177
let undefinedSymbolCountLimit = 100
178178

179+
override public func write(bytes: ByteString) {
180+
181+
// Split the buffer into slices separated by newlines. The last slice represents the partial last line (there always is one, even if it's empty).
182+
var lines = bytes.split(separator: UInt8(ascii: "\n"), maxSplits: .max, omittingEmptySubsequences: false)
183+
184+
// Any unparsed bytes belong to the first line. We don't want to run `split` over these because it can lead to accidentally quadratic behavior if write is called many times per line.
185+
lines[0] = unparsedBytes + lines[0]
186+
187+
let linesToParse = lines.dropLast()
188+
189+
if let target = self.task.forTarget?.target {
190+
// Linker errors and warnings take more effort to get actionable information out of build logs than those for source files. This is because the linker does not have the path to the project or target name so they are not included in the message.
191+
//
192+
// Prepend the path to the project and target name to any error or warning lines.
193+
// Example input:
194+
// ld: warning: linking with (/System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio) but not using any symbols from it
195+
// Example output:
196+
// /Path/To/ProjectFolder/ProjectName.xcodeproj: TargetName: ld: warning: linking with (/System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio) but not using any symbols from it
197+
198+
let workspace = self.workspaceContext.workspace
199+
let projectPath = workspace.project(for: target).xcodeprojPath
200+
let targetName = target.name
201+
202+
let processedLines: [ByteString] = linesToParse.map { lineBytes in
203+
let lineString = String(decoding: lineBytes, as: Unicode.UTF8.self)
204+
if lineString.contains(": error:")
205+
|| lineString.contains(": warning:") {
206+
207+
let issueString = "\(projectPath.str): \(targetName): \(lineString)"
208+
return ByteString(encodingAsUTF8: issueString)
209+
}
210+
return ByteString(lineBytes)
211+
}
212+
213+
// Forward the bytes
214+
let processedBytes = ByteString(processedLines.joined(separator: ByteString("\n")))
215+
delegate.emitOutput(processedBytes)
216+
}
217+
else {
218+
// Forward the bytes
219+
let processedBytes = ByteString(linesToParse.joined(separator: ByteString("\n")))
220+
delegate.emitOutput(processedBytes)
221+
}
222+
223+
// Parse any complete lines of output.
224+
for line in linesToParse {
225+
parseLine(line)
226+
}
227+
228+
// Track the last, incomplete line to as the unparsed bytes.
229+
unparsedBytes = lines.last ?? []
230+
}
231+
232+
@discardableResult
179233
override func parseLine<S: Collection>(_ lineBytes: S) -> Bool where S.Element == UInt8 {
180234

181235
// Create a string that we can examine. Use the non-failable constructor, so that we are robust against potentially invalid UTF-8.
@@ -190,11 +244,14 @@ public struct DiscoveredLdLinkerToolSpecInfo: DiscoveredCommandLineToolSpecInfo
190244
}
191245
else if let match = LdLinkerOutputParser.problemMessageRegEx.firstMatch(in: lineString), match[3].hasPrefix("symbol(s) not found") {
192246
// It's time to emit all the symbols. We emit each as a separate message.
247+
let projectLocation = Workspace.projectLocation(for: self.task.forTarget?.target,
248+
workspace: self.workspaceContext.workspace)
249+
193250
for symbol in undefinedSymbols.prefix(undefinedSymbolCountLimit) {
194-
delegate.diagnosticsEngine.emit(Diagnostic(behavior: .error, location: .unknown, data: DiagnosticData("Undefined symbol: \(symbol)"), appendToOutputStream: false))
251+
delegate.diagnosticsEngine.emit(Diagnostic(behavior: .error, location: projectLocation, data: DiagnosticData("Undefined symbol: \(symbol)"), appendToOutputStream: false))
195252
}
196253
if undefinedSymbols.count > undefinedSymbolCountLimit {
197-
delegate.diagnosticsEngine.emit(Diagnostic(behavior: .note, location: .unknown, data: DiagnosticData("(\(undefinedSymbols.count - undefinedSymbolCountLimit) additional undefined symbols are shown in the transcript"), appendToOutputStream: false))
254+
delegate.diagnosticsEngine.emit(Diagnostic(behavior: .note, location: projectLocation, data: DiagnosticData("(\(undefinedSymbols.count - undefinedSymbolCountLimit) additional undefined symbols are shown in the transcript"), appendToOutputStream: false))
198255
}
199256
collectingUndefinedSymbols = false
200257
undefinedSymbols = []
@@ -213,7 +270,9 @@ public struct DiscoveredLdLinkerToolSpecInfo: DiscoveredCommandLineToolSpecInfo
213270
let severity = match[2].isEmpty ? "error" : match[2]
214271
let behavior = Diagnostic.Behavior(name: severity) ?? .note
215272
let message = match[3].prefix(1).localizedCapitalized + match[3].dropFirst()
216-
let diagnostic = Diagnostic(behavior: behavior, location: .unknown, data: DiagnosticData(message), appendToOutputStream: false)
273+
let projectLocation = Workspace.projectLocation(for: self.task.forTarget?.target,
274+
workspace: self.workspaceContext.workspace)
275+
let diagnostic = Diagnostic(behavior: behavior, location: projectLocation, data: DiagnosticData(message), appendToOutputStream: false)
217276
delegate.diagnosticsEngine.emit(diagnostic)
218277
}
219278
return true
@@ -724,7 +783,9 @@ public final class LdLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @unchec
724783
enumerateLinkerCommandLine(arguments: commandLine, handleWl: cbc.scope.evaluate(BuiltinMacros._DISCOVER_COMMAND_LINE_LINKER_INPUTS_INCLUDE_WL)) { arg, value in
725784
func emitDependencyDiagnostic(type: String, node: PlannedPathNode) {
726785
if delegate.userPreferences.enableDebugActivityLogs {
727-
delegate.note("Added \(type) dependency '\(node.path.str)' from command line argument \(arg)", location: .unknown)
786+
let projectLocation = cbc.producer.projectLocation
787+
788+
delegate.note("Added \(type) dependency '\(node.path.str)' from command line argument \(arg)", location: projectLocation)
728789
}
729790
}
730791

Sources/SWBCore/TaskGeneration.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ public protocol CommandProducer: PlatformBuildContext, SpecLookupContext, Refere
251251
/// - Returns: Information on the headers referenced by the project that the given target is a part of.
252252
func projectHeaderInfo(for target: Target) async -> ProjectHeaderInfo?
253253

254+
var projectLocation: Diagnostic.Location { get }
255+
254256
/// Whether or not an SDK stat cache should be used for the build of this target.
255257
func shouldUseSDKStatCache() async -> Bool
256258

Sources/SWBTaskConstruction/TaskProducers/TaskProducer.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,10 @@ extension TaskProducerContext: CommandProducer {
13551355
return await workspaceContext.headerIndex.projectHeaderInfo[workspaceContext.workspace.project(for: target)]
13561356
}
13571357

1358+
public var projectLocation: Diagnostic.Location {
1359+
return Workspace.projectLocation(for: self.configuredTarget?.target, workspace: self.workspaceContext.workspace)
1360+
}
1361+
13581362
public var canConstructAppIntentsMetadataTask: Bool {
13591363
let scope = settings.globalScope
13601364
let buildComponents = scope.evaluate(BuiltinMacros.BUILD_COMPONENTS)

Sources/SWBTestSupport/DummyCommandProducer.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ package struct MockCommandProducer: CommandProducer, Sendable {
203203
return nil
204204
}
205205

206+
public var projectLocation: Diagnostic.Location {
207+
return .unknown
208+
}
209+
206210
package func discoveredCommandLineToolSpecInfo(_ delegate: any SWBCore.CoreClientTargetDiagnosticProducingDelegate, _ toolName: String, _ path: Path, _ process: @Sendable (Data) async throws -> any SWBCore.DiscoveredCommandLineToolSpecInfo) async throws -> any SWBCore.DiscoveredCommandLineToolSpecInfo {
207211
try await discoveredCommandLineToolSpecInfoCache.run(delegate, toolName, path, process)
208212
}

Tests/SWBBuildSystemTests/LinkerTests.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ fileprivate struct LinkerTests: CoreBasedTests {
2525
func linkerDriverDiagnosticsParsing() async throws {
2626

2727
try await withTemporaryDirectory { tmpDir in
28+
let projectName = "TestProject"
2829
let testProject = try await TestProject(
29-
"TestProject",
30+
projectName,
3031
sourceRoot: tmpDir,
3132
groupTree: TestGroup(
3233
"SomeFiles",
@@ -61,7 +62,7 @@ fileprivate struct LinkerTests: CoreBasedTests {
6162
}
6263

6364
try await tester.checkBuild(runDestination: .macOS) { results in
64-
results.checkError(.prefix("Unknown argument: '-not-a-real-flag'"))
65+
results.checkError(.prefix("\(tmpDir.str)/\(projectName).xcodeproj: Unknown argument: '-not-a-real-flag'"))
6566
results.checkError(.prefix("Command Ld failed."))
6667
}
6768
}

0 commit comments

Comments
 (0)