16f60ff84SHaojian Wu //===-- RenameFunctionTest.cpp - unit tests for renaming functions --------===//
26f60ff84SHaojian Wu //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66f60ff84SHaojian Wu //
76f60ff84SHaojian Wu //===----------------------------------------------------------------------===//
86f60ff84SHaojian Wu 
96f60ff84SHaojian Wu #include "ClangRenameTest.h"
106f60ff84SHaojian Wu 
116f60ff84SHaojian Wu namespace clang {
126f60ff84SHaojian Wu namespace clang_rename {
136f60ff84SHaojian Wu namespace test {
146f60ff84SHaojian Wu namespace {
156f60ff84SHaojian Wu 
166f60ff84SHaojian Wu class RenameFunctionTest : public ClangRenameTest {
176f60ff84SHaojian Wu public:
RenameFunctionTest()186f60ff84SHaojian Wu   RenameFunctionTest() {
196f60ff84SHaojian Wu     AppendToHeader(R"(
206f60ff84SHaojian Wu       struct A {
216f60ff84SHaojian Wu         static bool Foo();
226f60ff84SHaojian Wu         static bool Spam();
236f60ff84SHaojian Wu       };
246f60ff84SHaojian Wu       struct B {
256f60ff84SHaojian Wu         static void Same();
266f60ff84SHaojian Wu         static bool Foo();
276f60ff84SHaojian Wu         static int Eric(int x);
286f60ff84SHaojian Wu       };
296f60ff84SHaojian Wu       void Same(int x);
306f60ff84SHaojian Wu       int Eric(int x);
316f60ff84SHaojian Wu       namespace base {
326f60ff84SHaojian Wu         void Same();
336f60ff84SHaojian Wu         void ToNanoSeconds();
346f60ff84SHaojian Wu         void ToInt64NanoSeconds();
356f60ff84SHaojian Wu       })");
366f60ff84SHaojian Wu   }
376f60ff84SHaojian Wu };
386f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,RefactorsAFoo)396f60ff84SHaojian Wu TEST_F(RenameFunctionTest, RefactorsAFoo) {
406f60ff84SHaojian Wu   std::string Before = R"(
416f60ff84SHaojian Wu       void f() {
426f60ff84SHaojian Wu         A::Foo();
436f60ff84SHaojian Wu         ::A::Foo();
446f60ff84SHaojian Wu       })";
456f60ff84SHaojian Wu   std::string Expected = R"(
466f60ff84SHaojian Wu       void f() {
476f60ff84SHaojian Wu         A::Bar();
486f60ff84SHaojian Wu         ::A::Bar();
496f60ff84SHaojian Wu       })";
506f60ff84SHaojian Wu 
516f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "A::Foo", "A::Bar");
526f60ff84SHaojian Wu   CompareSnippets(Expected, After);
536f60ff84SHaojian Wu }
546f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,RefactorsNonCallingAFoo)556f60ff84SHaojian Wu TEST_F(RenameFunctionTest, RefactorsNonCallingAFoo) {
566f60ff84SHaojian Wu   std::string Before = R"(
576f60ff84SHaojian Wu       bool g(bool (*func)()) {
586f60ff84SHaojian Wu         return func();
596f60ff84SHaojian Wu       }
606f60ff84SHaojian Wu       void f() {
616f60ff84SHaojian Wu         auto *ref1 = A::Foo;
626f60ff84SHaojian Wu         auto *ref2 = ::A::Foo;
636f60ff84SHaojian Wu         g(A::Foo);
646f60ff84SHaojian Wu       })";
656f60ff84SHaojian Wu   std::string Expected = R"(
666f60ff84SHaojian Wu       bool g(bool (*func)()) {
676f60ff84SHaojian Wu         return func();
686f60ff84SHaojian Wu       }
696f60ff84SHaojian Wu       void f() {
706f60ff84SHaojian Wu         auto *ref1 = A::Bar;
716f60ff84SHaojian Wu         auto *ref2 = ::A::Bar;
726f60ff84SHaojian Wu         g(A::Bar);
736f60ff84SHaojian Wu       })";
746f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "A::Foo", "A::Bar");
756f60ff84SHaojian Wu   CompareSnippets(Expected, After);
766f60ff84SHaojian Wu }
776f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,RefactorsEric)786f60ff84SHaojian Wu TEST_F(RenameFunctionTest, RefactorsEric) {
796f60ff84SHaojian Wu   std::string Before = R"(
806f60ff84SHaojian Wu       void f() {
816f60ff84SHaojian Wu         if (Eric(3)==4) ::Eric(2);
826f60ff84SHaojian Wu       })";
836f60ff84SHaojian Wu   std::string Expected = R"(
846f60ff84SHaojian Wu       void f() {
856f60ff84SHaojian Wu         if (Larry(3)==4) ::Larry(2);
866f60ff84SHaojian Wu       })";
876f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "Eric", "Larry");
886f60ff84SHaojian Wu   CompareSnippets(Expected, After);
896f60ff84SHaojian Wu }
906f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,RefactorsNonCallingEric)916f60ff84SHaojian Wu TEST_F(RenameFunctionTest, RefactorsNonCallingEric) {
926f60ff84SHaojian Wu   std::string Before = R"(
936f60ff84SHaojian Wu         int g(int (*func)(int)) {
946f60ff84SHaojian Wu           return func(1);
956f60ff84SHaojian Wu         }
966f60ff84SHaojian Wu         void f() {
976f60ff84SHaojian Wu           auto *ref = ::Eric;
986f60ff84SHaojian Wu           g(Eric);
996f60ff84SHaojian Wu         })";
1006f60ff84SHaojian Wu   std::string Expected = R"(
1016f60ff84SHaojian Wu         int g(int (*func)(int)) {
1026f60ff84SHaojian Wu           return func(1);
1036f60ff84SHaojian Wu         }
1046f60ff84SHaojian Wu         void f() {
1056f60ff84SHaojian Wu           auto *ref = ::Larry;
1066f60ff84SHaojian Wu           g(Larry);
1076f60ff84SHaojian Wu         })";
1086f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "Eric", "Larry");
1096f60ff84SHaojian Wu   CompareSnippets(Expected, After);
1106f60ff84SHaojian Wu }
1116f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,DoesNotRefactorBFoo)1126f60ff84SHaojian Wu TEST_F(RenameFunctionTest, DoesNotRefactorBFoo) {
1136f60ff84SHaojian Wu   std::string Before = R"(
1146f60ff84SHaojian Wu       void f() {
1156f60ff84SHaojian Wu         B::Foo();
1166f60ff84SHaojian Wu       })";
1176f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "A::Foo", "A::Bar");
1186f60ff84SHaojian Wu   CompareSnippets(Before, After);
1196f60ff84SHaojian Wu }
1206f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,DoesNotRefactorBEric)1216f60ff84SHaojian Wu TEST_F(RenameFunctionTest, DoesNotRefactorBEric) {
1226f60ff84SHaojian Wu   std::string Before = R"(
1236f60ff84SHaojian Wu       void f() {
1246f60ff84SHaojian Wu         B::Eric(2);
1256f60ff84SHaojian Wu       })";
1266f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "Eric", "Larry");
1276f60ff84SHaojian Wu   CompareSnippets(Before, After);
1286f60ff84SHaojian Wu }
1296f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,DoesNotRefactorCEric)1306f60ff84SHaojian Wu TEST_F(RenameFunctionTest, DoesNotRefactorCEric) {
1316f60ff84SHaojian Wu   std::string Before = R"(
1326f60ff84SHaojian Wu       namespace C { int Eric(int x); }
1336f60ff84SHaojian Wu       void f() {
1346f60ff84SHaojian Wu         if (C::Eric(3)==4) ::C::Eric(2);
1356f60ff84SHaojian Wu       })";
1366f60ff84SHaojian Wu   std::string Expected = R"(
1376f60ff84SHaojian Wu       namespace C { int Eric(int x); }
1386f60ff84SHaojian Wu       void f() {
1396f60ff84SHaojian Wu         if (C::Eric(3)==4) ::C::Eric(2);
1406f60ff84SHaojian Wu       })";
1416f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "Eric", "Larry");
1426f60ff84SHaojian Wu   CompareSnippets(Expected, After);
1436f60ff84SHaojian Wu }
1446f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,DoesNotRefactorEricInNamespaceC)1456f60ff84SHaojian Wu TEST_F(RenameFunctionTest, DoesNotRefactorEricInNamespaceC) {
1466f60ff84SHaojian Wu   std::string Before = R"(
1476f60ff84SHaojian Wu        namespace C {
1486f60ff84SHaojian Wu        int Eric(int x);
1496f60ff84SHaojian Wu        void f() {
1506f60ff84SHaojian Wu          if (Eric(3)==4) Eric(2);
1516f60ff84SHaojian Wu        }
1526f60ff84SHaojian Wu        }  // namespace C)";
1536f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "Eric", "Larry");
1546f60ff84SHaojian Wu   CompareSnippets(Before, After);
1556f60ff84SHaojian Wu }
1566f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,NamespaceQualified)1576f60ff84SHaojian Wu TEST_F(RenameFunctionTest, NamespaceQualified) {
1586f60ff84SHaojian Wu   std::string Before = R"(
1596f60ff84SHaojian Wu       void f() {
1606f60ff84SHaojian Wu         base::ToNanoSeconds();
1616f60ff84SHaojian Wu         ::base::ToNanoSeconds();
1626f60ff84SHaojian Wu       }
1636f60ff84SHaojian Wu       void g() {
1646f60ff84SHaojian Wu         using base::ToNanoSeconds;
1656f60ff84SHaojian Wu         base::ToNanoSeconds();
1666f60ff84SHaojian Wu         ::base::ToNanoSeconds();
1676f60ff84SHaojian Wu         ToNanoSeconds();
1686f60ff84SHaojian Wu       }
1696f60ff84SHaojian Wu       namespace foo {
1706f60ff84SHaojian Wu         namespace base {
1716f60ff84SHaojian Wu           void ToNanoSeconds();
1726f60ff84SHaojian Wu           void f() {
1736f60ff84SHaojian Wu             base::ToNanoSeconds();
1746f60ff84SHaojian Wu           }
1756f60ff84SHaojian Wu         }
1766f60ff84SHaojian Wu         void f() {
1776f60ff84SHaojian Wu           ::base::ToNanoSeconds();
1786f60ff84SHaojian Wu         }
1796f60ff84SHaojian Wu       })";
1806f60ff84SHaojian Wu   std::string Expected = R"(
1816f60ff84SHaojian Wu       void f() {
1826f60ff84SHaojian Wu         base::ToInt64NanoSeconds();
1836f60ff84SHaojian Wu         ::base::ToInt64NanoSeconds();
1846f60ff84SHaojian Wu       }
1856f60ff84SHaojian Wu       void g() {
1866f60ff84SHaojian Wu         using base::ToInt64NanoSeconds;
1876f60ff84SHaojian Wu         base::ToInt64NanoSeconds();
1886f60ff84SHaojian Wu         ::base::ToInt64NanoSeconds();
1896f60ff84SHaojian Wu         base::ToInt64NanoSeconds();
1906f60ff84SHaojian Wu       }
1916f60ff84SHaojian Wu       namespace foo {
1926f60ff84SHaojian Wu         namespace base {
1936f60ff84SHaojian Wu           void ToNanoSeconds();
1946f60ff84SHaojian Wu           void f() {
1956f60ff84SHaojian Wu             base::ToNanoSeconds();
1966f60ff84SHaojian Wu           }
1976f60ff84SHaojian Wu         }
1986f60ff84SHaojian Wu         void f() {
1996f60ff84SHaojian Wu           ::base::ToInt64NanoSeconds();
2006f60ff84SHaojian Wu         }
2016f60ff84SHaojian Wu       })";
2026f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "base::ToNanoSeconds",
2036f60ff84SHaojian Wu                                            "base::ToInt64NanoSeconds");
2046f60ff84SHaojian Wu   CompareSnippets(Expected, After);
2056f60ff84SHaojian Wu }
2066f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,RenameFunctionDecls)2076f60ff84SHaojian Wu TEST_F(RenameFunctionTest, RenameFunctionDecls) {
2086f60ff84SHaojian Wu   std::string Before = R"(
2096f60ff84SHaojian Wu       namespace na {
2106f60ff84SHaojian Wu         void X();
2116f60ff84SHaojian Wu         void X() {}
2126f60ff84SHaojian Wu       })";
2136f60ff84SHaojian Wu   std::string Expected = R"(
2146f60ff84SHaojian Wu       namespace na {
2156f60ff84SHaojian Wu         void Y();
2166f60ff84SHaojian Wu         void Y() {}
2176f60ff84SHaojian Wu       })";
2186f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "na::X", "na::Y");
2196f60ff84SHaojian Wu   CompareSnippets(Expected, After);
2206f60ff84SHaojian Wu }
2216f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,RenameTemplateFunctions)22254e84b39SHaojian Wu TEST_F(RenameFunctionTest, RenameTemplateFunctions) {
22354e84b39SHaojian Wu   std::string Before = R"(
22454e84b39SHaojian Wu       namespace na {
22554e84b39SHaojian Wu       template<typename T> T X();
22654e84b39SHaojian Wu       }
22754e84b39SHaojian Wu       namespace na { void f() { X<int>(); } }
22854e84b39SHaojian Wu       namespace nb { void g() { na::X          <int>(); } }
22954e84b39SHaojian Wu       )";
23054e84b39SHaojian Wu   std::string Expected = R"(
23154e84b39SHaojian Wu       namespace na {
23254e84b39SHaojian Wu       template<typename T> T Y();
23354e84b39SHaojian Wu       }
23454e84b39SHaojian Wu       namespace na { void f() { nb::Y<int>(); } }
23554e84b39SHaojian Wu       namespace nb { void g() { Y<int>(); } }
23654e84b39SHaojian Wu       )";
23754e84b39SHaojian Wu   std::string After = runClangRenameOnCode(Before, "na::X", "nb::Y");
23854e84b39SHaojian Wu   CompareSnippets(Expected, After);
23954e84b39SHaojian Wu }
24054e84b39SHaojian Wu 
TEST_F(RenameFunctionTest,RenameOutOfLineFunctionDecls)2416f60ff84SHaojian Wu TEST_F(RenameFunctionTest, RenameOutOfLineFunctionDecls) {
2426f60ff84SHaojian Wu   std::string Before = R"(
2436f60ff84SHaojian Wu       namespace na {
2446f60ff84SHaojian Wu         void X();
2456f60ff84SHaojian Wu       }
2466f60ff84SHaojian Wu       void na::X() {}
2476f60ff84SHaojian Wu       )";
2486f60ff84SHaojian Wu   std::string Expected = R"(
2496f60ff84SHaojian Wu       namespace na {
2506f60ff84SHaojian Wu         void Y();
2516f60ff84SHaojian Wu       }
2526f60ff84SHaojian Wu       void na::Y() {}
2536f60ff84SHaojian Wu       )";
2546f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "na::X", "na::Y");
2556f60ff84SHaojian Wu   CompareSnippets(Expected, After);
2566f60ff84SHaojian Wu }
2576f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,NewNamespaceWithoutLeadingDotDot)2586f60ff84SHaojian Wu TEST_F(RenameFunctionTest, NewNamespaceWithoutLeadingDotDot) {
2596f60ff84SHaojian Wu   std::string Before = R"(
2606f60ff84SHaojian Wu       namespace old_ns {
2616f60ff84SHaojian Wu         void X();
2626f60ff84SHaojian Wu         void X() {}
2636f60ff84SHaojian Wu       }
2646f60ff84SHaojian Wu       // Assume that the reference is in another file.
2656f60ff84SHaojian Wu       void f() { old_ns::X(); }
2666f60ff84SHaojian Wu       namespace old_ns { void g() { X(); } }
2676f60ff84SHaojian Wu       namespace new_ns { void h() { ::old_ns::X(); } }
2686f60ff84SHaojian Wu       )";
2696f60ff84SHaojian Wu   std::string Expected = R"(
2706f60ff84SHaojian Wu       namespace old_ns {
2716f60ff84SHaojian Wu         void Y();
2726f60ff84SHaojian Wu         void Y() {}
2736f60ff84SHaojian Wu       }
2746f60ff84SHaojian Wu       // Assume that the reference is in another file.
2756f60ff84SHaojian Wu       void f() { new_ns::Y(); }
2766f60ff84SHaojian Wu       namespace old_ns { void g() { new_ns::Y(); } }
2776f60ff84SHaojian Wu       namespace new_ns { void h() { Y(); } }
2786f60ff84SHaojian Wu       )";
2796f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "::old_ns::X", "new_ns::Y");
2806f60ff84SHaojian Wu   CompareSnippets(Expected, After);
2816f60ff84SHaojian Wu }
2826f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,NewNamespaceWithLeadingDotDot)2836f60ff84SHaojian Wu TEST_F(RenameFunctionTest, NewNamespaceWithLeadingDotDot) {
2846f60ff84SHaojian Wu   std::string Before = R"(
2856f60ff84SHaojian Wu       namespace old_ns {
2866f60ff84SHaojian Wu         void X();
2876f60ff84SHaojian Wu         void X() {}
2886f60ff84SHaojian Wu       }
2896f60ff84SHaojian Wu       // Assume that the reference is in another file.
2906f60ff84SHaojian Wu       void f() { old_ns::X(); }
2916f60ff84SHaojian Wu       namespace old_ns { void g() { X(); } }
2926f60ff84SHaojian Wu       namespace new_ns { void h() { ::old_ns::X(); } }
2936f60ff84SHaojian Wu       )";
2946f60ff84SHaojian Wu   std::string Expected = R"(
2956f60ff84SHaojian Wu       namespace old_ns {
2966f60ff84SHaojian Wu         void Y();
2976f60ff84SHaojian Wu         void Y() {}
2986f60ff84SHaojian Wu       }
2996f60ff84SHaojian Wu       // Assume that the reference is in another file.
3006f60ff84SHaojian Wu       void f() { ::new_ns::Y(); }
3016f60ff84SHaojian Wu       namespace old_ns { void g() { ::new_ns::Y(); } }
3026f60ff84SHaojian Wu       namespace new_ns { void h() { Y(); } }
3036f60ff84SHaojian Wu       )";
3046f60ff84SHaojian Wu   std::string After =
3056f60ff84SHaojian Wu       runClangRenameOnCode(Before, "::old_ns::X", "::new_ns::Y");
3066f60ff84SHaojian Wu   CompareSnippets(Expected, After);
3076f60ff84SHaojian Wu }
3086f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,DontRenameSymbolsDefinedInAnonymousNamespace)3096f60ff84SHaojian Wu TEST_F(RenameFunctionTest, DontRenameSymbolsDefinedInAnonymousNamespace) {
3106f60ff84SHaojian Wu   std::string Before = R"(
3116f60ff84SHaojian Wu       namespace old_ns {
3126f60ff84SHaojian Wu       class X {};
3136f60ff84SHaojian Wu       namespace {
3146f60ff84SHaojian Wu         void X();
3156f60ff84SHaojian Wu         void X() {}
3166f60ff84SHaojian Wu         void f() { X(); }
3176f60ff84SHaojian Wu       }
3186f60ff84SHaojian Wu       }
3196f60ff84SHaojian Wu       )";
3206f60ff84SHaojian Wu   std::string Expected = R"(
3216f60ff84SHaojian Wu       namespace old_ns {
3226f60ff84SHaojian Wu       class Y {};
3236f60ff84SHaojian Wu       namespace {
3246f60ff84SHaojian Wu         void X();
3256f60ff84SHaojian Wu         void X() {}
3266f60ff84SHaojian Wu         void f() { X(); }
3276f60ff84SHaojian Wu       }
3286f60ff84SHaojian Wu       }
3296f60ff84SHaojian Wu       )";
3306f60ff84SHaojian Wu   std::string After =
3316f60ff84SHaojian Wu       runClangRenameOnCode(Before, "::old_ns::X", "::old_ns::Y");
3326f60ff84SHaojian Wu   CompareSnippets(Expected, After);
3336f60ff84SHaojian Wu }
3346f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,NewNestedNamespace)3356f60ff84SHaojian Wu TEST_F(RenameFunctionTest, NewNestedNamespace) {
3366f60ff84SHaojian Wu   std::string Before = R"(
3376f60ff84SHaojian Wu       namespace old_ns {
3386f60ff84SHaojian Wu         void X();
3396f60ff84SHaojian Wu         void X() {}
3406f60ff84SHaojian Wu       }
3416f60ff84SHaojian Wu       // Assume that the reference is in another file.
3426f60ff84SHaojian Wu       namespace old_ns {
3436f60ff84SHaojian Wu       void f() { X(); }
3446f60ff84SHaojian Wu       }
3456f60ff84SHaojian Wu       )";
3466f60ff84SHaojian Wu   std::string Expected = R"(
3476f60ff84SHaojian Wu       namespace old_ns {
3486f60ff84SHaojian Wu         void X();
3496f60ff84SHaojian Wu         void X() {}
3506f60ff84SHaojian Wu       }
3516f60ff84SHaojian Wu       // Assume that the reference is in another file.
3526f60ff84SHaojian Wu       namespace old_ns {
3536f60ff84SHaojian Wu       void f() { older_ns::X(); }
3546f60ff84SHaojian Wu       }
3556f60ff84SHaojian Wu       )";
3566f60ff84SHaojian Wu   std::string After =
3576f60ff84SHaojian Wu       runClangRenameOnCode(Before, "::old_ns::X", "::old_ns::older_ns::X");
3586f60ff84SHaojian Wu   CompareSnippets(Expected, After);
3596f60ff84SHaojian Wu }
3606f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,MoveFromGlobalToNamespaceWithoutLeadingDotDot)3616f60ff84SHaojian Wu TEST_F(RenameFunctionTest, MoveFromGlobalToNamespaceWithoutLeadingDotDot) {
3626f60ff84SHaojian Wu   std::string Before = R"(
3636f60ff84SHaojian Wu       void X();
3646f60ff84SHaojian Wu       void X() {}
3656f60ff84SHaojian Wu 
3666f60ff84SHaojian Wu       // Assume that the reference is in another file.
3676f60ff84SHaojian Wu       namespace some_ns {
3686f60ff84SHaojian Wu       void f() { X(); }
3696f60ff84SHaojian Wu       }
3706f60ff84SHaojian Wu       )";
3716f60ff84SHaojian Wu   std::string Expected = R"(
3726f60ff84SHaojian Wu       void X();
3736f60ff84SHaojian Wu       void X() {}
3746f60ff84SHaojian Wu 
3756f60ff84SHaojian Wu       // Assume that the reference is in another file.
3766f60ff84SHaojian Wu       namespace some_ns {
3776f60ff84SHaojian Wu       void f() { ns::X(); }
3786f60ff84SHaojian Wu       }
3796f60ff84SHaojian Wu       )";
3806f60ff84SHaojian Wu   std::string After =
3816f60ff84SHaojian Wu       runClangRenameOnCode(Before, "::X", "ns::X");
3826f60ff84SHaojian Wu   CompareSnippets(Expected, After);
3836f60ff84SHaojian Wu }
3846f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,MoveFromGlobalToNamespaceWithLeadingDotDot)3856f60ff84SHaojian Wu TEST_F(RenameFunctionTest, MoveFromGlobalToNamespaceWithLeadingDotDot) {
3866f60ff84SHaojian Wu   std::string Before = R"(
3876f60ff84SHaojian Wu       void Y() {}
3886f60ff84SHaojian Wu 
3896f60ff84SHaojian Wu       // Assume that the reference is in another file.
3906f60ff84SHaojian Wu       namespace some_ns {
3916f60ff84SHaojian Wu       void f() { Y(); }
3926f60ff84SHaojian Wu       }
3936f60ff84SHaojian Wu       )";
3946f60ff84SHaojian Wu   std::string Expected = R"(
3956f60ff84SHaojian Wu       void Y() {}
3966f60ff84SHaojian Wu 
3976f60ff84SHaojian Wu       // Assume that the reference is in another file.
3986f60ff84SHaojian Wu       namespace some_ns {
3996f60ff84SHaojian Wu       void f() { ::ns::Y(); }
4006f60ff84SHaojian Wu       }
4016f60ff84SHaojian Wu       )";
4026f60ff84SHaojian Wu   std::string After =
4036f60ff84SHaojian Wu       runClangRenameOnCode(Before, "::Y", "::ns::Y");
4046f60ff84SHaojian Wu   CompareSnippets(Expected, After);
4056f60ff84SHaojian Wu }
4066f60ff84SHaojian Wu 
4076f60ff84SHaojian Wu // FIXME: the rename of overloaded operator is not fully supported yet.
TEST_F(RenameFunctionTest,DISABLED_DoNotRenameOverloadedOperatorCalls)4086f60ff84SHaojian Wu TEST_F(RenameFunctionTest, DISABLED_DoNotRenameOverloadedOperatorCalls) {
4096f60ff84SHaojian Wu   std::string Before = R"(
4106f60ff84SHaojian Wu       namespace old_ns {
4116f60ff84SHaojian Wu       class T { public: int x; };
4126f60ff84SHaojian Wu       bool operator==(const T& lhs, const T& rhs) {
4136f60ff84SHaojian Wu         return lhs.x == rhs.x;
4146f60ff84SHaojian Wu       }
4156f60ff84SHaojian Wu       }  // namespace old_ns
4166f60ff84SHaojian Wu 
4176f60ff84SHaojian Wu       // Assume that the reference is in another file.
4186f60ff84SHaojian Wu       bool f() {
4196f60ff84SHaojian Wu         auto eq = old_ns::operator==;
4206f60ff84SHaojian Wu         old_ns::T t1, t2;
4216f60ff84SHaojian Wu         old_ns::operator==(t1, t2);
4226f60ff84SHaojian Wu         return t1 == t2;
4236f60ff84SHaojian Wu       }
4246f60ff84SHaojian Wu       )";
4256f60ff84SHaojian Wu   std::string Expected = R"(
4266f60ff84SHaojian Wu       namespace old_ns {
4276f60ff84SHaojian Wu       class T { public: int x; };
4286f60ff84SHaojian Wu       bool operator==(const T& lhs, const T& rhs) {
4296f60ff84SHaojian Wu         return lhs.x == rhs.x;
4306f60ff84SHaojian Wu       }
4316f60ff84SHaojian Wu       }  // namespace old_ns
4326f60ff84SHaojian Wu 
4336f60ff84SHaojian Wu       // Assume that the reference is in another file.
4346f60ff84SHaojian Wu       bool f() {
4356f60ff84SHaojian Wu         auto eq = new_ns::operator==;
4366f60ff84SHaojian Wu         old_ns::T t1, t2;
4376f60ff84SHaojian Wu         new_ns::operator==(t1, t2);
4386f60ff84SHaojian Wu         return t1 == t2;
4396f60ff84SHaojian Wu       }
4406f60ff84SHaojian Wu       )";
4416f60ff84SHaojian Wu   std::string After =
4426f60ff84SHaojian Wu       runClangRenameOnCode(Before, "old_ns::operator==", "new_ns::operator==");
4436f60ff84SHaojian Wu   CompareSnippets(Expected, After);
4446f60ff84SHaojian Wu }
4456f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,FunctionRefAsTemplate)4466f60ff84SHaojian Wu TEST_F(RenameFunctionTest, FunctionRefAsTemplate) {
4476f60ff84SHaojian Wu   std::string Before = R"(
4486f60ff84SHaojian Wu       void X();
4496f60ff84SHaojian Wu 
4506f60ff84SHaojian Wu       // Assume that the reference is in another file.
4516f60ff84SHaojian Wu       namespace some_ns {
4526f60ff84SHaojian Wu       template <void (*Func)(void)>
4536f60ff84SHaojian Wu       class TIterator {};
4546f60ff84SHaojian Wu 
4556f60ff84SHaojian Wu       template <void (*Func)(void)>
4566f60ff84SHaojian Wu       class T {
4576f60ff84SHaojian Wu       public:
4586f60ff84SHaojian Wu         typedef TIterator<Func> IterType;
4596f60ff84SHaojian Wu         using TI = TIterator<Func>;
4606f60ff84SHaojian Wu         void g() {
4616f60ff84SHaojian Wu           Func();
4626f60ff84SHaojian Wu           auto func = Func;
4636f60ff84SHaojian Wu           TIterator<Func> iter;
4646f60ff84SHaojian Wu         }
4656f60ff84SHaojian Wu       };
4666f60ff84SHaojian Wu 
4676f60ff84SHaojian Wu 
4686f60ff84SHaojian Wu       void f() { T<X> tx; tx.g(); }
4696f60ff84SHaojian Wu       }  // namespace some_ns
4706f60ff84SHaojian Wu       )";
4716f60ff84SHaojian Wu   std::string Expected = R"(
4726f60ff84SHaojian Wu       void X();
4736f60ff84SHaojian Wu 
4746f60ff84SHaojian Wu       // Assume that the reference is in another file.
4756f60ff84SHaojian Wu       namespace some_ns {
4766f60ff84SHaojian Wu       template <void (*Func)(void)>
4776f60ff84SHaojian Wu       class TIterator {};
4786f60ff84SHaojian Wu 
4796f60ff84SHaojian Wu       template <void (*Func)(void)>
4806f60ff84SHaojian Wu       class T {
4816f60ff84SHaojian Wu       public:
4826f60ff84SHaojian Wu         typedef TIterator<Func> IterType;
4836f60ff84SHaojian Wu         using TI = TIterator<Func>;
4846f60ff84SHaojian Wu         void g() {
4856f60ff84SHaojian Wu           Func();
4866f60ff84SHaojian Wu           auto func = Func;
4876f60ff84SHaojian Wu           TIterator<Func> iter;
4886f60ff84SHaojian Wu         }
4896f60ff84SHaojian Wu       };
4906f60ff84SHaojian Wu 
4916f60ff84SHaojian Wu 
4926f60ff84SHaojian Wu       void f() { T<ns::X> tx; tx.g(); }
4936f60ff84SHaojian Wu       }  // namespace some_ns
4946f60ff84SHaojian Wu       )";
4956f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "::X", "ns::X");
4966f60ff84SHaojian Wu   CompareSnippets(Expected, After);
4976f60ff84SHaojian Wu }
4986f60ff84SHaojian Wu 
TEST_F(RenameFunctionTest,RenameFunctionInUsingDecl)4996f60ff84SHaojian Wu TEST_F(RenameFunctionTest, RenameFunctionInUsingDecl) {
5006f60ff84SHaojian Wu   std::string Before = R"(
5016f60ff84SHaojian Wu       using base::ToNanoSeconds;
5026f60ff84SHaojian Wu       namespace old_ns {
5036f60ff84SHaojian Wu       using base::ToNanoSeconds;
5046f60ff84SHaojian Wu       void f() {
5056f60ff84SHaojian Wu         using base::ToNanoSeconds;
5066f60ff84SHaojian Wu       }
5076f60ff84SHaojian Wu       }
5086f60ff84SHaojian Wu       )";
5096f60ff84SHaojian Wu   std::string Expected = R"(
5106f60ff84SHaojian Wu       using base::ToInt64NanoSeconds;
5116f60ff84SHaojian Wu       namespace old_ns {
5126f60ff84SHaojian Wu       using base::ToInt64NanoSeconds;
5136f60ff84SHaojian Wu       void f() {
5146f60ff84SHaojian Wu         using base::ToInt64NanoSeconds;
5156f60ff84SHaojian Wu       }
5166f60ff84SHaojian Wu       }
5176f60ff84SHaojian Wu       )";
5186f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "base::ToNanoSeconds",
5196f60ff84SHaojian Wu                                            "base::ToInt64NanoSeconds");
5206f60ff84SHaojian Wu   CompareSnippets(Expected, After);
5216f60ff84SHaojian Wu }
5226f60ff84SHaojian Wu 
5236f60ff84SHaojian Wu // FIXME: Fix the complex the case where the symbol being renamed is located in
5246f60ff84SHaojian Wu // `std::function<decltype<renamed_symbol>>`.
TEST_F(ClangRenameTest,DISABLED_ReferencesInLambdaFunctionParameters)5256f60ff84SHaojian Wu TEST_F(ClangRenameTest, DISABLED_ReferencesInLambdaFunctionParameters) {
5266f60ff84SHaojian Wu   std::string Before = R"(
5276f60ff84SHaojian Wu       template <class T>
5286f60ff84SHaojian Wu       class function;
5296f60ff84SHaojian Wu       template <class R, class... ArgTypes>
5306f60ff84SHaojian Wu       class function<R(ArgTypes...)> {
5316f60ff84SHaojian Wu       public:
5326f60ff84SHaojian Wu         template <typename Functor>
5336f60ff84SHaojian Wu         function(Functor f) {}
5346f60ff84SHaojian Wu 
5356f60ff84SHaojian Wu         function() {}
5366f60ff84SHaojian Wu 
5376f60ff84SHaojian Wu         R operator()(ArgTypes...) const {}
5386f60ff84SHaojian Wu       };
5396f60ff84SHaojian Wu 
5406f60ff84SHaojian Wu       namespace ns {
5416f60ff84SHaojian Wu       void Old() {}
5426f60ff84SHaojian Wu       void f() {
5436f60ff84SHaojian Wu         function<decltype(Old)> func;
5446f60ff84SHaojian Wu       }
5456f60ff84SHaojian Wu       }  // namespace ns)";
5466f60ff84SHaojian Wu   std::string Expected = R"(
5476f60ff84SHaojian Wu       template <class T>
5486f60ff84SHaojian Wu       class function;
5496f60ff84SHaojian Wu       template <class R, class... ArgTypes>
5506f60ff84SHaojian Wu       class function<R(ArgTypes...)> {
5516f60ff84SHaojian Wu       public:
5526f60ff84SHaojian Wu         template <typename Functor>
5536f60ff84SHaojian Wu         function(Functor f) {}
5546f60ff84SHaojian Wu 
5556f60ff84SHaojian Wu         function() {}
5566f60ff84SHaojian Wu 
5576f60ff84SHaojian Wu         R operator()(ArgTypes...) const {}
5586f60ff84SHaojian Wu       };
5596f60ff84SHaojian Wu 
5606f60ff84SHaojian Wu       namespace ns {
5616f60ff84SHaojian Wu       void New() {}
5626f60ff84SHaojian Wu       void f() {
5636f60ff84SHaojian Wu         function<decltype(::new_ns::New)> func;
5646f60ff84SHaojian Wu       }
5656f60ff84SHaojian Wu       }  // namespace ns)";
5666f60ff84SHaojian Wu   std::string After = runClangRenameOnCode(Before, "ns::Old", "::new_ns::New");
5676f60ff84SHaojian Wu   CompareSnippets(Expected, After);
5686f60ff84SHaojian Wu }
5696f60ff84SHaojian Wu 
5706f60ff84SHaojian Wu } // anonymous namespace
5716f60ff84SHaojian Wu } // namespace test
5726f60ff84SHaojian Wu } // namespace clang_rename
5736f60ff84SHaojian Wu } // namesdpace clang
574