1 //===-- SelectionTests.cpp - ----------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #include "Annotations.h"
9 #include "Selection.h"
10 #include "SourceCode.h"
11 #include "TestTU.h"
12 #include "support/TestTracer.h"
13 #include "clang/AST/Decl.h"
14 #include "llvm/Support/Casting.h"
15 #include "gmock/gmock.h"
16 #include "gtest/gtest.h"
17
18 namespace clang {
19 namespace clangd {
20 namespace {
21 using ::testing::ElementsAreArray;
22 using ::testing::UnorderedElementsAreArray;
23
24 // Create a selection tree corresponding to a point or pair of points.
25 // This uses the precisely-defined createRight semantics. The fuzzier
26 // createEach is tested separately.
makeSelectionTree(const StringRef MarkedCode,ParsedAST & AST)27 SelectionTree makeSelectionTree(const StringRef MarkedCode, ParsedAST &AST) {
28 Annotations Test(MarkedCode);
29 switch (Test.points().size()) {
30 case 1: { // Point selection.
31 unsigned Offset = cantFail(positionToOffset(Test.code(), Test.point()));
32 return SelectionTree::createRight(AST.getASTContext(), AST.getTokens(),
33 Offset, Offset);
34 }
35 case 2: // Range selection.
36 return SelectionTree::createRight(
37 AST.getASTContext(), AST.getTokens(),
38 cantFail(positionToOffset(Test.code(), Test.points()[0])),
39 cantFail(positionToOffset(Test.code(), Test.points()[1])));
40 default:
41 ADD_FAILURE() << "Expected 1-2 points for selection.\n" << MarkedCode;
42 return SelectionTree::createRight(AST.getASTContext(), AST.getTokens(), 0u,
43 0u);
44 }
45 }
46
nodeRange(const SelectionTree::Node * N,ParsedAST & AST)47 Range nodeRange(const SelectionTree::Node *N, ParsedAST &AST) {
48 if (!N)
49 return Range{};
50 const SourceManager &SM = AST.getSourceManager();
51 const LangOptions &LangOpts = AST.getLangOpts();
52 StringRef Buffer = SM.getBufferData(SM.getMainFileID());
53 if (llvm::isa_and_nonnull<TranslationUnitDecl>(N->ASTNode.get<Decl>()))
54 return Range{Position{}, offsetToPosition(Buffer, Buffer.size())};
55 auto FileRange =
56 toHalfOpenFileRange(SM, LangOpts, N->ASTNode.getSourceRange());
57 assert(FileRange && "We should be able to get the File Range");
58 return Range{
59 offsetToPosition(Buffer, SM.getFileOffset(FileRange->getBegin())),
60 offsetToPosition(Buffer, SM.getFileOffset(FileRange->getEnd()))};
61 }
62
nodeKind(const SelectionTree::Node * N)63 std::string nodeKind(const SelectionTree::Node *N) {
64 return N ? N->kind() : "<null>";
65 }
66
allNodes(const SelectionTree & T)67 std::vector<const SelectionTree::Node *> allNodes(const SelectionTree &T) {
68 std::vector<const SelectionTree::Node *> Result = {&T.root()};
69 for (unsigned I = 0; I < Result.size(); ++I) {
70 const SelectionTree::Node *N = Result[I];
71 Result.insert(Result.end(), N->Children.begin(), N->Children.end());
72 }
73 return Result;
74 }
75
76 // Returns true if Common is a descendent of Root.
77 // Verifies nothing is selected above Common.
verifyCommonAncestor(const SelectionTree::Node & Root,const SelectionTree::Node * Common,StringRef MarkedCode)78 bool verifyCommonAncestor(const SelectionTree::Node &Root,
79 const SelectionTree::Node *Common,
80 StringRef MarkedCode) {
81 if (&Root == Common)
82 return true;
83 if (Root.Selected)
84 ADD_FAILURE() << "Selected nodes outside common ancestor\n" << MarkedCode;
85 bool Seen = false;
86 for (const SelectionTree::Node *Child : Root.Children)
87 if (verifyCommonAncestor(*Child, Common, MarkedCode)) {
88 if (Seen)
89 ADD_FAILURE() << "Saw common ancestor twice\n" << MarkedCode;
90 Seen = true;
91 }
92 return Seen;
93 }
94
TEST(SelectionTest,CommonAncestor)95 TEST(SelectionTest, CommonAncestor) {
96 struct Case {
97 // Selection is between ^marks^.
98 // common ancestor marked with a [[range]].
99 const char *Code;
100 const char *CommonAncestorKind;
101 };
102 Case Cases[] = {
103 {
104 R"cpp(
105 template <typename T>
106 int x = [[T::^U::]]ccc();
107 )cpp",
108 "NestedNameSpecifierLoc",
109 },
110 {
111 R"cpp(
112 struct AAA { struct BBB { static int ccc(); };};
113 int x = AAA::[[B^B^B]]::ccc();
114 )cpp",
115 "RecordTypeLoc",
116 },
117 {
118 R"cpp(
119 struct AAA { struct BBB { static int ccc(); };};
120 int x = AAA::[[B^BB^]]::ccc();
121 )cpp",
122 "RecordTypeLoc",
123 },
124 {
125 R"cpp(
126 struct AAA { struct BBB { static int ccc(); };};
127 int x = [[AAA::BBB::c^c^c]]();
128 )cpp",
129 "DeclRefExpr",
130 },
131 {
132 R"cpp(
133 struct AAA { struct BBB { static int ccc(); };};
134 int x = [[AAA::BBB::cc^c(^)]];
135 )cpp",
136 "CallExpr",
137 },
138
139 {
140 R"cpp(
141 void foo() { [[if (1^11) { return; } else {^ }]] }
142 )cpp",
143 "IfStmt",
144 },
145 {
146 R"cpp(
147 int x(int);
148 #define M(foo) x(foo)
149 int a = 42;
150 int b = M([[^a]]);
151 )cpp",
152 "DeclRefExpr",
153 },
154 {
155 R"cpp(
156 void foo();
157 #define CALL_FUNCTION(X) X()
158 void bar() { CALL_FUNCTION([[f^o^o]]); }
159 )cpp",
160 "DeclRefExpr",
161 },
162 {
163 R"cpp(
164 void foo();
165 #define CALL_FUNCTION(X) X()
166 void bar() { [[CALL_FUNC^TION(fo^o)]]; }
167 )cpp",
168 "CallExpr",
169 },
170 {
171 R"cpp(
172 void foo();
173 #define CALL_FUNCTION(X) X()
174 void bar() { [[C^ALL_FUNC^TION(foo)]]; }
175 )cpp",
176 "CallExpr",
177 },
178 {
179 R"cpp(
180 void foo();
181 #^define CALL_FUNCTION(X) X(^)
182 void bar() { CALL_FUNCTION(foo); }
183 )cpp",
184 nullptr,
185 },
186 {
187 R"cpp(
188 void foo();
189 #define CALL_FUNCTION(X) X()
190 void bar() { CALL_FUNCTION(foo^)^; }
191 )cpp",
192 nullptr,
193 },
194 {
195 R"cpp(
196 namespace ns {
197 #if 0
198 void fo^o() {}
199 #endif
200 }
201 )cpp",
202 nullptr,
203 },
204 {
205 R"cpp(
206 struct S { S(const char*); };
207 S [[s ^= "foo"]];
208 )cpp",
209 "CXXConstructExpr",
210 },
211 {
212 R"cpp(
213 struct S { S(const char*); };
214 [[S ^s = "foo"]];
215 )cpp",
216 "VarDecl",
217 },
218 {
219 R"cpp(
220 [[^void]] (*S)(int) = nullptr;
221 )cpp",
222 "BuiltinTypeLoc",
223 },
224 {
225 R"cpp(
226 [[void (*S)^(int)]] = nullptr;
227 )cpp",
228 "FunctionProtoTypeLoc",
229 },
230 {
231 R"cpp(
232 [[void (^*S)(int)]] = nullptr;
233 )cpp",
234 "FunctionProtoTypeLoc",
235 },
236 {
237 R"cpp(
238 [[void (*^S)(int) = nullptr]];
239 )cpp",
240 "VarDecl",
241 },
242 {
243 R"cpp(
244 [[void ^(*S)(int)]] = nullptr;
245 )cpp",
246 "FunctionProtoTypeLoc",
247 },
248 {
249 R"cpp(
250 struct S {
251 int foo() const;
252 int bar() { return [[f^oo]](); }
253 };
254 )cpp",
255 "MemberExpr", // Not implicit CXXThisExpr, or its implicit cast!
256 },
257 {
258 R"cpp(
259 auto lambda = [](const char*){ return 0; };
260 int x = lambda([["y^"]]);
261 )cpp",
262 "StringLiteral", // Not DeclRefExpr to operator()!
263 },
264 {
265 R"cpp(
266 struct Foo {};
267 struct Bar : [[v^ir^tual private Foo]] {};
268 )cpp",
269 "CXXBaseSpecifier",
270 },
271 {
272 R"cpp(
273 struct Foo {};
274 struct Bar : private [[Fo^o]] {};
275 )cpp",
276 "RecordTypeLoc",
277 },
278 {
279 R"cpp(
280 struct Foo {};
281 struct Bar : [[Fo^o]] {};
282 )cpp",
283 "RecordTypeLoc",
284 },
285
286 // Point selections.
287 {"void foo() { [[^foo]](); }", "DeclRefExpr"},
288 {"void foo() { [[f^oo]](); }", "DeclRefExpr"},
289 {"void foo() { [[fo^o]](); }", "DeclRefExpr"},
290 {"void foo() { [[foo^()]]; }", "CallExpr"},
291 {"void foo() { [[foo^]] (); }", "DeclRefExpr"},
292 {"int bar; void foo() [[{ foo (); }]]^", "CompoundStmt"},
293 {"int x = [[42]]^;", "IntegerLiteral"},
294
295 // Ignores whitespace, comments, and semicolons in the selection.
296 {"void foo() { [[foo^()]]; /*comment*/^}", "CallExpr"},
297
298 // Tricky case: FunctionTypeLoc in FunctionDecl has a hole in it.
299 {"[[^void]] foo();", "BuiltinTypeLoc"},
300 {"[[void foo^()]];", "FunctionProtoTypeLoc"},
301 {"[[^void foo^()]];", "FunctionDecl"},
302 {"[[void ^foo()]];", "FunctionDecl"},
303 // Tricky case: two VarDecls share a specifier.
304 {"[[int ^a]], b;", "VarDecl"},
305 {"[[int a, ^b]];", "VarDecl"},
306 // Tricky case: CXXConstructExpr wants to claim the whole init range.
307 {
308 R"cpp(
309 struct X { X(int); };
310 class Y {
311 X x;
312 Y() : [[^x(4)]] {}
313 };
314 )cpp",
315 "CXXCtorInitializer", // Not the CXXConstructExpr!
316 },
317 // Tricky case: anonymous struct is a sibling of the VarDecl.
318 {"[[st^ruct {int x;}]] y;", "CXXRecordDecl"},
319 {"[[struct {int x;} ^y]];", "VarDecl"},
320 {"struct {[[int ^x]];} y;", "FieldDecl"},
321 // FIXME: the AST has no location info for qualifiers.
322 {"const [[a^uto]] x = 42;", "AutoTypeLoc"},
323 {"[[co^nst auto x = 42]];", "VarDecl"},
324
325 {"^", nullptr},
326 {"void foo() { [[foo^^]] (); }", "DeclRefExpr"},
327
328 // FIXME: Ideally we'd get a declstmt or the VarDecl itself here.
329 // This doesn't happen now; the RAV doesn't traverse a node containing ;.
330 {"int x = 42;^", nullptr},
331
332 // Common ancestor is logically TUDecl, but we never return that.
333 {"^int x; int y;^", nullptr},
334
335 // Node types that have caused problems in the past.
336 {"template <typename T> void foo() { [[^T]] t; }",
337 "TemplateTypeParmTypeLoc"},
338
339 // No crash
340 {
341 R"cpp(
342 template <class T> struct Foo {};
343 template <[[template<class> class /*cursor here*/^U]]>
344 struct Foo<U<int>*> {};
345 )cpp",
346 "TemplateTemplateParmDecl"},
347
348 // Foreach has a weird AST, ensure we can select parts of the range init.
349 // This used to fail, because the DeclStmt for C claimed the whole range.
350 {
351 R"cpp(
352 struct Str {
353 const char *begin();
354 const char *end();
355 };
356 Str makeStr(const char*);
357 void loop() {
358 for (const char C : [[mak^eStr("foo"^)]])
359 ;
360 }
361 )cpp",
362 "CallExpr"},
363
364 // User-defined literals are tricky: is 12_i one token or two?
365 // For now we treat it as one, and the UserDefinedLiteral as a leaf.
366 {
367 R"cpp(
368 struct Foo{};
369 Foo operator""_ud(unsigned long long);
370 Foo x = [[^12_ud]];
371 )cpp",
372 "UserDefinedLiteral"},
373
374 {
375 R"cpp(
376 int a;
377 decltype([[^a]] + a) b;
378 )cpp",
379 "DeclRefExpr"},
380
381 // Objective-C nullability attributes.
382 {
383 R"cpp(
384 @interface I{}
385 @property(nullable) [[^I]] *x;
386 @end
387 )cpp",
388 "ObjCInterfaceTypeLoc"},
389 {
390 R"cpp(
391 @interface I{}
392 - (void)doSomething:(nonnull [[i^d]])argument;
393 @end
394 )cpp",
395 "TypedefTypeLoc"},
396
397 // Objective-C OpaqueValueExpr/PseudoObjectExpr has weird ASTs.
398 // Need to traverse the contents of the OpaqueValueExpr to the POE,
399 // and ensure we traverse only the syntactic form of the PseudoObjectExpr.
400 {
401 R"cpp(
402 @interface I{}
403 @property(retain) I*x;
404 @property(retain) I*y;
405 @end
406 void test(I *f) { [[^f]].x.y = 0; }
407 )cpp",
408 "DeclRefExpr"},
409 {
410 R"cpp(
411 @interface I{}
412 @property(retain) I*x;
413 @property(retain) I*y;
414 @end
415 void test(I *f) { [[f.^x]].y = 0; }
416 )cpp",
417 "ObjCPropertyRefExpr"},
418 // Examples with implicit properties.
419 {
420 R"cpp(
421 @interface I{}
422 -(int)foo;
423 @end
424 int test(I *f) { return 42 + [[^f]].foo; }
425 )cpp",
426 "DeclRefExpr"},
427 {
428 R"cpp(
429 @interface I{}
430 -(int)foo;
431 @end
432 int test(I *f) { return 42 + [[f.^foo]]; }
433 )cpp",
434 "ObjCPropertyRefExpr"},
435 {"struct foo { [[int has^h<:32:>]]; };", "FieldDecl"},
436 {"struct foo { [[op^erator int()]]; };", "CXXConversionDecl"},
437 {"struct foo { [[^~foo()]]; };", "CXXDestructorDecl"},
438 // FIXME: The following to should be class itself instead.
439 {"struct foo { [[fo^o(){}]] };", "CXXConstructorDecl"},
440
441 {R"cpp(
442 struct S1 { void f(); };
443 struct S2 { S1 * operator->(); };
444 void test(S2 s2) {
445 s2[[-^>]]f();
446 }
447 )cpp",
448 "DeclRefExpr"}, // DeclRefExpr to the "operator->" method.
449
450 // Template template argument.
451 {R"cpp(
452 template <typename> class Vector {};
453 template <template <typename> class Container> class A {};
454 A<[[V^ector]]> a;
455 )cpp",
456 "TemplateArgumentLoc"}};
457
458 for (const Case &C : Cases) {
459 trace::TestTracer Tracer;
460 Annotations Test(C.Code);
461
462 TestTU TU;
463 TU.Code = std::string(Test.code());
464
465 // FIXME: Auto-completion in a template requires disabling delayed template
466 // parsing.
467 TU.ExtraArgs.push_back("-fno-delayed-template-parsing");
468 TU.ExtraArgs.push_back("-xobjective-c++");
469
470 auto AST = TU.build();
471 auto T = makeSelectionTree(C.Code, AST);
472 EXPECT_EQ("TranslationUnitDecl", nodeKind(&T.root())) << C.Code;
473
474 if (Test.ranges().empty()) {
475 // If no [[range]] is marked in the example, there should be no selection.
476 EXPECT_FALSE(T.commonAncestor()) << C.Code << "\n" << T;
477 EXPECT_THAT(Tracer.takeMetric("selection_recovery", "C++"),
478 testing::IsEmpty());
479 } else {
480 // If there is an expected selection, common ancestor should exist
481 // with the appropriate node type.
482 EXPECT_EQ(C.CommonAncestorKind, nodeKind(T.commonAncestor()))
483 << C.Code << "\n"
484 << T;
485 // Convert the reported common ancestor to a range and verify it.
486 EXPECT_EQ(nodeRange(T.commonAncestor(), AST), Test.range())
487 << C.Code << "\n"
488 << T;
489
490 // Check that common ancestor is reachable on exactly one path from root,
491 // and no nodes outside it are selected.
492 EXPECT_TRUE(verifyCommonAncestor(T.root(), T.commonAncestor(), C.Code))
493 << C.Code;
494 EXPECT_THAT(Tracer.takeMetric("selection_recovery", "C++"),
495 ElementsAreArray({0}));
496 }
497 }
498 }
499
500 // Regression test: this used to match the injected X, not the outer X.
TEST(SelectionTest,InjectedClassName)501 TEST(SelectionTest, InjectedClassName) {
502 const char *Code = "struct ^X { int x; };";
503 auto AST = TestTU::withCode(Annotations(Code).code()).build();
504 auto T = makeSelectionTree(Code, AST);
505 ASSERT_EQ("CXXRecordDecl", nodeKind(T.commonAncestor())) << T;
506 auto *D = dyn_cast<CXXRecordDecl>(T.commonAncestor()->ASTNode.get<Decl>());
507 EXPECT_FALSE(D->isInjectedClassName());
508 }
509
TEST(SelectionTree,Metrics)510 TEST(SelectionTree, Metrics) {
511 const char *Code = R"cpp(
512 // error-ok: testing behavior on recovery expression
513 int foo();
514 int foo(int, int);
515 int x = fo^o(42);
516 )cpp";
517 auto AST = TestTU::withCode(Annotations(Code).code()).build();
518 trace::TestTracer Tracer;
519 auto T = makeSelectionTree(Code, AST);
520 EXPECT_THAT(Tracer.takeMetric("selection_recovery", "C++"),
521 ElementsAreArray({1}));
522 EXPECT_THAT(Tracer.takeMetric("selection_recovery_type", "C++"),
523 ElementsAreArray({1}));
524 }
525
526 // FIXME: Doesn't select the binary operator node in
527 // #define FOO(X) X + 1
528 // int a, b = [[FOO(a)]];
TEST(SelectionTest,Selected)529 TEST(SelectionTest, Selected) {
530 // Selection with ^marks^.
531 // Partially selected nodes marked with a [[range]].
532 // Completely selected nodes marked with a $C[[range]].
533 const char *Cases[] = {
534 R"cpp( int abc, xyz = [[^ab^c]]; )cpp",
535 R"cpp( int abc, xyz = [[a^bc^]]; )cpp",
536 R"cpp( int abc, xyz = $C[[^abc^]]; )cpp",
537 R"cpp(
538 void foo() {
539 [[if ([[1^11]]) $C[[{
540 $C[[return]];
541 }]] else [[{^
542 }]]]]
543 char z;
544 }
545 )cpp",
546 R"cpp(
547 template <class T>
548 struct unique_ptr {};
549 void foo(^$C[[unique_ptr<$C[[unique_ptr<$C[[int]]>]]>]]^ a) {}
550 )cpp",
551 R"cpp(int a = [[5 >^> 1]];)cpp",
552 R"cpp(
553 #define ECHO(X) X
554 ECHO(EC^HO($C[[int]]) EC^HO(a));
555 )cpp",
556 R"cpp( $C[[^$C[[int]] a^]]; )cpp",
557 R"cpp( $C[[^$C[[int]] a = $C[[5]]^]]; )cpp",
558 };
559 for (const char *C : Cases) {
560 Annotations Test(C);
561 auto AST = TestTU::withCode(Test.code()).build();
562 auto T = makeSelectionTree(C, AST);
563
564 std::vector<Range> Complete, Partial;
565 for (const SelectionTree::Node *N : allNodes(T))
566 if (N->Selected == SelectionTree::Complete)
567 Complete.push_back(nodeRange(N, AST));
568 else if (N->Selected == SelectionTree::Partial)
569 Partial.push_back(nodeRange(N, AST));
570 EXPECT_THAT(Complete, UnorderedElementsAreArray(Test.ranges("C"))) << C;
571 EXPECT_THAT(Partial, UnorderedElementsAreArray(Test.ranges())) << C;
572 }
573 }
574
TEST(SelectionTest,PathologicalPreprocessor)575 TEST(SelectionTest, PathologicalPreprocessor) {
576 const char *Case = R"cpp(
577 #define MACRO while(1)
578 void test() {
579 #include "Expand.inc"
580 br^eak;
581 }
582 )cpp";
583 Annotations Test(Case);
584 auto TU = TestTU::withCode(Test.code());
585 TU.AdditionalFiles["Expand.inc"] = "MACRO\n";
586 auto AST = TU.build();
587 EXPECT_THAT(AST.getDiagnostics(), ::testing::IsEmpty());
588 auto T = makeSelectionTree(Case, AST);
589
590 EXPECT_EQ("BreakStmt", T.commonAncestor()->kind());
591 EXPECT_EQ("WhileStmt", T.commonAncestor()->Parent->kind());
592 }
593
TEST(SelectionTest,IncludedFile)594 TEST(SelectionTest, IncludedFile) {
595 const char *Case = R"cpp(
596 void test() {
597 #include "Exp^and.inc"
598 break;
599 }
600 )cpp";
601 Annotations Test(Case);
602 auto TU = TestTU::withCode(Test.code());
603 TU.AdditionalFiles["Expand.inc"] = "while(1)\n";
604 auto AST = TU.build();
605 auto T = makeSelectionTree(Case, AST);
606
607 EXPECT_EQ(nullptr, T.commonAncestor());
608 }
609
TEST(SelectionTest,MacroArgExpansion)610 TEST(SelectionTest, MacroArgExpansion) {
611 // If a macro arg is expanded several times, we only consider the first one
612 // selected.
613 const char *Case = R"cpp(
614 int mul(int, int);
615 #define SQUARE(X) mul(X, X);
616 int nine = SQUARE(^3);
617 )cpp";
618 Annotations Test(Case);
619 auto AST = TestTU::withCode(Test.code()).build();
620 auto T = makeSelectionTree(Case, AST);
621 EXPECT_EQ("IntegerLiteral", T.commonAncestor()->kind());
622 EXPECT_TRUE(T.commonAncestor()->Selected);
623
624 // Verify that the common assert() macro doesn't suffer from this.
625 // (This is because we don't associate the stringified token with the arg).
626 Case = R"cpp(
627 void die(const char*);
628 #define assert(x) (x ? (void)0 : die(#x))
629 void foo() { assert(^42); }
630 )cpp";
631 Test = Annotations(Case);
632 AST = TestTU::withCode(Test.code()).build();
633 T = makeSelectionTree(Case, AST);
634
635 EXPECT_EQ("IntegerLiteral", T.commonAncestor()->kind());
636 }
637
TEST(SelectionTest,Implicit)638 TEST(SelectionTest, Implicit) {
639 const char *Test = R"cpp(
640 struct S { S(const char*); };
641 int f(S);
642 int x = f("^");
643 )cpp";
644 auto AST = TestTU::withCode(Annotations(Test).code()).build();
645 auto T = makeSelectionTree(Test, AST);
646
647 const SelectionTree::Node *Str = T.commonAncestor();
648 EXPECT_EQ("StringLiteral", nodeKind(Str)) << "Implicit selected?";
649 EXPECT_EQ("ImplicitCastExpr", nodeKind(Str->Parent));
650 EXPECT_EQ("CXXConstructExpr", nodeKind(Str->Parent->Parent));
651 EXPECT_EQ(Str, &Str->Parent->Parent->ignoreImplicit())
652 << "Didn't unwrap " << nodeKind(&Str->Parent->Parent->ignoreImplicit());
653
654 EXPECT_EQ("CXXConstructExpr", nodeKind(&Str->outerImplicit()));
655 }
656
TEST(SelectionTest,CreateAll)657 TEST(SelectionTest, CreateAll) {
658 llvm::Annotations Test("int$unique^ a=1$ambiguous^+1; $empty^");
659 auto AST = TestTU::withCode(Test.code()).build();
660 unsigned Seen = 0;
661 SelectionTree::createEach(
662 AST.getASTContext(), AST.getTokens(), Test.point("ambiguous"),
663 Test.point("ambiguous"), [&](SelectionTree T) {
664 // Expect to see the right-biased tree first.
665 if (Seen == 0)
666 EXPECT_EQ("BinaryOperator", nodeKind(T.commonAncestor()));
667 else if (Seen == 1)
668 EXPECT_EQ("IntegerLiteral", nodeKind(T.commonAncestor()));
669 ++Seen;
670 return false;
671 });
672 EXPECT_EQ(2u, Seen);
673
674 Seen = 0;
675 SelectionTree::createEach(AST.getASTContext(), AST.getTokens(),
676 Test.point("ambiguous"), Test.point("ambiguous"),
677 [&](SelectionTree T) {
678 ++Seen;
679 return true;
680 });
681 EXPECT_EQ(1u, Seen) << "Return true --> stop iterating";
682
683 Seen = 0;
684 SelectionTree::createEach(AST.getASTContext(), AST.getTokens(),
685 Test.point("unique"), Test.point("unique"),
686 [&](SelectionTree T) {
687 ++Seen;
688 return false;
689 });
690 EXPECT_EQ(1u, Seen) << "no ambiguity --> only one tree";
691
692 Seen = 0;
693 SelectionTree::createEach(AST.getASTContext(), AST.getTokens(),
694 Test.point("empty"), Test.point("empty"),
695 [&](SelectionTree T) {
696 EXPECT_FALSE(T.commonAncestor());
697 ++Seen;
698 return false;
699 });
700 EXPECT_EQ(1u, Seen) << "empty tree still created";
701
702 Seen = 0;
703 SelectionTree::createEach(AST.getASTContext(), AST.getTokens(),
704 Test.point("unique"), Test.point("ambiguous"),
705 [&](SelectionTree T) {
706 ++Seen;
707 return false;
708 });
709 EXPECT_EQ(1u, Seen) << "one tree for nontrivial selection";
710 }
711
712 } // namespace
713 } // namespace clangd
714 } // namespace clang
715