1 //===- unittest/Tooling/SourceCodeTest.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 
9 #include "clang/Tooling/Transformer/SourceCode.h"
10 #include "TestVisitor.h"
11 #include "clang/Basic/Diagnostic.h"
12 #include "llvm/Testing/Support/Annotations.h"
13 #include "llvm/Testing/Support/Error.h"
14 #include "llvm/Testing/Support/SupportHelpers.h"
15 #include <gmock/gmock.h>
16 #include <gtest/gtest.h>
17 
18 using namespace clang;
19 
20 using llvm::Failed;
21 using llvm::Succeeded;
22 using llvm::ValueIs;
23 using tooling::getAssociatedRange;
24 using tooling::getExtendedText;
25 using tooling::getRangeForEdit;
26 using tooling::getText;
27 using tooling::validateEditRange;
28 
29 namespace {
30 
31 struct IntLitVisitor : TestVisitor<IntLitVisitor> {
32   bool VisitIntegerLiteral(IntegerLiteral *Expr) {
33     OnIntLit(Expr, Context);
34     return true;
35   }
36 
37   std::function<void(IntegerLiteral *, ASTContext *Context)> OnIntLit;
38 };
39 
40 struct CallsVisitor : TestVisitor<CallsVisitor> {
41   bool VisitCallExpr(CallExpr *Expr) {
42     OnCall(Expr, Context);
43     return true;
44   }
45 
46   std::function<void(CallExpr *, ASTContext *Context)> OnCall;
47 };
48 
49 // Equality matcher for `clang::CharSourceRange`, which lacks `operator==`.
50 MATCHER_P(EqualsRange, R, "") {
51   return arg.isTokenRange() == R.isTokenRange() &&
52          arg.getBegin() == R.getBegin() && arg.getEnd() == R.getEnd();
53 }
54 
55 MATCHER_P2(EqualsAnnotatedRange, SM, R, "") {
56   if (arg.getBegin().isMacroID()) {
57     *result_listener << "which starts in a macro";
58     return false;
59   }
60   if (arg.getEnd().isMacroID()) {
61     *result_listener << "which ends in a macro";
62     return false;
63   }
64 
65   unsigned Begin = SM->getFileOffset(arg.getBegin());
66   unsigned End = SM->getFileOffset(arg.getEnd());
67 
68   *result_listener << "which is [" << Begin << ",";
69   if (arg.isTokenRange()) {
70     *result_listener << End << "]";
71     return Begin == R.Begin && End + 1 == R.End;
72   }
73   *result_listener << End << ")";
74   return Begin == R.Begin && End == R.End;
75 }
76 
77 static ::testing::Matcher<CharSourceRange> AsRange(const SourceManager &SM,
78                                                    llvm::Annotations::Range R) {
79   return EqualsRange(CharSourceRange::getCharRange(
80       SM.getLocForStartOfFile(SM.getMainFileID()).getLocWithOffset(R.Begin),
81       SM.getLocForStartOfFile(SM.getMainFileID()).getLocWithOffset(R.End)));
82 }
83 
84 // Base class for visitors that expect a single match corresponding to a
85 // specific annotated range.
86 template <typename T> class AnnotatedCodeVisitor : public TestVisitor<T> {
87   llvm::Annotations Code;
88   int MatchCount = 0;
89 
90 public:
91   AnnotatedCodeVisitor() : Code("$r[[]]") {}
92   bool VisitDeclHelper(Decl *Decl) {
93     // Only consider explicit declarations.
94     if (Decl->isImplicit())
95       return true;
96 
97     ++MatchCount;
98     EXPECT_THAT(getAssociatedRange(*Decl, *this->Context),
99                 EqualsAnnotatedRange(&this->Context->getSourceManager(),
100                                      Code.range("r")))
101         << Code.code();
102     return true;
103   }
104 
105   bool runOverAnnotated(llvm::StringRef AnnotatedCode,
106                         std::vector<std::string> Args = {}) {
107     Code = llvm::Annotations(AnnotatedCode);
108     MatchCount = 0;
109     Args.push_back("-std=c++11");
110     Args.push_back("-fno-delayed-template-parsing");
111     bool result = tooling::runToolOnCodeWithArgs(this->CreateTestAction(),
112                                                  Code.code(), Args);
113     EXPECT_EQ(MatchCount, 1) << AnnotatedCode;
114     return result;
115   }
116 };
117 
118 TEST(SourceCodeTest, getText) {
119   CallsVisitor Visitor;
120 
121   Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
122     EXPECT_EQ("foo(x, y)", getText(*CE, *Context));
123   };
124   Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
125 
126   Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
127     EXPECT_EQ("APPLY(foo, x, y)", getText(*CE, *Context));
128   };
129   Visitor.runOver("#define APPLY(f, x, y) f(x, y)\n"
130                   "void foo(int x, int y) { APPLY(foo, x, y); }");
131 }
132 
133 TEST(SourceCodeTest, getTextWithMacro) {
134   CallsVisitor Visitor;
135 
136   Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
137     EXPECT_EQ("F OO", getText(*CE, *Context));
138     Expr *P0 = CE->getArg(0);
139     Expr *P1 = CE->getArg(1);
140     EXPECT_EQ("", getText(*P0, *Context));
141     EXPECT_EQ("", getText(*P1, *Context));
142   };
143   Visitor.runOver("#define F foo(\n"
144                   "#define OO x, y)\n"
145                   "void foo(int x, int y) { F OO ; }");
146 
147   Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
148     EXPECT_EQ("", getText(*CE, *Context));
149     Expr *P0 = CE->getArg(0);
150     Expr *P1 = CE->getArg(1);
151     EXPECT_EQ("x", getText(*P0, *Context));
152     EXPECT_EQ("y", getText(*P1, *Context));
153   };
154   Visitor.runOver("#define FOO(x, y) (void)x; (void)y; foo(x, y);\n"
155                   "void foo(int x, int y) { FOO(x,y) }");
156 }
157 
158 TEST(SourceCodeTest, getExtendedText) {
159   CallsVisitor Visitor;
160 
161   Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
162     EXPECT_EQ("foo(x, y);",
163               getExtendedText(*CE, tok::TokenKind::semi, *Context));
164 
165     Expr *P0 = CE->getArg(0);
166     Expr *P1 = CE->getArg(1);
167     EXPECT_EQ("x", getExtendedText(*P0, tok::TokenKind::semi, *Context));
168     EXPECT_EQ("x,", getExtendedText(*P0, tok::TokenKind::comma, *Context));
169     EXPECT_EQ("y", getExtendedText(*P1, tok::TokenKind::semi, *Context));
170   };
171   Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
172   Visitor.runOver("void foo(int x, int y) { if (true) foo(x, y); }");
173   Visitor.runOver("int foo(int x, int y) { if (true) return 3 + foo(x, y); }");
174   Visitor.runOver("void foo(int x, int y) { for (foo(x, y);;) ++x; }");
175   Visitor.runOver(
176       "bool foo(int x, int y) { for (;foo(x, y);) x = 1; return true; }");
177 
178   Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
179     EXPECT_EQ("foo()", getExtendedText(*CE, tok::TokenKind::semi, *Context));
180   };
181   Visitor.runOver("bool foo() { if (foo()) return true; return false; }");
182   Visitor.runOver("void foo() { int x; for (;; foo()) ++x; }");
183   Visitor.runOver("int foo() { return foo() + 3; }");
184 }
185 
186 TEST(SourceCodeTest, getAssociatedRange) {
187   struct VarDeclsVisitor : AnnotatedCodeVisitor<VarDeclsVisitor> {
188     bool VisitVarDecl(VarDecl *Decl) { return VisitDeclHelper(Decl); }
189   };
190   VarDeclsVisitor Visitor;
191 
192   // Includes semicolon.
193   Visitor.runOverAnnotated("$r[[int x = 4;]]");
194 
195   // Includes newline and semicolon.
196   Visitor.runOverAnnotated("$r[[int x = 4;\n]]");
197 
198   // Includes trailing comments.
199   Visitor.runOverAnnotated("$r[[int x = 4; // Comment\n]]");
200   Visitor.runOverAnnotated("$r[[int x = 4; /* Comment */\n]]");
201 
202   // Does *not* include trailing comments when another entity appears between
203   // the decl and the comment.
204   Visitor.runOverAnnotated("$r[[int x = 4;]] class C {}; // Comment\n");
205 
206   // Includes attributes.
207   Visitor.runOverAnnotated(R"cpp(
208       #define ATTR __attribute__((deprecated("message")))
209       $r[[ATTR
210       int x;]])cpp");
211 
212   // Includes attributes and comments together.
213   Visitor.runOverAnnotated(R"cpp(
214       #define ATTR __attribute__((deprecated("message")))
215       $r[[ATTR
216       // Commment.
217       int x;]])cpp");
218 }
219 
220 TEST(SourceCodeTest, getAssociatedRangeClasses) {
221   struct RecordDeclsVisitor : AnnotatedCodeVisitor<RecordDeclsVisitor> {
222     bool VisitRecordDecl(RecordDecl *Decl) { return VisitDeclHelper(Decl); }
223   };
224   RecordDeclsVisitor Visitor;
225 
226   Visitor.runOverAnnotated("$r[[class A;]]");
227   Visitor.runOverAnnotated("$r[[class A {};]]");
228 
229   // Includes leading template annotation.
230   Visitor.runOverAnnotated("$r[[template <typename T> class A;]]");
231   Visitor.runOverAnnotated("$r[[template <typename T> class A {};]]");
232 }
233 
234 TEST(SourceCodeTest, getAssociatedRangeClassTemplateSpecializations) {
235   struct CXXRecordDeclsVisitor : AnnotatedCodeVisitor<CXXRecordDeclsVisitor> {
236     bool VisitCXXRecordDecl(CXXRecordDecl *Decl) {
237       return Decl->getTemplateSpecializationKind() !=
238                  TSK_ExplicitSpecialization ||
239              VisitDeclHelper(Decl);
240     }
241   };
242   CXXRecordDeclsVisitor Visitor;
243 
244   Visitor.runOverAnnotated(R"cpp(
245       template <typename T> class A{};
246       $r[[template <> class A<int>;]])cpp");
247   Visitor.runOverAnnotated(R"cpp(
248       template <typename T> class A{};
249       $r[[template <> class A<int> {};]])cpp");
250 }
251 
252 TEST(SourceCodeTest, getAssociatedRangeFunctions) {
253   struct FunctionDeclsVisitor : AnnotatedCodeVisitor<FunctionDeclsVisitor> {
254     bool VisitFunctionDecl(FunctionDecl *Decl) { return VisitDeclHelper(Decl); }
255   };
256   FunctionDeclsVisitor Visitor;
257 
258   Visitor.runOverAnnotated("$r[[int f();]]");
259   Visitor.runOverAnnotated("$r[[int f() { return 0; }]]");
260   // Includes leading template annotation.
261   Visitor.runOverAnnotated("$r[[template <typename T> int f();]]");
262   Visitor.runOverAnnotated("$r[[template <typename T> int f() { return 0; }]]");
263 }
264 
265 TEST(SourceCodeTest, getAssociatedRangeMemberTemplates) {
266   struct CXXMethodDeclsVisitor : AnnotatedCodeVisitor<CXXMethodDeclsVisitor> {
267     bool VisitCXXMethodDecl(CXXMethodDecl *Decl) {
268       // Only consider the definition of the template.
269       return !Decl->doesThisDeclarationHaveABody() || VisitDeclHelper(Decl);
270     }
271   };
272   CXXMethodDeclsVisitor Visitor;
273 
274   Visitor.runOverAnnotated(R"cpp(
275       template <typename C>
276       struct A { template <typename T> int member(T v); };
277 
278       $r[[template <typename C>
279       template  <typename T>
280       int A<C>::member(T v) { return 0; }]])cpp");
281 }
282 
283 TEST(SourceCodeTest, getAssociatedRangeWithComments) {
284   struct VarDeclsVisitor : AnnotatedCodeVisitor<VarDeclsVisitor> {
285     bool VisitVarDecl(VarDecl *Decl) { return VisitDeclHelper(Decl); }
286   };
287 
288   VarDeclsVisitor Visitor;
289   auto Visit = [&](llvm::StringRef AnnotatedCode) {
290     Visitor.runOverAnnotated(AnnotatedCode, {"-fparse-all-comments"});
291   };
292 
293   // Includes leading comments.
294   Visit("$r[[// Comment.\nint x = 4;]]");
295   Visit("$r[[// Comment.\nint x = 4;\n]]");
296   Visit("$r[[/* Comment.*/\nint x = 4;\n]]");
297   // ... even if separated by (extra) horizontal whitespace.
298   Visit("$r[[/* Comment.*/  \nint x = 4;\n]]");
299 
300   // Includes comments even in the presence of trailing whitespace.
301   Visit("$r[[// Comment.\nint x = 4;]]  ");
302 
303   // Includes comments when the declaration is followed by the beginning or end
304   // of a compound statement.
305   Visit(R"cpp(
306   void foo() {
307     $r[[/* C */
308     int x = 4;
309   ]]};)cpp");
310   Visit(R"cpp(
311   void foo() {
312     $r[[/* C */
313     int x = 4;
314    ]]{ class Foo {}; }
315    })cpp");
316 
317   // Includes comments inside macros (when decl is in the same macro).
318   Visit(R"cpp(
319       #define DECL /* Comment */ int x
320       $r[[DECL;]])cpp");
321 
322   // Does not include comments when only the decl or the comment come from a
323   // macro.
324   // FIXME: Change code to allow this.
325   Visit(R"cpp(
326       #define DECL int x
327       // Comment
328       $r[[DECL;]])cpp");
329   Visit(R"cpp(
330       #define COMMENT /* Comment */
331       COMMENT
332       $r[[int x;]])cpp");
333 
334   // Includes multi-line comments.
335   Visit(R"cpp(
336       $r[[/* multi
337        * line
338        * comment
339        */
340       int x;]])cpp");
341   Visit(R"cpp(
342       $r[[// multi
343       // line
344       // comment
345       int x;]])cpp");
346 
347   // Does not include comments separated by multiple empty lines.
348   Visit("// Comment.\n\n\n$r[[int x = 4;\n]]");
349   Visit("/* Comment.*/\n\n\n$r[[int x = 4;\n]]");
350 
351   // Does not include comments before a *series* of declarations.
352   Visit(R"cpp(
353       // Comment.
354       $r[[int x = 4;
355       ]]class foo {};)cpp");
356 
357   // Does not include IfThisThenThat comments
358   Visit("// LINT.IfChange.\n$r[[int x = 4;]]");
359   Visit("// LINT.ThenChange.\n$r[[int x = 4;]]");
360 
361   // Includes attributes.
362   Visit(R"cpp(
363       #define ATTR __attribute__((deprecated("message")))
364       $r[[ATTR
365       int x;]])cpp");
366 
367   // Includes attributes and comments together.
368   Visit(R"cpp(
369       #define ATTR __attribute__((deprecated("message")))
370       $r[[ATTR
371       // Commment.
372       int x;]])cpp");
373 }
374 
375 TEST(SourceCodeTest, getAssociatedRangeInvalidForPartialExpansions) {
376   struct FailingVarDeclsVisitor : TestVisitor<FailingVarDeclsVisitor> {
377     FailingVarDeclsVisitor() {}
378     bool VisitVarDecl(VarDecl *Decl) {
379       EXPECT_TRUE(getAssociatedRange(*Decl, *Context).isInvalid());
380       return true;
381     }
382   };
383 
384   FailingVarDeclsVisitor Visitor;
385   // Should fail because it only includes a part of the expansion.
386   std::string Code = R"cpp(
387       #define DECL class foo { }; int x
388       DECL;)cpp";
389   Visitor.runOver(Code);
390 }
391 
392 TEST(SourceCodeTest, EditRangeWithMacroExpansionsShouldSucceed) {
393   // The call expression, whose range we are extracting, includes two macro
394   // expansions.
395   llvm::Annotations Code(R"cpp(
396 #define M(a) a * 13
397 int foo(int x, int y);
398 int a = $r[[foo(M(1), M(2))]];
399 )cpp");
400 
401   CallsVisitor Visitor;
402 
403   Visitor.OnCall = [&Code](CallExpr *CE, ASTContext *Context) {
404     auto Range = CharSourceRange::getTokenRange(CE->getSourceRange());
405     EXPECT_THAT(getRangeForEdit(Range, *Context),
406                 ValueIs(AsRange(Context->getSourceManager(), Code.range("r"))));
407   };
408   Visitor.runOver(Code.code());
409 }
410 
411 TEST(SourceCodeTest, EditWholeMacroExpansionShouldSucceed) {
412   llvm::Annotations Code(R"cpp(
413 #define FOO 10
414 int a = $r[[FOO]];
415 )cpp");
416 
417   IntLitVisitor Visitor;
418   Visitor.OnIntLit = [&Code](IntegerLiteral *Expr, ASTContext *Context) {
419     auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange());
420     EXPECT_THAT(getRangeForEdit(Range, *Context),
421                 ValueIs(AsRange(Context->getSourceManager(), Code.range("r"))));
422   };
423   Visitor.runOver(Code.code());
424 }
425 
426 TEST(SourceCodeTest, EditPartialMacroExpansionShouldFail) {
427   std::string Code = R"cpp(
428 #define BAR 10+
429 int c = BAR 3.0;
430 )cpp";
431 
432   IntLitVisitor Visitor;
433   Visitor.OnIntLit = [](IntegerLiteral *Expr, ASTContext *Context) {
434     auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange());
435     EXPECT_FALSE(getRangeForEdit(Range, *Context).hasValue());
436   };
437   Visitor.runOver(Code);
438 }
439 
440 TEST(SourceCodeTest, EditWholeMacroArgShouldSucceed) {
441   llvm::Annotations Code(R"cpp(
442 #define FOO(a) a + 7.0;
443 int a = FOO($r[[10]]);
444 )cpp");
445 
446   IntLitVisitor Visitor;
447   Visitor.OnIntLit = [&Code](IntegerLiteral *Expr, ASTContext *Context) {
448     auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange());
449     EXPECT_THAT(getRangeForEdit(Range, *Context),
450                 ValueIs(AsRange(Context->getSourceManager(), Code.range("r"))));
451   };
452   Visitor.runOver(Code.code());
453 }
454 
455 TEST(SourceCodeTest, EditPartialMacroArgShouldSucceed) {
456   llvm::Annotations Code(R"cpp(
457 #define FOO(a) a + 7.0;
458 int a = FOO($r[[10]] + 10.0);
459 )cpp");
460 
461   IntLitVisitor Visitor;
462   Visitor.OnIntLit = [&Code](IntegerLiteral *Expr, ASTContext *Context) {
463     auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange());
464     EXPECT_THAT(getRangeForEdit(Range, *Context),
465                 ValueIs(AsRange(Context->getSourceManager(), Code.range("r"))));
466   };
467   Visitor.runOver(Code.code());
468 }
469 
470 TEST(SourceCodeTest, EditRangeWithMacroExpansionsIsValid) {
471   // The call expression, whose range we are extracting, includes two macro
472   // expansions.
473   llvm::StringRef Code = R"cpp(
474 #define M(a) a * 13
475 int foo(int x, int y);
476 int a = foo(M(1), M(2));
477 )cpp";
478 
479   CallsVisitor Visitor;
480 
481   Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
482     auto Range = CharSourceRange::getTokenRange(CE->getSourceRange());
483     EXPECT_THAT_ERROR(validateEditRange(Range, Context->getSourceManager()),
484                       Succeeded());
485   };
486   Visitor.runOver(Code);
487 }
488 
489 TEST(SourceCodeTest, SpellingRangeOfMacroArgIsValid) {
490   llvm::StringRef Code = R"cpp(
491 #define FOO(a) a + 7.0;
492 int a = FOO(10);
493 )cpp";
494 
495   IntLitVisitor Visitor;
496   Visitor.OnIntLit = [](IntegerLiteral *Expr, ASTContext *Context) {
497     SourceLocation ArgLoc =
498         Context->getSourceManager().getSpellingLoc(Expr->getBeginLoc());
499     // The integer literal is a single token.
500     auto ArgRange = CharSourceRange::getTokenRange(ArgLoc);
501     EXPECT_THAT_ERROR(validateEditRange(ArgRange, Context->getSourceManager()),
502                       Succeeded());
503   };
504   Visitor.runOver(Code);
505 }
506 
507 TEST(SourceCodeTest, InvalidEditRangeIsInvalid) {
508   llvm::StringRef Code = "int c = 10;";
509 
510   // We use the visitor just to get a valid context.
511   IntLitVisitor Visitor;
512   Visitor.OnIntLit = [](IntegerLiteral *, ASTContext *Context) {
513     CharSourceRange Invalid;
514     EXPECT_THAT_ERROR(validateEditRange(Invalid, Context->getSourceManager()),
515                       Failed());
516   };
517   Visitor.runOver(Code);
518 }
519 
520 TEST(SourceCodeTest, InvertedEditRangeIsInvalid) {
521   llvm::StringRef Code = R"cpp(
522 int foo(int x);
523 int a = foo(2);
524 )cpp";
525 
526   CallsVisitor Visitor;
527   Visitor.OnCall = [](CallExpr *Expr, ASTContext *Context) {
528     auto InvertedRange = CharSourceRange::getTokenRange(
529         SourceRange(Expr->getEndLoc(), Expr->getBeginLoc()));
530     EXPECT_THAT_ERROR(
531         validateEditRange(InvertedRange, Context->getSourceManager()),
532         Failed());
533   };
534   Visitor.runOver(Code);
535 }
536 
537 TEST(SourceCodeTest, MacroArgIsInvalid) {
538   llvm::StringRef Code = R"cpp(
539 #define FOO(a) a + 7.0;
540 int a = FOO(10);
541 )cpp";
542 
543   IntLitVisitor Visitor;
544   Visitor.OnIntLit = [](IntegerLiteral *Expr, ASTContext *Context) {
545     auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange());
546     EXPECT_THAT_ERROR(validateEditRange(Range, Context->getSourceManager()),
547                       Failed());
548   };
549   Visitor.runOver(Code);
550 }
551 
552 TEST(SourceCodeTest, EditWholeMacroExpansionIsInvalid) {
553   llvm::StringRef Code = R"cpp(
554 #define FOO 10
555 int a = FOO;
556 )cpp";
557 
558   IntLitVisitor Visitor;
559   Visitor.OnIntLit = [](IntegerLiteral *Expr, ASTContext *Context) {
560     auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange());
561     EXPECT_THAT_ERROR(validateEditRange(Range, Context->getSourceManager()),
562                       Failed());
563 
564   };
565   Visitor.runOver(Code);
566 }
567 
568 TEST(SourceCodeTest, EditPartialMacroExpansionIsInvalid) {
569   llvm::StringRef Code = R"cpp(
570 #define BAR 10+
571 int c = BAR 3.0;
572 )cpp";
573 
574   IntLitVisitor Visitor;
575   Visitor.OnIntLit = [](IntegerLiteral *Expr, ASTContext *Context) {
576     auto Range = CharSourceRange::getTokenRange(Expr->getSourceRange());
577     EXPECT_THAT_ERROR(validateEditRange(Range, Context->getSourceManager()),
578                       Failed());
579   };
580   Visitor.runOver(Code);
581 }
582 } // end anonymous namespace
583