Index: clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp =================================================================== --- clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp +++ clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp @@ -151,6 +151,16 @@ const ObjCPropertyDecl *PDecl = M ? M->findPropertyDecl() : nullptr; return !PDecl || canRequestForDecl(*PDecl); } + +bool LooksLikeDocComment(llvm::StringRef CommentText) { + // We don't report comments that only contain "special" chars. + // This avoids reporting various delimiters, like: + // ================= + // ----------------- + // ***************** + return CommentText.find_first_not_of("/*-= \t\r\n") != llvm::StringRef::npos; +} + } // namespace std::string getDocComment(const ASTContext &Ctx, @@ -167,7 +177,10 @@ const RawComment *RC = getCompletionComment(Ctx, Decl); if (!RC) return ""; - return RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics()); + std::string Doc = RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics()); + if (!LooksLikeDocComment(Doc)) + return ""; + return Doc; } std::string @@ -180,7 +193,10 @@ const RawComment *RC = getParameterComment(Ctx, Result, ArgIndex); if (!RC) return ""; - return RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics()); + std::string Doc = RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics()); + if (!LooksLikeDocComment(Doc)) + return ""; + return Doc; } void getLabelAndInsertText(const CodeCompletionString &CCS, std::string *Label, Index: clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp =================================================================== --- clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp @@ -1100,6 +1100,65 @@ Contains(AllOf(Not(IsDocumented()), Named("func")))); } +TEST(CompletionTest, NonDocComments) { + MockFSProvider FS; + auto FooCpp = testPath("foo.cpp"); + FS.Files[FooCpp] = ""; + + MockCompilationDatabase CDB; + IgnoreDiagnostics DiagConsumer; + ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + + Annotations Source(R"cpp( + // ------------------ + int comments_foo(); + + // A comment and a decl are separated by newlines. + // Therefore, the comment shouldn't show up as doc comment. + + int comments_bar(); + + // this comment should be in the results. + int comments_baz(); + + + template + struct Struct { + int comments_qux(); + int comments_quux(); + }; + + + // This comment should not be there. + + template + int Struct::comments_qux() { + } + + // This comment **should** be in results. + template + int Struct::comments_quux() { + int a = comments^; + } + )cpp"); + Server.addDocument(FooCpp, Source.code(), WantDiagnostics::Yes); + CompletionList Completions = cantFail(runCodeComplete( + Server, FooCpp, Source.point(), clangd::CodeCompleteOptions())); + + // We should not get any of those comments in completion. + EXPECT_THAT( + Completions.items, + UnorderedElementsAre(AllOf(Not(IsDocumented()), Named("comments_foo")), + AllOf(IsDocumented(), Named("comments_baz")), + AllOf(IsDocumented(), Named("comments_quux")), + // FIXME(ibiryukov): the following items should have + // empty documentation, since they are separated from + // a comment with an empty line. Unfortunately, I + // couldn't make Sema tests pass if we ignore those. + AllOf(IsDocumented(), Named("comments_bar")), + AllOf(IsDocumented(), Named("comments_qux")))); +} + TEST(CompletionTest, CompleteOnInvalidLine) { auto FooCpp = testPath("foo.cpp");