13 #include "clang/AST/Decl.h"
14 #include "llvm/Support/Casting.h"
15 #include "gmock/gmock.h"
16 #include "gtest/gtest.h"
21 using ::testing::UnorderedElementsAreArray;
26 SelectionTree makeSelectionTree(
const StringRef MarkedCode, ParsedAST &AST) {
27 Annotations Test(MarkedCode);
28 switch (Test.points().size()) {
40 ADD_FAILURE() <<
"Expected 1-2 points for selection.\n" << MarkedCode;
46 Range nodeRange(
const SelectionTree::Node *N, ParsedAST &AST) {
51 StringRef Buffer = SM.getBufferData(SM.getMainFileID());
52 if (llvm::isa_and_nonnull<TranslationUnitDecl>(N->ASTNode.get<
Decl>()))
56 assert(FileRange &&
"We should be able to get the File Range");
62 std::string nodeKind(
const SelectionTree::Node *N) {
63 return N ? N->kind() :
"<null>";
66 std::vector<const SelectionTree::Node *> allNodes(
const SelectionTree &T) {
67 std::vector<const SelectionTree::Node *> Result = {&T.root()};
68 for (
unsigned I = 0; I < Result.size(); ++I) {
69 const SelectionTree::Node *N = Result[I];
70 Result.insert(Result.end(), N->Children.begin(), N->Children.end());
77 bool verifyCommonAncestor(
const SelectionTree::Node &Root,
78 const SelectionTree::Node *Common,
79 StringRef MarkedCode) {
83 ADD_FAILURE() <<
"Selected nodes outside common ancestor\n" << MarkedCode;
85 for (
const SelectionTree::Node *Child : Root.Children)
86 if (verifyCommonAncestor(*Child, Common, MarkedCode)) {
88 ADD_FAILURE() <<
"Saw common ancestor twice\n" << MarkedCode;
94 TEST(SelectionTest, CommonAncestor) {
99 const char *CommonAncestorKind;
104 template <typename T>
105 int x = [[T::^U::]]ccc();
107 "NestedNameSpecifierLoc",
111 struct AAA { struct BBB { static int ccc(); };};
112 int x = AAA::[[B^B^B]]::ccc();
118 struct AAA { struct BBB { static int ccc(); };};
119 int x = AAA::[[B^BB^]]::ccc();
125 struct AAA { struct BBB { static int ccc(); };};
126 int x = [[AAA::BBB::c^c^c]]();
132 struct AAA { struct BBB { static int ccc(); };};
133 int x = [[AAA::BBB::cc^c(^)]];
140 void foo() { [[if (1^11) { return; } else {^ }]] }
147 #define M(foo) x(foo)
156 #define CALL_FUNCTION(X) X()
157 void bar() { CALL_FUNCTION([[f^o^o]]); }
164 #define CALL_FUNCTION(X) X()
165 void bar() { [[CALL_FUNC^TION(fo^o)]]; }
172 #define CALL_FUNCTION(X) X()
173 void bar() { [[C^ALL_FUNC^TION(foo)]]; }
180 #define CALL_FUNCTION(X) X^()^
181 void bar() { CALL_FUNCTION(foo); }
187 struct S { S(const char*); };
194 struct S { S(const char*); };
201 [[^void]] (*S)(int) = nullptr;
207 [[void (*S)^(int)]] = nullptr;
209 "FunctionProtoTypeLoc",
213 [[void (^*S)(int)]] = nullptr;
215 "FunctionProtoTypeLoc",
219 [[void (*^S)(int) = nullptr]];
225 [[void ^(*S)(int)]] = nullptr;
227 "FunctionProtoTypeLoc",
233 int bar() { return [[f^oo]](); }
240 auto lambda = [](const char*){ return 0; };
241 int x = lambda([["y^"]]);
247 {
"void foo() { [[^foo]](); }",
"DeclRefExpr"},
248 {
"void foo() { [[f^oo]](); }",
"DeclRefExpr"},
249 {
"void foo() { [[fo^o]](); }",
"DeclRefExpr"},
250 {
"void foo() { [[foo^()]]; }",
"CallExpr"},
251 {
"void foo() { [[foo^]] (); }",
"DeclRefExpr"},
252 {
"int bar; void foo() [[{ foo (); }]]^",
"CompoundStmt"},
253 {
"int x = [[42]]^;",
"IntegerLiteral"},
256 {
"void foo() { [[foo^()]]; /*comment*/^}",
"CallExpr"},
259 {
"[[^void]] foo();",
"BuiltinTypeLoc"},
260 {
"[[void foo^()]];",
"FunctionProtoTypeLoc"},
261 {
"[[^void foo^()]];",
"FunctionDecl"},
262 {
"[[void ^foo()]];",
"FunctionDecl"},
264 {
"[[int ^a]], b;",
"VarDecl"},
265 {
"[[int a, ^b]];",
"VarDecl"},
269 struct X { X(int); };
275 "CXXCtorInitializer",
278 {
"[[st^ruct {int x;}]] y;",
"CXXRecordDecl"},
279 {
"[[struct {int x;} ^y]];",
"VarDecl"},
280 {
"struct {[[int ^x]];} y;",
"FieldDecl"},
282 {
"const [[a^uto]] x = 42;",
"AutoTypeLoc"},
283 {
"[[co^nst auto x = 42]];",
"VarDecl"},
286 {
"void foo() { [[foo^^]] (); }",
"DeclRefExpr"},
290 {
"int x = 42;^",
nullptr},
293 {
"^int x; int y;^",
nullptr},
296 {
"template <typename T> void foo() { [[^T]] t; }",
297 "TemplateTypeParmTypeLoc"},
302 template <class T> struct Foo {};
303 template <[[template<class> class /*cursor here*/^U]]>
304 struct Foo<U<int>*> {};
306 "TemplateTemplateParmDecl"},
316 Str makeStr(const char*);
318 for (const char C : [[mak^eStr("foo"^)]])
329 Foo operator""_ud(unsigned long long);
332 "UserDefinedLiteral"},
337 decltype([[^a]] + a) b;
347 @property(retain) I*x;
348 @property(retain) I*y;
350 void test(I *f) { [[^f]].x.y = 0; }
356 @property(retain) I*x;
357 @property(retain) I*y;
359 void test(I *f) { [[f.^x]].y = 0; }
361 "ObjCPropertyRefExpr"},
368 int test(I *f) { return 42 + [[^f]].foo; }
376 int test(I *f) { return 42 + [[f.^foo]]; }
378 "ObjCPropertyRefExpr"},
379 {
"struct foo { [[int has^h<:32:>]]; };",
"FieldDecl"},
380 {
"struct foo { [[op^erator int()]]; };",
"CXXConversionDecl"},
381 {
"struct foo { [[^~foo()]]; };",
"CXXDestructorDecl"},
383 {
"struct foo { [[fo^o(){}]] };",
"CXXConstructorDecl"},
386 struct S1 { void f(); };
387 struct S2 { S1 * operator->(); };
391 )cpp", "DeclRefExpr"}
393 for (
const Case &C : Cases) {
395 Annotations Test(C.Code);
398 TU.Code = std::string(Test.code());
402 TU.ExtraArgs.push_back(
"-fno-delayed-template-parsing");
403 TU.ExtraArgs.push_back(
"-xobjective-c++");
405 auto AST = TU.
build();
406 auto T = makeSelectionTree(C.Code, AST);
407 EXPECT_EQ(
"TranslationUnitDecl", nodeKind(&T.root())) << C.Code;
409 if (Test.ranges().empty()) {
411 EXPECT_FALSE(T.commonAncestor()) << C.Code <<
"\n" << T;
412 EXPECT_THAT(
Tracer.takeMetric(
"selection_recovery"), testing::IsEmpty());
416 EXPECT_EQ(C.CommonAncestorKind, nodeKind(T.commonAncestor()))
420 EXPECT_EQ(nodeRange(T.commonAncestor(), AST), Test.range())
426 EXPECT_TRUE(verifyCommonAncestor(T.root(), T.commonAncestor(), C.Code))
428 EXPECT_THAT(
Tracer.takeMetric(
"selection_recovery"),
429 testing::ElementsAreArray({0}));
435 TEST(SelectionTest, InjectedClassName) {
436 const char *
Code =
"struct ^X { int x; };";
438 auto T = makeSelectionTree(
Code, AST);
439 ASSERT_EQ(
"CXXRecordDecl", nodeKind(T.commonAncestor())) << T;
440 auto *D = dyn_cast<CXXRecordDecl>(T.commonAncestor()->ASTNode.get<
Decl>());
441 EXPECT_FALSE(D->isInjectedClassName());
444 TEST(SelectionTree, Metrics) {
445 const char *
Code = R
"cpp(
446 // error-ok: testing behavior on recovery expression
453 auto T = makeSelectionTree(
Code, AST);
454 EXPECT_THAT(
Tracer.takeMetric(
"selection_recovery"),
455 testing::ElementsAreArray({1}));
456 EXPECT_THAT(
Tracer.takeMetric(
"selection_recovery_type"),
457 testing::ElementsAreArray({1}));
467 const char *Cases[] = {
468 R
"cpp( int abc, xyz = [[^ab^c]]; )cpp",
469 R"cpp( int abc, xyz = [[a^bc^]]; )cpp",
470 R"cpp( int abc, xyz = $C[[^abc^]]; )cpp",
473 [[if ([[1^11]]) $C[[{
482 struct unique_ptr {};
483 void foo(^$C[[unique_ptr<$C[[unique_ptr<$C[[int]]>]]>]]^ a) {}
485 R"cpp(int a = [[5 >^> 1]];)cpp",
488 ECHO(EC^HO($C[[int]]) EC^HO(a));
490 R"cpp( $C[[^$C[[int]] a^]]; )cpp",
491 R"cpp( $C[[^$C[[int]] a = $C[[5]]^]]; )cpp",
493 for (
const char *C : Cases) {
496 auto T = makeSelectionTree(C, AST);
498 std::vector<Range> Complete, Partial;
499 for (
const SelectionTree::Node *N : allNodes(T))
501 Complete.push_back(nodeRange(N, AST));
503 Partial.push_back(nodeRange(N, AST));
504 EXPECT_THAT(Complete, UnorderedElementsAreArray(Test.ranges(
"C"))) << C;
505 EXPECT_THAT(Partial, UnorderedElementsAreArray(Test.ranges())) << C;
509 TEST(SelectionTest, PathologicalPreprocessor) {
510 const char *Case = R
"cpp(
511 #define MACRO while(1)
513 #include "Expand.inc"
517 Annotations Test(Case);
520 auto AST = TU.
build();
522 auto T = makeSelectionTree(Case, AST);
524 EXPECT_EQ(
"BreakStmt", T.commonAncestor()->kind());
525 EXPECT_EQ(
"WhileStmt", T.commonAncestor()->Parent->kind());
528 TEST(SelectionTest, IncludedFile) {
529 const char *Case = R
"cpp(
531 #include "Exp^and.inc"
535 Annotations Test(Case);
538 auto AST = TU.
build();
539 auto T = makeSelectionTree(Case, AST);
541 EXPECT_EQ(
"WhileStmt", T.commonAncestor()->kind());
544 TEST(SelectionTest, MacroArgExpansion) {
547 const char *Case = R
"cpp(
549 #define SQUARE(X) mul(X, X);
550 int nine = SQUARE(^3);
552 Annotations Test(Case);
554 auto T = makeSelectionTree(Case, AST);
555 EXPECT_EQ(
"IntegerLiteral", T.commonAncestor()->kind());
556 EXPECT_TRUE(T.commonAncestor()->Selected);
561 void die(const char*);
562 #define assert(x) (x ? (void)0 : die(#x))
563 void foo() { assert(^42); }
565 Test = Annotations(Case);
567 T = makeSelectionTree(Case, AST);
569 EXPECT_EQ("IntegerLiteral", T.commonAncestor()->kind());
572 TEST(SelectionTest, Implicit) {
573 const char *Test = R
"cpp(
574 struct S { S(const char*); };
579 auto T = makeSelectionTree(Test, AST);
581 const SelectionTree::Node *Str = T.commonAncestor();
582 EXPECT_EQ(
"StringLiteral", nodeKind(Str)) <<
"Implicit selected?";
583 EXPECT_EQ(
"ImplicitCastExpr", nodeKind(Str->Parent));
584 EXPECT_EQ(
"CXXConstructExpr", nodeKind(Str->Parent->Parent));
585 EXPECT_EQ(Str, &Str->Parent->Parent->ignoreImplicit())
586 <<
"Didn't unwrap " << nodeKind(&Str->Parent->Parent->ignoreImplicit());
588 EXPECT_EQ(
"CXXConstructExpr", nodeKind(&Str->outerImplicit()));
591 TEST(SelectionTest, CreateAll) {
592 llvm::Annotations Test(
"int$unique^ a=1$ambiguous^+1; $empty^");
597 Test.point(
"ambiguous"), [&](SelectionTree T) {
600 EXPECT_EQ(
"BinaryOperator", nodeKind(T.commonAncestor()));
602 EXPECT_EQ(
"IntegerLiteral", nodeKind(T.commonAncestor()));
610 Test.point(
"ambiguous"), Test.point(
"ambiguous"),
611 [&](SelectionTree T) {
615 EXPECT_EQ(1u, Seen) <<
"Return true --> stop iterating";
619 Test.point(
"unique"), Test.point(
"unique"),
620 [&](SelectionTree T) {
624 EXPECT_EQ(1u, Seen) <<
"no ambiguity --> only one tree";
628 Test.point(
"empty"), Test.point(
"empty"),
629 [&](SelectionTree T) {
630 EXPECT_FALSE(T.commonAncestor());
634 EXPECT_EQ(1u, Seen) <<
"empty tree still created";
638 Test.point(
"unique"), Test.point(
"ambiguous"),
639 [&](SelectionTree T) {
643 EXPECT_EQ(1u, Seen) <<
"one tree for nontrivial selection";