This revision was automatically updated to reflect the committed changes.
Closed by commit rL283333: [change-namespace] Fixed a bug in 
getShortestQualifiedNameInNamespace. (authored by ioeric).

Changed prior to commit:
  https://reviews.llvm.org/D25065?vs=73459&id=73653#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D25065

Files:
  clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
  clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp


Index: 
clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
===================================================================
--- clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
+++ clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
@@ -113,6 +113,24 @@
   EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
 }
 
+TEST_F(ChangeNamespaceTest, MoveIntoAnotherNestedNamespaceWithRef) {
+  NewNamespace = "na::nc";
+  std::string Code = "namespace na {\n"
+                     "class A {};\n"
+                     "namespace nb {\n"
+                     "class X { A a; };\n"
+                     "} // namespace nb\n"
+                     "} // namespace na\n";
+  std::string Expected = "namespace na {\n"
+                         "class A {};\n"
+                         "\n"
+                         "namespace nc {\n"
+                         "class X { A a; };\n"
+                         "} // namespace nc\n"
+                         "} // namespace na\n";
+  EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
+}
+
 TEST_F(ChangeNamespaceTest, SimpleMoveNestedNamespace) {
   NewNamespace = "na::x::y";
   std::string Code = "namespace na {\n"
Index: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
===================================================================
--- clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
+++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
@@ -173,21 +173,24 @@
 // Returns the shortest qualified name for declaration `DeclName` in the
 // namespace `NsName`. For example, if `DeclName` is "a::b::X" and `NsName`
 // is "a::c::d", then "b::X" will be returned.
+// \param DeclName A fully qualified name, "::a::b::X" or "a::b::X".
+// \param NsName A fully qualified name, "::a::b" or "a::b". Global namespace
+//        will have empty name.
 std::string getShortestQualifiedNameInNamespace(llvm::StringRef DeclName,
                                                 llvm::StringRef NsName) {
-  llvm::SmallVector<llvm::StringRef, 4> DeclNameSplitted;
-  DeclName.split(DeclNameSplitted, "::");
-  if (DeclNameSplitted.size() == 1)
-    return DeclName;
-  const auto UnqualifiedName = DeclNameSplitted.back();
-  while (true) {
+  DeclName = DeclName.ltrim(':');
+  NsName = NsName.ltrim(':');
+  // If `DeclName` is a global variable, we prepend "::" to it if it is not in
+  // the global namespace.
+  if (DeclName.find(':') == llvm::StringRef::npos)
+    return NsName.empty() ? DeclName.str() : ("::" + DeclName).str();
+
+  while (!DeclName.consume_front((NsName + "::").str())) {
     const auto Pos = NsName.find_last_of(':');
     if (Pos == llvm::StringRef::npos)
       return DeclName;
-    const auto Prefix = NsName.substr(0, Pos - 1);
-    if (DeclName.startswith(Prefix))
-      return (Prefix + "::" + UnqualifiedName).str();
-    NsName = Prefix;
+    assert(Pos > 0);
+    NsName = NsName.substr(0, Pos - 1);
   }
   return DeclName;
 }


Index: clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
===================================================================
--- clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
+++ clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
@@ -113,6 +113,24 @@
   EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
 }
 
+TEST_F(ChangeNamespaceTest, MoveIntoAnotherNestedNamespaceWithRef) {
+  NewNamespace = "na::nc";
+  std::string Code = "namespace na {\n"
+                     "class A {};\n"
+                     "namespace nb {\n"
+                     "class X { A a; };\n"
+                     "} // namespace nb\n"
+                     "} // namespace na\n";
+  std::string Expected = "namespace na {\n"
+                         "class A {};\n"
+                         "\n"
+                         "namespace nc {\n"
+                         "class X { A a; };\n"
+                         "} // namespace nc\n"
+                         "} // namespace na\n";
+  EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
+}
+
 TEST_F(ChangeNamespaceTest, SimpleMoveNestedNamespace) {
   NewNamespace = "na::x::y";
   std::string Code = "namespace na {\n"
Index: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
===================================================================
--- clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
+++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
@@ -173,21 +173,24 @@
 // Returns the shortest qualified name for declaration `DeclName` in the
 // namespace `NsName`. For example, if `DeclName` is "a::b::X" and `NsName`
 // is "a::c::d", then "b::X" will be returned.
+// \param DeclName A fully qualified name, "::a::b::X" or "a::b::X".
+// \param NsName A fully qualified name, "::a::b" or "a::b". Global namespace
+//        will have empty name.
 std::string getShortestQualifiedNameInNamespace(llvm::StringRef DeclName,
                                                 llvm::StringRef NsName) {
-  llvm::SmallVector<llvm::StringRef, 4> DeclNameSplitted;
-  DeclName.split(DeclNameSplitted, "::");
-  if (DeclNameSplitted.size() == 1)
-    return DeclName;
-  const auto UnqualifiedName = DeclNameSplitted.back();
-  while (true) {
+  DeclName = DeclName.ltrim(':');
+  NsName = NsName.ltrim(':');
+  // If `DeclName` is a global variable, we prepend "::" to it if it is not in
+  // the global namespace.
+  if (DeclName.find(':') == llvm::StringRef::npos)
+    return NsName.empty() ? DeclName.str() : ("::" + DeclName).str();
+
+  while (!DeclName.consume_front((NsName + "::").str())) {
     const auto Pos = NsName.find_last_of(':');
     if (Pos == llvm::StringRef::npos)
       return DeclName;
-    const auto Prefix = NsName.substr(0, Pos - 1);
-    if (DeclName.startswith(Prefix))
-      return (Prefix + "::" + UnqualifiedName).str();
-    NsName = Prefix;
+    assert(Pos > 0);
+    NsName = NsName.substr(0, Pos - 1);
   }
   return DeclName;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to