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

Reply via email to