9
9
#include " Selection.h"
10
10
#include " SourceCode.h"
11
11
#include " TestTU.h"
12
+ #include " clang/AST/Decl.h"
13
+ #include " llvm/Support/Casting.h"
12
14
#include " gmock/gmock.h"
13
15
#include " gtest/gtest.h"
14
16
@@ -40,6 +42,8 @@ Range nodeRange(const SelectionTree::Node *N, ParsedAST &AST) {
40
42
const SourceManager &SM = AST.getSourceManager ();
41
43
const LangOptions &LangOpts = AST.getASTContext ().getLangOpts ();
42
44
StringRef Buffer = SM.getBufferData (SM.getMainFileID ());
45
+ if (llvm::isa_and_nonnull<TranslationUnitDecl>(N->ASTNode .get <Decl>()))
46
+ return Range{Position{}, offsetToPosition (Buffer, Buffer.size ())};
43
47
auto FileRange =
44
48
toHalfOpenFileRange (SM, LangOpts, N->ASTNode .getSourceRange ());
45
49
assert (FileRange && " We should be able to get the File Range" );
@@ -53,7 +57,7 @@ std::string nodeKind(const SelectionTree::Node *N) {
53
57
}
54
58
55
59
std::vector<const SelectionTree::Node *> allNodes (const SelectionTree &T) {
56
- std::vector<const SelectionTree::Node *> Result = {T.root ()};
60
+ std::vector<const SelectionTree::Node *> Result = {& T.root ()};
57
61
for (unsigned I = 0 ; I < Result.size (); ++I) {
58
62
const SelectionTree::Node *N = Result[I];
59
63
Result.insert (Result.end (), N->Children .begin (), N->Children .end ());
@@ -63,16 +67,16 @@ std::vector<const SelectionTree::Node *> allNodes(const SelectionTree &T) {
63
67
64
68
// Returns true if Common is a descendent of Root.
65
69
// Verifies nothing is selected above Common.
66
- bool verifyCommonAncestor (const SelectionTree::Node * Root,
70
+ bool verifyCommonAncestor (const SelectionTree::Node & Root,
67
71
const SelectionTree::Node *Common,
68
72
StringRef MarkedCode) {
69
- if (Root == Common)
73
+ if (& Root == Common)
70
74
return true ;
71
- if (Root-> Selected )
75
+ if (Root. Selected )
72
76
ADD_FAILURE () << " Selected nodes outside common ancestor\n " << MarkedCode;
73
77
bool Seen = false ;
74
- for (const SelectionTree::Node *Child : Root-> Children )
75
- if (verifyCommonAncestor (Child, Common, MarkedCode)) {
78
+ for (const SelectionTree::Node *Child : Root. Children )
79
+ if (verifyCommonAncestor (* Child, Common, MarkedCode)) {
76
80
if (Seen)
77
81
ADD_FAILURE () << " Saw common ancestor twice\n " << MarkedCode;
78
82
Seen = true ;
@@ -239,6 +243,9 @@ TEST(SelectionTest, CommonAncestor) {
239
243
{" int x = 42;^" , nullptr },
240
244
{" int x = 42^;" , nullptr },
241
245
246
+ // Common ancestor is logically TUDecl, but we never return that.
247
+ {" ^int x; int y;^" , nullptr },
248
+
242
249
// Node types that have caused problems in the past.
243
250
{" template <typename T> void foo() { [[^T]] t; }" ,
244
251
" TemplateTypeParmTypeLoc" },
@@ -256,18 +263,17 @@ TEST(SelectionTest, CommonAncestor) {
256
263
Annotations Test (C.Code );
257
264
auto AST = TestTU::withCode (Test.code ()).build ();
258
265
auto T = makeSelectionTree (C.Code , AST);
266
+ EXPECT_EQ (" TranslationUnitDecl" , nodeKind (&T.root ())) << C.Code ;
259
267
260
268
if (Test.ranges ().empty ()) {
261
269
// If no [[range]] is marked in the example, there should be no selection.
262
270
EXPECT_FALSE (T.commonAncestor ()) << C.Code << " \n " << T;
263
- EXPECT_FALSE (T.root ()) << C.Code << " \n " << T;
264
271
} else {
265
- // If there is an expected selection, both common ancestor and root
266
- // should exist with the appropriate node types in them .
272
+ // If there is an expected selection, common ancestor should exist
273
+ // with the appropriate node type .
267
274
EXPECT_EQ (C.CommonAncestorKind , nodeKind (T.commonAncestor ()))
268
275
<< C.Code << " \n "
269
276
<< T;
270
- EXPECT_EQ (" TranslationUnitDecl" , nodeKind (T.root ())) << C.Code ;
271
277
// Convert the reported common ancestor to a range and verify it.
272
278
EXPECT_EQ (nodeRange (T.commonAncestor (), AST), Test.range ())
273
279
<< C.Code << " \n "
@@ -316,10 +322,10 @@ TEST(SelectionTest, Selected) {
316
322
void foo(^$C[[unique_ptr<$C[[unique_ptr<$C[[int]]>]]>]]^ a) {}
317
323
)cpp" ,
318
324
R"cpp( int a = [[5 >^> 1]];)cpp" ,
319
- R"cpp(
325
+ R"cpp( [[
320
326
#define ECHO(X) X
321
327
ECHO(EC^HO([[$C[[int]]) EC^HO(a]]));
322
- )cpp" ,
328
+ ]] )cpp" ,
323
329
};
324
330
for (const char *C : Cases) {
325
331
Annotations Test (C);
0 commit comments