summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/unittests/HoverTests.cpp
diff options
context:
space:
mode:
authorKadir Cetinkaya <kadircet@google.com>2019-12-17 12:13:28 +0100
committerKadir Cetinkaya <kadircet@google.com>2019-12-19 11:55:22 +0100
commitac3f9e48421712168884d59cbfe8b294dd76a19b (patch)
tree6a8e3ee6911f9d5bebb6d43ec40a307ef9a2b8ee /clang-tools-extra/clangd/unittests/HoverTests.cpp
parent119cd70322af15ae61f5bd3530cf85fb27891d9f (diff)
downloadbcm5719-llvm-ac3f9e48421712168884d59cbfe8b294dd76a19b.tar.gz
bcm5719-llvm-ac3f9e48421712168884d59cbfe8b294dd76a19b.zip
[clangd] Improve documentation for auto and implicit specs
Summary: Clangd didn't fill documentation for `auto` when it wasn't available in index. Also it wasn't showing any documentations for implicit instantiations. This patch ensures auto and normal decl case behaves in the same way and also makes use of the explicit template specialization while fetching comments for implicit instantiations. Reviewers: ilya-biryukov Subscribers: MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D71596
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