@@ -123,6 +123,124 @@ func emitDiagnostic(
123123 }
124124}
125125
126+ extension SourceManager {
127+ private func diagnoseSingle< Node: SyntaxProtocol > (
128+ message: String ,
129+ severity: DiagnosticSeverity ,
130+ node: Node ,
131+ position: AbsolutePosition ,
132+ highlights: [ Syntax ] = [ ] ,
133+ fixItChanges: [ FixIt . Change ] = [ ]
134+ ) {
135+ // Map severity
136+ let bridgedSeverity : BridgedDiagnosticSeverity
137+ switch severity {
138+ case . error: bridgedSeverity = . error
139+ case . note: bridgedSeverity = . note
140+ case . warning: bridgedSeverity = . warning
141+ }
142+
143+ // Emit the diagnostic
144+ var mutableMessage = message
145+ let diag = mutableMessage. withUTF8 { messageBuffer in
146+ SwiftDiagnostic_create (
147+ cxxDiagnosticEngine, bridgedSeverity,
148+ cxxSourceLocation ( for: node, at: position) ,
149+ messageBuffer. baseAddress, messageBuffer. count
150+ )
151+ }
152+
153+ // Emit highlights
154+ for highlight in highlights {
155+ SwiftDiagnostic_highlight (
156+ diag,
157+ cxxSourceLocation ( for: highlight) ,
158+ cxxSourceLocation ( for: highlight, at: highlight. endPosition)
159+ )
160+ }
161+
162+ // Emit changes for a Fix-It.
163+ for change in fixItChanges {
164+ let replaceStartLoc : CxxSourceLoc ?
165+ let replaceEndLoc : CxxSourceLoc ?
166+ var newText : String
167+
168+ switch change {
169+ case . replace( let oldNode, let newNode) :
170+ replaceStartLoc = cxxSourceLocation ( for: oldNode)
171+ replaceEndLoc = cxxSourceLocation (
172+ for: oldNode,
173+ at: oldNode. endPosition
174+ )
175+ newText = newNode. description
176+
177+ case . replaceLeadingTrivia( let oldToken, let newTrivia) :
178+ replaceStartLoc = cxxSourceLocation ( for: oldToken)
179+ replaceEndLoc = cxxSourceLocation (
180+ for: oldToken,
181+ at: oldToken. positionAfterSkippingLeadingTrivia
182+ )
183+ newText = newTrivia. description
184+
185+ case . replaceTrailingTrivia( let oldToken, let newTrivia) :
186+ replaceStartLoc = cxxSourceLocation (
187+ for: oldToken,
188+ at: oldToken. endPositionBeforeTrailingTrivia)
189+ replaceEndLoc = cxxSourceLocation (
190+ for: oldToken,
191+ at: oldToken. endPosition
192+ )
193+ newText = newTrivia. description
194+ }
195+
196+ newText. withUTF8 { textBuffer in
197+ SwiftDiagnostic_fixItReplace (
198+ diag, replaceStartLoc, replaceEndLoc,
199+ textBuffer. baseAddress, textBuffer. count
200+ )
201+ }
202+ }
203+
204+ SwiftDiagnostic_finish ( diag) ;
205+ }
206+
207+ /// Emit a diagnostic via the C++ diagnostic engine.
208+ func diagnose(
209+ diagnostic: Diagnostic ,
210+ messageSuffix: String ? = nil
211+ ) {
212+ // Emit the main diagnostic.
213+ diagnoseSingle (
214+ message: diagnostic. diagMessage. message + ( messageSuffix ?? " " ) ,
215+ severity: diagnostic. diagMessage. severity,
216+ node: diagnostic. node,
217+ position: diagnostic. position,
218+ highlights: diagnostic. highlights
219+ )
220+
221+ // Emit Fix-Its.
222+ for fixIt in diagnostic. fixIts {
223+ diagnoseSingle (
224+ message: fixIt. message. message,
225+ severity: . note,
226+ node: diagnostic. node,
227+ position: diagnostic. position,
228+ fixItChanges: fixIt. changes. changes
229+ )
230+ }
231+
232+ // Emit any notes as follow-ons.
233+ for note in diagnostic. notes {
234+ diagnoseSingle (
235+ message: note. message,
236+ severity: . note,
237+ node: note. node,
238+ position: note. position
239+ )
240+ }
241+ }
242+ }
243+
126244/// A set of queued diagnostics created by the C++ compiler and rendered
127245/// via the swift-syntax renderer.
128246struct QueuedDiagnostics {
0 commit comments