summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/unittests/HoverTests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clangd/unittests/HoverTests.cpp')
-rw-r--r--clang-tools-extra/clangd/unittests/HoverTests.cpp136
1 files changed, 109 insertions, 27 deletions
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 8435544f37c..0c71d76e3c0 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "AST.h"
#include "Annotations.h"
#include "Hover.h"
#include "TestIndex.h"
@@ -130,12 +131,9 @@ TEST(Hover, Structured) {
)cpp",
[](HoverInfo &HI) {
HI.NamespaceScope = "";
- HI.Name = "vector";
+ HI.Name = "vector<int>";
HI.Kind = index::SymbolKind::Class;
- HI.Definition = "template <typename T> class vector {}";
- HI.TemplateParameters = {
- {std::string("typename"), std::string("T"), llvm::None},
- };
+ HI.Definition = "template <> class vector<int> {}";
}},
// Class template
{R"cpp(
@@ -181,21 +179,10 @@ class Foo {})cpp";
HI.NamespaceScope = "";
HI.Name = "foo";
HI.Kind = index::SymbolKind::Function;
- HI.Definition =
- R"cpp(template <template <typename, bool...> class C, typename = char, int = 0,
- bool Q = false, class... Ts>
-void foo())cpp";
+ HI.Definition = "template <> void foo<Foo, char, 0, false, <>>()";
HI.ReturnType = "void";
HI.Type = "void ()";
HI.Parameters.emplace();
- HI.TemplateParameters = {
- {std::string("template <typename, bool...> class"),
- std::string("C"), llvm::None},
- {std::string("typename"), llvm::None, std::string("char")},
- {std::string("int"), llvm::None, std::string("0")},
- {std::string("bool"), std::string("Q"), std::string("false")},
- {std::string("class..."), std::string("Ts"), llvm::None},
- };
}},
// Function decl
{R"cpp(
@@ -464,8 +451,6 @@ void foo())cpp";
HI.Type = "enum Color";
HI.Value = "GREEN (1)"; // Symbolic when hovering on an expression.
}},
- // FIXME: We should use the Decl referenced, even if from an implicit
- // instantiation. Then the scope would be Add<1, 2>.
{R"cpp(
template<int a, int b> struct Add {
static constexpr int result = a + b;
@@ -474,11 +459,11 @@ void foo())cpp";
)cpp",
[](HoverInfo &HI) {
HI.Name = "result";
- HI.Definition = "static constexpr int result = a + b";
+ HI.Definition = "static constexpr int result = 1 + 2";
HI.Kind = index::SymbolKind::StaticProperty;
HI.Type = "const int";
HI.NamespaceScope = "";
- HI.LocalScope = "Add<a, b>::";
+ HI.LocalScope = "Add<1, 2>::";
HI.Value = "3";
}},
{R"cpp(
@@ -1116,14 +1101,13 @@ TEST(Hover, All) {
HI.Name = "foo";
HI.Kind = index::SymbolKind::Function;
HI.NamespaceScope = "";
- HI.Type = "T ()";
- HI.Definition = "template <typename T> T foo()";
+ HI.Type = "int ()";
+ HI.Definition = "template <> int foo<int>()";
HI.Documentation = "Templated function";
- HI.ReturnType = "T";
+ HI.ReturnType = "int";
HI.Parameters = std::vector<HoverInfo::Param>{};
- HI.TemplateParameters = {
- {std::string("typename"), std::string("T"), llvm::None},
- };
+ // FIXME: We should populate template parameters with arguments in
+ // case of instantiations.
}},
{
R"cpp(// Anonymous union
@@ -1271,6 +1255,7 @@ TEST(Hover, All) {
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.Documentation = "auto function return with trailing type";
}},
{
R"cpp(// trailing return type
@@ -1282,6 +1267,7 @@ TEST(Hover, All) {
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.Documentation = "trailing return type";
}},
{
R"cpp(// auto in function return
@@ -1293,6 +1279,7 @@ TEST(Hover, All) {
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.Documentation = "auto in function return";
}},
{
R"cpp(// auto& in function return
@@ -1305,6 +1292,7 @@ TEST(Hover, All) {
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.Documentation = "auto& in function return";
}},
{
R"cpp(// auto* in function return
@@ -1317,6 +1305,7 @@ TEST(Hover, All) {
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.Documentation = "auto* in function return";
}},
{
R"cpp(// const auto& in function return
@@ -1329,6 +1318,7 @@ TEST(Hover, All) {
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.Documentation = "const auto& in function return";
}},
{
R"cpp(// decltype(auto) in function return
@@ -1340,6 +1330,7 @@ TEST(Hover, All) {
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.Documentation = "decltype(auto) in function return";
}},
{
R"cpp(// decltype(auto) reference in function return
@@ -1404,6 +1395,8 @@ TEST(Hover, All) {
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.Documentation =
+ "decltype of function with trailing return type.";
}},
{
R"cpp(// decltype of var with decltype.
@@ -1449,6 +1442,7 @@ TEST(Hover, All) {
[](HoverInfo &HI) {
HI.Name = "cls";
HI.Kind = index::SymbolKind::Struct;
+ HI.Documentation = "auto on alias";
}},
{
R"cpp(// auto on alias
@@ -1459,6 +1453,7 @@ TEST(Hover, All) {
[](HoverInfo &HI) {
HI.Name = "templ<int>";
HI.Kind = index::SymbolKind::Struct;
+ HI.Documentation = "auto on alias";
}},
};
@@ -1503,6 +1498,93 @@ TEST(Hover, All) {
}
}
+TEST(Hover, DocsFromIndex) {
+ Annotations T(R"cpp(
+ template <typename T> class X {};
+ void foo() {
+ au^to t = X<int>();
+ X^<int> w;
+ (void)w;
+ })cpp");
+
+ TestTU TU = TestTU::withCode(T.code());
+ auto AST = TU.build();
+ for (const auto &D : AST.getDiagnostics())
+ ADD_FAILURE() << D;
+ ASSERT_TRUE(AST.getDiagnostics().empty());
+
+ Symbol IndexSym;
+ IndexSym.ID = *getSymbolID(&findDecl(AST, "X"));
+ IndexSym.Documentation = "comment from index";
+ SymbolSlab::Builder Symbols;
+ Symbols.insert(IndexSym);
+ auto Index =
+ MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab());
+
+ for (const auto &P : T.points()) {
+ auto H = getHover(AST, P, format::getLLVMStyle(), Index.get());
+ ASSERT_TRUE(H);
+ EXPECT_EQ(H->Documentation, IndexSym.Documentation);
+ }
+}
+
+TEST(Hover, DocsFromAST) {
+ Annotations T(R"cpp(
+ // doc
+ template <typename T> class X {};
+ // doc
+ template <typename T> void bar() {}
+ // doc
+ template <typename T> T baz;
+ void foo() {
+ au^to t = X<int>();
+ X^<int>();
+ b^ar<int>();
+ au^to T = ba^z<X<int>>;
+ ba^z<int> = 0;
+ })cpp");
+
+ TestTU TU = TestTU::withCode(T.code());
+ auto AST = TU.build();
+ for (const auto &D : AST.getDiagnostics())
+ ADD_FAILURE() << D;
+ ASSERT_TRUE(AST.getDiagnostics().empty());
+
+ for (const auto &P : T.points()) {
+ auto H = getHover(AST, P, format::getLLVMStyle(), nullptr);
+ ASSERT_TRUE(H);
+ EXPECT_EQ(H->Documentation, "doc");
+ }
+}
+
+TEST(Hover, DocsFromMostSpecial) {
+ Annotations T(R"cpp(
+ // doc1
+ template <typename T> class $doc1^X {};
+ // doc2
+ template <> class $doc2^X<int> {};
+ // doc3
+ template <typename T> class $doc3^X<T*> {};
+ void foo() {
+ X$doc1^<char>();
+ X$doc2^<int>();
+ X$doc3^<int*>();
+ })cpp");
+
+ TestTU TU = TestTU::withCode(T.code());
+ auto AST = TU.build();
+ for (const auto &D : AST.getDiagnostics())
+ ADD_FAILURE() << D;
+ ASSERT_TRUE(AST.getDiagnostics().empty());
+
+ for (auto Comment : {"doc1", "doc2", "doc3"}) {
+ for (const auto &P : T.points(Comment)) {
+ auto H = getHover(AST, P, format::getLLVMStyle(), nullptr);
+ ASSERT_TRUE(H);
+ EXPECT_EQ(H->Documentation, Comment);
+ }
+ }
+}
} // namespace
} // namespace clangd
} // namespace clang
OpenPOWER on IntegriCloud