Merge remote-tracking branch 'origin/master' into master-next

This commit is contained in:
swift-ci
2018-03-30 17:29:07 -07:00
11 changed files with 155 additions and 68 deletions

View File

@@ -0,0 +1 @@
func 1() {}

View File

@@ -0,0 +1,2 @@
_ = unknown
// code-completion at 2:1

View File

@@ -0,0 +1,45 @@
// RUN: %sourcekitd-test -req=track-compiles == -req=sema %s -- %s | %FileCheck %s -check-prefix=NODIAGS
// NODIAGS: key.notification: source.notification.compile-did-finish
// NODIAGS-NEXT: key.diagnostics: [
// NODIAGS-NEXT: ]
// RUN: %sourcekitd-test -req=track-compiles == -req=sema %S/Inputs/parse-error.swift -- %S/Inputs/parse-error.swift | %FileCheck %s -check-prefix=PARSE
// PARSE: key.notification: source.notification.compile-did-finish
// PARSE-NEXT: key.diagnostics: [
// PARSE-NEXT: {
// PARSE-NEXT: key.line: 1
// PARSE-NEXT: key.column: 6
// PARSE-NEXT: key.filepath: "{{.*}}parse-error.swift"
// PARSE-NEXT: key.severity: source.diagnostic.severity.error
// PARSE-NEXT: key.description: "function name
// PARSE-NEXT: }
// PARSE-NEXT: ]
// Diagnostic from other file.
// RUN: %sourcekitd-test -req=track-compiles == -req=sema %s -- %s %S/Inputs/parse-error.swift | %FileCheck %s -check-prefix=PARSE
// RUN: %sourcekitd-test -req=track-compiles == -req=sema %S/Inputs/sema-error.swift -- %S/Inputs/sema-error.swift | %FileCheck %s -check-prefix=SEMA
// SEMA: key.notification: source.notification.compile-did-finish
// SEMA-NEXT: key.diagnostics: [
// SEMA-NEXT: {
// SEMA-NEXT: key.line: 1
// SEMA-NEXT: key.column: 5
// SEMA-NEXT: key.filepath: "{{.*}}sema-error.swift"
// SEMA-NEXT: key.severity: source.diagnostic.severity.error
// SEMA-NEXT: key.description: "use of
// SEMA-NEXT: key.ranges: [
// RUN: %sourcekitd-test -req=track-compiles == -req=sema %s -- %s -Xcc -include -Xcc /doesnotexist | %FileCheck %s -check-prefix=CLANG_IMPORTER
// CLANG_IMPORTER: key.notification: source.notification.compile-did-finish,
// CLANG_IMPORTER-NEXT: key.diagnostics: [
// CLANG_IMPORTER-NEXT: {
// CLANG_IMPORTER-NEXT: key.line:
// CLANG_IMPORTER-NEXT: key.column:
// CLANG_IMPORTER-NEXT: key.filepath: "<{{.*}}>"
// CLANG_IMPORTER-NEXT: key.severity: source.diagnostic.severity.error,
// CLANG_IMPORTER-NEXT: key.description: {{.*}}not found
// Note: we're missing the "compiler is in code completion mode" diagnostic,
// which is probably just as well.
// RUN: %sourcekitd-test -req=track-compiles == -req=complete -offset=0 %s -- %s | %FileCheck %s -check-prefix=NODIAGS
// RUN: %sourcekitd-test -req=track-compiles == -req=complete -pos=2:1 %S/Inputs/sema-error.swift -- %S/Inputs/sema-error.swift | %FileCheck %s -check-prefix=SEMA

View File

@@ -13,13 +13,17 @@
#ifndef LLVM_SOURCEKIT_SUPPORT_TRACING_H
#define LLVM_SOURCEKIT_SUPPORT_TRACING_H
#include "SourceKit/Core/LLVM.h"
#include "SourceKit/Support/UIdent.h"
#include "swift/Basic/OptionSet.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include <vector>
namespace SourceKit {
struct DiagnosticEntryInfo;
namespace trace {
struct SwiftArguments {
@@ -76,7 +80,8 @@ public:
const StringPairs &OpArgs) = 0;
// Operation previously started with startXXX has finished
virtual void operationFinished(uint64_t OpId, OperationKind OpKind) = 0;
virtual void operationFinished(uint64_t OpId, OperationKind OpKind,
ArrayRef<DiagnosticEntryInfo> Diagnostics) = 0;
/// Returns the set of operations this consumer is interested in.
///
@@ -99,7 +104,8 @@ uint64_t startOperation(OperationKind OpKind,
const StringPairs &OpArgs = StringPairs());
// Operation previously started with startXXX has finished
void operationFinished(uint64_t OpId, OperationKind OpKind);
void operationFinished(uint64_t OpId, OperationKind OpKind,
ArrayRef<DiagnosticEntryInfo> Diagnostics);
// Register trace consumer.
void registerConsumer(TraceConsumer *Consumer);
@@ -134,9 +140,9 @@ public:
OpId = startOperation(OpKind, Inv, OpArgs);
}
void finish() {
void finish(ArrayRef<DiagnosticEntryInfo> Diagnostics = llvm::None) {
if (OpId.hasValue()) {
operationFinished(OpId.getValue(), OpKind);
operationFinished(OpId.getValue(), OpKind, Diagnostics);
OpId.reset();
}
}

View File

@@ -54,11 +54,12 @@ uint64_t trace::startOperation(trace::OperationKind OpKind,
}
// Operation previously started with startXXX has finished
void trace::operationFinished(uint64_t OpId, trace::OperationKind OpKind) {
void trace::operationFinished(uint64_t OpId, trace::OperationKind OpKind,
ArrayRef<DiagnosticEntryInfo> Diagnostics) {
if (trace::anyEnabled()) {
llvm::sys::ScopedLock L(consumersLock);
for (auto *consumer : consumers) {
consumer->operationFinished(OpId, OpKind);
consumer->operationFinished(OpId, OpKind, Diagnostics);
}
}
}

View File

@@ -878,6 +878,12 @@ 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;
}

View File

@@ -13,6 +13,7 @@
#include "CodeCompletionOrganizer.h"
#include "SwiftASTManager.h"
#include "SwiftLangSupport.h"
#include "SwiftEditorDiagConsumer.h"
#include "SourceKit/Support/Logging.h"
#include "SourceKit/Support/UIdent.h"
@@ -138,6 +139,12 @@ static bool swiftCodeCompleteImpl(SwiftLangSupport &Lang,
PrintingDiagnosticConsumer PrintDiags;
CI.addDiagnosticConsumer(&PrintDiags);
EditorDiagConsumer TraceDiags;
trace::TracedOperation TracedOp(trace::OperationKind::CodeCompletion);
if (TracedOp.enabled()) {
CI.addDiagnosticConsumer(&TraceDiags);
}
CompilerInvocation Invocation;
bool Failed = Lang.getASTManager().initCompilerInvocation(
Invocation, Args, CI.getDiags(), InputFile->getBufferIdentifier(), Error);
@@ -188,8 +195,6 @@ static bool swiftCodeCompleteImpl(SwiftLangSupport &Lang,
TracedInit.finish();
trace::TracedOperation TracedOp(trace::OperationKind::CodeCompletion);
if (TracedOp.enabled()) {
trace::SwiftInvocation SwiftArgs;
trace::initTraceInfo(SwiftArgs, InputFile->getBufferIdentifier(), Args);
@@ -215,6 +220,13 @@ static bool swiftCodeCompleteImpl(SwiftLangSupport &Lang,
&CompletionContext);
CI.performSema();
SwiftConsumer.clearContext();
if (TracedOp.enabled()) {
SmallVector<DiagnosticEntryInfo, 8> Diagnostics;
TraceDiags.getAllDiagnostics(Diagnostics);
TracedOp.finish(Diagnostics);
}
return true;
}

View File

@@ -46,6 +46,28 @@ using namespace SourceKit;
using namespace swift;
using namespace ide;
static std::vector<unsigned> getSortedBufferIDs(
const llvm::DenseMap<unsigned, std::vector<DiagnosticEntryInfo>> &Map) {
std::vector<unsigned> bufferIDs;
bufferIDs.reserve(Map.size());
for (auto I = Map.begin(), E = Map.end(); I != E; ++I) {
bufferIDs.push_back(I->getFirst());
}
llvm::array_pod_sort(bufferIDs.begin(), bufferIDs.end());
return bufferIDs;
}
void EditorDiagConsumer::getAllDiagnostics(
SmallVectorImpl<DiagnosticEntryInfo> &Result) {
// Note: we cannot reuse InputBufIds because there may be diagnostics outside
// the inputs. Instead, sort the extant buffers.
auto bufferIDs = getSortedBufferIDs(BufferDiagnostics);
for (unsigned bufferID : bufferIDs) {
const auto &diags = BufferDiagnostics[bufferID];
Result.append(diags.begin(), diags.end());
}
}
void EditorDiagConsumer::handleDiagnostic(
SourceManager &SM, SourceLoc Loc, DiagnosticKind Kind,
StringRef FormatString, ArrayRef<DiagnosticArgument> FormatArgs,
@@ -92,15 +114,10 @@ void EditorDiagConsumer::handleDiagnostic(
if (!isInputBufferID(BufferID)) {
if (Info.ID == diag::error_from_clang.ID ||
Info.ID == diag::warning_from_clang.ID ||
Info.ID == diag::note_from_clang.ID) {
Info.ID == diag::note_from_clang.ID ||
!IsNote) {
// Handle it as other diagnostics.
} else {
if (!IsNote) {
LOG_WARN_FUNC("got swift diagnostic not pointing at input file, "
"buffer name: " << SM.getIdentifierForBuffer(BufferID));
return;
}
// FIXME: This is a note pointing to a synthesized declaration buffer for
// a declaration coming from a module.
// We should include the Decl* in the DiagnosticInfo and have a way for

View File

@@ -62,6 +62,8 @@ public:
return Diags;
}
void getAllDiagnostics(SmallVectorImpl<DiagnosticEntryInfo> &Result);
bool hadErrorWithInvalidLoc() const { return HadInvalidLocError; }
bool hadAnyError() const { return HadAnyError; }

View File

@@ -98,7 +98,9 @@ public:
const StringPairs &OpArgs) override;
// Operation previously started with startXXX has finished
void operationFinished(uint64_t OpId, OperationKind OpKind) override;
void operationFinished(
uint64_t OpId, OperationKind OpKind,
ArrayRef<SourceKit::DiagnosticEntryInfo> Diagnostics) override;
};
// Trace start of SourceKit operation
@@ -117,7 +119,9 @@ void XpcTraceConsumer::operationStarted(uint64_t OpId,
}
// Operation previously started with startXXX has finished
void XpcTraceConsumer::operationFinished(uint64_t OpId, OperationKind OpKind) {
void XpcTraceConsumer::operationFinished(
uint64_t OpId, OperationKind OpKind,
ArrayRef<SourceKit::DiagnosticEntryInfo> Diagnostics) {
xpc_object_t Contents = xpc_array_create(nullptr, 0);
append(Contents, trace::ActionKind::OperationFinished);
append(Contents, OpId);

View File

@@ -232,7 +232,7 @@ findRenameRanges(llvm::MemoryBuffer *InputBuf,
static bool isSemanticEditorDisabled();
static void fillDictionaryForDiagnosticInfo(
ResponseBuilder::Dictionary Elem, const DiagnosticEntryInfoBase &Info);
ResponseBuilder::Dictionary Elem, const DiagnosticEntryInfo &Info);
static void enableCompileNotifications(bool value);
@@ -1466,30 +1466,7 @@ bool SKDocConsumer::handleDiagnostic(const DiagnosticEntryInfo &Info) {
Arr = TopDict.setArray(KeyDiagnostics);
auto Elem = Arr.appendDictionary();
UIdent SeverityUID;
static UIdent UIDKindDiagWarning(KindDiagWarning.str());
static UIdent UIDKindDiagError(KindDiagError.str());
switch (Info.Severity) {
case DiagnosticSeverityKind::Warning:
SeverityUID = UIDKindDiagWarning;
break;
case DiagnosticSeverityKind::Error:
SeverityUID = UIDKindDiagError;
break;
}
Elem.set(KeySeverity, SeverityUID);
fillDictionaryForDiagnosticInfo(Elem, Info);
if (!Info.Notes.empty()) {
auto NotesArr = Elem.setArray(KeyDiagnostics);
for (auto &NoteDiag : Info.Notes) {
auto NoteElem = NotesArr.appendDictionary();
NoteElem.set(KeySeverity, KindDiagNote);
fillDictionaryForDiagnosticInfo(NoteElem, NoteDiag);
}
}
return true;
}
@@ -2335,7 +2312,38 @@ bool SKEditorConsumer::recordFormattedText(StringRef Text) {
return true;
}
static void fillDictionaryForDiagnosticInfoBase(
ResponseBuilder::Dictionary Elem, const DiagnosticEntryInfoBase &Info);
static void fillDictionaryForDiagnosticInfo(
ResponseBuilder::Dictionary Elem, const DiagnosticEntryInfo &Info) {
UIdent SeverityUID;
static UIdent UIDKindDiagWarning(KindDiagWarning.str());
static UIdent UIDKindDiagError(KindDiagError.str());
switch (Info.Severity) {
case DiagnosticSeverityKind::Warning:
SeverityUID = UIDKindDiagWarning;
break;
case DiagnosticSeverityKind::Error:
SeverityUID = UIDKindDiagError;
break;
}
Elem.set(KeySeverity, SeverityUID);
fillDictionaryForDiagnosticInfoBase(Elem, Info);
if (!Info.Notes.empty()) {
auto NotesArr = Elem.setArray(KeyDiagnostics);
for (auto &NoteDiag : Info.Notes) {
auto NoteElem = NotesArr.appendDictionary();
NoteElem.set(KeySeverity, KindDiagNote);
fillDictionaryForDiagnosticInfoBase(NoteElem, NoteDiag);
}
}
}
static void fillDictionaryForDiagnosticInfoBase(
ResponseBuilder::Dictionary Elem, const DiagnosticEntryInfoBase &Info) {
Elem.set(KeyDescription, Info.Description);
@@ -2383,31 +2391,8 @@ bool SKEditorConsumer::handleDiagnostic(const DiagnosticEntryInfo &Info,
Arr = Dict.setArray(KeyDiagnostics);
auto Elem = Arr.appendDictionary();
UIdent SeverityUID;
static UIdent UIDKindDiagWarning(KindDiagWarning.str());
static UIdent UIDKindDiagError(KindDiagError.str());
switch (Info.Severity) {
case DiagnosticSeverityKind::Warning:
SeverityUID = UIDKindDiagWarning;
break;
case DiagnosticSeverityKind::Error:
SeverityUID = UIDKindDiagError;
break;
}
Elem.set(KeySeverity, SeverityUID);
Elem.set(KeyDiagnosticStage, DiagStage);
fillDictionaryForDiagnosticInfo(Elem, Info);
if (!Info.Notes.empty()) {
auto NotesArr = Elem.setArray(KeyDiagnostics);
for (auto &NoteDiag : Info.Notes) {
auto NoteElem = NotesArr.appendDictionary();
NoteElem.set(KeySeverity, KindDiagNote);
fillDictionaryForDiagnosticInfo(NoteElem, NoteDiag);
}
}
return true;
}
@@ -2710,7 +2695,8 @@ public:
void operationStarted(uint64_t OpId, trace::OperationKind OpKind,
const trace::SwiftInvocation &Inv,
const trace::StringPairs &OpArgs) override;
void operationFinished(uint64_t OpId, trace::OperationKind OpKind) override;
void operationFinished(uint64_t OpId, trace::OperationKind OpKind,
ArrayRef<DiagnosticEntryInfo> Diagnostics) override;
swift::OptionSet<trace::OperationKind> desiredOperations() override {
return swift::OptionSet<trace::OperationKind>() |
trace::OperationKind::PerformSema |
@@ -2736,8 +2722,9 @@ void CompileTrackingConsumer::operationStarted(
sourcekitd::postNotification(RespBuilder.createResponse());
}
void CompileTrackingConsumer::operationFinished(uint64_t OpId,
trace::OperationKind OpKind) {
void CompileTrackingConsumer::operationFinished(
uint64_t OpId, trace::OperationKind OpKind,
ArrayRef<DiagnosticEntryInfo> Diagnostics) {
if (!desiredOperations().contains(OpKind))
return;
@@ -2746,7 +2733,11 @@ void CompileTrackingConsumer::operationFinished(uint64_t OpId,
auto Dict = RespBuilder.getDictionary();
Dict.set(KeyNotification, CompileDidFinishUID);
Dict.set(KeyCompileID, std::to_string(OpId));
// Diagnostics
auto DiagArray = Dict.setArray(KeyDiagnostics);
for (const auto &DiagInfo : Diagnostics) {
fillDictionaryForDiagnosticInfo(DiagArray.appendDictionary(), DiagInfo);
}
sourcekitd::postNotification(RespBuilder.createResponse());
}