@@ -18,6 +18,7 @@ import SwiftFormatRules
1818import SwiftFormatWhitespaceLinter
1919import SwiftSyntax
2020import SwiftParser
21+ import SwiftDiagnostics
2122
2223/// Diagnoses and reports problems in Swift source code or syntax trees according to the Swift style
2324/// guidelines.
@@ -53,7 +54,7 @@ public final class SwiftLinter {
5354 /// - Throws: If an unrecoverable error occurs when formatting the code.
5455 public func lint(
5556 contentsOf url: URL ,
56- parsingDiagnosticHandler: ( ( Diagnostic ) -> Void ) ? = nil
57+ parsingDiagnosticHandler: ( ( Diagnostic , SourceLocation ) -> Void ) ? = nil
5758 ) throws {
5859 guard FileManager . default. isReadableFile ( atPath: url. path) else {
5960 throw SwiftFormatError . fileNotReadable
@@ -64,7 +65,8 @@ public final class SwiftLinter {
6465 }
6566 let source = try String ( contentsOf: url, encoding: . utf8)
6667 let sourceFile = try Parser . parse ( source: source)
67- try lint ( syntax: sourceFile, assumingFileURL: url, source: source)
68+ try lint ( syntax: sourceFile, assumingFileURL: url,
69+ source: source, parsingDiagnosticHandler: parsingDiagnosticHandler)
6870 }
6971
7072 /// Lints the given Swift source code.
@@ -78,10 +80,11 @@ public final class SwiftLinter {
7880 public func lint(
7981 source: String ,
8082 assumingFileURL url: URL ,
81- parsingDiagnosticHandler: ( ( Diagnostic ) -> Void ) ? = nil
83+ parsingDiagnosticHandler: ( ( Diagnostic , SourceLocation ) -> Void ) ? = nil
8284 ) throws {
8385 let sourceFile = try Parser . parse ( source: source)
84- try lint ( syntax: sourceFile, assumingFileURL: url, source: source)
86+ try lint ( syntax: sourceFile, assumingFileURL: url,
87+ source: source, parsingDiagnosticHandler: parsingDiagnosticHandler)
8588 }
8689
8790 /// Lints the given Swift syntax tree.
@@ -93,14 +96,29 @@ public final class SwiftLinter {
9396 /// - url: A file URL denoting the filename/path that should be assumed for this syntax tree.
9497 /// - Throws: If an unrecoverable error occurs when formatting the code.
9598 public func lint( syntax: SourceFileSyntax , assumingFileURL url: URL ) throws {
96- try lint ( syntax: syntax, assumingFileURL: url, source: nil )
99+ try lint ( syntax: syntax, assumingFileURL: url,
100+ source: nil , parsingDiagnosticHandler: nil )
97101 }
98102
99- private func lint( syntax: SourceFileSyntax , assumingFileURL url: URL , source: String ? ) throws {
103+ private func lint(
104+ syntax: SourceFileSyntax ,
105+ assumingFileURL url: URL ,
106+ source: String ? ,
107+ parsingDiagnosticHandler: ( ( Diagnostic , SourceLocation ) -> Void ) ?
108+ ) throws {
100109 if let position = _firstInvalidSyntaxPosition ( in: Syntax ( syntax) ) {
101110 throw SwiftFormatError . fileContainsInvalidSyntax ( position: position)
102111 }
103112
113+ if let parsingDiagnosticHandler = parsingDiagnosticHandler {
114+ let expectedConverter = SourceLocationConverter ( file: url. path, tree: syntax)
115+ let diagnostics = ParseDiagnosticsGenerator . diagnostics ( for: syntax)
116+ for diagnostic in diagnostics {
117+ let location = diagnostic. location ( converter: expectedConverter)
118+ parsingDiagnosticHandler ( diagnostic, location)
119+ }
120+ }
121+
104122 let context = Context (
105123 configuration: configuration, findingConsumer: findingConsumer, fileURL: url,
106124 sourceFileSyntax: syntax, source: source, ruleNameCache: ruleNameCache)
0 commit comments