xref: /llvm-project/clang-tools-extra/clangd/unittests/tweaks/DefineInlineTests.cpp (revision 4d006520b8c0cc3a52913b4665bf741c737e5592)
1 //===-- DefineInlineTests.cpp -----------------------------------*- C++ -*-===//
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 "TweakTesting.h"
10 #include "TestFS.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
13 
14 using ::testing::ElementsAre;
15 
16 namespace clang {
17 namespace clangd {
18 namespace {
19 
20 TWEAK_TEST(DefineInline);
21 
TEST_F(DefineInlineTest,TriggersOnFunctionDecl)22 TEST_F(DefineInlineTest, TriggersOnFunctionDecl) {
23   // Basic check for function body and signature.
24   EXPECT_AVAILABLE(R"cpp(
25   class Bar {
26     void baz();
27   };
28 
29   [[void [[Bar::[[b^a^z]]]]() [[{
30     return;
31   }]]]]
32 
33   void foo();
34   [[void [[f^o^o]]() [[{
35     return;
36   }]]]]
37   )cpp");
38 
39   EXPECT_UNAVAILABLE(R"cpp(
40   // Not a definition
41   vo^i[[d^ ^f]]^oo();
42 
43   [[vo^id ]]foo[[()]] {[[
44     [[(void)(5+3);
45     return;]]
46   }]]
47 
48   // Definition with no body.
49   class Bar { Bar() = def^ault; };
50   )cpp");
51 }
52 
TEST_F(DefineInlineTest,NoForwardDecl)53 TEST_F(DefineInlineTest, NoForwardDecl) {
54   Header = "void bar();";
55   EXPECT_UNAVAILABLE(R"cpp(
56   void bar() {
57     return;
58   }
59   // FIXME: Generate a decl in the header.
60   void fo^o() {
61     return;
62   })cpp");
63 }
64 
TEST_F(DefineInlineTest,ReferencedDecls)65 TEST_F(DefineInlineTest, ReferencedDecls) {
66   EXPECT_AVAILABLE(R"cpp(
67     void bar();
68     void foo(int test);
69 
70     void fo^o(int baz) {
71       int x = 10;
72       bar();
73     })cpp");
74 
75   // Internal symbol usage.
76   Header = "void foo(int test);";
77   EXPECT_UNAVAILABLE(R"cpp(
78     void bar();
79     void fo^o(int baz) {
80       int x = 10;
81       bar();
82     })cpp");
83 
84   // Becomes available after making symbol visible.
85   Header = "void bar();" + Header;
86   EXPECT_AVAILABLE(R"cpp(
87     void fo^o(int baz) {
88       int x = 10;
89       bar();
90     })cpp");
91 
92   // FIXME: Move declaration below bar to make it visible.
93   Header.clear();
94   EXPECT_UNAVAILABLE(R"cpp(
95     void foo();
96     void bar();
97 
98     void fo^o() {
99       bar();
100     })cpp");
101 
102   // Order doesn't matter within a class.
103   EXPECT_AVAILABLE(R"cpp(
104     class Bar {
105       void foo();
106       void bar();
107     };
108 
109     void Bar::fo^o() {
110       bar();
111     })cpp");
112 
113   // FIXME: Perform include insertion to make symbol visible.
114   ExtraFiles["a.h"] = "void bar();";
115   Header = "void foo(int test);";
116   EXPECT_UNAVAILABLE(R"cpp(
117     #include "a.h"
118     void fo^o(int baz) {
119       int x = 10;
120       bar();
121     })cpp");
122 }
123 
TEST_F(DefineInlineTest,TemplateSpec)124 TEST_F(DefineInlineTest, TemplateSpec) {
125   EXPECT_UNAVAILABLE(R"cpp(
126     template <typename T> void foo();
127     template<> void foo<char>();
128 
129     template<> void f^oo<int>() {
130     })cpp");
131   EXPECT_UNAVAILABLE(R"cpp(
132     template <typename T> void foo();
133 
134     template<> void f^oo<int>() {
135     })cpp");
136   EXPECT_UNAVAILABLE(R"cpp(
137     template <typename T> struct Foo { void foo(); };
138 
139     template <typename T> void Foo<T>::f^oo() {
140     })cpp");
141   EXPECT_AVAILABLE(R"cpp(
142     template <typename T> void foo();
143     void bar();
144     template <> void foo<int>();
145 
146     template<> void f^oo<int>() {
147       bar();
148     })cpp");
149   EXPECT_UNAVAILABLE(R"cpp(
150     namespace bar {
151       template <typename T> void f^oo() {}
152       template void foo<int>();
153     })cpp");
154 }
155 
TEST_F(DefineInlineTest,CheckForCanonDecl)156 TEST_F(DefineInlineTest, CheckForCanonDecl) {
157   EXPECT_UNAVAILABLE(R"cpp(
158     void foo();
159 
160     void bar() {}
161     void f^oo() {
162       // This bar normally refers to the definition just above, but it is not
163       // visible from the forward declaration of foo.
164       bar();
165     })cpp");
166   // Make it available with a forward decl.
167   EXPECT_AVAILABLE(R"cpp(
168     void bar();
169     void foo();
170 
171     void bar() {}
172     void f^oo() {
173       bar();
174     })cpp");
175 }
176 
TEST_F(DefineInlineTest,UsingShadowDecls)177 TEST_F(DefineInlineTest, UsingShadowDecls) {
178   EXPECT_UNAVAILABLE(R"cpp(
179   namespace ns1 { void foo(int); }
180   namespace ns2 { void foo(int*); }
181   template <typename T>
182   void bar();
183 
184   using ns1::foo;
185   using ns2::foo;
186 
187   template <typename T>
188   void b^ar() {
189     foo(T());
190   })cpp");
191 }
192 
TEST_F(DefineInlineTest,TransformNestedNamespaces)193 TEST_F(DefineInlineTest, TransformNestedNamespaces) {
194   auto *Test = R"cpp(
195     namespace a {
196       void bar();
197       namespace b {
198         void baz();
199         namespace c {
200           void aux();
201         }
202       }
203     }
204 
205     void foo();
206     using namespace a;
207     using namespace b;
208     using namespace c;
209     void f^oo() {
210       bar();
211       a::bar();
212 
213       baz();
214       b::baz();
215       a::b::baz();
216 
217       aux();
218       c::aux();
219       b::c::aux();
220       a::b::c::aux();
221     })cpp";
222   auto *Expected = R"cpp(
223     namespace a {
224       void bar();
225       namespace b {
226         void baz();
227         namespace c {
228           void aux();
229         }
230       }
231     }
232 
233     void foo(){
234       a::bar();
235       a::bar();
236 
237       a::b::baz();
238       a::b::baz();
239       a::b::baz();
240 
241       a::b::c::aux();
242       a::b::c::aux();
243       a::b::c::aux();
244       a::b::c::aux();
245     }
246     using namespace a;
247     using namespace b;
248     using namespace c;
249     )cpp";
250   EXPECT_EQ(apply(Test), Expected);
251 }
252 
TEST_F(DefineInlineTest,TransformUsings)253 TEST_F(DefineInlineTest, TransformUsings) {
254   auto *Test = R"cpp(
255     namespace a { namespace b { namespace c { void aux(); } } }
256 
257     void foo();
258     void f^oo() {
259       using namespace a;
260       using namespace b;
261       using namespace c;
262       using c::aux;
263       namespace d = c;
264     })cpp";
265   auto *Expected = R"cpp(
266     namespace a { namespace b { namespace c { void aux(); } } }
267 
268     void foo(){
269       using namespace a;
270       using namespace a::b;
271       using namespace a::b::c;
272       using a::b::c::aux;
273       namespace d = a::b::c;
274     }
275     )cpp";
276   EXPECT_EQ(apply(Test), Expected);
277 }
278 
TEST_F(DefineInlineTest,TransformDecls)279 TEST_F(DefineInlineTest, TransformDecls) {
280   auto *Test = R"cpp(
281     void foo();
282     void f^oo() {
283       class Foo {
284       public:
285         void foo();
286         int x;
287       };
288 
289       enum En { Zero, One };
290       En x = Zero;
291 
292       enum class EnClass { Zero, One };
293       EnClass y = EnClass::Zero;
294     })cpp";
295   auto *Expected = R"cpp(
296     void foo(){
297       class Foo {
298       public:
299         void foo();
300         int x;
301       };
302 
303       enum En { Zero, One };
304       En x = Zero;
305 
306       enum class EnClass { Zero, One };
307       EnClass y = EnClass::Zero;
308     }
309     )cpp";
310   EXPECT_EQ(apply(Test), Expected);
311 }
312 
TEST_F(DefineInlineTest,TransformTemplDecls)313 TEST_F(DefineInlineTest, TransformTemplDecls) {
314   auto *Test = R"cpp(
315     namespace a {
316       template <typename T> class Bar {
317       public:
318         void bar();
319       };
320       template <typename T> T bar;
321       template <typename T> void aux() {}
322     }
323 
324     void foo();
325 
326     using namespace a;
327     void f^oo() {
328       bar<Bar<int>>.bar();
329       aux<Bar<int>>();
330     })cpp";
331   auto *Expected = R"cpp(
332     namespace a {
333       template <typename T> class Bar {
334       public:
335         void bar();
336       };
337       template <typename T> T bar;
338       template <typename T> void aux() {}
339     }
340 
341     void foo(){
342       a::bar<a::Bar<int>>.bar();
343       a::aux<a::Bar<int>>();
344     }
345 
346     using namespace a;
347     )cpp";
348   EXPECT_EQ(apply(Test), Expected);
349 }
350 
TEST_F(DefineInlineTest,TransformMembers)351 TEST_F(DefineInlineTest, TransformMembers) {
352   auto *Test = R"cpp(
353     class Foo {
354       void foo();
355     };
356 
357     void Foo::f^oo() {
358       return;
359     })cpp";
360   auto *Expected = R"cpp(
361     class Foo {
362       void foo(){
363       return;
364     }
365     };
366 
367     )cpp";
368   EXPECT_EQ(apply(Test), Expected);
369 
370   ExtraFiles["a.h"] = R"cpp(
371     class Foo {
372       void foo();
373     };)cpp";
374 
375   llvm::StringMap<std::string> EditedFiles;
376   Test = R"cpp(
377     #include "a.h"
378     void Foo::f^oo() {
379       return;
380     })cpp";
381   Expected = R"cpp(
382     #include "a.h"
383     )cpp";
384   EXPECT_EQ(apply(Test, &EditedFiles), Expected);
385 
386   Expected = R"cpp(
387     class Foo {
388       void foo(){
389       return;
390     }
391     };)cpp";
392   EXPECT_THAT(EditedFiles,
393               ElementsAre(FileWithContents(testPath("a.h"), Expected)));
394 }
395 
TEST_F(DefineInlineTest,TransformDependentTypes)396 TEST_F(DefineInlineTest, TransformDependentTypes) {
397   auto *Test = R"cpp(
398     namespace a {
399       template <typename T> class Bar {};
400     }
401 
402     template <typename T>
403     void foo();
404 
405     using namespace a;
406     template <typename T>
407     void f^oo() {
408       Bar<T> B;
409       Bar<Bar<T>> q;
410     })cpp";
411   auto *Expected = R"cpp(
412     namespace a {
413       template <typename T> class Bar {};
414     }
415 
416     template <typename T>
417     void foo(){
418       a::Bar<T> B;
419       a::Bar<a::Bar<T>> q;
420     }
421 
422     using namespace a;
423     )cpp";
424 
425   EXPECT_EQ(apply(Test), Expected);
426 }
427 
TEST_F(DefineInlineTest,TransformFunctionTempls)428 TEST_F(DefineInlineTest, TransformFunctionTempls) {
429   // Check we select correct specialization decl.
430   std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
431       {R"cpp(
432           template <typename T>
433           void foo(T p);
434 
435           template <>
436           void foo<int>(int p);
437 
438           template <>
439           void foo<char>(char p);
440 
441           template <>
442           void fo^o<int>(int p) {
443             return;
444           })cpp",
445        R"cpp(
446           template <typename T>
447           void foo(T p);
448 
449           template <>
450           void foo<int>(int p){
451             return;
452           }
453 
454           template <>
455           void foo<char>(char p);
456 
457           )cpp"},
458       {// Make sure we are not selecting the first specialization all the time.
459        R"cpp(
460           template <typename T>
461           void foo(T p);
462 
463           template <>
464           void foo<int>(int p);
465 
466           template <>
467           void foo<char>(char p);
468 
469           template <>
470           void fo^o<char>(char p) {
471             return;
472           })cpp",
473        R"cpp(
474           template <typename T>
475           void foo(T p);
476 
477           template <>
478           void foo<int>(int p);
479 
480           template <>
481           void foo<char>(char p){
482             return;
483           }
484 
485           )cpp"},
486       {R"cpp(
487           template <typename T>
488           void foo(T p);
489 
490           template <>
491           void foo<int>(int p);
492 
493           template <typename T>
494           void fo^o(T p) {
495             return;
496           })cpp",
497        R"cpp(
498           template <typename T>
499           void foo(T p){
500             return;
501           }
502 
503           template <>
504           void foo<int>(int p);
505 
506           )cpp"},
507   };
508   for (const auto &Case : Cases)
509     EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
510 }
511 
TEST_F(DefineInlineTest,TransformTypeLocs)512 TEST_F(DefineInlineTest, TransformTypeLocs) {
513   auto *Test = R"cpp(
514     namespace a {
515       template <typename T> class Bar {
516       public:
517         template <typename Q> class Baz {};
518       };
519       class Foo{};
520     }
521 
522     void foo();
523 
524     using namespace a;
525     void f^oo() {
526       Bar<int> B;
527       Foo foo;
528       a::Bar<Bar<int>>::Baz<Bar<int>> q;
529     })cpp";
530   auto *Expected = R"cpp(
531     namespace a {
532       template <typename T> class Bar {
533       public:
534         template <typename Q> class Baz {};
535       };
536       class Foo{};
537     }
538 
539     void foo(){
540       a::Bar<int> B;
541       a::Foo foo;
542       a::Bar<a::Bar<int>>::Baz<a::Bar<int>> q;
543     }
544 
545     using namespace a;
546     )cpp";
547   EXPECT_EQ(apply(Test), Expected);
548 }
549 
TEST_F(DefineInlineTest,TransformDeclRefs)550 TEST_F(DefineInlineTest, TransformDeclRefs) {
551   auto *Test = R"cpp(
552     namespace a {
553       template <typename T> class Bar {
554       public:
555         void foo();
556         static void bar();
557         int x;
558         static int y;
559       };
560       void bar();
561       void test();
562     }
563 
564     void foo();
565     using namespace a;
566     void f^oo() {
567       a::Bar<int> B;
568       B.foo();
569       a::bar();
570       Bar<Bar<int>>::bar();
571       a::Bar<int>::bar();
572       B.x = Bar<int>::y;
573       Bar<int>::y = 3;
574       bar();
575       a::test();
576     })cpp";
577   auto *Expected = R"cpp(
578     namespace a {
579       template <typename T> class Bar {
580       public:
581         void foo();
582         static void bar();
583         int x;
584         static int y;
585       };
586       void bar();
587       void test();
588     }
589 
590     void foo(){
591       a::Bar<int> B;
592       B.foo();
593       a::bar();
594       a::Bar<a::Bar<int>>::bar();
595       a::Bar<int>::bar();
596       B.x = a::Bar<int>::y;
597       a::Bar<int>::y = 3;
598       a::bar();
599       a::test();
600     }
601     using namespace a;
602     )cpp";
603   EXPECT_EQ(apply(Test), Expected);
604 }
605 
TEST_F(DefineInlineTest,StaticMembers)606 TEST_F(DefineInlineTest, StaticMembers) {
607   auto *Test = R"cpp(
608     namespace ns { class X { static void foo(); void bar(); }; }
609     void ns::X::b^ar() {
610       foo();
611     })cpp";
612   auto *Expected = R"cpp(
613     namespace ns { class X { static void foo(); void bar(){
614       foo();
615     } }; }
616     )cpp";
617   EXPECT_EQ(apply(Test), Expected);
618 }
619 
TEST_F(DefineInlineTest,TransformParamNames)620 TEST_F(DefineInlineTest, TransformParamNames) {
621   std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
622       {R"cpp(
623         void foo(int, bool b, int T\
624 est);
625         void ^foo(int f, bool x, int z) {})cpp",
626        R"cpp(
627         void foo(int f, bool x, int z){}
628         )cpp"},
629       {R"cpp(
630         #define PARAM int Z
631         void foo(PARAM);
632 
633         void ^foo(int X) {})cpp",
634        "fail: Cant rename parameter inside macro body."},
635       {R"cpp(
636         #define TYPE int
637         #define PARAM TYPE Z
638         #define BODY(x) 5 * (x) + 2
639         template <int P>
640         void foo(PARAM, TYPE Q, TYPE, TYPE W = BODY(P));
641         template <int x>
642         void ^foo(int Z, int b, int c, int d) {})cpp",
643        R"cpp(
644         #define TYPE int
645         #define PARAM TYPE Z
646         #define BODY(x) 5 * (x) + 2
647         template <int x>
648         void foo(PARAM, TYPE b, TYPE c, TYPE d = BODY(x)){}
649         )cpp"},
650   };
651   for (const auto &Case : Cases)
652     EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
653 }
654 
TEST_F(DefineInlineTest,TransformTemplParamNames)655 TEST_F(DefineInlineTest, TransformTemplParamNames) {
656   auto *Test = R"cpp(
657     struct Foo {
658       struct Bar {
659         template <class, class X,
660                   template<typename> class, template<typename> class Y,
661                   int, int Z>
662         void foo(X, Y<X>, int W = 5 * Z + 2);
663       };
664     };
665 
666     template <class T, class U,
667               template<typename> class V, template<typename> class W,
668               int X, int Y>
669     void Foo::Bar::f^oo(U, W<U>, int Q) {})cpp";
670   auto *Expected = R"cpp(
671     struct Foo {
672       struct Bar {
673         template <class T, class U,
674                   template<typename> class V, template<typename> class W,
675                   int X, int Y>
676         void foo(U, W<U>, int Q = 5 * Y + 2){}
677       };
678     };
679 
680     )cpp";
681   EXPECT_EQ(apply(Test), Expected);
682 }
683 
TEST_F(DefineInlineTest,TransformInlineNamespaces)684 TEST_F(DefineInlineTest, TransformInlineNamespaces) {
685   auto *Test = R"cpp(
686     namespace a { inline namespace b { namespace { struct Foo{}; } } }
687     void foo();
688 
689     using namespace a;
690     void ^foo() {Foo foo;})cpp";
691   auto *Expected = R"cpp(
692     namespace a { inline namespace b { namespace { struct Foo{}; } } }
693     void foo(){a::Foo foo;}
694 
695     using namespace a;
696     )cpp";
697   EXPECT_EQ(apply(Test), Expected);
698 }
699 
TEST_F(DefineInlineTest,TokensBeforeSemicolon)700 TEST_F(DefineInlineTest, TokensBeforeSemicolon) {
701   std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
702       {R"cpp(
703           void foo()    /*Comment -_-*/ /*Com 2*/ ;
704           void fo^o() { return ; })cpp",
705        R"cpp(
706           void foo()    /*Comment -_-*/ /*Com 2*/ { return ; }
707           )cpp"},
708 
709       {R"cpp(
710           void foo();
711           void fo^o() { return ; })cpp",
712        R"cpp(
713           void foo(){ return ; }
714           )cpp"},
715 
716       {R"cpp(
717           #define SEMI ;
718           void foo() SEMI
719           void fo^o() { return ; })cpp",
720        "fail: Couldn't find semicolon for target declaration."},
721   };
722   for (const auto &Case : Cases)
723     EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
724 }
725 
TEST_F(DefineInlineTest,HandleMacros)726 TEST_F(DefineInlineTest, HandleMacros) {
727   EXPECT_UNAVAILABLE(R"cpp(
728     #define BODY { return; }
729     void foo();
730     void f^oo()BODY)cpp");
731 
732   EXPECT_UNAVAILABLE(R"cpp(
733     #define BODY void foo(){ return; }
734     void foo();
735     [[BODY]])cpp");
736 
737   std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
738       // We don't qualify declarations coming from macros.
739       {R"cpp(
740           #define BODY Foo
741           namespace a { class Foo{}; }
742           void foo();
743           using namespace a;
744           void f^oo(){BODY();})cpp",
745        R"cpp(
746           #define BODY Foo
747           namespace a { class Foo{}; }
748           void foo(){BODY();}
749           using namespace a;
750           )cpp"},
751 
752       // Macro is not visible at declaration location, but we proceed.
753       {R"cpp(
754           void foo();
755           #define BODY return;
756           void f^oo(){BODY})cpp",
757        R"cpp(
758           void foo(){BODY}
759           #define BODY return;
760           )cpp"},
761 
762       {R"cpp(
763           #define TARGET void foo()
764           TARGET;
765           void f^oo(){ return; })cpp",
766        R"cpp(
767           #define TARGET void foo()
768           TARGET{ return; }
769           )cpp"},
770 
771       {R"cpp(
772           #define TARGET foo
773           void TARGET();
774           void f^oo(){ return; })cpp",
775        R"cpp(
776           #define TARGET foo
777           void TARGET(){ return; }
778           )cpp"},
779   };
780   for (const auto &Case : Cases)
781     EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
782 }
783 
TEST_F(DefineInlineTest,DropCommonNameSpecifiers)784 TEST_F(DefineInlineTest, DropCommonNameSpecifiers) {
785   struct {
786     llvm::StringRef Test;
787     llvm::StringRef Expected;
788   } Cases[] = {
789       {R"cpp(
790         namespace a { namespace b { void aux(); } }
791         namespace ns1 {
792           void foo();
793           namespace qq { void test(); }
794           namespace ns2 {
795             void bar();
796             namespace ns3 { void baz(); }
797           }
798         }
799 
800         using namespace a;
801         using namespace a::b;
802         using namespace ns1::qq;
803         void ns1::ns2::ns3::b^az() {
804           foo();
805           bar();
806           baz();
807           ns1::ns2::ns3::baz();
808           aux();
809           test();
810         })cpp",
811        R"cpp(
812         namespace a { namespace b { void aux(); } }
813         namespace ns1 {
814           void foo();
815           namespace qq { void test(); }
816           namespace ns2 {
817             void bar();
818             namespace ns3 { void baz(){
819           foo();
820           bar();
821           baz();
822           ns1::ns2::ns3::baz();
823           a::b::aux();
824           qq::test();
825         } }
826           }
827         }
828 
829         using namespace a;
830         using namespace a::b;
831         using namespace ns1::qq;
832         )cpp"},
833       {R"cpp(
834         namespace ns1 {
835           namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
836           namespace ns2 { void baz(); }
837         }
838 
839         using namespace ns1::qq;
840         void ns1::ns2::b^az() { Foo f; B b; })cpp",
841        R"cpp(
842         namespace ns1 {
843           namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
844           namespace ns2 { void baz(){ qq::Foo f; qq::B b; } }
845         }
846 
847         using namespace ns1::qq;
848         )cpp"},
849       {R"cpp(
850         namespace ns1 {
851           namespace qq {
852             template<class T> struct Foo { template <class U> struct Bar {}; };
853             template<class T, class U>
854             using B = typename Foo<T>::template Bar<U>;
855           }
856           namespace ns2 { void baz(); }
857         }
858 
859         using namespace ns1::qq;
860         void ns1::ns2::b^az() { B<int, bool> b; })cpp",
861        R"cpp(
862         namespace ns1 {
863           namespace qq {
864             template<class T> struct Foo { template <class U> struct Bar {}; };
865             template<class T, class U>
866             using B = typename Foo<T>::template Bar<U>;
867           }
868           namespace ns2 { void baz(){ qq::B<int, bool> b; } }
869         }
870 
871         using namespace ns1::qq;
872         )cpp"},
873   };
874   for (const auto &Case : Cases)
875     EXPECT_EQ(apply(Case.Test), Case.Expected) << Case.Test;
876 }
877 
TEST_F(DefineInlineTest,QualifyWithUsingDirectives)878 TEST_F(DefineInlineTest, QualifyWithUsingDirectives) {
879   llvm::StringRef Test = R"cpp(
880     namespace a {
881       void bar();
882       namespace b { struct Foo{}; void aux(); }
883       namespace c { void cux(); }
884     }
885     using namespace a;
886     using X = b::Foo;
887     void foo();
888 
889     using namespace b;
890     using namespace c;
891     void ^foo() {
892       cux();
893       bar();
894       X x;
895       aux();
896       using namespace c;
897       // FIXME: The last reference to cux() in body of foo should not be
898       // qualified, since there is a using directive inside the function body.
899       cux();
900     })cpp";
901   llvm::StringRef Expected = R"cpp(
902     namespace a {
903       void bar();
904       namespace b { struct Foo{}; void aux(); }
905       namespace c { void cux(); }
906     }
907     using namespace a;
908     using X = b::Foo;
909     void foo(){
910       c::cux();
911       bar();
912       X x;
913       b::aux();
914       using namespace c;
915       // FIXME: The last reference to cux() in body of foo should not be
916       // qualified, since there is a using directive inside the function body.
917       c::cux();
918     }
919 
920     using namespace b;
921     using namespace c;
922     )cpp";
923   EXPECT_EQ(apply(Test), Expected) << Test;
924 }
925 
TEST_F(DefineInlineTest,AddInline)926 TEST_F(DefineInlineTest, AddInline) {
927   llvm::StringMap<std::string> EditedFiles;
928   ExtraFiles["a.h"] = "void foo();";
929   apply(R"cpp(#include "a.h"
930               void fo^o() {})cpp",
931         &EditedFiles);
932   EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
933                                testPath("a.h"), "inline void foo(){}")));
934 
935   // Check we put inline before cv-qualifiers.
936   ExtraFiles["a.h"] = "const int foo();";
937   apply(R"cpp(#include "a.h"
938               const int fo^o() {})cpp",
939         &EditedFiles);
940   EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
941                                testPath("a.h"), "inline const int foo(){}")));
942 
943   // No double inline.
944   ExtraFiles["a.h"] = "inline void foo();";
945   apply(R"cpp(#include "a.h"
946               inline void fo^o() {})cpp",
947         &EditedFiles);
948   EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
949                                testPath("a.h"), "inline void foo(){}")));
950 
951   // Constexprs don't need "inline".
952   ExtraFiles["a.h"] = "constexpr void foo();";
953   apply(R"cpp(#include "a.h"
954               constexpr void fo^o() {})cpp",
955         &EditedFiles);
956   EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
957                                testPath("a.h"), "constexpr void foo(){}")));
958 
959   // Class members don't need "inline".
960   ExtraFiles["a.h"] = "struct Foo { void foo(); };";
961   apply(R"cpp(#include "a.h"
962               void Foo::fo^o() {})cpp",
963         &EditedFiles);
964   EXPECT_THAT(EditedFiles,
965               testing::ElementsAre(FileWithContents(
966                   testPath("a.h"), "struct Foo { void foo(){} };")));
967 
968   // Function template doesn't need to be "inline"d.
969   ExtraFiles["a.h"] = "template <typename T> void foo();";
970   apply(R"cpp(#include "a.h"
971               template <typename T>
972               void fo^o() {})cpp",
973         &EditedFiles);
974   EXPECT_THAT(EditedFiles,
975               testing::ElementsAre(FileWithContents(
976                   testPath("a.h"), "template <typename T> void foo(){}")));
977 
978   // Specializations needs to be marked "inline".
979   ExtraFiles["a.h"] = R"cpp(
980                             template <typename T> void foo();
981                             template <> void foo<int>();)cpp";
982   apply(R"cpp(#include "a.h"
983               template <>
984               void fo^o<int>() {})cpp",
985         &EditedFiles);
986   EXPECT_THAT(EditedFiles,
987               testing::ElementsAre(FileWithContents(testPath("a.h"),
988                                                     R"cpp(
989                             template <typename T> void foo();
990                             template <> inline void foo<int>(){})cpp")));
991 }
992 
993 } // namespace
994 } // namespace clangd
995 } // namespace clang
996