Skip to content

Commit 6030474

Browse files
committed
Refactor DiagnosticsFormatter and extend its functionality
This commit refactors the existing code for `DiagnosticsFormatter` and introduces several new features, complete with documentation and unit tests. Key Enhancements: 1. Nested Diagnostic Support: Enhanced to include not only top-level diagnostics but also related notes, improving the debugging experience. 2. Custom Decorators: Incorporate the `DiagnosticDecorator` protocol, allowing for custom formatting and styling of diagnostic output. 3. Context Size Control: Added options to control the `ContextSize`, providing more flexibility in how much source code context is displayed around each diagnostic. Documentation: - Comprehensive documentation added, detailing the purpose, usage examples, and future developments for `DiagnosticsFormatter`. Testing: - Added robust unit tests to validate the new features and ensure reliability. This refactor and feature addition make `DiagnosticsFormatter` a more versatile and developer-friendly tool for debugging and understanding Swift code.
1 parent 2f5dd64 commit 6030474

8 files changed

+1170
-270
lines changed

Sources/SwiftDiagnostics/DiagnosticsFormatter.swift

Lines changed: 728 additions & 236 deletions
Large diffs are not rendered by default.

Sources/SwiftDiagnostics/GroupedDiagnostics.swift

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -254,21 +254,24 @@ extension GroupedDiagnostics {
254254
// Render the buffer.
255255
return prefixString
256256
+ formatter.annotatedSource(
257-
tree: sourceFile.tree,
258-
diags: sourceFile.diagnostics,
259-
indentString: diagnosticDecorator.decorateBufferOutline(indentString),
260-
suffixTexts: childSources,
261-
sourceLocationConverter: slc
262-
) + suffixString
257+
inSyntaxTree: sourceFile.tree,
258+
withDiagnostics: sourceFile.diagnostics,
259+
usingIndentString: diagnosticDecorator.decorateBufferOutline(indentString),
260+
appendingSuffixTexts: childSources,
261+
employingSourceLocationConverter: slc
262+
)
263+
+ suffixString
263264
}
264265
}
265266

266267
extension DiagnosticsFormatter {
267268
/// Annotate all of the source files in the given set of grouped diagnostics.
268269
public func annotateSources(in group: GroupedDiagnostics) -> String {
269-
return group.rootSourceFiles.map { rootSourceFileID in
270-
group.annotateSource(rootSourceFileID, formatter: self, indentString: "")
271-
}.joined(separator: "\n")
270+
group.rootSourceFiles
271+
.map { rootSourceFileID in
272+
group.annotateSource(rootSourceFileID, formatter: self, indentString: "")
273+
}
274+
.joined(separator: "\n")
272275
}
273276

274277
public static func annotateSources(
@@ -279,4 +282,12 @@ extension DiagnosticsFormatter {
279282
let formatter = DiagnosticsFormatter(contextSize: contextSize, colorize: colorize)
280283
return formatter.annotateSources(in: group)
281284
}
285+
// public static func annotateSources(
286+
// in group: GroupedDiagnostics,
287+
// contextSize: ContextSize = .limited(2),
288+
// diagnosticDecorator: DiagnosticDecorator = BasicDiagnosticDecorator()
289+
// ) -> String {
290+
// let formatter = DiagnosticsFormatter(contextSize: contextSize, diagnosticDecorator: diagnosticDecorator)
291+
// return formatter.annotateSources(in: group)
292+
// }
282293
}

Sources/SwiftSyntaxBuilder/Syntax+StringInterpolation.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ struct SyntaxStringInterpolationDiagnosticError: Error, CustomStringConvertible
185185
var description: String {
186186
// Start the diagnostic on a new line so it isn't prefixed with the file, which messes up the
187187
// column-aligned message from ``DiagnosticsFormatter``.
188+
// return "\n" + DiagnosticsFormatter.annotatedSource(inSyntaxTree: tree, withDiagnostics: diagnostics)
188189
return "\n" + DiagnosticsFormatter.annotatedSource(tree: tree, diags: diagnostics)
189190
}
190191
}

Sources/SwiftSyntaxBuilder/SyntaxParsable+ExpressibleByStringInterpolation.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ extension SyntaxParseable {
4747
!suppressStringInterpolationParsingErrors
4848
{
4949
let diagnostics = ParseDiagnosticsGenerator.diagnostics(for: self)
50-
let formattedDiagnostics = DiagnosticsFormatter().annotatedSource(tree: self, diags: diagnostics)
51-
Logger(subsystem: "org.swift.swift-syntax", category: "ParseError").fault(
50+
// let formattedDiagnostics = DiagnosticsFormatter.annotatedSource(inSyntaxTree: self, withDiagnostics: diagnostics)
51+
let formattedDiagnostics = DiagnosticsFormatter.annotatedSource(tree: self, diags: diagnostics)
52+
Logger(subsystem: "SwiftSyntax", category: "ParseError").fault(
5253
"""
5354
Parsing a `\(Self.self)` node from string interpolation produced the following parsing errors.
5455
Set a breakpoint in `SyntaxParseable.logStringInterpolationParsingError()` to debug the failure.

Tests/SwiftDiagnosticsTest/DiagnosticTestingUtils.swift

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ struct DiagnosticDescriptor {
8383
/// - fixIts: An array of Fix-It descriptors for quick fixes. Default is an empty array.
8484
init(
8585
locationMarker: LocationMarker,
86-
id: MessageID = MessageID(domain: "test", id: "conjured"),
86+
id: MessageID = .test,
8787
message: String,
8888
severity: DiagnosticSeverity = .error,
8989
highlight: [Syntax] = [],
@@ -158,6 +158,22 @@ struct NoteDescriptor {
158158

159159
/// The textual content of the note to be displayed.
160160
let message: String
161+
162+
/// Initializes a new `NoteDescriptor`.
163+
///
164+
/// - Parameters:
165+
/// - locationMarker: The marker pointing to location in source code.
166+
/// - id: The ID associated with the note message.
167+
/// - message: The textual content of the note to be displayed.
168+
init(
169+
locationMarker: LocationMarker,
170+
id: MessageID = .test,
171+
message: String
172+
) {
173+
self.locationMarker = locationMarker
174+
self.id = id
175+
self.message = message
176+
}
161177
}
162178

163179
/// A simple implementation of the `NoteMessage` protocol for testing.
@@ -168,6 +184,19 @@ struct SimpleNoteMessage: NoteMessage {
168184

169185
/// The unique identifier for this note message.
170186
let noteID: MessageID
187+
188+
/// Initializes a new `SimpleNoteMessage`.
189+
///
190+
/// - Parameters:
191+
/// - message: The textual content of the note to be displayed.
192+
/// - noteID: The unique identifier for this note message.
193+
init(
194+
message: String,
195+
noteID: MessageID = .test
196+
) {
197+
self.message = message
198+
self.noteID = noteID
199+
}
171200
}
172201

173202
/// A simple implementation of the `DiagnosticMessage` protocol for testing.
@@ -181,6 +210,22 @@ struct SimpleDiagnosticMessage: DiagnosticMessage {
181210

182211
/// The severity level of the diagnostic message.
183212
let severity: DiagnosticSeverity
213+
214+
/// Initializes a new `SimpleDiagnosticMessage`.
215+
///
216+
/// - Parameters:
217+
/// - message: The textual content of the diagnostic message to be displayed.
218+
/// - diagnosticID: The ID associated with the diagnostic message for categorization or referencing.
219+
/// - severity: The severity level of the diagnostic message.
220+
init(
221+
message: String,
222+
diagnosticID: MessageID = .test,
223+
severity: DiagnosticSeverity
224+
) {
225+
self.message = message
226+
self.diagnosticID = diagnosticID
227+
self.severity = severity
228+
}
184229
}
185230

186231
/// Asserts that the annotated source generated from diagnostics matches an expected annotated source.
@@ -211,12 +256,17 @@ func assertAnnotated(
211256
XCTFail(error.localizedDescription, file: file, line: line)
212257
}
213258

259+
// let annotatedSource = DiagnosticsFormatter.annotatedSource(inSyntaxTree: tree, withDiagnostics: diagnostics)
214260
let annotatedSource = DiagnosticsFormatter.annotatedSource(tree: tree, diags: diagnostics)
215-
261+
216262
assertStringsEqualWithDiff(
217263
annotatedSource,
218264
expectedAnnotatedSource,
219265
file: file,
220266
line: line
221267
)
222268
}
269+
270+
extension MessageID {
271+
fileprivate static var test = Self(domain: "test", id: "conjured")
272+
}

0 commit comments

Comments
 (0)