Skip to content

Commit dd7b5a3

Browse files
authored
Deserialize diagnostics with no location correctly (#213)
1 parent 907b747 commit dd7b5a3

File tree

3 files changed

+53
-35
lines changed

3 files changed

+53
-35
lines changed

Sources/TSCUtility/SerializedDiagnostics.swift

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ extension SerializedDiagnostics {
7878
/// The level the diagnostic was emitted at.
7979
public var level: Level
8080
/// The location the diagnostic was emitted at in the source file.
81-
public var location: SourceLocation
81+
public var location: SourceLocation?
8282
/// The diagnostic category. Currently only Clang emits this.
8383
public var category: String?
8484
/// The corresponding diagnostic command-line flag. Currently only Clang emits this.
@@ -109,20 +109,20 @@ extension SerializedDiagnostics {
109109

110110
text = String(data: diagnosticBlob, encoding: .utf8)
111111
level = Level(rawValue: record.fields[0])
112-
location = try SourceLocation(fields: record.fields[1...4],
113-
filenameMap: filenameMap)
112+
location = SourceLocation(fields: record.fields[1...4],
113+
filenameMap: filenameMap)
114114
category = categoryMap[record.fields[5]]
115115
flag = flagMap[record.fields[6]]
116116

117117
case .sourceRange:
118118
guard record.fields.count == 8 else { throw Error.malformedRecord }
119119

120-
let start = try SourceLocation(fields: record.fields[0...3],
121-
filenameMap: filenameMap)
122-
let end = try SourceLocation(fields: record.fields[4...7],
123-
filenameMap: filenameMap)
124-
ranges.append((start, end))
125-
120+
if let start = SourceLocation(fields: record.fields[0...3],
121+
filenameMap: filenameMap),
122+
let end = SourceLocation(fields: record.fields[4...7],
123+
filenameMap: filenameMap) {
124+
ranges.append((start, end))
125+
}
126126
case .flag:
127127
guard record.fields.count == 2,
128128
case .blob(let flagBlob) = record.payload,
@@ -157,19 +157,20 @@ extension SerializedDiagnostics {
157157
let fixItText = String(data: fixItBlob, encoding: .utf8)
158158
else { throw Error.malformedRecord }
159159

160-
let start = try SourceLocation(fields: record.fields[0...3],
161-
filenameMap: filenameMap)
162-
let end = try SourceLocation(fields: record.fields[4...7],
163-
filenameMap: filenameMap)
164-
fixIts.append(FixIt(start: start, end: end, text: fixItText))
160+
if let start = SourceLocation(fields: record.fields[0...3],
161+
filenameMap: filenameMap),
162+
let end = SourceLocation(fields: record.fields[4...7],
163+
filenameMap: filenameMap) {
164+
fixIts.append(FixIt(start: start, end: end, text: fixItText))
165+
}
165166

166167
case .version, nil:
167168
throw Error.unexpectedRecord
168169
}
169170
}
170171

171172
do {
172-
guard let text = text, let level = level, let location = location else {
173+
guard let text = text, let level = level else {
173174
throw Error.missingInformation
174175
}
175176
self.text = text
@@ -192,12 +193,10 @@ extension SerializedDiagnostics {
192193
/// Clang includes this, it is set to 0 by Swift.
193194
public var offset: UInt64
194195

195-
fileprivate init(fields: ArraySlice<UInt64>,
196-
filenameMap: [UInt64: String]) throws {
197-
guard let name = filenameMap[fields[fields.startIndex]] else {
198-
throw Error.missingInformation
199-
}
200-
self.filename = name
196+
fileprivate init?(fields: ArraySlice<UInt64>,
197+
filenameMap: [UInt64: String]) {
198+
guard let filename = filenameMap[fields[fields.startIndex]] else { return nil }
199+
self.filename = filename
201200
self.line = fields[fields.startIndex + 1]
202201
self.column = fields[fields.startIndex + 2]
203202
self.offset = fields[fields.startIndex + 3]
336 Bytes
Binary file not shown.

Tests/TSCUtilityTests/SerializedDiagnosticsTests.swift

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,42 +26,61 @@ final class SerializedDiagnosticsTests: XCTestCase {
2626
let one = serializedDiags.diagnostics[5]
2727
XCTAssertEqual(one.text, "expected ',' separator")
2828
XCTAssertEqual(one.level, .error)
29-
XCTAssertTrue(one.location.filename.hasSuffix("/StoreSearchCoordinator.swift"))
30-
XCTAssertEqual(one.location.line, 21)
31-
XCTAssertEqual(one.location.column, 69)
32-
XCTAssertEqual(one.location.offset, 0)
29+
XCTAssertEqual(one.location?.filename.hasSuffix("/StoreSearchCoordinator.swift"), true)
30+
XCTAssertEqual(one.location?.line, 21)
31+
XCTAssertEqual(one.location?.column, 69)
32+
XCTAssertEqual(one.location?.offset, 0)
3333
XCTAssertNil(one.category)
3434
XCTAssertNil(one.flag)
3535
XCTAssertEqual(one.ranges.count, 0)
3636
XCTAssertEqual(one.fixIts.count, 1)
3737
XCTAssertEqual(one.fixIts[0].text, ",")
3838
XCTAssertEqual(one.fixIts[0].start, one.fixIts[0].end)
39-
XCTAssertTrue(one.fixIts[0].start.filename.hasSuffix("/StoreSearchCoordinator.swift"))
39+
XCTAssertEqual(one.fixIts[0].start.filename.hasSuffix("/StoreSearchCoordinator.swift"), true)
4040
XCTAssertEqual(one.fixIts[0].start.line, 21)
4141
XCTAssertEqual(one.fixIts[0].start.column, 69)
4242
XCTAssertEqual(one.fixIts[0].start.offset, 0)
4343

4444
let two = serializedDiags.diagnostics[16]
4545
XCTAssertEqual(two.text, "use of unresolved identifier 'DispatchQueue'")
4646
XCTAssertEqual(two.level, .error)
47-
XCTAssertTrue(two.location.filename.hasSuffix("/Observable.swift"))
48-
XCTAssertEqual(two.location.line, 34)
49-
XCTAssertEqual(two.location.column, 13)
50-
XCTAssertEqual(two.location.offset, 0)
47+
XCTAssertEqual(two.location?.filename.hasSuffix("/Observable.swift"), true)
48+
XCTAssertEqual(two.location?.line, 34)
49+
XCTAssertEqual(two.location?.column, 13)
50+
XCTAssertEqual(two.location?.offset, 0)
5151
XCTAssertNil(two.category)
5252
XCTAssertNil(two.flag)
5353
XCTAssertEqual(two.ranges.count, 1)
54-
XCTAssertTrue(two.ranges[0].0.filename.hasSuffix("/Observable.swift"))
54+
XCTAssertEqual(two.ranges[0].0.filename.hasSuffix("/Observable.swift"), true)
5555
XCTAssertEqual(two.ranges[0].0.line, 34)
5656
XCTAssertEqual(two.ranges[0].0.column, 13)
5757
XCTAssertEqual(two.ranges[0].0.offset, 0)
58-
XCTAssertTrue(two.ranges[0].1.filename.hasSuffix("/Observable.swift"))
58+
XCTAssertEqual(two.ranges[0].1.filename.hasSuffix("/Observable.swift"), true)
5959
XCTAssertEqual(two.ranges[0].1.line, 34)
6060
XCTAssertEqual(two.ranges[0].1.column, 26)
6161
XCTAssertEqual(two.ranges[0].1.offset, 0)
6262
XCTAssertEqual(two.fixIts.count, 0)
6363
}
6464

65+
func testReadDiagsWithNoLocation() throws {
66+
let serializedDiagnosticsPath = AbsolutePath(#file).parentDirectory
67+
.appending(components: "Inputs", "no-location.dia")
68+
let contents = try localFileSystem.readFileContents(serializedDiagnosticsPath)
69+
let serializedDiags = try SerializedDiagnostics(bytes: contents)
70+
71+
XCTAssertEqual(serializedDiags.versionNumber, 2)
72+
XCTAssertEqual(serializedDiags.diagnostics.count, 1)
73+
74+
let diag = serializedDiags.diagnostics[0]
75+
XCTAssertEqual(diag.text, "API breakage: func foo() has been removed")
76+
XCTAssertEqual(diag.level, .error)
77+
XCTAssertNil(diag.location)
78+
XCTAssertEqual(diag.category, "api-digester-breaking-change")
79+
XCTAssertNil(diag.flag)
80+
XCTAssertEqual(diag.ranges.count, 0)
81+
XCTAssertEqual(diag.fixIts.count, 0)
82+
}
83+
6584
func testReadClangSerializedDiags() throws {
6685
let serializedDiagnosticsPath = AbsolutePath(#file).parentDirectory
6786
.appending(components: "Inputs", "clang.dia")
@@ -74,9 +93,9 @@ final class SerializedDiagnosticsTests: XCTestCase {
7493
let one = serializedDiags.diagnostics[1]
7594
XCTAssertEqual(one.text, "values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead")
7695
XCTAssertEqual(one.level, .warning)
77-
XCTAssertEqual(one.location.line, 252)
78-
XCTAssertEqual(one.location.column, 137)
79-
XCTAssertEqual(one.location.offset, 10046)
96+
XCTAssertEqual(one.location?.line, 252)
97+
XCTAssertEqual(one.location?.column, 137)
98+
XCTAssertEqual(one.location?.offset, 10046)
8099
XCTAssertEqual(one.category, "Format String Issue")
81100
XCTAssertEqual(one.flag, "format")
82101
XCTAssertEqual(one.ranges.count, 4)

0 commit comments

Comments
 (0)