[clang-tools-extra] [clangd] Remove redundant symbol name from hierarchy item details (PR #170112)
Christian Kandeler via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 1 04:06:56 PST 2025
https://github.com/ckandeler created https://github.com/llvm/llvm-project/pull/170112
Closes #2346.
>From f3a97db5787e2f447c253b0ac1aaa790942cf84c Mon Sep 17 00:00:00 2001
From: Christian Kandeler <christian.kandeler at qt.io>
Date: Mon, 1 Dec 2025 13:03:19 +0100
Subject: [PATCH] [clangd] Remove redundant symbol name from hierarchy item
details
Closes #2346.
---
clang-tools-extra/clangd/XRefs.cpp | 3 +-
.../clangd/test/type-hierarchy-ext.test | 4 +-
.../clangd/test/type-hierarchy.test | 4 +-
.../clangd/unittests/CallHierarchyTests.cpp | 116 +++++++++---------
4 files changed, 61 insertions(+), 66 deletions(-)
diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
index ef45acf501612..171465f17b86f 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -1831,7 +1831,8 @@ static std::optional<HierarchyItem> symbolToHierarchyItem(const Symbol &S,
}
HierarchyItem HI;
HI.name = std::string(S.Name);
- HI.detail = (S.Scope + S.Name).str();
+ HI.detail = S.Scope.empty() ? std::string()
+ : S.Scope.drop_back(2).str(); // Trailing "::"
HI.kind = indexSymbolKindToSymbolKind(S.SymInfo.Kind);
HI.selectionRange = Loc->range;
// FIXME: Populate 'range' correctly
diff --git a/clang-tools-extra/clangd/test/type-hierarchy-ext.test b/clang-tools-extra/clangd/test/type-hierarchy-ext.test
index 8d1a5dc31da0f..324d15e255673 100644
--- a/clang-tools-extra/clangd/test/type-hierarchy-ext.test
+++ b/clang-tools-extra/clangd/test/type-hierarchy-ext.test
@@ -12,7 +12,7 @@
# CHECK-NEXT: "data": {
# CHECK-NEXT: "symbolID": "A6576FE083F2949A"
# CHECK-NEXT: },
-# CHECK-NEXT: "detail": "Child3",
+# CHECK-NEXT: "detail": "",
# CHECK-NEXT: "kind": 23,
# CHECK-NEXT: "name": "Child3",
# CHECK-NEXT: "range": {
@@ -154,7 +154,7 @@
# CHECK-NEXT: "data": {
# CHECK-NEXT: "symbolID": "5705B382DFC77CBC"
# CHECK-NEXT: },
-# CHECK-NEXT: "detail": "Child4",
+# CHECK-NEXT: "detail": "",
# CHECK-NEXT: "kind": 23,
# CHECK-NEXT: "name": "Child4",
# CHECK-NEXT: "range": {
diff --git a/clang-tools-extra/clangd/test/type-hierarchy.test b/clang-tools-extra/clangd/test/type-hierarchy.test
index a5f13ab13d0b3..acb9688ec17a8 100644
--- a/clang-tools-extra/clangd/test/type-hierarchy.test
+++ b/clang-tools-extra/clangd/test/type-hierarchy.test
@@ -62,7 +62,7 @@
# CHECK-NEXT: ],
# CHECK-NEXT: "symbolID": "ECDC0C46D75120F4"
# CHECK-NEXT: },
-# CHECK-NEXT: "detail": "Child1",
+# CHECK-NEXT: "detail": "",
# CHECK-NEXT: "kind": 23,
# CHECK-NEXT: "name": "Child1",
# CHECK-NEXT: "range": {
@@ -113,7 +113,7 @@
# CHECK-NEXT: ],
# CHECK-NEXT: "symbolID": "A6576FE083F2949A"
# CHECK-NEXT: },
-# CHECK-NEXT: "detail": "Child3",
+# CHECK-NEXT: "detail": "",
# CHECK-NEXT: "kind": 23,
# CHECK-NEXT: "name": "Child3",
# CHECK-NEXT: "range": {
diff --git a/clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp b/clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp
index 9859577c7cf7e..4fd294c41a3b2 100644
--- a/clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp
@@ -92,21 +92,21 @@ TEST(CallHierarchy, IncomingOneFileCpp) {
auto IncomingLevel1 = incomingCalls(Items[0], Index.get());
ASSERT_THAT(
IncomingLevel1,
- ElementsAre(AllOf(from(AllOf(withName("caller1"), withDetail("caller1"))),
+ ElementsAre(AllOf(from(AllOf(withName("caller1"), withDetail(""))),
iFromRanges(Source.range("Callee")))));
auto IncomingLevel2 = incomingCalls(IncomingLevel1[0].from, Index.get());
ASSERT_THAT(
IncomingLevel2,
- ElementsAre(AllOf(from(AllOf(withName("caller2"), withDetail("caller2"))),
+ ElementsAre(AllOf(from(AllOf(withName("caller2"), withDetail(""))),
iFromRanges(Source.range("Caller1A"),
Source.range("Caller1B"))),
- AllOf(from(AllOf(withName("caller3"), withDetail("caller3"))),
+ AllOf(from(AllOf(withName("caller3"), withDetail(""))),
iFromRanges(Source.range("Caller1C")))));
auto IncomingLevel3 = incomingCalls(IncomingLevel2[0].from, Index.get());
ASSERT_THAT(
IncomingLevel3,
- ElementsAre(AllOf(from(AllOf(withName("caller3"), withDetail("caller3"))),
+ ElementsAre(AllOf(from(AllOf(withName("caller3"), withDetail(""))),
iFromRanges(Source.range("Caller2")))));
auto IncomingLevel4 = incomingCalls(IncomingLevel3[0].from, Index.get());
@@ -138,25 +138,24 @@ TEST(CallHierarchy, IncomingOneFileObjC) {
prepareCallHierarchy(AST, Source.point(), testPath(TU.Filename));
ASSERT_THAT(Items, ElementsAre(withName("callee")));
auto IncomingLevel1 = incomingCalls(Items[0], Index.get());
- ASSERT_THAT(IncomingLevel1,
- ElementsAre(AllOf(from(AllOf(withName("caller1"),
- withDetail("MyClass::caller1"))),
- iFromRanges(Source.range("Callee")))));
+ ASSERT_THAT(
+ IncomingLevel1,
+ ElementsAre(AllOf(from(AllOf(withName("caller1"), withDetail("MyClass"))),
+ iFromRanges(Source.range("Callee")))));
auto IncomingLevel2 = incomingCalls(IncomingLevel1[0].from, Index.get());
- ASSERT_THAT(IncomingLevel2,
- ElementsAre(AllOf(from(AllOf(withName("caller2"),
- withDetail("MyClass::caller2"))),
- iFromRanges(Source.range("Caller1A"),
- Source.range("Caller1B"))),
- AllOf(from(AllOf(withName("caller3"),
- withDetail("MyClass::caller3"))),
- iFromRanges(Source.range("Caller1C")))));
+ ASSERT_THAT(
+ IncomingLevel2,
+ ElementsAre(AllOf(from(AllOf(withName("caller2"), withDetail("MyClass"))),
+ iFromRanges(Source.range("Caller1A"),
+ Source.range("Caller1B"))),
+ AllOf(from(AllOf(withName("caller3"), withDetail("MyClass"))),
+ iFromRanges(Source.range("Caller1C")))));
auto IncomingLevel3 = incomingCalls(IncomingLevel2[0].from, Index.get());
- ASSERT_THAT(IncomingLevel3,
- ElementsAre(AllOf(from(AllOf(withName("caller3"),
- withDetail("MyClass::caller3"))),
- iFromRanges(Source.range("Caller2")))));
+ ASSERT_THAT(
+ IncomingLevel3,
+ ElementsAre(AllOf(from(AllOf(withName("caller3"), withDetail("MyClass"))),
+ iFromRanges(Source.range("Caller2")))));
auto IncomingLevel4 = incomingCalls(IncomingLevel3[0].from, Index.get());
EXPECT_THAT(IncomingLevel4, IsEmpty());
@@ -186,14 +185,13 @@ TEST(CallHierarchy, IncomingIncludeOverrides) {
ASSERT_THAT(Items, ElementsAre(withName("callee")));
auto IncomingLevel1 = incomingCalls(Items[0], Index.get());
ASSERT_THAT(IncomingLevel1,
- ElementsAre(AllOf(from(AllOf(withName("Func"),
- withDetail("Implementation::Func"))),
- iFromRanges(Source.range("Callee")))));
+ ElementsAre(AllOf(
+ from(AllOf(withName("Func"), withDetail("Implementation"))),
+ iFromRanges(Source.range("Callee")))));
auto IncomingLevel2 = incomingCalls(IncomingLevel1[0].from, Index.get());
- ASSERT_THAT(
- IncomingLevel2,
- ElementsAre(AllOf(from(AllOf(withName("Test"), withDetail("Test"))),
- iFromRanges(Source.range("FuncCall")))));
+ ASSERT_THAT(IncomingLevel2,
+ ElementsAre(AllOf(from(AllOf(withName("Test"), withDetail(""))),
+ iFromRanges(Source.range("FuncCall")))));
auto IncomingLevel3 = incomingCalls(IncomingLevel2[0].from, Index.get());
EXPECT_THAT(IncomingLevel3, IsEmpty());
@@ -224,13 +222,13 @@ TEST(CallHierarchy, MainFileOnlyRef) {
auto IncomingLevel1 = incomingCalls(Items[0], Index.get());
ASSERT_THAT(
IncomingLevel1,
- ElementsAre(AllOf(from(AllOf(withName("caller1"), withDetail("caller1"))),
+ ElementsAre(AllOf(from(AllOf(withName("caller1"), withDetail(""))),
iFromRanges(Source.range("Callee")))));
auto IncomingLevel2 = incomingCalls(IncomingLevel1[0].from, Index.get());
EXPECT_THAT(
IncomingLevel2,
- ElementsAre(AllOf(from(AllOf(withName("caller2"), withDetail("caller2"))),
+ ElementsAre(AllOf(from(AllOf(withName("caller2"), withDetail(""))),
iFromRanges(Source.range("Caller1")))));
}
@@ -259,11 +257,10 @@ TEST(CallHierarchy, IncomingQualified) {
auto Incoming = incomingCalls(Items[0], Index.get());
EXPECT_THAT(
Incoming,
- ElementsAre(
- AllOf(from(AllOf(withName("caller1"), withDetail("ns::caller1"))),
- iFromRanges(Source.range("Caller1"))),
- AllOf(from(AllOf(withName("caller2"), withDetail("ns::caller2"))),
- iFromRanges(Source.range("Caller2")))));
+ ElementsAre(AllOf(from(AllOf(withName("caller1"), withDetail("ns"))),
+ iFromRanges(Source.range("Caller1"))),
+ AllOf(from(AllOf(withName("caller2"), withDetail("ns"))),
+ iFromRanges(Source.range("Caller2")))));
}
TEST(CallHierarchy, OutgoingOneFile) {
@@ -299,24 +296,22 @@ TEST(CallHierarchy, OutgoingOneFile) {
auto OugoingLevel1 = outgoingCalls(Items[0], Index.get());
ASSERT_THAT(
OugoingLevel1,
- ElementsAre(
- AllOf(to(AllOf(withName("caller1"), withDetail("ns::Foo::caller1"))),
- oFromRanges(Source.range("Caller1C"))),
- AllOf(to(AllOf(withName("caller2"), withDetail("caller2"))),
- oFromRanges(Source.range("Caller2")))));
+ ElementsAre(AllOf(to(AllOf(withName("caller1"), withDetail("ns::Foo"))),
+ oFromRanges(Source.range("Caller1C"))),
+ AllOf(to(AllOf(withName("caller2"), withDetail(""))),
+ oFromRanges(Source.range("Caller2")))));
auto OutgoingLevel2 = outgoingCalls(OugoingLevel1[1].to, Index.get());
ASSERT_THAT(
OutgoingLevel2,
ElementsAre(AllOf(
- to(AllOf(withName("caller1"), withDetail("ns::Foo::caller1"))),
+ to(AllOf(withName("caller1"), withDetail("ns::Foo"))),
oFromRanges(Source.range("Caller1A"), Source.range("Caller1B")))));
auto OutgoingLevel3 = outgoingCalls(OutgoingLevel2[0].to, Index.get());
- ASSERT_THAT(
- OutgoingLevel3,
- ElementsAre(AllOf(to(AllOf(withName("callee"), withDetail("callee"))),
- oFromRanges(Source.range("Callee")))));
+ ASSERT_THAT(OutgoingLevel3,
+ ElementsAre(AllOf(to(AllOf(withName("callee"), withDetail(""))),
+ oFromRanges(Source.range("Callee")))));
auto OutgoingLevel4 = outgoingCalls(OutgoingLevel3[0].to, Index.get());
EXPECT_THAT(OutgoingLevel4, IsEmpty());
@@ -397,25 +392,25 @@ TEST(CallHierarchy, MultiFileCpp) {
prepareCallHierarchy(AST, Pos, TUPath);
ASSERT_THAT(Items, ElementsAre(withName("callee")));
auto IncomingLevel1 = incomingCalls(Items[0], Index.get());
- ASSERT_THAT(IncomingLevel1,
- ElementsAre(AllOf(from(AllOf(withName("caller1"),
- withDetail("nsa::caller1"))),
- iFromRanges(Caller1C.range()))));
+ ASSERT_THAT(
+ IncomingLevel1,
+ ElementsAre(AllOf(from(AllOf(withName("caller1"), withDetail("nsa"))),
+ iFromRanges(Caller1C.range()))));
auto IncomingLevel2 = incomingCalls(IncomingLevel1[0].from, Index.get());
ASSERT_THAT(
IncomingLevel2,
ElementsAre(
- AllOf(from(AllOf(withName("caller2"), withDetail("nsb::caller2"))),
+ AllOf(from(AllOf(withName("caller2"), withDetail("nsb"))),
iFromRanges(Caller2C.range("A"), Caller2C.range("B"))),
- AllOf(from(AllOf(withName("caller3"), withDetail("nsa::caller3"))),
+ AllOf(from(AllOf(withName("caller3"), withDetail("nsa"))),
iFromRanges(Caller3C.range("Caller1")))));
auto IncomingLevel3 = incomingCalls(IncomingLevel2[0].from, Index.get());
- ASSERT_THAT(IncomingLevel3,
- ElementsAre(AllOf(from(AllOf(withName("caller3"),
- withDetail("nsa::caller3"))),
- iFromRanges(Caller3C.range("Caller2")))));
+ ASSERT_THAT(
+ IncomingLevel3,
+ ElementsAre(AllOf(from(AllOf(withName("caller3"), withDetail("nsa"))),
+ iFromRanges(Caller3C.range("Caller2")))));
auto IncomingLevel4 = incomingCalls(IncomingLevel3[0].from, Index.get());
EXPECT_THAT(IncomingLevel4, IsEmpty());
@@ -437,24 +432,23 @@ TEST(CallHierarchy, MultiFileCpp) {
// If that's the header, we can't get ranges from the implementation
// file!
ElementsAre(
- AllOf(to(AllOf(withName("caller1"), withDetail("nsa::caller1"))),
+ AllOf(to(AllOf(withName("caller1"), withDetail("nsa"))),
IsDeclaration ? oFromRanges()
: oFromRanges(Caller3C.range("Caller1"))),
- AllOf(to(AllOf(withName("caller2"), withDetail("nsb::caller2"))),
+ AllOf(to(AllOf(withName("caller2"), withDetail("nsb"))),
IsDeclaration ? oFromRanges()
: oFromRanges(Caller3C.range("Caller2")))));
auto OutgoingLevel2 = outgoingCalls(OutgoingLevel1[1].to, Index.get());
ASSERT_THAT(OutgoingLevel2,
ElementsAre(AllOf(
- to(AllOf(withName("caller1"), withDetail("nsa::caller1"))),
+ to(AllOf(withName("caller1"), withDetail("nsa"))),
oFromRanges(Caller2C.range("A"), Caller2C.range("B")))));
auto OutgoingLevel3 = outgoingCalls(OutgoingLevel2[0].to, Index.get());
- ASSERT_THAT(
- OutgoingLevel3,
- ElementsAre(AllOf(to(AllOf(withName("callee"), withDetail("callee"))),
- oFromRanges(Caller1C.range()))));
+ ASSERT_THAT(OutgoingLevel3,
+ ElementsAre(AllOf(to(AllOf(withName("callee"), withDetail(""))),
+ oFromRanges(Caller1C.range()))));
auto OutgoingLevel4 = outgoingCalls(OutgoingLevel3[0].to, Index.get());
EXPECT_THAT(OutgoingLevel4, IsEmpty());
More information about the cfe-commits
mailing list