@@ -2,6 +2,124 @@ import CASTBridging
2
2
import SwiftDiagnostics
3
3
import SwiftSyntax
4
4
5
+ extension SourceManager {
6
+ private func diagnoseSingle(
7
+ message: String ,
8
+ severity: DiagnosticSeverity ,
9
+ node: some SyntaxProtocol ,
10
+ position: AbsolutePosition ,
11
+ highlights: [ Syntax ] = [ ] ,
12
+ fixItChanges: [ FixIt . Change ] = [ ]
13
+ ) {
14
+ // Map severity
15
+ let bridgedSeverity : BridgedDiagnosticSeverity
16
+ switch severity {
17
+ case . error: bridgedSeverity = . error
18
+ case . note: bridgedSeverity = . note
19
+ case . warning: bridgedSeverity = . warning
20
+ }
21
+
22
+ // Emit the diagnostic
23
+ var mutableMessage = message
24
+ let diag = mutableMessage. withUTF8 { messageBuffer in
25
+ SwiftDiagnostic_create (
26
+ cxxDiagnosticEngine, bridgedSeverity,
27
+ cxxSourceLocation ( for: node, at: position) ,
28
+ messageBuffer. baseAddress, messageBuffer. count
29
+ )
30
+ }
31
+
32
+ // Emit highlights
33
+ for highlight in highlights {
34
+ SwiftDiagnostic_highlight (
35
+ diag,
36
+ cxxSourceLocation ( for: highlight) ,
37
+ cxxSourceLocation ( for: highlight, at: highlight. endPosition)
38
+ )
39
+ }
40
+
41
+ // Emit changes for a Fix-It.
42
+ for change in fixItChanges {
43
+ let replaceStartLoc : CxxSourceLoc ?
44
+ let replaceEndLoc : CxxSourceLoc ?
45
+ var newText : String
46
+
47
+ switch change {
48
+ case . replace( let oldNode, let newNode) :
49
+ replaceStartLoc = cxxSourceLocation ( for: oldNode)
50
+ replaceEndLoc = cxxSourceLocation (
51
+ for: oldNode,
52
+ at: oldNode. endPosition
53
+ )
54
+ newText = newNode. description
55
+
56
+ case . replaceLeadingTrivia( let oldToken, let newTrivia) :
57
+ replaceStartLoc = cxxSourceLocation ( for: oldToken)
58
+ replaceEndLoc = cxxSourceLocation (
59
+ for: oldToken,
60
+ at: oldToken. positionAfterSkippingLeadingTrivia
61
+ )
62
+ newText = newTrivia. description
63
+
64
+ case . replaceTrailingTrivia( let oldToken, let newTrivia) :
65
+ replaceStartLoc = cxxSourceLocation (
66
+ for: oldToken,
67
+ at: oldToken. endPositionBeforeTrailingTrivia)
68
+ replaceEndLoc = cxxSourceLocation (
69
+ for: oldToken,
70
+ at: oldToken. endPosition
71
+ )
72
+ newText = newTrivia. description
73
+ }
74
+
75
+ newText. withUTF8 { textBuffer in
76
+ SwiftDiagnostic_fixItReplace (
77
+ diag, replaceStartLoc, replaceEndLoc,
78
+ textBuffer. baseAddress, textBuffer. count
79
+ )
80
+ }
81
+ }
82
+
83
+ SwiftDiagnostic_finish ( diag) ;
84
+ }
85
+
86
+ /// Emit a diagnostic via the C++ diagnostic engine.
87
+ func diagnose(
88
+ diagnostic: Diagnostic ,
89
+ messageSuffix: String ? = nil
90
+ ) {
91
+ // Emit the main diagnostic.
92
+ diagnoseSingle (
93
+ message: diagnostic. diagMessage. message + ( messageSuffix ?? " " ) ,
94
+ severity: diagnostic. diagMessage. severity,
95
+ node: diagnostic. node,
96
+ position: diagnostic. position,
97
+ highlights: diagnostic. highlights
98
+ )
99
+
100
+ // Emit Fix-Its.
101
+ for fixIt in diagnostic. fixIts {
102
+ diagnoseSingle (
103
+ message: fixIt. message. message,
104
+ severity: . note,
105
+ node: diagnostic. node,
106
+ position: diagnostic. position,
107
+ fixItChanges: fixIt. changes. changes
108
+ )
109
+ }
110
+
111
+ // Emit any notes as follow-ons.
112
+ for note in diagnostic. notes {
113
+ diagnoseSingle (
114
+ message: note. message,
115
+ severity: . note,
116
+ node: note. node,
117
+ position: note. position
118
+ )
119
+ }
120
+ }
121
+ }
122
+
5
123
/// A set of queued diagnostics created by the C++ compiler and rendered
6
124
/// via the swift-syntax renderer.
7
125
struct QueuedDiagnostics {
0 commit comments