Re: [PATCH] D13931: [Tooling] Add a utility function to replace one nested name with another.
bkramer updated this revision to Diff 38130. bkramer added a comment. Enforce :: at the beginning of the new name. http://reviews.llvm.org/D13931 Files: include/clang/Tooling/Core/Lookup.h lib/Tooling/Core/CMakeLists.txt lib/Tooling/Core/Lookup.cpp unittests/Tooling/CMakeLists.txt unittests/Tooling/LookupTest.cpp Index: unittests/Tooling/LookupTest.cpp === --- /dev/null +++ unittests/Tooling/LookupTest.cpp @@ -0,0 +1,108 @@ +//===- unittest/Tooling/LookupTest.cpp ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TestVisitor.h" +#include "clang/Tooling/Core/Lookup.h" +using namespace clang; + +namespace { +struct GetDeclsVisitor : TestVisitor { + std::functionOnCall; + SmallVector DeclStack; + + bool VisitCallExpr(CallExpr *Expr) { +OnCall(Expr); +return true; + } + + bool TraverseDecl(Decl *D) { +DeclStack.push_back(D); +bool Ret = TestVisitor::TraverseDecl(D); +DeclStack.pop_back(); +return Ret; + } +}; + +TEST(LookupTest, replaceNestedName) { + GetDeclsVisitor Visitor; + + auto replaceCallExpr = [&](const CallExpr *Expr, + StringRef ReplacementString) { +const auto *Callee = cast(Expr->getCallee()->IgnoreImplicit()); +const ValueDecl *FD = Callee->getDecl(); +return tooling::replaceNestedName( +Callee->getQualifier(), Visitor.DeclStack.back()->getDeclContext(), FD, +ReplacementString); + }; + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace a { void f() { foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace a { void f() { foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace b { void f() { a::foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace b { namespace a { void foo(); }\n" + "void f() { a::foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("c::bar", replaceCallExpr(Expr, "::a::c::bar")); + }; + Visitor.runOver("namespace a { namespace b { void foo(); }\n" + "void f() { b::foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver("namespace a { namespace b { void foo(); }\n" + "void f() { b::foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "::bar")); + }; + Visitor.runOver("void foo(); void f() { foo(); }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("::bar", replaceCallExpr(Expr, "::bar")); + }; + Visitor.runOver("void foo(); void f() { ::foo(); }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\nvoid f() { a::foo(); }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver("namespace a { int foo(); }\nauto f = a::foo();\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver( + "namespace a { int foo(); }\nusing a::foo;\nauto f = foo();\n"); +} + +} // end anonymous namespace Index: unittests/Tooling/CMakeLists.txt === --- unittests/Tooling/CMakeLists.txt +++ unittests/Tooling/CMakeLists.txt @@ -6,6 +6,7 @@ add_clang_unittest(ToolingTests CommentHandlerTest.cpp CompilationDatabaseTest.cpp + LookupTest.cpp ToolingTest.cpp RecursiveASTVisitorTest.cpp RecursiveASTVisitorTestCallVisitor.cpp Index: lib/Tooling/Core/Lookup.cpp === --- /dev/null +++ lib/Tooling/Core/Lookup.cpp @@ -0,0 +1,113 @@ +//===--- Lookup.cpp - Framework for clang refactoring tools ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +//
Re: [PATCH] D13931: [Tooling] Add a utility function to replace one nested name with another.
bkramer updated this revision to Diff 38117. bkramer added a comment. - Removed "fully qualified" in favor of just "qualified" to clarify that the name should be qualified but the leading "::" is not necessary. - Renamed isNameSpecifierGlobal - Removed always true conditional from test http://reviews.llvm.org/D13931 Files: include/clang/Tooling/Core/Lookup.h lib/Tooling/Core/CMakeLists.txt lib/Tooling/Core/Lookup.cpp unittests/Tooling/CMakeLists.txt unittests/Tooling/LookupTest.cpp Index: unittests/Tooling/LookupTest.cpp === --- /dev/null +++ unittests/Tooling/LookupTest.cpp @@ -0,0 +1,91 @@ +//===- unittest/Tooling/LookupTest.cpp ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TestVisitor.h" +#include "clang/Tooling/Core/Lookup.h" +using namespace clang; + +namespace { +struct GetDeclsVisitor : TestVisitor { + std::functionOnCall; + + bool VisitCallExpr(CallExpr *Expr) { +OnCall(Expr); +return true; + } +}; + +static std::string replaceCallExpr(const CallExpr *Expr, + StringRef ReplacementString) { + const auto *Callee = cast(Expr->getCallee()->IgnoreImplicit()); + const ValueDecl *FD = Callee->getDecl(); + ASTContext = FD->getASTContext(); + const DeclContext *DC = + Context.getParents(ast_type_traits::DynTypedNode::create(*Expr))[0] + .get(); + return tooling::replaceNestedName(Callee->getQualifier(), DC, FD, +ReplacementString); +} + +TEST(LookupTest, replaceNestedName) { + GetDeclsVisitor Visitor; + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace a { void f() { foo(); } }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace a { void f() { foo(); } }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace b { void f() { a::foo(); } }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace b { namespace a { void foo(); }\n" + "void f() { a::foo(); } }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "bar")); + }; + Visitor.runOver("void foo(); void f() { foo(); }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("::bar", replaceCallExpr(Expr, "bar")); + }; + Visitor.runOver("void foo(); void f() { ::foo(); }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\nvoid f() { a::foo(); }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { int foo(); }\nauto f = a::foo()\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver( + "namespace a { int foo(); }\nusing a::foo;\nauto f = foo()\n"); +} + +} // end anonymous namespace Index: unittests/Tooling/CMakeLists.txt === --- unittests/Tooling/CMakeLists.txt +++ unittests/Tooling/CMakeLists.txt @@ -6,6 +6,7 @@ add_clang_unittest(ToolingTests CommentHandlerTest.cpp CompilationDatabaseTest.cpp + LookupTest.cpp ToolingTest.cpp RecursiveASTVisitorTest.cpp RecursiveASTVisitorTestCallVisitor.cpp Index: lib/Tooling/Core/Lookup.cpp === --- /dev/null +++ lib/Tooling/Core/Lookup.cpp @@ -0,0 +1,106 @@ +//===--- Lookup.cpp - Framework for clang refactoring tools ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// +// +// This file defines helper methods for clang tools performing name lookup. +// +//===--===// + +#include "clang/Tooling/Core/Lookup.h" +#include "clang/AST/Decl.h" +using namespace clang; +using namespace clang::tooling; + +static bool
Re: [PATCH] D13931: [Tooling] Add a utility function to replace one nested name with another.
bkramer updated this revision to Diff 38122. bkramer added a comment. Add more comments and polish test cases. http://reviews.llvm.org/D13931 Files: include/clang/Tooling/Core/Lookup.h lib/Tooling/Core/CMakeLists.txt lib/Tooling/Core/Lookup.cpp unittests/Tooling/CMakeLists.txt unittests/Tooling/LookupTest.cpp Index: unittests/Tooling/LookupTest.cpp === --- /dev/null +++ unittests/Tooling/LookupTest.cpp @@ -0,0 +1,102 @@ +//===- unittest/Tooling/LookupTest.cpp ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TestVisitor.h" +#include "clang/Tooling/Core/Lookup.h" +using namespace clang; + +namespace { +struct GetDeclsVisitor : TestVisitor { + std::functionOnCall; + SmallVector DeclStack; + + bool VisitCallExpr(CallExpr *Expr) { +OnCall(Expr); +return true; + } + + bool TraverseDecl(Decl *D) { +DeclStack.push_back(D); +bool Ret = TestVisitor::TraverseDecl(D); +DeclStack.pop_back(); +return Ret; + } +}; + +TEST(LookupTest, replaceNestedName) { + GetDeclsVisitor Visitor; + + auto replaceCallExpr = [&](const CallExpr *Expr, + StringRef ReplacementString) { +const auto *Callee = cast(Expr->getCallee()->IgnoreImplicit()); +const ValueDecl *FD = Callee->getDecl(); +return tooling::replaceNestedName( +Callee->getQualifier(), Visitor.DeclStack.back()->getDeclContext(), FD, +ReplacementString); + }; + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace a { void f() { foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace a { void f() { foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace b { void f() { a::foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace b { namespace a { void foo(); }\n" + "void f() { a::foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { namespace b { void foo(); }\n" + "void f() { b::foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "bar")); + }; + Visitor.runOver("void foo(); void f() { foo(); }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("::bar", replaceCallExpr(Expr, "bar")); + }; + Visitor.runOver("void foo(); void f() { ::foo(); }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\nvoid f() { a::foo(); }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { int foo(); }\nauto f = a::foo();\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver( + "namespace a { int foo(); }\nusing a::foo;\nauto f = foo();\n"); +} + +} // end anonymous namespace Index: unittests/Tooling/CMakeLists.txt === --- unittests/Tooling/CMakeLists.txt +++ unittests/Tooling/CMakeLists.txt @@ -6,6 +6,7 @@ add_clang_unittest(ToolingTests CommentHandlerTest.cpp CompilationDatabaseTest.cpp + LookupTest.cpp ToolingTest.cpp RecursiveASTVisitorTest.cpp RecursiveASTVisitorTestCallVisitor.cpp Index: lib/Tooling/Core/Lookup.cpp === --- /dev/null +++ lib/Tooling/Core/Lookup.cpp @@ -0,0 +1,112 @@ +//===--- Lookup.cpp - Framework for clang refactoring tools ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// +// +// This file defines helper methods for clang tools performing name lookup. +// +//===--===// + +#include "clang/Tooling/Core/Lookup.h" +#include "clang/AST/Decl.h"
Re: [PATCH] D13931: [Tooling] Add a utility function to replace one nested name with another.
klimek accepted this revision. klimek added a comment. This revision is now accepted and ready to land. lg http://reviews.llvm.org/D13931 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13931: [Tooling] Add a utility function to replace one nested name with another.
This revision was automatically updated to reflect the committed changes. Closed by commit rL251022: [Tooling] Add a utility function to replace one nested name with another. (authored by d0k). Changed prior to commit: http://reviews.llvm.org/D13931?vs=38130=38131#toc Repository: rL LLVM http://reviews.llvm.org/D13931 Files: cfe/trunk/include/clang/Tooling/Core/Lookup.h cfe/trunk/lib/Tooling/Core/CMakeLists.txt cfe/trunk/lib/Tooling/Core/Lookup.cpp cfe/trunk/unittests/Tooling/CMakeLists.txt cfe/trunk/unittests/Tooling/LookupTest.cpp Index: cfe/trunk/unittests/Tooling/CMakeLists.txt === --- cfe/trunk/unittests/Tooling/CMakeLists.txt +++ cfe/trunk/unittests/Tooling/CMakeLists.txt @@ -6,6 +6,7 @@ add_clang_unittest(ToolingTests CommentHandlerTest.cpp CompilationDatabaseTest.cpp + LookupTest.cpp ToolingTest.cpp RecursiveASTVisitorTest.cpp RecursiveASTVisitorTestCallVisitor.cpp Index: cfe/trunk/unittests/Tooling/LookupTest.cpp === --- cfe/trunk/unittests/Tooling/LookupTest.cpp +++ cfe/trunk/unittests/Tooling/LookupTest.cpp @@ -0,0 +1,108 @@ +//===- unittest/Tooling/LookupTest.cpp ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TestVisitor.h" +#include "clang/Tooling/Core/Lookup.h" +using namespace clang; + +namespace { +struct GetDeclsVisitor : TestVisitor { + std::functionOnCall; + SmallVector DeclStack; + + bool VisitCallExpr(CallExpr *Expr) { +OnCall(Expr); +return true; + } + + bool TraverseDecl(Decl *D) { +DeclStack.push_back(D); +bool Ret = TestVisitor::TraverseDecl(D); +DeclStack.pop_back(); +return Ret; + } +}; + +TEST(LookupTest, replaceNestedName) { + GetDeclsVisitor Visitor; + + auto replaceCallExpr = [&](const CallExpr *Expr, + StringRef ReplacementString) { +const auto *Callee = cast(Expr->getCallee()->IgnoreImplicit()); +const ValueDecl *FD = Callee->getDecl(); +return tooling::replaceNestedName( +Callee->getQualifier(), Visitor.DeclStack.back()->getDeclContext(), FD, +ReplacementString); + }; + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace a { void f() { foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace a { void f() { foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace b { void f() { a::foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace b { namespace a { void foo(); }\n" + "void f() { a::foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("c::bar", replaceCallExpr(Expr, "::a::c::bar")); + }; + Visitor.runOver("namespace a { namespace b { void foo(); }\n" + "void f() { b::foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver("namespace a { namespace b { void foo(); }\n" + "void f() { b::foo(); } }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "::bar")); + }; + Visitor.runOver("void foo(); void f() { foo(); }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("::bar", replaceCallExpr(Expr, "::bar")); + }; + Visitor.runOver("void foo(); void f() { ::foo(); }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\nvoid f() { a::foo(); }\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver("namespace a { int foo(); }\nauto f = a::foo();\n"); + + Visitor.OnCall = [&](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "::a::bar")); + }; + Visitor.runOver( + "namespace a { int foo(); }\nusing a::foo;\nauto f = foo();\n"); +} + +} // end anonymous namespace Index: cfe/trunk/include/clang/Tooling/Core/Lookup.h === --- cfe/trunk/include/clang/Tooling/Core/Lookup.h +++
[PATCH] D13931: [Tooling] Add a utility function to replace one nested name with another.
bkramer created this revision. bkramer added a reviewer: klimek. bkramer added a subscriber: cfe-commits. Herald added a subscriber: klimek. One problem in clang-tidy and other clang tools face is that there is no way to lookup an arbitrary name in the AST, that's buried deep inside Sema and might not even be what the user wants as the new name may be freshly inserted and not available in the AST. A common use case for lookups is replacing one nested name with another while minimizing namespace qualifications, so replacing 'ns::foo' with 'ns::bar' will use just 'bar' if we happen to be inside the namespace 'ns'. This adds a little helper utility for exactly that use case. http://reviews.llvm.org/D13931 Files: include/clang/Tooling/Core/Lookup.h lib/Tooling/Core/CMakeLists.txt lib/Tooling/Core/Lookup.cpp unittests/Tooling/CMakeLists.txt unittests/Tooling/LookupTest.cpp Index: unittests/Tooling/LookupTest.cpp === --- /dev/null +++ unittests/Tooling/LookupTest.cpp @@ -0,0 +1,92 @@ +//===- unittest/Tooling/LookupTest.cpp ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TestVisitor.h" +#include "clang/Tooling/Core/Lookup.h" +using namespace clang; + +namespace { +struct GetDeclsVisitor : TestVisitor { + std::functionOnCall; + + bool VisitCallExpr(CallExpr *Expr) { +if (OnCall) + OnCall(Expr); +return true; + } +}; + +static std::string replaceCallExpr(const CallExpr *Expr, + StringRef ReplacementString) { + const auto *Callee = cast(Expr->getCallee()->IgnoreImplicit()); + const ValueDecl *FD = Callee->getDecl(); + ASTContext = FD->getASTContext(); + const DeclContext *DC = + Context.getParents(ast_type_traits::DynTypedNode::create(*Expr))[0] + .get(); + return tooling::replaceNestedName(Callee->getQualifier(), DC, FD, +ReplacementString); +} + +TEST(LookupTest, replaceNestedName) { + GetDeclsVisitor Visitor; + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace a { void f() { foo(); } }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace a { void f() { foo(); } }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace b { void f() { a::foo(); } }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\n" + "namespace b { namespace a { void foo(); }\n" + "void f() { a::foo(); } }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "bar")); + }; + Visitor.runOver("void foo(); void f() { foo(); }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("::bar", replaceCallExpr(Expr, "bar")); + }; + Visitor.runOver("void foo(); void f() { ::foo(); }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { void foo(); }\nvoid f() { a::foo(); }\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("a::bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver("namespace a { int foo(); }\nauto f = a::foo()\n"); + + Visitor.OnCall = [](CallExpr *Expr) { +EXPECT_EQ("bar", replaceCallExpr(Expr, "a::bar")); + }; + Visitor.runOver( + "namespace a { int foo(); }\nusing a::foo;\nauto f = foo()\n"); +} + +} // end anonymous namespace Index: unittests/Tooling/CMakeLists.txt === --- unittests/Tooling/CMakeLists.txt +++ unittests/Tooling/CMakeLists.txt @@ -6,6 +6,7 @@ add_clang_unittest(ToolingTests CommentHandlerTest.cpp CompilationDatabaseTest.cpp + LookupTest.cpp ToolingTest.cpp RecursiveASTVisitorTest.cpp RecursiveASTVisitorTestCallVisitor.cpp Index: lib/Tooling/Core/Lookup.cpp === --- /dev/null +++ lib/Tooling/Core/Lookup.cpp @@ -0,0 +1,106 @@ +//===--- Lookup.cpp - Framework for clang refactoring tools ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +//
Re: [PATCH] D13931: [Tooling] Add a utility function to replace one nested name with another.
klimek added inline comments. Comment at: include/clang/Tooling/Core/Lookup.h:37-38 @@ +36,4 @@ +/// \param FromDecl The declaration to which the nested name points. +/// \param ReplacementString The replacement nested name. Should be fully +/// qualified. +/// \returns The new name to be inserted in place of the current nested name. Don't most tests violate the "should be fully qualified" requirement here? Comment at: lib/Tooling/Core/Lookup.cpp:60 @@ +59,3 @@ + +// Otherwise strip of redundant namespace qualifications from the new name. +std::string NS = s/of/off/ Comment at: lib/Tooling/Core/Lookup.cpp:63-66 @@ +62,6 @@ +cast(DeclA)->getQualifiedNameAsString() + "::"; +if (NewName.startswith("::")) + NS = "::" + NS; +if (NewName.startswith(NS)) + return NewName.substr(NS.size()); +DeclA = DeclA->getParent(); If NewName is fully qualified, why would we ever want to allow that to match from a non-global namespace? namespace a { namespace b { namespace c { void foo(); }}} -> if NewName is "::c::bar" (for whatever reason), this should probably not silently go to bar inside 'c', or to c::bar inside 'b'. Comment at: lib/Tooling/Core/Lookup.cpp:72 @@ +71,3 @@ +/// Check if the name specifier begins with a written "::". +static bool isNameSpecifierGlobal(const NestedNameSpecifier *NNS) { + while (NNS) { Isn't that more like isFullyQualified then? Comment at: unittests/Tooling/LookupTest.cpp:19-20 @@ +18,4 @@ + bool VisitCallExpr(CallExpr *Expr) { +if (OnCall) + OnCall(Expr); +return true; Is this ever not true? http://reviews.llvm.org/D13931 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits