v1nh1shungry created this revision. v1nh1shungry added reviewers: nridge, tom-anders. Herald added subscribers: kadircet, arphaman. Herald added a project: All. v1nh1shungry requested review of this revision. Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov. Herald added a project: clang-tools-extra.
Show C++ string-literals' character's type and length in a hover card Issue related: https://github.com/clangd/clangd/issues/1016 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D137650 Files: clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/unittests/HoverTests.cpp Index: clang-tools-extra/clangd/unittests/HoverTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/HoverTests.cpp +++ clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -1300,7 +1300,6 @@ "auto x = ^42.0i;", "auto x = ^42;", "auto x = ^nullptr;", - "auto x = ^\"asdf\";", }; for (const auto &Test : Tests) { @@ -1326,6 +1325,11 @@ HI.Type = "char"; HI.Value = "65 (0x41)"; }}, + {"auto s = ^[[\"Hello, world!\"]]; // string literal", + [](HoverInfo &HI) { + HI.Name = "String Literal"; + HI.Type = "const char[14]"; + }}, { R"cpp(// Local variable int main() { Index: clang-tools-extra/clangd/Hover.cpp =================================================================== --- clang-tools-extra/clangd/Hover.cpp +++ clang-tools-extra/clangd/Hover.cpp @@ -777,6 +777,52 @@ return HI; } +llvm::Optional<HoverInfo> +getStringLiteralHoverContents(const StringLiteral *SL, + const LangOptions &LangOpts) { + HoverInfo HI; + + // TODO: Show string literal's contents + HI.Name = "String Literal"; + + // In C++ string literals have `const` qualifier, but in C it don't. + std::string Qualifier; + + std::string CharType; + // C++ + // TODO: Support different C++ standards + if (LangOpts.CPlusPlus) { + Qualifier = "const "; + switch (SL->getKind()) { + case StringLiteral::Ordinary: + CharType = "char"; + break; + case StringLiteral::Wide: + CharType = "wchar_t"; + break; + case StringLiteral::UTF8: + CharType = "char8_t"; + break; + case StringLiteral::UTF16: + CharType = "char16_t"; + break; + case StringLiteral::UTF32: + CharType = "char32_t"; + break; + } + } else { + // TODO: For other languages + return llvm::None; + } + + HoverInfo::PrintedType Type; + Type.Type = + Qualifier + CharType + "[" + std::to_string(SL->getLength() + 1) + "]"; + HI.Type = Type; + + return HI; +} + bool isLiteral(const Expr *E) { // Unfortunately there's no common base Literal classes inherits from // (apart from Expr), therefore these exclusions. @@ -806,8 +852,14 @@ const SymbolIndex *Index) { // There's not much value in hovering over "42" and getting a hover card // saying "42 is an int", similar for other literals. - if (isLiteral(E)) + if (isLiteral(E)) { + // Generate hover info for string literals showing + // its character's type and length + if (const StringLiteral *SL = dyn_cast<StringLiteral>(E)) { + return getStringLiteralHoverContents(SL, AST.getLangOpts()); + } return llvm::None; + } HoverInfo HI; // For `this` expr we currently generate hover with pointee type.
Index: clang-tools-extra/clangd/unittests/HoverTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/HoverTests.cpp +++ clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -1300,7 +1300,6 @@ "auto x = ^42.0i;", "auto x = ^42;", "auto x = ^nullptr;", - "auto x = ^\"asdf\";", }; for (const auto &Test : Tests) { @@ -1326,6 +1325,11 @@ HI.Type = "char"; HI.Value = "65 (0x41)"; }}, + {"auto s = ^[[\"Hello, world!\"]]; // string literal", + [](HoverInfo &HI) { + HI.Name = "String Literal"; + HI.Type = "const char[14]"; + }}, { R"cpp(// Local variable int main() { Index: clang-tools-extra/clangd/Hover.cpp =================================================================== --- clang-tools-extra/clangd/Hover.cpp +++ clang-tools-extra/clangd/Hover.cpp @@ -777,6 +777,52 @@ return HI; } +llvm::Optional<HoverInfo> +getStringLiteralHoverContents(const StringLiteral *SL, + const LangOptions &LangOpts) { + HoverInfo HI; + + // TODO: Show string literal's contents + HI.Name = "String Literal"; + + // In C++ string literals have `const` qualifier, but in C it don't. + std::string Qualifier; + + std::string CharType; + // C++ + // TODO: Support different C++ standards + if (LangOpts.CPlusPlus) { + Qualifier = "const "; + switch (SL->getKind()) { + case StringLiteral::Ordinary: + CharType = "char"; + break; + case StringLiteral::Wide: + CharType = "wchar_t"; + break; + case StringLiteral::UTF8: + CharType = "char8_t"; + break; + case StringLiteral::UTF16: + CharType = "char16_t"; + break; + case StringLiteral::UTF32: + CharType = "char32_t"; + break; + } + } else { + // TODO: For other languages + return llvm::None; + } + + HoverInfo::PrintedType Type; + Type.Type = + Qualifier + CharType + "[" + std::to_string(SL->getLength() + 1) + "]"; + HI.Type = Type; + + return HI; +} + bool isLiteral(const Expr *E) { // Unfortunately there's no common base Literal classes inherits from // (apart from Expr), therefore these exclusions. @@ -806,8 +852,14 @@ const SymbolIndex *Index) { // There's not much value in hovering over "42" and getting a hover card // saying "42 is an int", similar for other literals. - if (isLiteral(E)) + if (isLiteral(E)) { + // Generate hover info for string literals showing + // its character's type and length + if (const StringLiteral *SL = dyn_cast<StringLiteral>(E)) { + return getStringLiteralHoverContents(SL, AST.getLangOpts()); + } return llvm::None; + } HoverInfo HI; // For `this` expr we currently generate hover with pointee type.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits