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