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,14 +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
- clearLastDiag ();
86
- return ;
87
- }
88
89
bool IsNote = (Kind == DiagnosticKind::Note);
89
90
90
91
if (IsNote && !haveLastDiag ())
@@ -107,9 +108,12 @@ void EditorDiagConsumer::handleDiagnostic(
107
108
}
108
109
SKInfo.Description = Text.str ();
109
110
110
- unsigned BufferID = SM.findBufferContainingLoc (Loc);
111
+ Optional<unsigned > BufferIDOpt;
112
+ if (Loc.isValid ()) {
113
+ BufferIDOpt = SM.findBufferContainingLoc (Loc);
114
+ }
111
115
112
- if (!isInputBufferID (BufferID )) {
116
+ if (BufferIDOpt && !isInputBufferID (*BufferIDOpt )) {
113
117
if (Info.ID == diag::error_from_clang.ID ||
114
118
Info.ID == diag::warning_from_clang.ID ||
115
119
Info.ID == diag::note_from_clang.ID ||
@@ -125,7 +129,7 @@ void EditorDiagConsumer::handleDiagnostic(
125
129
// buffer identifier and append it to the diagnostic message.
126
130
auto &LastDiag = getLastDiag ();
127
131
SKInfo.Description += " (" ;
128
- SKInfo.Description += SM.getIdentifierForBuffer (BufferID );
132
+ SKInfo.Description += SM.getIdentifierForBuffer (*BufferIDOpt );
129
133
SKInfo.Description += " )" ;
130
134
SKInfo.Offset = LastDiag.Offset ;
131
135
SKInfo.Line = LastDiag.Line ;
@@ -136,35 +140,39 @@ void EditorDiagConsumer::handleDiagnostic(
136
140
}
137
141
}
138
142
139
- SKInfo.Offset = SM.getLocOffsetInBuffer (Loc, BufferID);
140
- std::tie (SKInfo.Line , SKInfo.Column ) = SM.getLineAndColumn (Loc, BufferID);
141
- SKInfo.Filename = SM.getIdentifierForBuffer (BufferID);
143
+ if (BufferIDOpt.hasValue ()) {
144
+ unsigned BufferID = *BufferIDOpt;
142
145
143
- for (auto R : Info.Ranges ) {
144
- if (R.isInvalid () || SM.findBufferContainingLoc (R.getStart ()) != BufferID)
145
- continue ;
146
- unsigned Offset = SM.getLocOffsetInBuffer (R.getStart (), BufferID);
147
- unsigned Length = R.getByteLength ();
148
- SKInfo.Ranges .push_back ({ Offset, Length });
149
- }
146
+ SKInfo.Offset = SM.getLocOffsetInBuffer (Loc, BufferID);
147
+ std::tie (SKInfo.Line , SKInfo.Column ) = SM.getLineAndColumn (Loc, BufferID);
148
+ SKInfo.Filename = SM.getIdentifierForBuffer (BufferID);
150
149
151
- for (auto F : Info.FixIts ) {
152
- if (F.getRange ().isInvalid () ||
153
- SM.findBufferContainingLoc (F.getRange ().getStart ()) != BufferID)
154
- continue ;
155
- unsigned Offset = SM.getLocOffsetInBuffer (F.getRange ().getStart (),
156
- BufferID);
157
- unsigned Length = F.getRange ().getByteLength ();
158
- 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>" ;
159
169
}
160
170
161
171
if (IsNote) {
162
172
getLastDiag ().Notes .push_back (std::move (SKInfo));
163
173
return ;
164
174
}
165
175
166
- DiagnosticsTy &Diagnostics = BufferDiagnostics[BufferID];
167
-
168
176
switch (Kind) {
169
177
case DiagnosticKind::Error:
170
178
SKInfo.Severity = DiagnosticSeverityKind::Error;
@@ -177,6 +185,15 @@ void EditorDiagConsumer::handleDiagnostic(
177
185
llvm_unreachable (" already covered" );
178
186
}
179
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
+
180
197
if (Diagnostics.empty () || Diagnostics.back ().Offset <= SKInfo.Offset ) {
181
198
Diagnostics.push_back (std::move (SKInfo));
182
199
LastDiagBufferID = BufferID;
0 commit comments