diff --git a/include/swift/IDE/CodeCompletion.h b/include/swift/IDE/CodeCompletion.h index 150f6793097..66c4f57c83d 100644 --- a/include/swift/IDE/CodeCompletion.h +++ b/include/swift/IDE/CodeCompletion.h @@ -399,6 +399,7 @@ public: private: CodeCompletionString *const CompletionString; + StringRef ModuleName; StringRef BriefDocComment; ArrayRef AssociatedUSRs; @@ -416,17 +417,14 @@ private: CodeCompletionResult(SemanticContextKind SemanticContext, unsigned NumBytesToErase, CodeCompletionString *CompletionString, - const Decl *AssociatedDecl, - bool NotRecommended, - StringRef BriefDocComment, + const Decl *AssociatedDecl, StringRef ModuleName, + bool NotRecommended, StringRef BriefDocComment, ArrayRef AssociatedUSRs) : Kind(ResultKind::Declaration), SemanticContext(unsigned(SemanticContext)), - NotRecommended(NotRecommended), - NumBytesToErase(NumBytesToErase), - CompletionString(CompletionString), - BriefDocComment(BriefDocComment), - AssociatedUSRs(AssociatedUSRs) { + NotRecommended(NotRecommended), NumBytesToErase(NumBytesToErase), + CompletionString(CompletionString), ModuleName(ModuleName), + BriefDocComment(BriefDocComment), AssociatedUSRs(AssociatedUSRs) { assert(AssociatedDecl && "should have a decl"); AssociatedDeclKind = unsigned(getCodeCompletionDeclKind(AssociatedDecl)); assert(CompletionString); @@ -456,6 +454,8 @@ public: return CompletionString; } + StringRef getModuleName() const { return ModuleName; } + StringRef getBriefDocComment() const { return BriefDocComment; } @@ -483,6 +483,10 @@ struct CodeCompletionResultSink { std::vector Results; + /// A single-element cache for module names stored in Allocator, keyed by a + /// clang::Module * or swift::Module *. + std::pair LastModule; + CodeCompletionResultSink() : Allocator(std::make_shared()) {} }; diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp index 00370cb5e15..420bc2428e0 100644 --- a/lib/IDE/CodeCompletion.cpp +++ b/lib/IDE/CodeCompletion.cpp @@ -401,6 +401,19 @@ void CodeCompletionResultBuilder::addChunkWithText( addChunkWithTextNoCopy(Kind, copyString(*Sink.Allocator, Text)); } +void CodeCompletionResultBuilder::setAssociatedDecl(const Decl *D) { + assert(Kind == CodeCompletionResult::ResultKind::Declaration); + AssociatedDecl = D; + + if (auto *ClangD = D->getClangDecl()) + CurrentModule = ClangD->getOwningModule(); + // FIXME: macros + // FIXME: imported header module + + if (!CurrentModule) + CurrentModule = D->getModuleContext(); +} + StringRef CodeCompletionContext::copyString(StringRef Str) { return ::copyString(*CurrentResults.Allocator, Str); } @@ -472,10 +485,27 @@ CodeCompletionResult *CodeCompletionResultBuilder::takeResult() { } else { BriefComment = AssociatedDecl->getBriefComment(); } + + StringRef ModuleName; + if (CurrentModule) { + if (Sink.LastModule.first == CurrentModule.getOpaqueValue()) { + ModuleName = Sink.LastModule.second; + } else { + if (auto *C = CurrentModule.dyn_cast()) { + ModuleName = copyString(*Sink.Allocator, C->getFullModuleName()); + } else { + ModuleName = copyString( + *Sink.Allocator, + CurrentModule.get()->getName().str()); + } + Sink.LastModule.first = CurrentModule.getOpaqueValue(); + Sink.LastModule.second = ModuleName; + } + } + return new (*Sink.Allocator) CodeCompletionResult( - SemanticContext, NumBytesToErase, CCS, AssociatedDecl, - /*NotRecommended=*/false, - copyString(*Sink.Allocator, BriefComment), + SemanticContext, NumBytesToErase, CCS, AssociatedDecl, ModuleName, + /*NotRecommended=*/false, copyString(*Sink.Allocator, BriefComment), copyAssociatedUSRs(*Sink.Allocator, AssociatedDecl)); } diff --git a/lib/IDE/CodeCompletionResultBuilder.h b/lib/IDE/CodeCompletionResultBuilder.h index 77bd2474552..a6f0d76580c 100644 --- a/lib/IDE/CodeCompletionResultBuilder.h +++ b/lib/IDE/CodeCompletionResultBuilder.h @@ -18,8 +18,13 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +namespace clang { +class Module; +} + namespace swift { class Decl; +class Module; namespace ide { @@ -31,6 +36,8 @@ class CodeCompletionResultBuilder { const Decl *AssociatedDecl = nullptr; unsigned CurrentNestingLevel = 0; SmallVector Chunks; + llvm::PointerUnion + CurrentModule; void addChunkWithText(CodeCompletionString::Chunk::ChunkKind Kind, StringRef Text); @@ -69,10 +76,7 @@ public: NumBytesToErase = N; } - void setAssociatedDecl(const Decl *D) { - assert(Kind == CodeCompletionResult::ResultKind::Declaration); - AssociatedDecl = D; - } + void setAssociatedDecl(const Decl *D); void addAccessControlKeyword(Accessibility Access) { switch (Access) {