Author: arphaman Date: Tue Nov 14 14:06:55 2017 New Revision: 318205 URL: http://llvm.org/viewvc/llvm-project?rev=318205&view=rev Log: [refactor][selection] canonicalize member expr callee to the full member call expression
We would like to extract the full call when just the callee is selected. Modified: cfe/trunk/lib/Tooling/Refactoring/ASTSelection.cpp cfe/trunk/unittests/Tooling/ASTSelectionTest.cpp Modified: cfe/trunk/lib/Tooling/Refactoring/ASTSelection.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/ASTSelection.cpp?rev=318205&r1=318204&r2=318205&view=diff ============================================================================== --- cfe/trunk/lib/Tooling/Refactoring/ASTSelection.cpp (original) +++ cfe/trunk/lib/Tooling/Refactoring/ASTSelection.cpp Tue Nov 14 14:06:55 2017 @@ -115,6 +115,11 @@ public: return true; if (auto *Opaque = dyn_cast<OpaqueValueExpr>(S)) return TraverseOpaqueValueExpr(Opaque); + // Avoid selecting implicit 'this' expressions. + if (auto *TE = dyn_cast<CXXThisExpr>(S)) { + if (TE->isImplicit()) + return true; + } // FIXME (Alex Lorenz): Improve handling for macro locations. SourceSelectionKind SelectionKind = selectionKindFor(CharSourceRange::getTokenRange(S->getSourceRange())); @@ -268,9 +273,15 @@ void SelectedNodeWithParents::canonicali // ~~~~~~ ~~~~~~~ if (isa<StringLiteral>(S) && isa<ObjCStringLiteral>(Parent)) Node = Parents.pop_back_val(); + // The entire call should be selected when just the member expression + // that refers to the method is selected. + // f.call(args) becomes f.call(args) + // ~~~~ ~~~~~~~~~~~~ + else if (isa<MemberExpr>(S) && isa<CXXMemberCallExpr>(Parent) && + cast<CXXMemberCallExpr>(Parent)->getCallee() == S) + Node = Parents.pop_back_val(); // FIXME: Syntactic form -> Entire pseudo-object expr. // FIXME: Callee -> Call. - // FIXME: Callee member expr -> Call. } /// Finds the set of bottom-most selected AST nodes that are in the selection Modified: cfe/trunk/unittests/Tooling/ASTSelectionTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/ASTSelectionTest.cpp?rev=318205&r1=318204&r2=318205&view=diff ============================================================================== --- cfe/trunk/unittests/Tooling/ASTSelectionTest.cpp (original) +++ cfe/trunk/unittests/Tooling/ASTSelectionTest.cpp Tue Nov 14 14:06:55 2017 @@ -1004,4 +1004,56 @@ void foo() { SelectionFinderVisitor::Lang_OBJC); } +TEST(ASTSelectionFinder, CanonicalizeMemberCalleeToCall) { + StringRef Source = R"( +class AClass { public: + void method(); + int afield; + void selectWholeCallWhenJustMethodSelected(int &i) { + method(); + } +}; +void selectWholeCallWhenJustMethodSelected() { + AClass a; + a.method(); +} +void dontSelectArgument(AClass &a) { + a.selectWholeCallWhenJustMethodSelected(a.afield); +} + )"; + // Just 'method' with implicit 'this': + findSelectedASTNodesWithRange( + Source, {6, 5}, FileRange{{6, 5}, {6, 11}}, + [](SourceRange SelectionRange, Optional<SelectedASTNode> Node) { + EXPECT_TRUE(Node); + Optional<CodeRangeASTSelection> SelectedCode = + CodeRangeASTSelection::create(SelectionRange, std::move(*Node)); + EXPECT_TRUE(SelectedCode); + EXPECT_EQ(SelectedCode->size(), 1u); + EXPECT_TRUE(isa<CXXMemberCallExpr>((*SelectedCode)[0])); + }); + // Just 'method': + findSelectedASTNodesWithRange( + Source, {11, 5}, FileRange{{11, 5}, {11, 11}}, + [](SourceRange SelectionRange, Optional<SelectedASTNode> Node) { + EXPECT_TRUE(Node); + Optional<CodeRangeASTSelection> SelectedCode = + CodeRangeASTSelection::create(SelectionRange, std::move(*Node)); + EXPECT_TRUE(SelectedCode); + EXPECT_EQ(SelectedCode->size(), 1u); + EXPECT_TRUE(isa<CXXMemberCallExpr>((*SelectedCode)[0])); + }); + // Just 'afield', which should not select the call. + findSelectedASTNodesWithRange( + Source, {14, 5}, FileRange{{14, 45}, {14, 51}}, + [](SourceRange SelectionRange, Optional<SelectedASTNode> Node) { + EXPECT_TRUE(Node); + Optional<CodeRangeASTSelection> SelectedCode = + CodeRangeASTSelection::create(SelectionRange, std::move(*Node)); + EXPECT_TRUE(SelectedCode); + EXPECT_EQ(SelectedCode->size(), 1u); + EXPECT_FALSE(isa<CXXMemberCallExpr>((*SelectedCode)[0])); + }); +} + } // end anonymous namespace _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits