16 #include "llvm/ADT/ArrayRef.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/Support/Error.h" 19 #include "gmock/gmock.h" 26 MATCHER_P(LineNumber, L,
"") {
return arg.Line == L; }
27 MATCHER(EmptyHighlightings,
"") {
return arg.Tokens.empty(); }
29 std::vector<HighlightingToken>
31 std::vector<HighlightingToken> Tokens(Ranges.size());
32 for (
int I = 0, End = Ranges.size(); I < End; ++I) {
33 Tokens[I].R = Ranges[I];
34 Tokens[I].Kind =
Kind;
40 std::vector<HighlightingToken> getExpectedTokens(Annotations &Test) {
41 static const std::map<HighlightingKind, std::string> KindToString{
60 std::vector<HighlightingToken> ExpectedTokens;
61 for (
const auto &KindString : KindToString) {
62 std::vector<HighlightingToken> Toks = makeHighlightingTokens(
63 Test.ranges(KindString.second), KindString.first);
64 ExpectedTokens.insert(ExpectedTokens.end(), Toks.begin(), Toks.end());
66 llvm::sort(ExpectedTokens);
67 return ExpectedTokens;
75 std::string annotate(llvm::StringRef Input,
76 llvm::ArrayRef<HighlightingToken> Tokens) {
77 assert(std::is_sorted(
78 Tokens.begin(), Tokens.end(),
79 [](
const HighlightingToken &L,
const HighlightingToken &R) {
80 return L.R.start < R.R.start;
84 unsigned NextChar = 0;
85 for (
auto &T : Tokens) {
88 assert(StartOffset <= EndOffset);
89 assert(NextChar <= StartOffset);
91 Result += Input.substr(NextChar, StartOffset - NextChar);
92 Result += llvm::formatv(
"${0}[[{1}]]", T.Kind,
93 Input.substr(StartOffset, EndOffset - StartOffset));
96 Result += Input.substr(NextChar);
100 void checkHighlightings(llvm::StringRef
Code,
101 std::vector<std::pair< llvm::StringRef,
103 AdditionalFiles = {}) {
104 Annotations Test(Code);
106 TU.Code = Test.code();
110 TU.ExtraArgs.push_back(
"-fno-delayed-template-parsing");
112 for (
auto File : AdditionalFiles)
113 TU.AdditionalFiles.insert({File.first, File.second});
114 auto AST = TU.
build();
124 void checkDiffedHighlights(llvm::StringRef OldCode, llvm::StringRef NewCode) {
125 Annotations OldTest(OldCode);
126 Annotations NewTest(NewCode);
127 std::vector<HighlightingToken> OldTokens = getExpectedTokens(OldTest);
128 std::vector<HighlightingToken> NewTokens = getExpectedTokens(NewTest);
130 llvm::DenseMap<int, std::vector<HighlightingToken>> ExpectedLines;
131 for (
const Position &Point : NewTest.points()) {
132 ExpectedLines[Point.line];
135 std::vector<LineHighlightings> ExpectedLinePairHighlighting;
136 for (
const HighlightingToken &Token : NewTokens) {
137 auto It = ExpectedLines.find(Token.R.start.line);
138 if (It != ExpectedLines.end())
139 It->second.push_back(Token);
141 for (
auto &LineTokens : ExpectedLines)
142 ExpectedLinePairHighlighting.push_back(
143 {LineTokens.first, LineTokens.second,
false});
145 std::vector<LineHighlightings> ActualDiffed =
147 EXPECT_THAT(ActualDiffed,
148 testing::UnorderedElementsAreArray(ExpectedLinePairHighlighting))
152 TEST(SemanticHighlighting, GetsCorrectTokens) {
153 const char *TestCases[] = {
155 struct $Class[[AS]] { 156 double $Field[[SomeMember]]; 160 void $Function[[foo]](int $Parameter[[A]], $Class[[AS]] $Parameter[[As]]) { 161 $Primitive[[auto]] $LocalVariable[[VeryLongVariableName]] = 12312; 162 $Class[[AS]] $LocalVariable[[AA]]; 163 $Primitive[[auto]] $LocalVariable[[L]] = $LocalVariable[[AA]].$Field[[SomeMember]] + $Parameter[[A]]; 164 auto $LocalVariable[[FN]] = [ $LocalVariable[[AA]]](int $Parameter[[A]]) -> void {}; 165 $LocalVariable[[FN]](12312); 169 void $Function[[foo]](int); 170 void $Function[[Gah]](); 171 void $Function[[foo]]() { 172 auto $LocalVariable[[Bou]] = $Function[[Gah]]; 175 void $Method[[abc]](); 179 namespace $Namespace[[abc]] { 180 template<typename $TemplateParameter[[T]]> 182 $TemplateParameter[[T]] $Field[[t]]; 185 template<typename $TemplateParameter[[T]]> 186 struct $Class[[C]] : $Namespace[[abc]]::$Class[[A]]<$TemplateParameter[[T]]> { 187 typename $TemplateParameter[[T]]::$DependentType[[A]]* $Field[[D]]; 189 $Namespace[[abc]]::$Class[[A]]<int> $Variable[[AA]]; 190 typedef $Namespace[[abc]]::$Class[[A]]<int> $Class[[AAA]]; 194 void operator<<($Class[[B]]); 195 $Class[[AAA]] $Field[[AA]]; 197 $Class[[B]]::$Class[[B]]() {} 198 $Class[[B]]::~$Class[[B]]() {} 199 void $Function[[f]] () { 200 $Class[[B]] $LocalVariable[[BB]] = $Class[[B]](); 201 $LocalVariable[[BB]].~$Class[[B]](); 206 enum class $Enum[[E]] { 214 $Enum[[E]] $Field[[EEE]]; 215 $Enum[[EE]] $Field[[EEEE]]; 217 int $Variable[[I]] = $EnumConstant[[Hi]]; 218 $Enum[[E]] $Variable[[L]] = $Enum[[E]]::$EnumConstant[[B]]; 221 namespace $Namespace[[abc]] { 223 namespace $Namespace[[bcd]] { 224 struct $Class[[A]] {}; 225 namespace $Namespace[[cde]] { 227 enum class $Enum[[B]] { 234 using namespace $Namespace[[abc]]::$Namespace[[bcd]]; 235 namespace $Namespace[[vwz]] = 236 $Namespace[[abc]]::$Namespace[[bcd]]::$Namespace[[cde]]; 237 $Namespace[[abc]]::$Namespace[[bcd]]::$Class[[A]] $Variable[[AA]]; 238 $Namespace[[vwz]]::$Class[[A]]::$Enum[[B]] $Variable[[AAA]] = 239 $Namespace[[vwz]]::$Class[[A]]::$Enum[[B]]::$EnumConstant[[Hi]]; 240 ::$Namespace[[vwz]]::$Class[[A]] $Variable[[B]]; 241 ::$Namespace[[abc]]::$Namespace[[bcd]]::$Class[[A]] $Variable[[BB]]; 249 $Class[[D]] $Field[[E]]; 250 static double $StaticField[[S]]; 251 static void $StaticMethod[[bar]]() {} 252 void $Method[[foo]]() { 254 this->$Field[[B]] = 156; 255 this->$Method[[foo]](); 257 $StaticMethod[[bar]](); 258 $StaticField[[S]] = 90.1; 261 void $Function[[foo]]() { 262 $Class[[A]] $LocalVariable[[AA]]; 263 $LocalVariable[[AA]].$Field[[B]] += 2; 264 $LocalVariable[[AA]].$Method[[foo]](); 265 $LocalVariable[[AA]].$Field[[E]].$Field[[C]]; 266 $Class[[A]]::$StaticField[[S]] = 90; 270 struct $Class[[AA]] { 274 $Class[[AA]] $Variable[[A]]{$Variable[[B]]}; 277 namespace $Namespace[[a]] { 278 struct $Class[[A]] {}; 279 typedef char $Primitive[[C]]; 281 typedef $Namespace[[a]]::$Class[[A]] $Class[[B]]; 282 using $Class[[BB]] = $Namespace[[a]]::$Class[[A]]; 283 enum class $Enum[[E]] {}; 284 typedef $Enum[[E]] $Enum[[C]]; 285 typedef $Enum[[C]] $Enum[[CC]]; 286 using $Enum[[CD]] = $Enum[[CC]]; 287 $Enum[[CC]] $Function[[f]]($Class[[B]]); 288 $Enum[[CD]] $Function[[f]]($Class[[BB]]); 289 typedef $Namespace[[a]]::$Primitive[[C]] $Primitive[[PC]]; 290 typedef float $Primitive[[F]]; 293 template<typename $TemplateParameter[[T]], typename = void> 295 $TemplateParameter[[T]] $Field[[AA]]; 296 $TemplateParameter[[T]] $Method[[foo]](); 298 template<class $TemplateParameter[[TT]]> 300 $Class[[A]]<$TemplateParameter[[TT]]> $Field[[AA]]; 302 template<class $TemplateParameter[[TT]], class $TemplateParameter[[GG]]> 303 class $Class[[BB]] {}; 304 template<class $TemplateParameter[[T]]> 305 class $Class[[BB]]<$TemplateParameter[[T]], int> {}; 306 template<class $TemplateParameter[[T]]> 307 class $Class[[BB]]<$TemplateParameter[[T]], $TemplateParameter[[T]]*> {}; 309 template<template<class> class $TemplateParameter[[T]], class $TemplateParameter[[C]]> 310 $TemplateParameter[[T]]<$TemplateParameter[[C]]> $Function[[f]](); 313 class $Class[[Foo]] {}; 315 template<typename $TemplateParameter[[T]]> 316 void $Function[[foo]]($TemplateParameter[[T]] ...); 319 template <class $TemplateParameter[[T]]> 320 struct $Class[[Tmpl]] {$TemplateParameter[[T]] $Field[[x]] = 0;}; 321 extern template struct $Class[[Tmpl]]<float>; 322 template struct $Class[[Tmpl]]<double>; 328 class $Class[[Foo]] {}; 329 struct $Class[[Bar]] { 330 explicit operator $Class[[Foo]]*() const; 331 explicit operator int() const; 332 operator $Class[[Foo]](); 334 void $Function[[f]]() { 335 $Class[[Bar]] $LocalVariable[[B]]; 336 $Class[[Foo]] $LocalVariable[[F]] = $LocalVariable[[B]]; 337 $Class[[Foo]] *$LocalVariable[[FP]] = ($Class[[Foo]]*)$LocalVariable[[B]]; 338 int $LocalVariable[[I]] = (int)$LocalVariable[[B]]; 342 struct $Class[[B]] {}; 344 $Class[[B]] $Field[[BB]]; 345 $Class[[A]] &operator=($Class[[A]] &&$Parameter[[O]]); 348 $Class[[A]] &$Class[[A]]::operator=($Class[[A]] &&$Parameter[[O]]) = default; 354 class $Class[[Foo]] {}; 355 class $Class[[Bar]] { 356 $Class[[Foo]] $Field[[Fo]]; 357 $Enum[[En]] $Field[[E]]; 359 $Class[[Bar]] ($Class[[Foo]] $Parameter[[F]], 360 $Enum[[En]] $Parameter[[E]]) 361 : $Field[[Fo]] ($Parameter[[F]]), $Field[[E]] ($Parameter[[E]]), 364 class $Class[[Bar2]] : public $Class[[Bar]] { 365 $Class[[Bar2]]() : $Class[[Bar]]($Class[[Foo]](), $EnumConstant[[EC]]) {} 372 class $Class[[Foo]] {}; 373 $Enum[[auto]] $Variable[[AE]] = $Enum[[E]]::$EnumConstant[[E]]; 374 $Class[[auto]] $Variable[[AF]] = $Class[[Foo]](); 375 $Class[[decltype]](auto) $Variable[[AF2]] = $Class[[Foo]](); 376 $Class[[auto]] *$Variable[[AFP]] = &$Variable[[AF]]; 377 $Enum[[auto]] &$Variable[[AER]] = $Variable[[AE]]; 378 $Primitive[[auto]] $Variable[[Form]] = 10.2 + 2 * 4; 379 $Primitive[[decltype]]($Variable[[Form]]) $Variable[[F]] = 10; 380 auto $Variable[[Fun]] = []()->void{}; 383 class $Class[[G]] {}; 384 template<$Class[[G]] *$TemplateParameter[[U]]> 385 class $Class[[GP]] {}; 386 template<$Class[[G]] &$TemplateParameter[[U]]> 387 class $Class[[GR]] {}; 388 template<int *$TemplateParameter[[U]]> 390 void $Method[[f]]() { 391 *$TemplateParameter[[U]] += 5; 394 template<unsigned $TemplateParameter[[U]] = 2> 395 class $Class[[Foo]] { 396 void $Method[[f]]() { 397 for(int $LocalVariable[[I]] = 0; 398 $LocalVariable[[I]] < $TemplateParameter[[U]];) {} 402 $Class[[G]] $Variable[[L]]; 403 void $Function[[f]]() { 404 $Class[[Foo]]<123> $LocalVariable[[F]]; 405 $Class[[GP]]<&$Variable[[L]]> $LocalVariable[[LL]]; 406 $Class[[GR]]<$Variable[[L]]> $LocalVariable[[LLL]]; 410 template<typename $TemplateParameter[[T]], 411 void ($TemplateParameter[[T]]::*$TemplateParameter[[method]])(int)> 414 $TemplateParameter[[T]] *$Parameter[[O]]) { 415 ($Parameter[[O]]->*$TemplateParameter[[method]])(10); 419 void $Method[[f]](int); 421 template<void (*$TemplateParameter[[Func]])()> 423 void $Method[[f]]() { 424 (*$TemplateParameter[[Func]])(); 428 void $Function[[foo]]() { 429 $Class[[F]] $LocalVariable[[FF]]; 430 $Class[[G]]<$Class[[F]], &$Class[[F]]::$Method[[f]]> $LocalVariable[[GG]]; 431 $LocalVariable[[GG]].$Method[[foo]](&$LocalVariable[[FF]]); 432 $Class[[A]]<$Function[[foo]]> $LocalVariable[[AA]]; 437 #define $Macro[[DEF_MULTIPLE]](X) namespace X { class X { int X; }; } 438 #define $Macro[[DEF_CLASS]](T) class T {}; 440 $Macro[[DEF_MULTIPLE]](XYZ); 441 $Macro[[DEF_MULTIPLE]](XYZW); 442 $Macro[[DEF_CLASS]]($Class[[A]]) 443 #define $Macro[[MACRO_CONCAT]](X, V, T) T foo##X = V 444 #define $Macro[[DEF_VAR]](X, V) int X = V 445 #define $Macro[[DEF_VAR_T]](T, X, V) T X = V 446 #define $Macro[[DEF_VAR_REV]](V, X) DEF_VAR(X, V) 447 #define $Macro[[CPY]](X) X 448 #define $Macro[[DEF_VAR_TYPE]](X, Y) X Y 449 #define $Macro[[SOME_NAME]] variable 450 #define $Macro[[SOME_NAME_SET]] variable2 = 123 451 #define $Macro[[INC_VAR]](X) X += 2 452 void $Function[[foo]]() { 453 $Macro[[DEF_VAR]]($LocalVariable[[X]], 123); 454 $Macro[[DEF_VAR_REV]](908, $LocalVariable[[XY]]); 455 int $Macro[[CPY]]( $LocalVariable[[XX]] ); 456 $Macro[[DEF_VAR_TYPE]]($Class[[A]], $LocalVariable[[AA]]); 457 double $Macro[[SOME_NAME]]; 458 int $Macro[[SOME_NAME_SET]]; 459 $LocalVariable[[variable]] = 20.1; 460 $Macro[[MACRO_CONCAT]](var, 2, float); 461 $Macro[[DEF_VAR_T]]($Class[[A]], $Macro[[CPY]]( 462 $Macro[[CPY]]($LocalVariable[[Nested]])), 463 $Macro[[CPY]]($Class[[A]]())); 464 $Macro[[INC_VAR]]($LocalVariable[[variable]]); 466 void $Macro[[SOME_NAME]](); 467 $Macro[[DEF_VAR]]($Variable[[XYZ]], 567); 468 $Macro[[DEF_VAR_REV]](756, $Variable[[AB]]); 470 #define $Macro[[CALL_FN]](F) F(); 471 #define $Macro[[DEF_FN]](F) void F () 472 $Macro[[DEF_FN]]($Function[[g]]) { 473 $Macro[[CALL_FN]]($Function[[foo]]); 477 #define $Macro[[fail]](expr) expr 478 #define $Macro[[assert]](COND) if (!(COND)) { fail("assertion failed" #COND); } 482 int $Function[[f]](); 483 void $Function[[foo]]() { 484 $Macro[[assert]]($Variable[[x]] != $Variable[[y]]); 485 $Macro[[assert]]($Variable[[x]] != $Function[[f]]()); 490 #ifndef $Macro[[name]] 491 #define $Macro[[name]] 494 #define $Macro[[test]] 495 #undef $Macro[[test]] 496 $InactiveCode[[]] #ifdef $Macro[[test]] 497 $InactiveCode[[]] #endif 499 $InactiveCode[[]] #if defined($Macro[[test]]) 500 $InactiveCode[[]] #endif 504 float $Field[[Value]]; 505 $Class[[S]] *$Field[[Next]]; 507 $Class[[S]] $Variable[[Global]][2] = {$Class[[S]](), $Class[[S]]()}; 508 void $Function[[f]]($Class[[S]] $Parameter[[P]]) { 509 int $LocalVariable[[A]][2] = {1,2}; 510 auto [$Variable[[B1]], $Variable[[B2]]] = $LocalVariable[[A]]; 511 auto [$Variable[[G1]], $Variable[[G2]]] = $Variable[[Global]]; 512 $Class[[auto]] [$Variable[[P1]], $Variable[[P2]]] = $Parameter[[P]]; 513 // Highlights references to BindingDecls. 518 template<class $TemplateParameter[[T]]> 520 using $TemplateParameter[[TemplateParam1]] = $TemplateParameter[[T]]; 521 typedef $TemplateParameter[[T]] $TemplateParameter[[TemplateParam2]]; 522 using $Primitive[[IntType]] = int; 524 using $Typedef[[Pointer]] = $TemplateParameter[[T]] *; 525 using $Typedef[[LVReference]] = $TemplateParameter[[T]] &; 526 using $Typedef[[RVReference]] = $TemplateParameter[[T]]&&; 527 using $Typedef[[Array]] = $TemplateParameter[[T]]*[3]; 528 using $Typedef[[MemberPointer]] = int (A::*)(int); 530 // Use various previously defined typedefs in a function type. 531 void $Method[[func]]( 532 $Typedef[[Pointer]], $Typedef[[LVReference]], $Typedef[[RVReference]], 533 $Typedef[[Array]], $Typedef[[MemberPointer]]); 537 template <class $TemplateParameter[[T]]> 538 void $Function[[phase1]]($TemplateParameter[[T]]); 539 template <class $TemplateParameter[[T]]> 540 void $Function[[foo]]($TemplateParameter[[T]] $Parameter[[P]]) { 541 $Function[[phase1]]($Parameter[[P]]); 542 $DependentName[[phase2]]($Parameter[[P]]); 547 template <class $TemplateParameter[[T]]> 548 void $Method[[bar]]($TemplateParameter[[T]]); 551 template <class $TemplateParameter[[U]]> 552 void $Function[[foo]]($TemplateParameter[[U]] $Parameter[[P]]) { 553 $Class[[A]]().$Method[[bar]]($Parameter[[P]]); 558 template <class $TemplateParameter[[T]]> 559 static void $StaticMethod[[foo]]($TemplateParameter[[T]]); 562 template <class $TemplateParameter[[T]]> 564 void $Method[[bar]]() { 565 $Class[[A]]::$StaticMethod[[foo]]($TemplateParameter[[T]]()); 570 template <class $TemplateParameter[[T]]> 571 void $Function[[foo]](typename $TemplateParameter[[T]]::$DependentType[[Type]] 572 = $TemplateParameter[[T]]::$DependentName[[val]]); 575 template <class $TemplateParameter[[T]]> 576 void $Function[[foo]]($TemplateParameter[[T]] $Parameter[[P]]) { 577 $Parameter[[P]].$DependentName[[Field]]; 581 template <class $TemplateParameter[[T]]> 583 int $Method[[foo]]() { 584 return $TemplateParameter[[T]]::$DependentName[[Field]]; 590 void $Function[[foo]](); 591 using ::$Function[[foo]]; 595 template <template <class> class $TemplateParameter[[TT]], 596 template <class> class ...$TemplateParameter[[TTs]]> 597 struct $Class[[Foo]] { 598 $Class[[Foo]]<$TemplateParameter[[TT]], $TemplateParameter[[TTs]]...> 604 // Code in the preamble. 605 // Inactive lines get an empty InactiveCode token at the beginning. 606 $InactiveCode[[]] #ifdef $Macro[[test]] 607 $InactiveCode[[]] #endif 609 // A declaration to cause the preamble to end. 610 int $Variable[[EndPreamble]]; 612 // Code after the preamble. 613 // Code inside inactive blocks does not get regular highlightings 614 // because it's not part of the AST. 615 $InactiveCode[[]] #ifdef $Macro[[test]] 616 $InactiveCode[[]] int Inactive2; 617 $InactiveCode[[]] #endif 619 #ifndef $Macro[[test]] 620 int $Variable[[Active1]]; 623 $InactiveCode[[]] #ifdef $Macro[[test]] 624 $InactiveCode[[]] int Inactive3; 625 $InactiveCode[[]] #else 626 int $Variable[[Active2]]; 631 template <typename... $TemplateParameter[[Elements]]> 632 struct $Class[[TupleSize]] { 633 static const int $StaticField[[size]] = 634 sizeof...($TemplateParameter[[Elements]]); 639 template <typename $TemplateParameter[[T]]> 640 struct $Class[[Waldo]] { 641 using $Typedef[[Location1]] = typename $TemplateParameter[[T]] 642 ::$DependentType[[Resolver]]::$DependentType[[Location]]; 643 using $Typedef[[Location2]] = typename $TemplateParameter[[T]] 644 ::template $DependentType[[Resolver]]<$TemplateParameter[[T]]> 645 ::$DependentType[[Location]]; 646 using $Typedef[[Location3]] = typename $TemplateParameter[[T]] 647 ::$DependentType[[Resolver]] 648 ::template $DependentType[[Location]]<$TemplateParameter[[T]]>; 649 static const int $StaticField[[Value]] = $TemplateParameter[[T]] 650 ::$DependentType[[Resolver]]::$DependentName[[Value]]; 653 for (
const auto &TestCase : TestCases) {
654 checkHighlightings(TestCase);
657 checkHighlightings(R
"cpp( 669 checkHighlightings(R
"cpp( 675 #define DXYZ(X) class X {}; 676 #define DXYZ_Y(Y) DXYZ(x##Y) 677 #define DEFINE(X) int X; 678 #define DEFINE_Y DEFINE(Y) 682 TEST(SemanticHighlighting, GeneratesHighlightsWhenFileChange) { 683 class HighlightingsCounterDiagConsumer :
public DiagnosticsConsumer {
685 std::atomic<int> Count = {0};
687 void onDiagnosticsReady(
PathRef, std::vector<Diag>)
override {}
688 void onHighlightingsReady(
689 PathRef File, std::vector<HighlightingToken> Highlightings)
override {
696 FS.Files[FooCpp] =
"";
698 MockCompilationDatabase MCD;
701 Server.addDocument(FooCpp,
"int a;");
702 ASSERT_TRUE(
Server.blockUntilIdleForTest()) <<
"Waiting for server";
703 ASSERT_EQ(DiagConsumer.Count, 1);
707 auto CreatePosition = [](
int Line,
int Character) -> Position {
710 Pos.character = Character;
714 std::vector<LineHighlightings> Tokens{
717 Range{CreatePosition(3, 8), CreatePosition(3, 12)}},
719 Range{CreatePosition(3, 4), CreatePosition(3, 7)}}},
723 Range{CreatePosition(1, 1), CreatePosition(1, 5)}}},
725 std::vector<SemanticHighlightingInformation> ActualResults =
727 std::vector<SemanticHighlightingInformation> ExpectedResults = {
728 {3,
"AAAACAAEAAAAAAAEAAMAAw=="}, {1,
"AAAAAQAEAAA="}};
729 EXPECT_EQ(ActualResults, ExpectedResults);
732 TEST(SemanticHighlighting, HighlightingDiffer) {
734 llvm::StringRef OldCode;
735 llvm::StringRef NewCode;
752 $Class[[C]] $Variable[[V]] $Field[[F]] 758 $Class[[C]] $Variable[[V]] $Field[[F]] 777 $Class[[C]] $Variable[[V]] $Field[[F]] 783 $Class[[C]] $Variable[[V]] $Field[[F]] 819 for (
const auto &Test : TestCases)
820 checkDiffedHighlights(Test.OldCode, Test.NewCode);
823 TEST(SemanticHighlighting, DiffBeyondTheEndOfFile) {
824 llvm::StringRef OldCode =
831 llvm::StringRef NewCode = 833 $Class[[A]] // line 1 834 $Variable[[A]] // line 2 837 Annotations OldTest(OldCode); 838 Annotations NewTest(NewCode); 839 std::vector<HighlightingToken> OldTokens = getExpectedTokens(OldTest); 840 std::vector<HighlightingToken> NewTokens = getExpectedTokens(NewTest); 843 EXPECT_THAT(ActualDiff,
844 testing::UnorderedElementsAre(
845 testing::AllOf(LineNumber(3), EmptyHighlightings()),
846 testing::AllOf(LineNumber(4), EmptyHighlightings())));
llvm::StringRef PathRef
A typedef to represent a ref to file path.
static Options optsForTest()
std::vector< SemanticHighlightingInformation > toSemanticHighlightingInformation(llvm::ArrayRef< LineHighlightings > Tokens)
Convert to LSP's semantic highlighting information.
TEST(BackgroundQueueTest, Priority)
llvm::Expected< size_t > positionToOffset(llvm::StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Turn a [line, column] pair into an offset in Code.
std::string testPath(PathRef File)
std::vector< LineHighlightings > diffHighlightings(ArrayRef< HighlightingToken > New, ArrayRef< HighlightingToken > Old)
Return a line-by-line diff between two highlightings.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
CharSourceRange Range
SourceRange for the file name.
std::vector< HighlightingToken > getSemanticHighlightings(ParsedAST &AST)
IgnoreDiagnostics DiagConsumer
static llvm::Optional< ParsedAST > build(std::unique_ptr< clang::CompilerInvocation > CI, llvm::ArrayRef< Diag > CompilerInvocationDiags, std::shared_ptr< const PreambleData > Preamble, std::unique_ptr< llvm::MemoryBuffer > Buffer, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, const SymbolIndex *Index, const ParseOptions &Opts)
Attempts to run Clang and store parsed AST.