Skip to content

Commit bcaa192

Browse files
committed
[sourcekit] Attempt to provide diagnostics when compilation fails for any reason
Refactors the diagnostic code to be run whenever a compilation notification has been started and there are diagnostics available in the consumer. This allows us to capture diagnostics on all exit paths, and specifically when code-completion fails because of invalid arguments. Note: the editor.open code path still doesn't report invalid arguments because it fails before even trying to create an AST.
1 parent 6aadb64 commit bcaa192

File tree

4 files changed

+33
-23
lines changed

4 files changed

+33
-23
lines changed

test/SourceKit/CompileNotifications/arg-parsing.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@
77
// ARG_PARSE_1: {
88
// ARG_PARSE_1: key.notification: source.notification.compile-did-finish
99
// ARG_PARSE_1: key.diagnostics: [
10-
// FIXME: we should pass through the error from parsing the arguments
11-
// ARG_PARSE_1-NEXT: ]
10+
// ARG_PARSE_1: {
11+
// ARG_PARSE_1: key.filepath: "<unknown>",
12+
// ARG_PARSE_1: key.severity: source.diagnostic.severity.error,
13+
// ARG_PARSE_1: key.description: "unknown argument: '-no-such-arg'"
14+
// ARG_PARSE_1: }
15+
// ARG_PARSE_1: ]
1216
// ARG_PARSE_1: key.compileid: [[CID1]]
1317
// ARG_PARSE_1: }
1418
// ARG_PARSE_1-NOT: compile-will-start

tools/SourceKit/include/SourceKit/Support/Tracing.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define LLVM_SOURCEKIT_SUPPORT_TRACING_H
1515

1616
#include "SourceKit/Core/LLVM.h"
17+
#include "SourceKit/Core/LangSupport.h"
1718
#include "SourceKit/Support/UIdent.h"
1819
#include "swift/Basic/OptionSet.h"
1920
#include "llvm/ADT/ArrayRef.h"
@@ -91,8 +92,11 @@ void unregisterConsumer(TraceConsumer *Consumer);
9192

9293
// Class that utilizes the RAII idiom for the operations being traced
9394
class TracedOperation final {
95+
using DiagnosticProvider = std::function<void(SmallVectorImpl<DiagnosticEntryInfo> &)>;
96+
9497
OperationKind OpKind;
9598
llvm::Optional<uint64_t> OpId;
99+
llvm::Optional<DiagnosticProvider> DiagProvider;
96100
bool Enabled;
97101

98102
public:
@@ -116,13 +120,20 @@ class TracedOperation final {
116120
OpId = startOperation(OpKind, Inv, OpArgs);
117121
}
118122

119-
void finish(ArrayRef<DiagnosticEntryInfo> Diagnostics = llvm::None) {
123+
void finish() {
120124
if (OpId.hasValue()) {
125+
SmallVector<DiagnosticEntryInfo, 8> Diagnostics;
126+
if (DiagProvider.hasValue())
127+
(*DiagProvider)(Diagnostics);
121128
operationFinished(OpId.getValue(), OpKind, Diagnostics);
122129
OpId.reset();
123130
}
124131
}
125132

133+
void setDiagnosticProvider(DiagnosticProvider &&DiagProvider) {
134+
assert(!this->DiagProvider.hasValue());
135+
this->DiagProvider = std::move(DiagProvider);
136+
}
126137
};
127138

128139
} // namespace sourcekitd

tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -794,24 +794,27 @@ ASTUnitRef ASTProducer::createASTUnit(SwiftASTManager::Implementation &MgrImpl,
794794
for (auto &Content : Contents)
795795
Stamps.push_back(Content.Stamp);
796796

797-
trace::TracedOperation TracedOp(trace::OperationKind::PerformSema);
798-
trace::SwiftInvocation TraceInfo;
799-
if (TracedOp.enabled()) {
800-
trace::initTraceInfo(TraceInfo, InvokRef->Impl.Opts.PrimaryFile,
801-
InvokRef->Impl.Opts.Args);
802-
}
803-
804797
ASTUnitRef ASTRef = new ASTUnit(++ASTUnitGeneration, MgrImpl.Stats);
805798
for (auto &Content : Contents) {
806799
if (Content.Snapshot)
807800
ASTRef->Impl.Snapshots.push_back(Content.Snapshot);
808801
}
809802
auto &CompIns = ASTRef->Impl.CompInst;
810803
auto &Consumer = ASTRef->Impl.CollectDiagConsumer;
811-
812804
// Display diagnostics to stderr.
813805
CompIns.addDiagnosticConsumer(&Consumer);
814806

807+
trace::TracedOperation TracedOp(trace::OperationKind::PerformSema);
808+
trace::SwiftInvocation TraceInfo;
809+
if (TracedOp.enabled()) {
810+
trace::initTraceInfo(TraceInfo, InvokRef->Impl.Opts.PrimaryFile,
811+
InvokRef->Impl.Opts.Args);
812+
TracedOp.setDiagnosticProvider(
813+
[&Consumer](SmallVectorImpl<DiagnosticEntryInfo> &diags) {
814+
Consumer.getAllDiagnostics(diags);
815+
});
816+
}
817+
815818
CompilerInvocation Invocation;
816819
InvokRef->Impl.Opts.applyToSubstitutingInputs(
817820
Invocation, convertFileContentsToInputs(Contents));
@@ -875,12 +878,6 @@ ASTUnitRef ASTProducer::createASTUnit(SwiftASTManager::Implementation &MgrImpl,
875878
// TypeResolver is set before.
876879
ASTRef->Impl.TypeResolver = createLazyResolver(CompIns.getASTContext());
877880

878-
if (TracedOp.enabled()) {
879-
SmallVector<DiagnosticEntryInfo, 8> Diagnostics;
880-
Consumer.getAllDiagnostics(Diagnostics);
881-
TracedOp.finish(Diagnostics);
882-
}
883-
884881
return ASTRef;
885882
}
886883

tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ static bool swiftCodeCompleteImpl(SwiftLangSupport &Lang,
136136
CI.addDiagnosticConsumer(&TraceDiags);
137137
trace::SwiftInvocation SwiftArgs;
138138
trace::initTraceInfo(SwiftArgs, InputFile->getBufferIdentifier(), Args);
139+
TracedOp.setDiagnosticProvider(
140+
[&TraceDiags](SmallVectorImpl<DiagnosticEntryInfo> &diags) {
141+
TraceDiags.getAllDiagnostics(diags);
142+
});
139143
TracedOp.start(SwiftArgs,
140144
{std::make_pair("OriginalOffset", std::to_string(Offset)),
141145
std::make_pair("Offset",
@@ -191,12 +195,6 @@ static bool swiftCodeCompleteImpl(SwiftLangSupport &Lang,
191195
CI.performSema();
192196
SwiftConsumer.clearContext();
193197

194-
if (TracedOp.enabled()) {
195-
SmallVector<DiagnosticEntryInfo, 8> Diagnostics;
196-
TraceDiags.getAllDiagnostics(Diagnostics);
197-
TracedOp.finish(Diagnostics);
198-
}
199-
200198
return true;
201199
}
202200

0 commit comments

Comments
 (0)