@@ -123,6 +123,124 @@ func emitDiagnostic(
123
123
}
124
124
}
125
125
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
+
126
244
/// A set of queued diagnostics created by the C++ compiler and rendered
127
245
/// via the swift-syntax renderer.
128
246
struct QueuedDiagnostics {
0 commit comments