[PATCH] D113974: [clangd] Put additional qualifiers to enum constants not declared as "enum class"
Kirill Bobyrev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 16 02:06:05 PST 2021
kbobyrev created this revision.
kbobyrev added a reviewer: kadircet.
Herald added subscribers: usaxena95, arphaman.
kbobyrev requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.
This is a cheap "fix" of the problem described in
https://github.com/clangd/clangd/issues/39. Currently, for this code:
c++
namespace ns {
enum Color { Green };
enum class Vehicle { Car };
}
The following is true:
- `Vehicle::Car` scope is `ns::Vehicle::` - it can't be accessed without spelling full enum class name
- `Color::Green` scope is `ns::` because it can be accessed as `ns::Car`
However, this causes index FuzzyFind to show empty results when querying
`ns::Color::` - `Color::Green` will only show up for `ns::`.
This patch changes the behavior and makes `SymbolCollector` treat plain `enum`
the same way it does handle `enum class`. Ideally, the index would point to the
same symbol for both `ns::Green` and `ns::Color::Green` but that increases
coupling since the enum information has to be propagated to the index builder
which is logically quite far from the `SymbolCollector`.
Fixes: https://github.com/clangd/clangd/issues/39
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D113974
Files:
clang-tools-extra/clangd/index/SymbolCollector.cpp
clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
Index: clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
+++ clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
@@ -1232,7 +1232,7 @@
UnorderedElementsAre(
AllOf(QName("Red"), ForCodeCompletion(true)),
AllOf(QName("Color"), ForCodeCompletion(true)),
- AllOf(QName("Green"), ForCodeCompletion(true)),
+ AllOf(QName("Color::Green"), ForCodeCompletion(true)),
AllOf(QName("Color2"), ForCodeCompletion(true)),
AllOf(QName("Color2::Yellow"), ForCodeCompletion(false)),
AllOf(QName("ns"), ForCodeCompletion(true)),
Index: clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
+++ clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
@@ -250,14 +250,15 @@
)cpp";
EXPECT_THAT(getSymbols(TU, "Red"), ElementsAre(QName("Red")));
EXPECT_THAT(getSymbols(TU, "::Red"), ElementsAre(QName("Red")));
- EXPECT_THAT(getSymbols(TU, "Green"), ElementsAre(QName("Green")));
- EXPECT_THAT(getSymbols(TU, "Green"), ElementsAre(QName("Green")));
+ EXPECT_THAT(getSymbols(TU, "Color::Green"),
+ ElementsAre(QName("Color::Green")));
EXPECT_THAT(getSymbols(TU, "Color2::Yellow"),
ElementsAre(QName("Color2::Yellow")));
EXPECT_THAT(getSymbols(TU, "Yellow"), ElementsAre(QName("Color2::Yellow")));
EXPECT_THAT(getSymbols(TU, "ns::Black"), ElementsAre(QName("ns::Black")));
- EXPECT_THAT(getSymbols(TU, "ns::Blue"), ElementsAre(QName("ns::Blue")));
+ EXPECT_THAT(getSymbols(TU, "ns::Color3::Blue"),
+ ElementsAre(QName("ns::Color3::Blue")));
EXPECT_THAT(getSymbols(TU, "ns::Color4::White"),
ElementsAre(QName("ns::Color4::White")));
}
Index: clang-tools-extra/clangd/index/SymbolCollector.cpp
===================================================================
--- clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -828,6 +828,23 @@
// FIXME: this returns foo:bar: for objective-C methods, we prefer only foo:
// for consistency with CodeCompletionString and a clean name/signature split.
std::tie(S.Scope, S.Name) = splitQualifiedName(QName);
+ std::string Scope = S.Scope.str();
+ // Put additional qualifiers for enum constants: technically, they can be
+ // accessed without using the enum name prefix (unless declared as enum
+ // class) but it is more convenient to enhance the scope with the enum type
+ // name.
+ // FIXME: It would be better to just have the SymbolIndex look up the same
+ // enum constant both with and without enum type name but at the time the
+ // index is built the information about ND is already lost.
+ if (const auto *EnumConstant = llvm::dyn_cast<EnumConstantDecl>(&ND)) {
+ if (const auto *II = EnumConstant->getType().getBaseTypeIdentifier()) {
+ std::string EnumScope = II->getName().str() + "::";
+ // For "enum class" the qualified name already has EnumScope.
+ if (!S.Scope.endswith(EnumScope))
+ Scope += EnumScope;
+ }
+ }
+ S.Scope = Scope;
std::string TemplateSpecializationArgs = printTemplateSpecializationArgs(ND);
S.TemplateSpecializationArgs = TemplateSpecializationArgs;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113974.387535.patch
Type: text/x-patch
Size: 3525 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211116/622471dc/attachment.bin>
More information about the cfe-commits
mailing list