Skip to content

Commit b021cef

Browse files
authored
[Build] Enable diagnostic serialization by default for swift modules (#8531)
### Motivation: Adds a flag and entry into outputs file map per file in a swift module to emit any diagnostics in serialized form. This is preliminary work to for future `swift migrate` command that needs serialized diagnostics to get the fix-its and enables future improvements like diagnostic de-duplication. ### Modifications: - Add a new flag to `compileArguments` : `-serialize-diagnostics` - Add an entry per source file an swift module that presents a path to a `.dia` file where the diagnostic information should be stored. - Add a computed property to fetch diagnostic file locations per swift module ### Result: The build would now emit serialized diagnostic files for every swift module.
1 parent 387c4e0 commit b021cef

File tree

3 files changed

+79
-2
lines changed

3 files changed

+79
-2
lines changed

Sources/Build/BuildDescription/SwiftModuleBuildDescription.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,8 @@ public final class SwiftModuleBuildDescription {
495495
args += ["-enable-batch-mode"]
496496
}
497497

498+
args += ["-serialize-diagnostics"]
499+
498500
args += self.buildParameters.indexStoreArguments(for: self.target)
499501
args += self.optimizationArguments
500502
args += self.testingArguments
@@ -851,6 +853,7 @@ public final class SwiftModuleBuildDescription {
851853
let sourceFileName = source.basenameWithoutExt
852854
let partialModulePath = self.tempsPath.appending(component: sourceFileName + "~partial.swiftmodule")
853855
let swiftDepsPath = self.tempsPath.appending(component: sourceFileName + ".swiftdeps")
856+
let diagnosticsPath = self.diagnosticFile(sourceFile: source)
854857

855858
content +=
856859
#"""
@@ -872,7 +875,8 @@ public final class SwiftModuleBuildDescription {
872875
#"""
873876
"\#(objectKey)": "\#(object._nativePathString(escaped: true))",
874877
"swiftmodule": "\#(partialModulePath._nativePathString(escaped: true))",
875-
"swift-dependencies": "\#(swiftDepsPath._nativePathString(escaped: true))"
878+
"swift-dependencies": "\#(swiftDepsPath._nativePathString(escaped: true))",
879+
"diagnostics": "\#(diagnosticsPath._nativePathString(escaped: true))"
876880
}\#((idx + 1) < sources.count ? "," : "")
877881

878882
"""#
@@ -1055,3 +1059,13 @@ extension SwiftModuleBuildDescription {
10551059
ModuleBuildDescription.swift(self).recursiveDependencies(using: plan)
10561060
}
10571061
}
1062+
1063+
extension SwiftModuleBuildDescription {
1064+
package var diagnosticFiles: [AbsolutePath] {
1065+
self.sources.compactMap { self.diagnosticFile(sourceFile: $0) }
1066+
}
1067+
1068+
private func diagnosticFile(sourceFile: AbsolutePath) -> AbsolutePath {
1069+
self.tempsPath.appending(component: "\(sourceFile.basenameWithoutExt).dia")
1070+
}
1071+
}

Tests/BuildTests/BuildPlanTests.swift

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import Workspace
3333
import XCTest
3434

3535
import struct TSCBasic.ByteString
36+
import func TSCBasic.withTemporaryFile
3637

3738
import enum TSCUtility.Diagnostics
3839

@@ -785,6 +786,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
785786
exe,
786787
[
787788
"-enable-batch-mode",
789+
"-serialize-diagnostics",
788790
"-Onone",
789791
"-enable-testing",
790792
.equal(self.j),
@@ -803,6 +805,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
803805
lib,
804806
[
805807
"-enable-batch-mode",
808+
"-serialize-diagnostics",
806809
"-Onone",
807810
"-enable-testing",
808811
.equal(self.j),
@@ -1854,6 +1857,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
18541857
[
18551858
.anySequence,
18561859
"-enable-batch-mode",
1860+
"-serialize-diagnostics",
18571861
"-Onone",
18581862
"-enable-testing",
18591863
.equal(self.j),
@@ -2355,6 +2359,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
23552359
[
23562360
.anySequence,
23572361
"-enable-batch-mode",
2362+
"-serialize-diagnostics",
23582363
"-Onone",
23592364
"-enable-testing",
23602365
.equal(self.j),
@@ -2374,6 +2379,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
23742379
[
23752380
.anySequence,
23762381
"-enable-batch-mode",
2382+
"-serialize-diagnostics",
23772383
"-Onone",
23782384
"-enable-testing",
23792385
"-Xfrontend",
@@ -2852,6 +2858,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
28522858
let matchText = try result.moduleBuildDescription(for: "exe").swift().compileArguments()
28532859
let assertionText: [StringPattern] = [
28542860
"-enable-batch-mode",
2861+
"-serialize-diagnostics",
28552862
"-Onone",
28562863
"-enable-testing",
28572864
.equal(self.j),
@@ -3153,6 +3160,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
31533160
exe,
31543161
[
31553162
"-enable-batch-mode",
3163+
"-serialize-diagnostics",
31563164
"-Onone",
31573165
"-enable-testing",
31583166
.equal(self.j),
@@ -3171,6 +3179,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
31713179
lib,
31723180
[
31733181
"-enable-batch-mode",
3182+
"-serialize-diagnostics",
31743183
"-Onone",
31753184
"-enable-testing",
31763185
.equal(self.j),
@@ -3811,6 +3820,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
38113820
let exe = try result.moduleBuildDescription(for: "exe").swift().compileArguments()
38123821
XCTAssertMatch(exe, [
38133822
"-enable-batch-mode",
3823+
"-serialize-diagnostics",
38143824
"-Onone",
38153825
"-enable-testing",
38163826
.equal(self.j),
@@ -6975,6 +6985,59 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
69756985
print(myLib.additionalFlags)
69766986
XCTAssertFalse(myLib.additionalFlags.contains(where: { $0.contains("-tool/include")}), "flags shouldn't contain tools items")
69776987
}
6988+
6989+
func testDiagnosticsAreMentionedInOutputsFileMap() async throws {
6990+
let fs = InMemoryFileSystem(
6991+
emptyFiles:
6992+
"/Pkg/Sources/exe/main.swift",
6993+
"/Pkg/Sources/exe/aux.swift",
6994+
"/Pkg/Sources/lib/lib.swift"
6995+
)
6996+
6997+
let observability = ObservabilitySystem.makeForTesting()
6998+
let graph = try loadModulesGraph(
6999+
fileSystem: fs,
7000+
manifests: [
7001+
Manifest.createRootManifest(
7002+
displayName: "Pkg",
7003+
path: "/Pkg",
7004+
targets: [
7005+
TargetDescription(name: "exe", dependencies: ["lib"]),
7006+
TargetDescription(name: "lib", dependencies: []),
7007+
]
7008+
),
7009+
],
7010+
observabilityScope: observability.topScope
7011+
)
7012+
XCTAssertNoDiagnostics(observability.diagnostics)
7013+
7014+
let plan = try await mockBuildPlan(
7015+
graph: graph,
7016+
linkingParameters: .init(
7017+
shouldLinkStaticSwiftStdlib: true
7018+
),
7019+
fileSystem: fs,
7020+
observabilityScope: observability.topScope
7021+
)
7022+
let result = try BuildPlanResult(plan: plan)
7023+
7024+
result.checkProductsCount(1)
7025+
result.checkTargetsCount(2)
7026+
7027+
for module in result.targetMap {
7028+
let buildDescription = try module.swift()
7029+
7030+
try withTemporaryFile { file in
7031+
try buildDescription.writeOutputFileMap(to: .init(file.path.pathString))
7032+
7033+
let fileMap = try String(bytes: fs.readFileContents(file.path).contents, encoding: .utf8)
7034+
7035+
for diagnosticFile in buildDescription.diagnosticFiles {
7036+
XCTAssertMatch(fileMap, .contains(diagnosticFile.pathString))
7037+
}
7038+
}
7039+
}
7040+
}
69787041
}
69797042

69807043
class BuildPlanNativeTests: BuildPlanTestCase {

Tests/BuildTests/CrossCompilationBuildPlanTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ final class CrossCompilationBuildPlanTests: XCTestCase {
178178
XCTAssertMatch(
179179
exe,
180180
[
181-
"-enable-batch-mode", "-Onone", "-enable-testing",
181+
"-enable-batch-mode", "-serialize-diagnostics", "-Onone", "-enable-testing",
182182
"-j3", "-DSWIFT_PACKAGE", "-DDEBUG", "-Xcc",
183183
"-fmodule-map-file=\(buildPath.appending(components: "lib.build", "module.modulemap"))",
184184
"-Xcc", "-I", "-Xcc", "\(pkgPath.appending(components: "Sources", "lib", "include"))",

0 commit comments

Comments
 (0)