Skip to content

[4.2] [sourcekit] Send compile notifications when argument parsing files #16922

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions test/SourceKit/CompileNotifications/arg-parsing.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// RUN: not %sourcekitd-test -req=track-compiles == -req=complete %s -offset=0 -- %s -no-such-arg | %FileCheck %s -check-prefix=ARG_PARSE_1
// RUN: %sourcekitd-test -req=track-compiles == -req=sema %s -print-raw-response -- %s -no-such-arg | %FileCheck %s -check-prefix=ARG_PARSE_1
// RUN: %sourcekitd-test -req=track-compiles == -req=cursor -offset=0 %s -- %s -no-such-arg | %FileCheck %s -check-prefix=ARG_PARSE_1
// ARG_PARSE_1: {
// ARG_PARSE_1: key.notification: source.notification.compile-will-start
// ARG_PARSE_1: key.compileid: [[CID1:".*"]]
// ARG_PARSE_1: key.compilerargs-string: "{{.*}}.swift -no-such-arg"
// ARG_PARSE_1: }
// ARG_PARSE_1: {
// ARG_PARSE_1: key.notification: source.notification.compile-did-finish
// ARG_PARSE_1: key.diagnostics: [
// ARG_PARSE_1: {
// ARG_PARSE_1: key.filepath: "<unknown>",
// ARG_PARSE_1: key.severity: source.diagnostic.severity.error,
// ARG_PARSE_1: key.description: "unknown argument: '-no-such-arg'"
// ARG_PARSE_1: }
// ARG_PARSE_1: ]
// ARG_PARSE_1: key.compileid: [[CID1]]
// ARG_PARSE_1: }
// ARG_PARSE_1-NOT: compile-will-start
// ARG_PARSE_1-NOT: compile-did-finish

// RUN: not %sourcekitd-test -req=track-compiles == -req=complete %s -offset=0 | %FileCheck %s -check-prefix=ARG_PARSE_2
// RUN: %sourcekitd-test -req=track-compiles == -req=sema %s -print-raw-response | %FileCheck %s -check-prefix=ARG_PARSE_2
// ARG_PARSE_2: {
// ARG_PARSE_2: key.notification: source.notification.compile-will-start
// ARG_PARSE_2: key.compileid: [[CID1:".*"]]
// ARG_PARSE_2: }
// ARG_PARSE_2: {
// ARG_PARSE_2: key.notification: source.notification.compile-did-finish
// ARG_PARSE_2: key.diagnostics: [
// ARG_PARSE_2: {
// ARG_PARSE_2: key.filepath: "<unknown>",
// ARG_PARSE_2: key.severity: source.diagnostic.severity.error,
// ARG_PARSE_2: key.description: "no input files"
// ARG_PARSE_2: }
// ARG_PARSE_2: ]
// ARG_PARSE_2: key.compileid: [[CID1]]
// ARG_PARSE_2: }
// ARG_PARSE_2-NOT: compile-will-start
// ARG_PARSE_2-NOT: compile-did-finish
13 changes: 12 additions & 1 deletion tools/SourceKit/include/SourceKit/Support/Tracing.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define LLVM_SOURCEKIT_SUPPORT_TRACING_H

#include "SourceKit/Core/LLVM.h"
#include "SourceKit/Core/LangSupport.h"
#include "SourceKit/Support/UIdent.h"
#include "swift/Basic/OptionSet.h"
#include "llvm/ADT/ArrayRef.h"
Expand Down Expand Up @@ -91,8 +92,11 @@ void unregisterConsumer(TraceConsumer *Consumer);

// Class that utilizes the RAII idiom for the operations being traced
class TracedOperation final {
using DiagnosticProvider = std::function<void(SmallVectorImpl<DiagnosticEntryInfo> &)>;

OperationKind OpKind;
llvm::Optional<uint64_t> OpId;
llvm::Optional<DiagnosticProvider> DiagProvider;
bool Enabled;

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

void finish(ArrayRef<DiagnosticEntryInfo> Diagnostics = llvm::None) {
void finish() {
if (OpId.hasValue()) {
SmallVector<DiagnosticEntryInfo, 8> Diagnostics;
if (DiagProvider.hasValue())
(*DiagProvider)(Diagnostics);
operationFinished(OpId.getValue(), OpKind, Diagnostics);
OpId.reset();
}
}

void setDiagnosticProvider(DiagnosticProvider &&DiagProvider) {
assert(!this->DiagProvider.hasValue());
this->DiagProvider = std::move(DiagProvider);
}
};

} // namespace sourcekitd
Expand Down
45 changes: 30 additions & 15 deletions tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,8 +512,26 @@ SwiftInvocationRef
SwiftASTManager::getInvocation(ArrayRef<const char *> OrigArgs,
StringRef PrimaryFile,
std::string &Error) {

DiagnosticEngine Diags(Impl.SourceMgr);
EditorDiagConsumer CollectDiagConsumer;
Diags.addConsumer(CollectDiagConsumer);

CompilerInvocation CompInvok;
if (initCompilerInvocation(CompInvok, OrigArgs, PrimaryFile, Error)) {
if (initCompilerInvocation(CompInvok, OrigArgs, Diags, PrimaryFile, Error)) {
// We create a traced operation here to represent the failure to parse
// arguments since we cannot reach `createAST` where that would normally
// happen.
trace::TracedOperation TracedOp(trace::OperationKind::PerformSema);
if (TracedOp.enabled()) {
trace::SwiftInvocation TraceInfo;
trace::initTraceInfo(TraceInfo, PrimaryFile, OrigArgs);
TracedOp.setDiagnosticProvider(
[&CollectDiagConsumer](SmallVectorImpl<DiagnosticEntryInfo> &diags) {
CollectDiagConsumer.getAllDiagnostics(diags);
});
TracedOp.start(TraceInfo);
}
return nullptr;
}

Expand Down Expand Up @@ -794,24 +812,27 @@ ASTUnitRef ASTProducer::createASTUnit(SwiftASTManager::Implementation &MgrImpl,
for (auto &Content : Contents)
Stamps.push_back(Content.Stamp);

trace::TracedOperation TracedOp(trace::OperationKind::PerformSema);
trace::SwiftInvocation TraceInfo;
if (TracedOp.enabled()) {
trace::initTraceInfo(TraceInfo, InvokRef->Impl.Opts.PrimaryFile,
InvokRef->Impl.Opts.Args);
}

ASTUnitRef ASTRef = new ASTUnit(++ASTUnitGeneration, MgrImpl.Stats);
for (auto &Content : Contents) {
if (Content.Snapshot)
ASTRef->Impl.Snapshots.push_back(Content.Snapshot);
}
auto &CompIns = ASTRef->Impl.CompInst;
auto &Consumer = ASTRef->Impl.CollectDiagConsumer;

// Display diagnostics to stderr.
CompIns.addDiagnosticConsumer(&Consumer);

trace::TracedOperation TracedOp(trace::OperationKind::PerformSema);
trace::SwiftInvocation TraceInfo;
if (TracedOp.enabled()) {
trace::initTraceInfo(TraceInfo, InvokRef->Impl.Opts.PrimaryFile,
InvokRef->Impl.Opts.Args);
TracedOp.setDiagnosticProvider(
[&Consumer](SmallVectorImpl<DiagnosticEntryInfo> &diags) {
Consumer.getAllDiagnostics(diags);
});
}

CompilerInvocation Invocation;
InvokRef->Impl.Opts.applyToSubstitutingInputs(
Invocation, convertFileContentsToInputs(Contents));
Expand Down Expand Up @@ -875,12 +896,6 @@ ASTUnitRef ASTProducer::createASTUnit(SwiftASTManager::Implementation &MgrImpl,
// TypeResolver is set before.
ASTRef->Impl.TypeResolver = createLazyResolver(CompIns.getASTContext());

if (TracedOp.enabled()) {
SmallVector<DiagnosticEntryInfo, 8> Diagnostics;
Consumer.getAllDiagnostics(Diagnostics);
TracedOp.finish(Diagnostics);
}

return ASTRef;
}

Expand Down
37 changes: 16 additions & 21 deletions tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ static bool swiftCodeCompleteImpl(SwiftLangSupport &Lang,
UnresolvedInputFile->getBuffer(),
Lang.resolvePathSymlinks(UnresolvedInputFile->getBufferIdentifier()));

auto origBuffSize = InputFile->getBufferSize();
unsigned CodeCompletionOffset = Offset;
if (CodeCompletionOffset > origBuffSize) {
CodeCompletionOffset = origBuffSize;
}

CompilerInstance CI;
// Display diagnostics to stderr.
PrintingDiagnosticConsumer PrintDiags;
Expand All @@ -128,6 +134,16 @@ static bool swiftCodeCompleteImpl(SwiftLangSupport &Lang,
trace::TracedOperation TracedOp(trace::OperationKind::CodeCompletion);
if (TracedOp.enabled()) {
CI.addDiagnosticConsumer(&TraceDiags);
trace::SwiftInvocation SwiftArgs;
trace::initTraceInfo(SwiftArgs, InputFile->getBufferIdentifier(), Args);
TracedOp.setDiagnosticProvider(
[&TraceDiags](SmallVectorImpl<DiagnosticEntryInfo> &diags) {
TraceDiags.getAllDiagnostics(diags);
});
TracedOp.start(SwiftArgs,
{std::make_pair("OriginalOffset", std::to_string(Offset)),
std::make_pair("Offset",
std::to_string(CodeCompletionOffset))});
}

CompilerInvocation Invocation;
Expand All @@ -141,12 +157,6 @@ static bool swiftCodeCompleteImpl(SwiftLangSupport &Lang,
return false;
}

auto origBuffSize = InputFile->getBufferSize();
unsigned CodeCompletionOffset = Offset;
if (CodeCompletionOffset > origBuffSize) {
CodeCompletionOffset = origBuffSize;
}

const char *Position = InputFile->getBufferStart() + CodeCompletionOffset;
std::unique_ptr<llvm::WritableMemoryBuffer> NewBuffer =
llvm::WritableMemoryBuffer::getNewUninitMemBuffer(
Expand Down Expand Up @@ -178,28 +188,13 @@ static bool swiftCodeCompleteImpl(SwiftLangSupport &Lang,
return true;
}

if (TracedOp.enabled()) {
trace::SwiftInvocation SwiftArgs;
trace::initTraceInfo(SwiftArgs, InputFile->getBufferIdentifier(), Args);
TracedOp.start(SwiftArgs,
{std::make_pair("OriginalOffset", std::to_string(Offset)),
std::make_pair("Offset",
std::to_string(CodeCompletionOffset))});
}

CloseClangModuleFiles scopedCloseFiles(
*CI.getASTContext().getClangModuleLoader());
SwiftConsumer.setContext(&CI.getASTContext(), &Invocation,
&CompletionContext);
CI.performSema();
SwiftConsumer.clearContext();

if (TracedOp.enabled()) {
SmallVector<DiagnosticEntryInfo, 8> Diagnostics;
TraceDiags.getAllDiagnostics(Diagnostics);
TracedOp.finish(Diagnostics);
}

return true;
}

Expand Down
17 changes: 9 additions & 8 deletions tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ struct NotificationBuffer {
};
static NotificationBuffer notificationBuffer;

static void printBufferedNotifications() {
notificationBuffer.handleNotifications([](sourcekitd_response_t note) {
sourcekitd_response_description_dump_filedesc(note, STDOUT_FILENO);
});
}

static int skt_main(int argc, const char **argv);

int main(int argc, const char **argv) {
Expand Down Expand Up @@ -173,12 +179,6 @@ static int skt_main(int argc, const char **argv) {
#define REFACTORING(KIND, NAME, ID) Kind##Refactoring##KIND = sourcekitd_uid_get_from_cstr("source.refactoring.kind."#ID);
#include "swift/IDE/RefactoringKinds.def"

auto printBufferedNotifications = []{
notificationBuffer.handleNotifications([](sourcekitd_response_t note) {
sourcekitd_response_description_dump_filedesc(note, STDOUT_FILENO);
});
};

// A test invocation may initialize the options to be used for subsequent
// invocations.
TestOptions InitOpts;
Expand All @@ -196,7 +196,6 @@ static int skt_main(int argc, const char **argv) {
sourcekitd_shutdown();
return ret;
}
printBufferedNotifications();
Args = Args.slice(i+1);
}

Expand Down Expand Up @@ -343,7 +342,9 @@ static int handleTestInvocation(ArrayRef<const char *> Args,

assert(Opts.repeatRequest >= 1);
for (unsigned i = 0; i < Opts.repeatRequest; ++i) {
if (int ret = handleTestInvocation(Opts, InitOpts)) {
int ret = handleTestInvocation(Opts, InitOpts);
printBufferedNotifications();
if (ret) {
return ret;
}
}
Expand Down