diff --git a/src/libs/clangbackendipc/codecompletion.cpp b/src/libs/clangbackendipc/codecompletion.cpp index 717b2e11f24..f67f7dad04f 100644 --- a/src/libs/clangbackendipc/codecompletion.cpp +++ b/src/libs/clangbackendipc/codecompletion.cpp @@ -110,6 +110,16 @@ quint32 CodeCompletion::priority() const return priority_; } +void CodeCompletion::setBriefComment(const Utf8String &briefComment) +{ + briefComment_ = briefComment; +} + +const Utf8String &CodeCompletion::briefComment() const +{ + return briefComment_; +} + quint32 &CodeCompletion::completionKindAsInt() { return reinterpret_cast(completionKind_); @@ -123,6 +133,7 @@ quint32 &CodeCompletion::availabilityAsInt() QDataStream &operator<<(QDataStream &out, const CodeCompletion &message) { out << message.text_; + out << message.briefComment_; out << message.chunks_; out << message.priority_; out << message.completionKind_; @@ -135,6 +146,7 @@ QDataStream &operator<<(QDataStream &out, const CodeCompletion &message) QDataStream &operator>>(QDataStream &in, CodeCompletion &message) { in >> message.text_; + in >> message.briefComment_; in >> message.chunks_; in >> message.priority_; in >> message.completionKindAsInt(); diff --git a/src/libs/clangbackendipc/codecompletion.h b/src/libs/clangbackendipc/codecompletion.h index 8e8ce1f08b5..059496bc547 100644 --- a/src/libs/clangbackendipc/codecompletion.h +++ b/src/libs/clangbackendipc/codecompletion.h @@ -107,12 +107,16 @@ public: void setPriority(quint32 priority); quint32 priority() const; + void setBriefComment(const Utf8String &briefComment); + const Utf8String &briefComment() const; + private: quint32 &completionKindAsInt(); quint32 &availabilityAsInt(); private: Utf8String text_; + Utf8String briefComment_; CodeCompletionChunks chunks_; quint32 priority_ = 0; Kind completionKind_ = Other; diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp index 99e3ff1f1e2..50a827d4d3b 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp @@ -100,7 +100,12 @@ QList toAssistProposalItems(const CodeCompletions &complet items.insert(name, item); item->setText(name); item->setOrder(ccr.priority()); - item->setDetail(CompletionChunksToTextConverter::convertToToolTip(ccr.chunks())); + QString detail = CompletionChunksToTextConverter::convertToToolTip(ccr.chunks()); + + if (!ccr.briefComment().isEmpty()) + detail += QStringLiteral("\n\n") + ccr.briefComment().toString(); + + item->setDetail(detail); item->setCodeCompletion(ccr); } diff --git a/src/tools/clangbackend/ipcsource/codecompletionsextractor.cpp b/src/tools/clangbackend/ipcsource/codecompletionsextractor.cpp index 1a3e7cb9c39..311cde61ae0 100644 --- a/src/tools/clangbackend/ipcsource/codecompletionsextractor.cpp +++ b/src/tools/clangbackend/ipcsource/codecompletionsextractor.cpp @@ -63,6 +63,7 @@ bool CodeCompletionsExtractor::next() extractPriority(); extractAvailability(); extractHasParameters(); + extractBriefComment(); extractCompletionChunks(); adaptPriority(); @@ -249,6 +250,13 @@ void CodeCompletionsExtractor::extractHasParameters() } } +void CodeCompletionsExtractor::extractBriefComment() +{ + ClangString briefComment = clang_getCompletionBriefComment(currentCxCodeCompleteResult.CompletionString); + + currentCodeCompletion_.setBriefComment(briefComment); +} + void CodeCompletionsExtractor::extractCompletionChunks() { currentCodeCompletion_.setChunks(CodeCompletionChunkConverter::extract(currentCxCodeCompleteResult.CompletionString)); diff --git a/src/tools/clangbackend/ipcsource/codecompletionsextractor.h b/src/tools/clangbackend/ipcsource/codecompletionsextractor.h index dbfbb8af4b7..00492ef5de5 100644 --- a/src/tools/clangbackend/ipcsource/codecompletionsextractor.h +++ b/src/tools/clangbackend/ipcsource/codecompletionsextractor.h @@ -65,6 +65,7 @@ private: void extractPriority(); void extractAvailability(); void extractHasParameters(); + void extractBriefComment(); void extractCompletionChunks(); void adaptPriority(); diff --git a/src/tools/clangbackend/ipcsource/translationunit.cpp b/src/tools/clangbackend/ipcsource/translationunit.cpp index 7d0a0735c8b..859e81c3844 100644 --- a/src/tools/clangbackend/ipcsource/translationunit.cpp +++ b/src/tools/clangbackend/ipcsource/translationunit.cpp @@ -230,7 +230,8 @@ void TranslationUnit::reparseTranslationUnit() const int TranslationUnit::defaultOptions() { return CXTranslationUnit_CacheCompletionResults - | CXTranslationUnit_PrecompiledPreamble; + | CXTranslationUnit_PrecompiledPreamble + | CXTranslationUnit_IncludeBriefCommentsInCodeCompletion; } uint TranslationUnit::unsavedFilesCount() const diff --git a/tests/unit/unittest/codecompletionsextractortest.cpp b/tests/unit/unittest/codecompletionsextractortest.cpp index eed59dde0a2..2c31f034b61 100644 --- a/tests/unit/unittest/codecompletionsextractortest.cpp +++ b/tests/unit/unittest/codecompletionsextractortest.cpp @@ -101,6 +101,26 @@ MATCHER_P2(HasCompletionChunks, name, chunks, return false; } +MATCHER_P2(HasBriefComment, name, briefComment, + std::string(negation ? "hasn't" : "has") + " completion of name " + PrintToString(name) + + " with the brief comment " + PrintToString(briefComment)) +{ + ::CodeCompletionsExtractor &extractor = const_cast<::CodeCompletionsExtractor&>(arg); + while (extractor.next()) { + if (extractor.currentCodeCompletion().text() == name) { + if (extractor.currentCodeCompletion().briefComment() == briefComment) { + return true; + } else if (!extractor.peek(name)) { + *result_listener << "briefComment is " << PrintToString(arg.currentCodeCompletion().briefComment()) << " and not " << PrintToString(briefComment); + return false; + } + } + } + + return false; +} + + const Utf8String unsavedFileContent(const char *unsavedFilePath) { QFile unsavedFileContentFile(QString::fromUtf8(unsavedFilePath)); @@ -133,39 +153,18 @@ ClangCodeCompleteResults getResults(const TranslationUnit &translationUnit, uint class CodeCompletionsExtractor : public ::testing::Test { -public: - static void TearDownTestCase(); - protected: - static ClangBackEnd::ProjectPart project; - static ClangBackEnd::UnsavedFiles unsavedFiles; - static TranslationUnit functionTranslationUnit; - static TranslationUnit variableTranslationUnit; - static TranslationUnit classTranslationUnit ; - static TranslationUnit namespaceTranslationUnit; - static TranslationUnit enumerationTranslationUnit; - static TranslationUnit constructorTranslationUnit; + ClangBackEnd::ProjectPart project{Utf8StringLiteral("/path/to/projectfile")}; + ClangBackEnd::UnsavedFiles unsavedFiles; + TranslationUnit functionTranslationUnit{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_function.cpp"), unsavedFiles, project}; + TranslationUnit variableTranslationUnit{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_variable.cpp"), unsavedFiles, project}; + TranslationUnit classTranslationUnit{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_class.cpp"), unsavedFiles, project}; + TranslationUnit namespaceTranslationUnit{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_namespace.cpp"), unsavedFiles, project}; + TranslationUnit enumerationTranslationUnit{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_enumeration.cpp"), unsavedFiles, project}; + TranslationUnit constructorTranslationUnit{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_constructor.cpp"), unsavedFiles, project}; + TranslationUnit briefCommentTranslationUnit{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_brief_comment.cpp"), unsavedFiles, project}; }; -ClangBackEnd::ProjectPart CodeCompletionsExtractor::project(Utf8StringLiteral("/path/to/projectfile")); -ClangBackEnd::UnsavedFiles CodeCompletionsExtractor::unsavedFiles; -TranslationUnit CodeCompletionsExtractor::functionTranslationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_function.cpp"), unsavedFiles, project); -TranslationUnit CodeCompletionsExtractor::variableTranslationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_variable.cpp"), unsavedFiles, project); -TranslationUnit CodeCompletionsExtractor::classTranslationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_class.cpp"), unsavedFiles, project); -TranslationUnit CodeCompletionsExtractor::namespaceTranslationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_namespace.cpp"), unsavedFiles, project); -TranslationUnit CodeCompletionsExtractor::enumerationTranslationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_enumeration.cpp"), unsavedFiles, project); -TranslationUnit CodeCompletionsExtractor::constructorTranslationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_constructor.cpp"), unsavedFiles, project); - -void CodeCompletionsExtractor::TearDownTestCase() -{ - functionTranslationUnit.reset(); - variableTranslationUnit.reset(); - classTranslationUnit.reset(); - namespaceTranslationUnit.reset(); - enumerationTranslationUnit.reset(); - constructorTranslationUnit.reset(); -} - TEST_F(CodeCompletionsExtractor, Function) { ClangCodeCompleteResults completeResults(getResults(functionTranslationUnit, 20)); @@ -657,5 +656,14 @@ TEST_F(CodeCompletionsExtractor, CompletionChunksClass) CodeCompletionChunks({{CodeCompletionChunk::TypedText, Utf8StringLiteral("Class")}}))); } +TEST_F(CodeCompletionsExtractor, BriefComment) +{ + ClangCodeCompleteResults completeResults(getResults(briefCommentTranslationUnit, 10)); + + ::CodeCompletionsExtractor extractor(completeResults.data()); + + ASSERT_THAT(extractor, HasBriefComment(Utf8StringLiteral("BriefComment"), Utf8StringLiteral("A brief comment"))); +} + } diff --git a/tests/unit/unittest/data/complete_extractor_brief_comment.cpp b/tests/unit/unittest/data/complete_extractor_brief_comment.cpp new file mode 100644 index 00000000000..a42315550cf --- /dev/null +++ b/tests/unit/unittest/data/complete_extractor_brief_comment.cpp @@ -0,0 +1,11 @@ +/** + * A brief comment + */ +void BriefComment() +{ + +} + +void f() { + +}