Author: ibiryukov Date: Mon Sep 9 01:47:05 2019 New Revision: 371373 URL: http://llvm.org/viewvc/llvm-project?rev=371373&view=rev Log: [clangd] Improve output of semantic highlighting tests in case of failures
Summary: Instead of matching lists of highlightings, we annotate input code with resulting highlightings and diff it against the expected annotated input. In case of failures, this produces much nicer output in form of text-based diffs. Reviewers: hokein Reviewed By: hokein Subscribers: nridge, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D67274 Modified: clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp clang-tools-extra/trunk/clangd/SemanticHighlighting.h clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp Modified: clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp?rev=371373&r1=371372&r2=371373&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp (original) +++ clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp Mon Sep 9 01:47:05 2019 @@ -351,6 +351,43 @@ takeLine(ArrayRef<HighlightingToken> All } } // namespace +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, HighlightingKind K) { + switch (K) { + case HighlightingKind::Variable: + return OS << "Variable"; + case HighlightingKind::LocalVariable: + return OS << "LocalVariable"; + case HighlightingKind::Parameter: + return OS << "Parameter"; + case HighlightingKind::Function: + return OS << "Function"; + case HighlightingKind::Method: + return OS << "Method"; + case HighlightingKind::StaticMethod: + return OS << "StaticMethod"; + case HighlightingKind::Field: + return OS << "Field"; + case HighlightingKind::StaticField: + return OS << "StaticField"; + case HighlightingKind::Class: + return OS << "Class"; + case HighlightingKind::Enum: + return OS << "Enum"; + case HighlightingKind::EnumConstant: + return OS << "EnumConstant"; + case HighlightingKind::Namespace: + return OS << "Namespace"; + case HighlightingKind::TemplateParameter: + return OS << "TemplateParameter"; + case HighlightingKind::Primitive: + return OS << "Primitive"; + case HighlightingKind::Macro: + return OS << "Macro"; + case HighlightingKind::NumKinds: + llvm_unreachable("NumKinds is not a valid HighlightingKind"); + } +} + std::vector<LineHighlightings> diffHighlightings(ArrayRef<HighlightingToken> New, ArrayRef<HighlightingToken> Old) { Modified: clang-tools-extra/trunk/clangd/SemanticHighlighting.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/SemanticHighlighting.h?rev=371373&r1=371372&r2=371373&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/SemanticHighlighting.h (original) +++ clang-tools-extra/trunk/clangd/SemanticHighlighting.h Mon Sep 9 01:47:05 2019 @@ -18,6 +18,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICHIGHLIGHTING_H #include "Protocol.h" +#include "llvm/Support/raw_ostream.h" namespace clang { namespace clangd { @@ -42,6 +43,7 @@ enum class HighlightingKind { NumKinds, }; +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, HighlightingKind K); // Contains all information needed for the highlighting a token. struct HighlightingToken { Modified: clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp?rev=371373&r1=371372&r2=371373&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp (original) +++ clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp Mon Sep 9 01:47:05 2019 @@ -10,9 +10,14 @@ #include "ClangdServer.h" #include "Protocol.h" #include "SemanticHighlighting.h" +#include "SourceCode.h" #include "TestFS.h" #include "TestTU.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" #include "gmock/gmock.h" +#include <algorithm> namespace clang { namespace clangd { @@ -59,6 +64,36 @@ std::vector<HighlightingToken> getExpect return ExpectedTokens; } +/// Annotates the input code with provided semantic highlightings. Results look +/// something like: +/// class $Class[[X]] { +/// $Primitive[[int]] $Field[[a]] = 0; +/// }; +std::string annotate(llvm::StringRef Input, + llvm::ArrayRef<HighlightingToken> Tokens) { + assert(std::is_sorted( + Tokens.begin(), Tokens.end(), + [](const HighlightingToken &L, const HighlightingToken &R) { + return L.R.start < R.R.start; + })); + + std::string Result; + unsigned NextChar = 0; + for (auto &T : Tokens) { + unsigned StartOffset = llvm::cantFail(positionToOffset(Input, T.R.start)); + unsigned EndOffset = llvm::cantFail(positionToOffset(Input, T.R.end)); + assert(StartOffset <= EndOffset); + assert(NextChar <= StartOffset); + + Result += Input.substr(NextChar, StartOffset - NextChar); + Result += llvm::formatv("${0}[[{1}]]", T.Kind, + Input.substr(StartOffset, EndOffset - StartOffset)); + NextChar = EndOffset; + } + Result += Input.substr(NextChar); + return Result; +} + void checkHighlightings(llvm::StringRef Code, std::vector<std::pair</*FileName*/ llvm::StringRef, /*FileContent*/ llvm::StringRef>> @@ -68,8 +103,8 @@ void checkHighlightings(llvm::StringRef for (auto File : AdditionalFiles) TU.AdditionalFiles.insert({File.first, File.second}); auto AST = TU.build(); - std::vector<HighlightingToken> ActualTokens = getSemanticHighlightings(AST); - EXPECT_THAT(ActualTokens, getExpectedTokens(Test)) << Code; + + EXPECT_EQ(Code, annotate(Test.code(), getSemanticHighlightings(AST))); } // Any annotations in OldCode and NewCode are converted into their corresponding _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits