ioeric created this revision. ioeric added a reviewer: hokein. ioeric added a subscriber: cfe-commits. | View Revision
Also test phabricator.
Files:
change-namespace/ChangeNamespace.cpp
unittests/change-namespace/ChangeNamespaceTests.cpp
unittests/change-namespace/ChangeNamespaceTests.cpp
}
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";
// 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".
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();
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();
llvm::StringRef Prefix = NsName;
while (true) {
if (DeclName.consume_front((Prefix + "::").str()))
return DeclName.str();
NsName = Prefix;
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;
Prefix = NsName.substr(0, Pos - 1);
}
return DeclName;
Index: unittests/change-namespace/ChangeNamespaceTests.cpp =================================================================== --- unittests/change-namespace/ChangeNamespaceTests.cpp +++ 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: change-namespace/ChangeNamespace.cpp =================================================================== --- change-namespace/ChangeNamespace.cpp +++ change-namespace/ChangeNamespace.cpp @@ -172,21 +172,26 @@ // 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". 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(); + 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(); + + llvm::StringRef Prefix = NsName; while (true) { + if (DeclName.consume_front((Prefix + "::").str())) + return DeclName.str(); + NsName = Prefix; 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; + Prefix = 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