sammccall created this revision.
sammccall added a reviewer: kadircet.
Herald added subscribers: cfe-commits, usaxena95, arphaman, jkorous, MaskRay, 
ilya-biryukov.
Herald added a project: clang.

CODE: int foo(int);
OLD:  TTT FFFTTTTT
NEW:  TTT FFFFTTTF

This works around targeting issues when the cursor is between name and (


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D71284

Files:
  clang-tools-extra/clangd/Selection.cpp
  clang-tools-extra/clangd/test/hover.test
  clang-tools-extra/clangd/unittests/SelectionTests.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -971,7 +971,7 @@
   // Not a definition
   vo^i[[d^ ^f]]^oo();
 
-  [[vo^id ]]foo[[()]] {[[
+  [[vo^id ]]foo() {[[
     [[(void)(5+3);
     return;]]
   }]]
@@ -1879,7 +1879,7 @@
     // Not a definition
     vo^i[[d^ ^f]]^oo();
 
-    [[vo^id ]]foo[[()]] {[[
+    [[vo^id ]]foo() {[[
       [[(void)(5+3);
       return;]]
     }]])cpp");
Index: clang-tools-extra/clangd/unittests/SelectionTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -249,10 +249,10 @@
       {"void foo() { [[foo^()]]; /*comment*/^}", "CallExpr"},
 
       // Tricky case: FunctionTypeLoc in FunctionDecl has a hole in it.
-      {"[[^void]] foo();", "BuiltinTypeLoc"},
-      {"[[void foo^()]];", "FunctionProtoTypeLoc"},
-      {"[[^void foo^()]];", "FunctionDecl"},
-      {"[[void ^foo()]];", "FunctionDecl"},
+      {"[[^void]] foo(int);", "BuiltinTypeLoc"},
+      {"[[void foo^(int)]];", "FunctionDecl"},
+      {"[[^void foo^(int)]];", "FunctionDecl"},
+      {"[[void ^foo(int)]];", "FunctionDecl"},
       // Tricky case: two VarDecls share a specifier.
       {"[[int ^a]], b;", "VarDecl"},
       {"[[int a, ^b]];", "VarDecl"},
Index: clang-tools-extra/clangd/test/hover.test
===================================================================
--- clang-tools-extra/clangd/test/hover.test
+++ clang-tools-extra/clangd/test/hover.test
@@ -24,7 +24,7 @@
 # CHECK-NEXT:  }
 # CHECK-NEXT:}
 ---
-{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":0,"character":10}}}
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":0,"character":0}}}
 #      CHECK:  "id": 1,
 # CHECK-NEXT:  "jsonrpc": "2.0",
 # CHECK-NEXT:  "result": null
Index: clang-tools-extra/clangd/Selection.cpp
===================================================================
--- clang-tools-extra/clangd/Selection.cpp
+++ clang-tools-extra/clangd/Selection.cpp
@@ -547,14 +547,13 @@
   // Pushes a node onto the ancestor stack. Pairs with pop().
   // Performs early hit detection for some nodes (on the earlySourceRange).
   void push(DynTypedNode Node) {
-    SourceRange Early = earlySourceRange(Node);
     dlog("{1}push: {0}", printNodeToString(Node, PrintPolicy), indent());
     Nodes.emplace_back();
     Nodes.back().ASTNode = std::move(Node);
     Nodes.back().Parent = Stack.top();
     Nodes.back().Selected = NoTokens;
     Stack.push(&Nodes.back());
-    claimRange(Early, Nodes.back().Selected);
+    claimEarlyRange(Node, Nodes.back().Selected);
   }
 
   // Pops a node off the ancestor stack, and finalizes it. Pairs with push().
@@ -579,19 +578,26 @@
   // Returns the range of tokens that this node will claim directly, and
   // is not available to the node's children.
   // Usually empty, but sometimes children cover tokens but shouldn't own them.
-  SourceRange earlySourceRange(const DynTypedNode &N) {
+  void claimEarlyRange(const DynTypedNode &N,
+                       SelectionTree::Selection &Selected) {
+    auto Claim = [&](SourceRange R) { claimRange(R, Selected); };
     if (const Decl *D = N.get<Decl>()) {
-      // void [[foo]]();
-      if (auto *FD = llvm::dyn_cast<FunctionDecl>(D))
-        return FD->getNameInfo().getSourceRange();
+      if (auto *FD = llvm::dyn_cast<FunctionDecl>(D)) {
+        // void [[foo]]();
+        Claim(FD->getNameInfo().getSourceRange());
+        // Also claim the parens. Formally, the FunctionTypeLoc is more precise,
+        // but it's not a very "useful" node (e.g. we can't find its target).
+        // Associating the parens with the function is what users expect.
+        Claim(FD->getFunctionTypeLoc().getLParenLoc());
+        Claim(FD->getFunctionTypeLoc().getRParenLoc());
+      }
       // int (*[[s]])();
       else if (auto *VD = llvm::dyn_cast<VarDecl>(D))
-        return VD->getLocation();
+        Claim(VD->getLocation());
     } else if (const auto* CCI = N.get<CXXCtorInitializer>()) {
       // : [[b_]](42)
-      return CCI->getMemberLocation();
+      Claim(CCI->getMemberLocation());
     }
-    return SourceRange();
   }
 
   // Perform hit-testing of a complete Node against the selection.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D71284: [cl... Sam McCall via Phabricator via cfe-commits

Reply via email to