12 #include "gmock/gmock.h" 13 #include "gtest/gtest.h" 18 using ::testing::UnorderedElementsAreArray;
20 SelectionTree makeSelectionTree(
const StringRef MarkedCode, ParsedAST &AST) {
21 Annotations Test(MarkedCode);
22 switch (Test.points().size()) {
24 return SelectionTree(AST.getASTContext(),
32 ADD_FAILURE() <<
"Expected 1-2 points for selection.\n" << MarkedCode;
33 return SelectionTree(AST.getASTContext(), 0u, 0u);
37 Range nodeRange(
const SelectionTree::Node *N, ParsedAST &AST) {
40 SourceManager &SM = AST.getSourceManager();
41 StringRef Buffer = SM.getBufferData(SM.getMainFileID());
42 SourceRange SR = N->ASTNode.getSourceRange();
43 SR.setBegin(SM.getFileLoc(SR.getBegin()));
44 SR.setEnd(SM.getFileLoc(SR.getEnd()));
46 Lexer::getAsCharRange(SR, SM, AST.getASTContext().getLangOpts());
51 std::string nodeKind(
const SelectionTree::Node *N) {
54 return N->ASTNode.getNodeKind().asStringRef().str();
57 std::vector<const SelectionTree::Node *> allNodes(
const SelectionTree &T) {
58 std::vector<const SelectionTree::Node *>
Result = {T.root()};
59 for (
unsigned I = 0; I < Result.size(); ++I) {
60 const SelectionTree::Node *N = Result[I];
61 Result.insert(Result.end(), N->Children.begin(), N->Children.end());
68 bool verifyCommonAncestor(
const SelectionTree::Node *Root,
69 const SelectionTree::Node *Common,
70 StringRef MarkedCode) {
74 ADD_FAILURE() <<
"Selected nodes outside common ancestor\n" << MarkedCode;
76 for (
const SelectionTree::Node *Child : Root->Children)
77 if (verifyCommonAncestor(Child, Common, MarkedCode)) {
79 ADD_FAILURE() <<
"Saw common ancestor twice\n" << MarkedCode;
85 TEST(SelectionTest, CommonAncestor) {
90 const char *CommonAncestorKind;
96 int x = [[T::^U::]]ccc(); 98 "NestedNameSpecifierLoc",
102 struct AAA { struct BBB { static int ccc(); };}; 103 int x = AAA::[[B^B^B]]::ccc(); 109 struct AAA { struct BBB { static int ccc(); };}; 110 int x = AAA::[[B^BB^]]::ccc(); 116 struct AAA { struct BBB { static int ccc(); };}; 117 int x = [[AAA::BBB::c^c^c]](); 123 struct AAA { struct BBB { static int ccc(); };}; 124 int x = [[AAA::BBB::cc^c(^)]]; 131 void foo() { [[if (1^11) { return; } else {^ }]] } 138 #define CALL_FUNCTION(X) X() 139 void bar() { CALL_FUNCTION([[f^o^o]]); } 146 #define CALL_FUNCTION(X) X() 147 void bar() [[{ CALL_FUNC^TION(fo^o); }]] 154 #define CALL_FUNCTION(X) X() 155 void bar() [[{ C^ALL_FUNC^TION(foo); }]] 162 #define CALL_FUNCTION(X) X^()^ 163 void bar() { CALL_FUNCTION(foo); } 169 struct S { S(const char*); }; 176 struct S { S(const char*); }; 183 [[^void]] (*S)(int) = nullptr; 189 [[void (*S)^(int)]] = nullptr; 195 [[void (^*S)(int)]] = nullptr; 201 [[void (*^S)(int) = nullptr]]; 207 [[void ^(*S)(int)]] = nullptr; 213 {
"void foo() { [[^foo]](); }",
"DeclRefExpr"},
214 {
"void foo() { [[f^oo]](); }",
"DeclRefExpr"},
215 {
"void foo() { [[fo^o]](); }",
"DeclRefExpr"},
216 {
"void foo() { [[foo^()]]; }",
"CallExpr"},
217 {
"void foo() { [[foo^]] (); }",
"DeclRefExpr"},
218 {
"int bar; void foo() [[{ foo (); }]]^",
"CompoundStmt"},
221 {
"[[^void]] foo();",
"TypeLoc"},
222 {
"[[void foo^()]];",
"TypeLoc"},
223 {
"[[^void foo^()]];",
"FunctionDecl"},
224 {
"[[void ^foo()]];",
"FunctionDecl"},
226 {
"[[int ^a]], b;",
"VarDecl"},
227 {
"[[int a, ^b]];",
"VarDecl"},
229 {
"[[st^ruct {int x;}]] y;",
"CXXRecordDecl"},
230 {
"[[struct {int x;} ^y]];",
"VarDecl"},
231 {
"struct {[[int ^x]];} y;",
"FieldDecl"},
234 {
"void foo() { [[foo^^]] (); }",
"DeclRefExpr"},
238 {
"int x = 42;^",
nullptr},
239 {
"int x = 42^;",
nullptr},
242 {
"template <typename T> void foo() { [[^T]] t; }",
"TypeLoc"},
247 template <class T> struct Foo {}; 248 template <[[template<class> class /*cursor here*/^U]]> 249 struct Foo<U<int>*> {}; 251 "TemplateTemplateParmDecl"},
253 for (
const Case &C : Cases) {
254 Annotations Test(C.Code);
256 auto T = makeSelectionTree(C.Code, AST);
258 if (Test.ranges().empty()) {
260 EXPECT_FALSE(T.commonAncestor()) << C.Code <<
"\n" << T;
261 EXPECT_FALSE(T.root()) << C.Code <<
"\n" << T;
265 EXPECT_EQ(C.CommonAncestorKind, nodeKind(T.commonAncestor()))
268 EXPECT_EQ(
"TranslationUnitDecl", nodeKind(T.root())) << C.Code;
270 EXPECT_EQ(nodeRange(T.commonAncestor(),
AST), Test.range())
276 EXPECT_TRUE(verifyCommonAncestor(T.root(), T.commonAncestor(), C.Code))
283 TEST(SelectionTest, InjectedClassName) {
284 const char* Code =
"struct ^X { int x; };";
286 auto T = makeSelectionTree(Code, AST);
287 ASSERT_EQ(
"CXXRecordDecl", nodeKind(T.commonAncestor())) << T;
288 auto *
D = dyn_cast<CXXRecordDecl>(T.commonAncestor()->ASTNode.get<Decl>());
289 EXPECT_FALSE(
D->isInjectedClassName());
292 TEST(SelectionTest, Selected) {
296 const char *Cases[] = {
297 R
"cpp( int abc, xyz = [[^ab^c]]; )cpp", 298 R"cpp( int abc, xyz = [[a^bc^]]; )cpp", 299 R"cpp( int abc, xyz = $C[[^abc^]]; )cpp", 302 [[if ([[1^11]]) $C[[{ 310 struct unique_ptr {}; 311 void foo(^$C[[unique_ptr<unique_ptr<$C[[int]]>>]]^ a) {} 314 for (
const char *C : Cases) {
317 auto T = makeSelectionTree(C, AST);
319 std::vector<Range> Complete, Partial;
320 for (
const SelectionTree::Node *N : allNodes(T))
322 Complete.push_back(nodeRange(N, AST));
324 Partial.push_back(nodeRange(N, AST));
325 EXPECT_THAT(Complete, UnorderedElementsAreArray(Test.ranges(
"C"))) << C;
326 EXPECT_THAT(Partial, UnorderedElementsAreArray(Test.ranges())) << C;
Position offsetToPosition(llvm::StringRef Code, size_t Offset)
Turn an offset in Code into a [line, column] pair.
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.
static TestTU withCode(llvm::StringRef Code)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
CharSourceRange Range
SourceRange for the file name.
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result