25
25
#include " swift/AST/ASTWalker.h"
26
26
#include " swift/AST/DiagnosticsClangImporter.h"
27
27
#include " swift/AST/DiagnosticsParse.h"
28
+ #include " swift/AST/DiagnosticsFrontend.h"
28
29
#include " swift/Basic/SourceManager.h"
29
30
#include " swift/Demangling/ManglingUtils.h"
30
31
#include " swift/Frontend/Frontend.h"
@@ -59,6 +60,9 @@ static std::vector<unsigned> getSortedBufferIDs(
59
60
60
61
void EditorDiagConsumer::getAllDiagnostics (
61
62
SmallVectorImpl<DiagnosticEntryInfo> &Result) {
63
+
64
+ Result.append (InvalidLocDiagnostics.begin (), InvalidLocDiagnostics.end ());
65
+
62
66
// Note: we cannot reuse InputBufIds because there may be diagnostics outside
63
67
// the inputs. Instead, sort the extant buffers.
64
68
auto bufferIDs = getSortedBufferIDs (BufferDiagnostics);
@@ -77,16 +81,11 @@ void EditorDiagConsumer::handleDiagnostic(
77
81
HadAnyError = true ;
78
82
}
79
83
80
- // Filter out lexer errors for placeholders.
81
- if (Info.ID == diag::lex_editor_placeholder.ID )
84
+ // Filter out benign diagnostics for editing.
85
+ if (Info.ID == diag::lex_editor_placeholder.ID ||
86
+ Info.ID == diag::error_doing_code_completion.ID )
82
87
return ;
83
88
84
- if (Loc.isInvalid ()) {
85
- if (Kind == DiagnosticKind::Error)
86
- HadInvalidLocError = true ;
87
- clearLastDiag ();
88
- return ;
89
- }
90
89
bool IsNote = (Kind == DiagnosticKind::Note);
91
90
92
91
if (IsNote && !haveLastDiag ())
@@ -109,9 +108,12 @@ void EditorDiagConsumer::handleDiagnostic(
109
108
}
110
109
SKInfo.Description = Text.str ();
111
110
112
- unsigned BufferID = SM.findBufferContainingLoc (Loc);
111
+ Optional<unsigned > BufferIDOpt;
112
+ if (Loc.isValid ()) {
113
+ BufferIDOpt = SM.findBufferContainingLoc (Loc);
114
+ }
113
115
114
- if (!isInputBufferID (BufferID )) {
116
+ if (BufferIDOpt && !isInputBufferID (*BufferIDOpt )) {
115
117
if (Info.ID == diag::error_from_clang.ID ||
116
118
Info.ID == diag::warning_from_clang.ID ||
117
119
Info.ID == diag::note_from_clang.ID ||
@@ -127,7 +129,7 @@ void EditorDiagConsumer::handleDiagnostic(
127
129
// buffer identifier and append it to the diagnostic message.
128
130
auto &LastDiag = getLastDiag ();
129
131
SKInfo.Description += " (" ;
130
- SKInfo.Description += SM.getIdentifierForBuffer (BufferID );
132
+ SKInfo.Description += SM.getIdentifierForBuffer (*BufferIDOpt );
131
133
SKInfo.Description += " )" ;
132
134
SKInfo.Offset = LastDiag.Offset ;
133
135
SKInfo.Line = LastDiag.Line ;
@@ -138,35 +140,39 @@ void EditorDiagConsumer::handleDiagnostic(
138
140
}
139
141
}
140
142
141
- SKInfo.Offset = SM.getLocOffsetInBuffer (Loc, BufferID);
142
- std::tie (SKInfo.Line , SKInfo.Column ) = SM.getLineAndColumn (Loc, BufferID);
143
- SKInfo.Filename = SM.getIdentifierForBuffer (BufferID);
143
+ if (BufferIDOpt.hasValue ()) {
144
+ unsigned BufferID = *BufferIDOpt;
144
145
145
- for (auto R : Info.Ranges ) {
146
- if (R.isInvalid () || SM.findBufferContainingLoc (R.getStart ()) != BufferID)
147
- continue ;
148
- unsigned Offset = SM.getLocOffsetInBuffer (R.getStart (), BufferID);
149
- unsigned Length = R.getByteLength ();
150
- SKInfo.Ranges .push_back ({ Offset, Length });
151
- }
146
+ SKInfo.Offset = SM.getLocOffsetInBuffer (Loc, BufferID);
147
+ std::tie (SKInfo.Line , SKInfo.Column ) = SM.getLineAndColumn (Loc, BufferID);
148
+ SKInfo.Filename = SM.getIdentifierForBuffer (BufferID);
152
149
153
- for (auto F : Info.FixIts ) {
154
- if (F.getRange ().isInvalid () ||
155
- SM.findBufferContainingLoc (F.getRange ().getStart ()) != BufferID)
156
- continue ;
157
- unsigned Offset = SM.getLocOffsetInBuffer (F.getRange ().getStart (),
158
- BufferID);
159
- unsigned Length = F.getRange ().getByteLength ();
160
- SKInfo.Fixits .push_back ({ Offset, Length, F.getText () });
150
+ for (auto R : Info.Ranges ) {
151
+ if (R.isInvalid () || SM.findBufferContainingLoc (R.getStart ()) != BufferID)
152
+ continue ;
153
+ unsigned Offset = SM.getLocOffsetInBuffer (R.getStart (), BufferID);
154
+ unsigned Length = R.getByteLength ();
155
+ SKInfo.Ranges .push_back ({Offset, Length});
156
+ }
157
+
158
+ for (auto F : Info.FixIts ) {
159
+ if (F.getRange ().isInvalid () ||
160
+ SM.findBufferContainingLoc (F.getRange ().getStart ()) != BufferID)
161
+ continue ;
162
+ unsigned Offset =
163
+ SM.getLocOffsetInBuffer (F.getRange ().getStart (), BufferID);
164
+ unsigned Length = F.getRange ().getByteLength ();
165
+ SKInfo.Fixits .push_back ({Offset, Length, F.getText ()});
166
+ }
167
+ } else {
168
+ SKInfo.Filename = " <unknown>" ;
161
169
}
162
170
163
171
if (IsNote) {
164
172
getLastDiag ().Notes .push_back (std::move (SKInfo));
165
173
return ;
166
174
}
167
175
168
- DiagnosticsTy &Diagnostics = BufferDiagnostics[BufferID];
169
-
170
176
switch (Kind) {
171
177
case DiagnosticKind::Error:
172
178
SKInfo.Severity = DiagnosticSeverityKind::Error;
@@ -179,6 +185,15 @@ void EditorDiagConsumer::handleDiagnostic(
179
185
llvm_unreachable (" already covered" );
180
186
}
181
187
188
+ if (!BufferIDOpt) {
189
+ InvalidLocDiagnostics.push_back (std::move (SKInfo));
190
+ clearLastDiag ();
191
+ return ;
192
+ }
193
+
194
+ unsigned BufferID = *BufferIDOpt;
195
+ DiagnosticsTy &Diagnostics = BufferDiagnostics[BufferID];
196
+
182
197
if (Diagnostics.empty () || Diagnostics.back ().Offset <= SKInfo.Offset ) {
183
198
Diagnostics.push_back (std::move (SKInfo));
184
199
LastDiagBufferID = BufferID;
0 commit comments