[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
//===-- FindSymbolsTests.cpp -------------------------*- C++ -*------------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "Annotations.h"
|
|
|
|
#include "ClangdServer.h"
|
|
|
|
#include "FindSymbols.h"
|
|
|
|
#include "SyncAPI.h"
|
|
|
|
#include "TestFS.h"
|
|
|
|
#include "gmock/gmock.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace clangd {
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
using ::testing::AllOf;
|
|
|
|
using ::testing::ElementsAre;
|
2018-07-06 03:35:01 +08:00
|
|
|
using ::testing::ElementsAreArray;
|
2018-11-23 23:21:19 +08:00
|
|
|
using ::testing::Field;
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
using ::testing::IsEmpty;
|
|
|
|
using ::testing::UnorderedElementsAre;
|
|
|
|
|
|
|
|
class IgnoreDiagnostics : public DiagnosticsConsumer {
|
|
|
|
void onDiagnosticsReady(PathRef File,
|
|
|
|
std::vector<Diag> Diagnostics) override {}
|
|
|
|
};
|
|
|
|
|
|
|
|
// GMock helpers for matching SymbolInfos items.
|
2018-06-27 00:57:44 +08:00
|
|
|
MATCHER_P(QName, Name, "") {
|
|
|
|
if (arg.containerName.empty())
|
|
|
|
return arg.name == Name;
|
|
|
|
return (arg.containerName + "::" + arg.name) == Name;
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
}
|
2018-11-23 23:21:19 +08:00
|
|
|
MATCHER_P(WithName, N, "") { return arg.name == N; }
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
MATCHER_P(WithKind, Kind, "") { return arg.kind == Kind; }
|
2018-07-06 03:35:01 +08:00
|
|
|
MATCHER_P(SymRange, Range, "") { return arg.location.range == Range; }
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
|
2018-11-23 23:21:19 +08:00
|
|
|
// GMock helpers for matching DocumentSymbol.
|
|
|
|
MATCHER_P(SymNameRange, Range, "") { return arg.selectionRange == Range; }
|
|
|
|
template <class... ChildMatchers>
|
2019-05-06 18:08:47 +08:00
|
|
|
::testing::Matcher<DocumentSymbol> Children(ChildMatchers... ChildrenM) {
|
2018-11-23 23:21:19 +08:00
|
|
|
return Field(&DocumentSymbol::children, ElementsAre(ChildrenM...));
|
|
|
|
}
|
|
|
|
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
ClangdServer::Options optsForTests() {
|
|
|
|
auto ServerOpts = ClangdServer::optsForTest();
|
2018-10-19 23:42:23 +08:00
|
|
|
ServerOpts.WorkspaceRoot = testRoot();
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
ServerOpts.BuildDynamicSymbolIndex = true;
|
|
|
|
return ServerOpts;
|
|
|
|
}
|
|
|
|
|
|
|
|
class WorkspaceSymbolsTest : public ::testing::Test {
|
|
|
|
public:
|
|
|
|
WorkspaceSymbolsTest()
|
2018-06-19 17:33:53 +08:00
|
|
|
: Server(CDB, FSProvider, DiagConsumer, optsForTests()) {
|
|
|
|
// Make sure the test root directory is created.
|
|
|
|
FSProvider.Files[testPath("unused")] = "";
|
2019-01-14 18:01:17 +08:00
|
|
|
CDB.ExtraClangFlags = {"-xc++"};
|
2018-06-19 17:33:53 +08:00
|
|
|
}
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
|
|
|
|
protected:
|
|
|
|
MockFSProvider FSProvider;
|
|
|
|
MockCompilationDatabase CDB;
|
|
|
|
IgnoreDiagnostics DiagConsumer;
|
|
|
|
ClangdServer Server;
|
2018-04-25 01:57:53 +08:00
|
|
|
int Limit = 0;
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
|
2019-01-07 23:45:19 +08:00
|
|
|
std::vector<SymbolInformation> getSymbols(llvm::StringRef Query) {
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
EXPECT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for preamble";
|
|
|
|
auto SymbolInfos = runWorkspaceSymbols(Server, Query, Limit);
|
|
|
|
EXPECT_TRUE(bool(SymbolInfos)) << "workspaceSymbols returned an error";
|
|
|
|
return *SymbolInfos;
|
|
|
|
}
|
|
|
|
|
2019-01-07 23:45:19 +08:00
|
|
|
void addFile(llvm::StringRef FileName, llvm::StringRef Contents) {
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
auto Path = testPath(FileName);
|
|
|
|
FSProvider.Files[Path] = Contents;
|
|
|
|
Server.addDocument(Path, Contents);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2019-01-28 22:11:49 +08:00
|
|
|
TEST_F(WorkspaceSymbolsTest, Macros) {
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
addFile("foo.cpp", R"cpp(
|
2019-01-28 22:11:49 +08:00
|
|
|
#define MACRO X
|
|
|
|
)cpp");
|
|
|
|
|
|
|
|
// LSP's SymbolKind doesn't have a "Macro" kind, and
|
|
|
|
// indexSymbolKindToSymbolKind() currently maps macros
|
|
|
|
// to SymbolKind::String.
|
|
|
|
EXPECT_THAT(getSymbols("macro"),
|
|
|
|
ElementsAre(AllOf(QName("MACRO"), WithKind(SymbolKind::String))));
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WorkspaceSymbolsTest, NoLocals) {
|
|
|
|
addFile("foo.cpp", R"cpp(
|
|
|
|
void test(int FirstParam, int SecondParam) {
|
|
|
|
struct LocalClass {};
|
|
|
|
int local_var;
|
|
|
|
})cpp");
|
|
|
|
EXPECT_THAT(getSymbols("l"), IsEmpty());
|
|
|
|
EXPECT_THAT(getSymbols("p"), IsEmpty());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WorkspaceSymbolsTest, Globals) {
|
|
|
|
addFile("foo.h", R"cpp(
|
|
|
|
int global_var;
|
|
|
|
|
|
|
|
int global_func();
|
|
|
|
|
|
|
|
struct GlobalStruct {};)cpp");
|
|
|
|
addFile("foo.cpp", R"cpp(
|
|
|
|
#include "foo.h"
|
|
|
|
)cpp");
|
|
|
|
EXPECT_THAT(getSymbols("global"),
|
2018-06-27 00:57:44 +08:00
|
|
|
UnorderedElementsAre(
|
|
|
|
AllOf(QName("GlobalStruct"), WithKind(SymbolKind::Struct)),
|
|
|
|
AllOf(QName("global_func"), WithKind(SymbolKind::Function)),
|
|
|
|
AllOf(QName("global_var"), WithKind(SymbolKind::Variable))));
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WorkspaceSymbolsTest, Unnamed) {
|
|
|
|
addFile("foo.h", R"cpp(
|
|
|
|
struct {
|
|
|
|
int InUnnamed;
|
|
|
|
} UnnamedStruct;)cpp");
|
|
|
|
addFile("foo.cpp", R"cpp(
|
|
|
|
#include "foo.h"
|
|
|
|
)cpp");
|
|
|
|
EXPECT_THAT(getSymbols("UnnamedStruct"),
|
2018-06-27 00:57:44 +08:00
|
|
|
ElementsAre(AllOf(QName("UnnamedStruct"),
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
WithKind(SymbolKind::Variable))));
|
2018-06-27 00:57:44 +08:00
|
|
|
EXPECT_THAT(getSymbols("InUnnamed"),
|
|
|
|
ElementsAre(AllOf(QName("(anonymous struct)::InUnnamed"),
|
|
|
|
WithKind(SymbolKind::Field))));
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WorkspaceSymbolsTest, InMainFile) {
|
|
|
|
addFile("foo.cpp", R"cpp(
|
2019-01-14 18:01:17 +08:00
|
|
|
int test() {}
|
|
|
|
static test2() {}
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
)cpp");
|
2019-04-12 18:09:37 +08:00
|
|
|
EXPECT_THAT(getSymbols("test"), ElementsAre(QName("test"), QName("test2")));
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WorkspaceSymbolsTest, Namespaces) {
|
|
|
|
addFile("foo.h", R"cpp(
|
|
|
|
namespace ans1 {
|
|
|
|
int ai1;
|
|
|
|
namespace ans2 {
|
|
|
|
int ai2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
addFile("foo.cpp", R"cpp(
|
|
|
|
#include "foo.h"
|
|
|
|
)cpp");
|
2018-06-27 00:57:44 +08:00
|
|
|
EXPECT_THAT(getSymbols("a"),
|
|
|
|
UnorderedElementsAre(QName("ans1"), QName("ans1::ai1"),
|
|
|
|
QName("ans1::ans2"),
|
|
|
|
QName("ans1::ans2::ai2")));
|
|
|
|
EXPECT_THAT(getSymbols("::"), ElementsAre(QName("ans1")));
|
|
|
|
EXPECT_THAT(getSymbols("::a"), ElementsAre(QName("ans1")));
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
EXPECT_THAT(getSymbols("ans1::"),
|
2018-06-27 00:57:44 +08:00
|
|
|
UnorderedElementsAre(QName("ans1::ai1"), QName("ans1::ans2")));
|
|
|
|
EXPECT_THAT(getSymbols("::ans1"), ElementsAre(QName("ans1")));
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
EXPECT_THAT(getSymbols("::ans1::"),
|
2018-06-27 00:57:44 +08:00
|
|
|
UnorderedElementsAre(QName("ans1::ai1"), QName("ans1::ans2")));
|
|
|
|
EXPECT_THAT(getSymbols("::ans1::ans2"), ElementsAre(QName("ans1::ans2")));
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
EXPECT_THAT(getSymbols("::ans1::ans2::"),
|
2018-06-27 00:57:44 +08:00
|
|
|
ElementsAre(QName("ans1::ans2::ai2")));
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WorkspaceSymbolsTest, AnonymousNamespace) {
|
|
|
|
addFile("foo.h", R"cpp(
|
|
|
|
namespace {
|
|
|
|
void test() {}
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
addFile("foo.cpp", R"cpp(
|
|
|
|
#include "foo.h"
|
|
|
|
)cpp");
|
2019-01-14 18:01:17 +08:00
|
|
|
EXPECT_THAT(getSymbols("test"), ElementsAre(QName("test")));
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WorkspaceSymbolsTest, MultiFile) {
|
|
|
|
addFile("foo.h", R"cpp(
|
|
|
|
int foo() {
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
addFile("foo2.h", R"cpp(
|
|
|
|
int foo2() {
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
addFile("foo.cpp", R"cpp(
|
|
|
|
#include "foo.h"
|
|
|
|
#include "foo2.h"
|
|
|
|
)cpp");
|
|
|
|
EXPECT_THAT(getSymbols("foo"),
|
2018-06-27 00:57:44 +08:00
|
|
|
UnorderedElementsAre(QName("foo"), QName("foo2")));
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WorkspaceSymbolsTest, GlobalNamespaceQueries) {
|
|
|
|
addFile("foo.h", R"cpp(
|
|
|
|
int foo() {
|
|
|
|
}
|
|
|
|
class Foo {
|
|
|
|
int a;
|
|
|
|
};
|
|
|
|
namespace ns {
|
|
|
|
int foo2() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
addFile("foo.cpp", R"cpp(
|
|
|
|
#include "foo.h"
|
|
|
|
)cpp");
|
2018-06-27 00:57:44 +08:00
|
|
|
EXPECT_THAT(getSymbols("::"),
|
|
|
|
UnorderedElementsAre(
|
|
|
|
AllOf(QName("Foo"), WithKind(SymbolKind::Class)),
|
|
|
|
AllOf(QName("foo"), WithKind(SymbolKind::Function)),
|
|
|
|
AllOf(QName("ns"), WithKind(SymbolKind::Namespace))));
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
EXPECT_THAT(getSymbols(":"), IsEmpty());
|
|
|
|
EXPECT_THAT(getSymbols(""), IsEmpty());
|
|
|
|
}
|
|
|
|
|
[clangd] Add "member" symbols to the index
Summary:
This adds more symbols to the index:
- member variables and functions
- enum constants in scoped enums
The code completion behavior should remain intact but workspace symbols should
now provide much more useful symbols.
Other symbols should be considered such as the ones in "main files" (files not
being included) but this can be done separately as this introduces its fair
share of problems.
Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Reviewers: ioeric, sammccall
Reviewed By: ioeric, sammccall
Subscribers: hokein, sammccall, jkorous, klimek, ilya-biryukov, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44954
llvm-svn: 334017
2018-06-05 22:01:40 +08:00
|
|
|
TEST_F(WorkspaceSymbolsTest, Enums) {
|
|
|
|
addFile("foo.h", R"cpp(
|
|
|
|
enum {
|
|
|
|
Red
|
|
|
|
};
|
|
|
|
enum Color {
|
|
|
|
Green
|
|
|
|
};
|
|
|
|
enum class Color2 {
|
|
|
|
Yellow
|
|
|
|
};
|
|
|
|
namespace ns {
|
|
|
|
enum {
|
|
|
|
Black
|
|
|
|
};
|
|
|
|
enum Color3 {
|
|
|
|
Blue
|
|
|
|
};
|
|
|
|
enum class Color4 {
|
|
|
|
White
|
|
|
|
};
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
addFile("foo.cpp", R"cpp(
|
|
|
|
#include "foo.h"
|
|
|
|
)cpp");
|
2018-06-27 00:57:44 +08:00
|
|
|
EXPECT_THAT(getSymbols("Red"), ElementsAre(QName("Red")));
|
|
|
|
EXPECT_THAT(getSymbols("::Red"), ElementsAre(QName("Red")));
|
|
|
|
EXPECT_THAT(getSymbols("Green"), ElementsAre(QName("Green")));
|
|
|
|
EXPECT_THAT(getSymbols("Green"), ElementsAre(QName("Green")));
|
|
|
|
EXPECT_THAT(getSymbols("Color2::Yellow"),
|
|
|
|
ElementsAre(QName("Color2::Yellow")));
|
|
|
|
EXPECT_THAT(getSymbols("Yellow"), ElementsAre(QName("Color2::Yellow")));
|
[clangd] Add "member" symbols to the index
Summary:
This adds more symbols to the index:
- member variables and functions
- enum constants in scoped enums
The code completion behavior should remain intact but workspace symbols should
now provide much more useful symbols.
Other symbols should be considered such as the ones in "main files" (files not
being included) but this can be done separately as this introduces its fair
share of problems.
Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Reviewers: ioeric, sammccall
Reviewed By: ioeric, sammccall
Subscribers: hokein, sammccall, jkorous, klimek, ilya-biryukov, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44954
llvm-svn: 334017
2018-06-05 22:01:40 +08:00
|
|
|
|
2018-06-27 00:57:44 +08:00
|
|
|
EXPECT_THAT(getSymbols("ns::Black"), ElementsAre(QName("ns::Black")));
|
|
|
|
EXPECT_THAT(getSymbols("ns::Blue"), ElementsAre(QName("ns::Blue")));
|
|
|
|
EXPECT_THAT(getSymbols("ns::Color4::White"),
|
|
|
|
ElementsAre(QName("ns::Color4::White")));
|
[clangd] Add "member" symbols to the index
Summary:
This adds more symbols to the index:
- member variables and functions
- enum constants in scoped enums
The code completion behavior should remain intact but workspace symbols should
now provide much more useful symbols.
Other symbols should be considered such as the ones in "main files" (files not
being included) but this can be done separately as this introduces its fair
share of problems.
Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Reviewers: ioeric, sammccall
Reviewed By: ioeric, sammccall
Subscribers: hokein, sammccall, jkorous, klimek, ilya-biryukov, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44954
llvm-svn: 334017
2018-06-05 22:01:40 +08:00
|
|
|
}
|
|
|
|
|
2018-06-07 14:55:59 +08:00
|
|
|
TEST_F(WorkspaceSymbolsTest, Ranking) {
|
|
|
|
addFile("foo.h", R"cpp(
|
|
|
|
namespace ns{}
|
2018-12-19 22:51:07 +08:00
|
|
|
void func();
|
2018-06-07 14:55:59 +08:00
|
|
|
)cpp");
|
|
|
|
addFile("foo.cpp", R"cpp(
|
|
|
|
#include "foo.h"
|
|
|
|
)cpp");
|
2018-06-27 00:57:44 +08:00
|
|
|
EXPECT_THAT(getSymbols("::"), ElementsAre(QName("func"), QName("ns")));
|
2018-06-07 14:55:59 +08:00
|
|
|
}
|
|
|
|
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
TEST_F(WorkspaceSymbolsTest, WithLimit) {
|
|
|
|
addFile("foo.h", R"cpp(
|
|
|
|
int foo;
|
|
|
|
int foo2;
|
|
|
|
)cpp");
|
|
|
|
addFile("foo.cpp", R"cpp(
|
|
|
|
#include "foo.h"
|
|
|
|
)cpp");
|
2018-06-07 14:55:59 +08:00
|
|
|
// Foo is higher ranked because of exact name match.
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
EXPECT_THAT(getSymbols("foo"),
|
2018-06-27 00:57:44 +08:00
|
|
|
UnorderedElementsAre(
|
|
|
|
AllOf(QName("foo"), WithKind(SymbolKind::Variable)),
|
|
|
|
AllOf(QName("foo2"), WithKind(SymbolKind::Variable))));
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
|
|
|
|
Limit = 1;
|
2018-06-27 00:57:44 +08:00
|
|
|
EXPECT_THAT(getSymbols("foo"), ElementsAre(QName("foo")));
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
}
|
|
|
|
|
2019-04-12 18:09:37 +08:00
|
|
|
TEST_F(WorkspaceSymbolsTest, TempSpecs) {
|
|
|
|
addFile("foo.h", R"cpp(
|
|
|
|
template <typename T, typename U, int X = 5> class Foo {};
|
|
|
|
template <typename T> class Foo<int, T> {};
|
|
|
|
template <> class Foo<bool, int> {};
|
|
|
|
template <> class Foo<bool, int, 3> {};
|
|
|
|
)cpp");
|
|
|
|
// Foo is higher ranked because of exact name match.
|
|
|
|
EXPECT_THAT(
|
|
|
|
getSymbols("Foo"),
|
|
|
|
UnorderedElementsAre(
|
|
|
|
AllOf(QName("Foo"), WithKind(SymbolKind::Class)),
|
|
|
|
AllOf(QName("Foo<int, T>"), WithKind(SymbolKind::Class)),
|
|
|
|
AllOf(QName("Foo<bool, int>"), WithKind(SymbolKind::Class)),
|
|
|
|
AllOf(QName("Foo<bool, int, 3>"), WithKind(SymbolKind::Class))));
|
|
|
|
}
|
|
|
|
|
2018-07-06 03:35:01 +08:00
|
|
|
namespace {
|
|
|
|
class DocumentSymbolsTest : public ::testing::Test {
|
|
|
|
public:
|
|
|
|
DocumentSymbolsTest()
|
|
|
|
: Server(CDB, FSProvider, DiagConsumer, optsForTests()) {}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
MockFSProvider FSProvider;
|
|
|
|
MockCompilationDatabase CDB;
|
|
|
|
IgnoreDiagnostics DiagConsumer;
|
|
|
|
ClangdServer Server;
|
|
|
|
|
2018-11-23 23:21:19 +08:00
|
|
|
std::vector<DocumentSymbol> getSymbols(PathRef File) {
|
2018-07-06 03:35:01 +08:00
|
|
|
EXPECT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for preamble";
|
|
|
|
auto SymbolInfos = runDocumentSymbols(Server, File);
|
|
|
|
EXPECT_TRUE(bool(SymbolInfos)) << "documentSymbols returned an error";
|
|
|
|
return *SymbolInfos;
|
|
|
|
}
|
|
|
|
|
2019-01-07 23:45:19 +08:00
|
|
|
void addFile(llvm::StringRef FilePath, llvm::StringRef Contents) {
|
2018-07-06 03:35:01 +08:00
|
|
|
FSProvider.Files[FilePath] = Contents;
|
|
|
|
Server.addDocument(FilePath, Contents);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
TEST_F(DocumentSymbolsTest, BasicSymbols) {
|
|
|
|
std::string FilePath = testPath("foo.cpp");
|
|
|
|
Annotations Main(R"(
|
|
|
|
class Foo;
|
|
|
|
class Foo {
|
|
|
|
Foo() {}
|
|
|
|
Foo(int a) {}
|
|
|
|
void $decl[[f]]();
|
|
|
|
friend void f1();
|
|
|
|
friend class Friend;
|
|
|
|
Foo& operator=(const Foo&);
|
|
|
|
~Foo();
|
|
|
|
class Nested {
|
|
|
|
void f();
|
|
|
|
};
|
|
|
|
};
|
|
|
|
class Friend {
|
|
|
|
};
|
|
|
|
|
|
|
|
void f1();
|
|
|
|
inline void f2() {}
|
|
|
|
static const int KInt = 2;
|
|
|
|
const char* kStr = "123";
|
|
|
|
|
|
|
|
void f1() {}
|
|
|
|
|
|
|
|
namespace foo {
|
|
|
|
// Type alias
|
|
|
|
typedef int int32;
|
|
|
|
using int32_t = int32;
|
|
|
|
|
|
|
|
// Variable
|
|
|
|
int v1;
|
|
|
|
|
|
|
|
// Namespace
|
|
|
|
namespace bar {
|
|
|
|
int v2;
|
|
|
|
}
|
|
|
|
// Namespace alias
|
|
|
|
namespace baz = bar;
|
|
|
|
|
|
|
|
using bar::v2;
|
|
|
|
} // namespace foo
|
|
|
|
)");
|
|
|
|
|
|
|
|
addFile(FilePath, Main.code());
|
2018-11-23 23:21:19 +08:00
|
|
|
EXPECT_THAT(
|
|
|
|
getSymbols(FilePath),
|
|
|
|
ElementsAreArray(
|
|
|
|
{AllOf(WithName("Foo"), WithKind(SymbolKind::Class), Children()),
|
|
|
|
AllOf(WithName("Foo"), WithKind(SymbolKind::Class),
|
|
|
|
Children(AllOf(WithName("Foo"), WithKind(SymbolKind::Method),
|
|
|
|
Children()),
|
|
|
|
AllOf(WithName("Foo"), WithKind(SymbolKind::Method),
|
|
|
|
Children()),
|
|
|
|
AllOf(WithName("f"), WithKind(SymbolKind::Method),
|
|
|
|
Children()),
|
|
|
|
AllOf(WithName("operator="),
|
|
|
|
WithKind(SymbolKind::Method), Children()),
|
|
|
|
AllOf(WithName("~Foo"), WithKind(SymbolKind::Method),
|
|
|
|
Children()),
|
|
|
|
AllOf(WithName("Nested"), WithKind(SymbolKind::Class),
|
|
|
|
Children(AllOf(WithName("f"),
|
|
|
|
WithKind(SymbolKind::Method),
|
|
|
|
Children()))))),
|
|
|
|
AllOf(WithName("Friend"), WithKind(SymbolKind::Class), Children()),
|
|
|
|
AllOf(WithName("f1"), WithKind(SymbolKind::Function), Children()),
|
|
|
|
AllOf(WithName("f2"), WithKind(SymbolKind::Function), Children()),
|
|
|
|
AllOf(WithName("KInt"), WithKind(SymbolKind::Variable), Children()),
|
|
|
|
AllOf(WithName("kStr"), WithKind(SymbolKind::Variable), Children()),
|
|
|
|
AllOf(WithName("f1"), WithKind(SymbolKind::Function), Children()),
|
2019-08-14 20:51:04 +08:00
|
|
|
AllOf(
|
|
|
|
WithName("foo"), WithKind(SymbolKind::Namespace),
|
|
|
|
Children(
|
|
|
|
AllOf(WithName("int32"), WithKind(SymbolKind::Class),
|
|
|
|
Children()),
|
|
|
|
AllOf(WithName("int32_t"), WithKind(SymbolKind::Class),
|
|
|
|
Children()),
|
|
|
|
AllOf(WithName("v1"), WithKind(SymbolKind::Variable),
|
|
|
|
Children()),
|
|
|
|
AllOf(WithName("bar"), WithKind(SymbolKind::Namespace),
|
|
|
|
Children(AllOf(WithName("v2"),
|
|
|
|
WithKind(SymbolKind::Variable),
|
|
|
|
Children()))),
|
|
|
|
AllOf(WithName("baz"), WithKind(SymbolKind::Namespace),
|
|
|
|
Children()),
|
|
|
|
AllOf(WithName("v2"), WithKind(SymbolKind::Namespace))))}));
|
2018-07-06 03:35:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DocumentSymbolsTest, DeclarationDefinition) {
|
|
|
|
std::string FilePath = testPath("foo.cpp");
|
|
|
|
Annotations Main(R"(
|
|
|
|
class Foo {
|
|
|
|
void $decl[[f]]();
|
|
|
|
};
|
|
|
|
void Foo::$def[[f]]() {
|
|
|
|
}
|
|
|
|
)");
|
|
|
|
|
|
|
|
addFile(FilePath, Main.code());
|
2019-08-14 20:51:04 +08:00
|
|
|
EXPECT_THAT(
|
|
|
|
getSymbols(FilePath),
|
|
|
|
ElementsAre(
|
|
|
|
AllOf(WithName("Foo"), WithKind(SymbolKind::Class),
|
|
|
|
Children(AllOf(WithName("f"), WithKind(SymbolKind::Method),
|
|
|
|
SymNameRange(Main.range("decl"))))),
|
|
|
|
AllOf(WithName("Foo::f"), WithKind(SymbolKind::Method),
|
|
|
|
SymNameRange(Main.range("def")))));
|
2018-07-06 03:35:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DocumentSymbolsTest, ExternSymbol) {
|
|
|
|
std::string FilePath = testPath("foo.cpp");
|
|
|
|
addFile(testPath("foo.h"), R"cpp(
|
2018-12-21 17:32:49 +08:00
|
|
|
extern int var;
|
2018-07-06 03:35:01 +08:00
|
|
|
)cpp");
|
|
|
|
addFile(FilePath, R"cpp(
|
|
|
|
#include "foo.h"
|
|
|
|
)cpp");
|
|
|
|
|
|
|
|
EXPECT_THAT(getSymbols(FilePath), IsEmpty());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DocumentSymbolsTest, NoLocals) {
|
|
|
|
std::string FilePath = testPath("foo.cpp");
|
|
|
|
addFile(FilePath,
|
|
|
|
R"cpp(
|
|
|
|
void test(int FirstParam, int SecondParam) {
|
|
|
|
struct LocalClass {};
|
|
|
|
int local_var;
|
|
|
|
})cpp");
|
2018-11-23 23:21:19 +08:00
|
|
|
EXPECT_THAT(getSymbols(FilePath), ElementsAre(WithName("test")));
|
2018-07-06 03:35:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DocumentSymbolsTest, Unnamed) {
|
|
|
|
std::string FilePath = testPath("foo.h");
|
|
|
|
addFile(FilePath,
|
|
|
|
R"cpp(
|
|
|
|
struct {
|
|
|
|
int InUnnamed;
|
|
|
|
} UnnamedStruct;
|
|
|
|
)cpp");
|
|
|
|
EXPECT_THAT(
|
|
|
|
getSymbols(FilePath),
|
2018-11-23 23:21:19 +08:00
|
|
|
ElementsAre(
|
|
|
|
AllOf(WithName("(anonymous struct)"), WithKind(SymbolKind::Struct),
|
|
|
|
Children(AllOf(WithName("InUnnamed"),
|
|
|
|
WithKind(SymbolKind::Field), Children()))),
|
|
|
|
AllOf(WithName("UnnamedStruct"), WithKind(SymbolKind::Variable),
|
|
|
|
Children())));
|
2018-07-06 03:35:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DocumentSymbolsTest, InHeaderFile) {
|
2018-11-26 19:18:16 +08:00
|
|
|
addFile(testPath("bar.h"), R"cpp(
|
2018-07-06 03:35:01 +08:00
|
|
|
int foo() {
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
std::string FilePath = testPath("foo.h");
|
|
|
|
addFile(FilePath, R"cpp(
|
|
|
|
#include "bar.h"
|
|
|
|
int test() {
|
|
|
|
}
|
|
|
|
)cpp");
|
2018-11-26 19:18:16 +08:00
|
|
|
addFile(testPath("foo.cpp"), R"cpp(
|
2018-07-06 03:35:01 +08:00
|
|
|
#include "foo.h"
|
|
|
|
)cpp");
|
2018-11-23 23:21:19 +08:00
|
|
|
EXPECT_THAT(getSymbols(FilePath), ElementsAre(WithName("test")));
|
2018-07-06 03:35:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DocumentSymbolsTest, Template) {
|
|
|
|
std::string FilePath = testPath("foo.cpp");
|
|
|
|
addFile(FilePath, R"(
|
|
|
|
template <class T> struct Tmpl {T x = 0;};
|
2018-11-23 23:21:19 +08:00
|
|
|
template <> struct Tmpl<int> {
|
|
|
|
int y = 0;
|
|
|
|
};
|
2018-07-06 03:35:01 +08:00
|
|
|
extern template struct Tmpl<float>;
|
|
|
|
template struct Tmpl<double>;
|
2018-11-23 23:21:19 +08:00
|
|
|
|
|
|
|
template <class T, class U, class Z = float>
|
|
|
|
int funcTmpl(U a);
|
|
|
|
template <>
|
|
|
|
int funcTmpl<int>(double a);
|
|
|
|
|
|
|
|
template <class T, class U = double>
|
|
|
|
int varTmpl = T();
|
|
|
|
template <>
|
|
|
|
double varTmpl<int> = 10.0;
|
2018-07-06 03:35:01 +08:00
|
|
|
)");
|
2018-11-23 23:21:19 +08:00
|
|
|
EXPECT_THAT(
|
|
|
|
getSymbols(FilePath),
|
|
|
|
ElementsAre(
|
|
|
|
AllOf(WithName("Tmpl"), WithKind(SymbolKind::Struct),
|
|
|
|
Children(AllOf(WithName("x"), WithKind(SymbolKind::Field)))),
|
|
|
|
AllOf(WithName("Tmpl<int>"), WithKind(SymbolKind::Struct),
|
|
|
|
Children(WithName("y"))),
|
|
|
|
AllOf(WithName("Tmpl<float>"), WithKind(SymbolKind::Struct),
|
|
|
|
Children()),
|
|
|
|
AllOf(WithName("Tmpl<double>"), WithKind(SymbolKind::Struct),
|
|
|
|
Children()),
|
|
|
|
AllOf(WithName("funcTmpl"), Children()),
|
2019-04-12 18:09:14 +08:00
|
|
|
AllOf(WithName("funcTmpl<int>"), Children()),
|
2018-11-23 23:21:19 +08:00
|
|
|
AllOf(WithName("varTmpl"), Children()),
|
2019-04-12 18:09:14 +08:00
|
|
|
AllOf(WithName("varTmpl<int>"), Children())));
|
2018-07-06 03:35:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DocumentSymbolsTest, Namespaces) {
|
|
|
|
std::string FilePath = testPath("foo.cpp");
|
|
|
|
addFile(FilePath, R"cpp(
|
|
|
|
namespace ans1 {
|
|
|
|
int ai1;
|
|
|
|
namespace ans2 {
|
|
|
|
int ai2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
namespace {
|
|
|
|
void test() {}
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace na {
|
|
|
|
inline namespace nb {
|
|
|
|
class Foo {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
namespace na {
|
|
|
|
// This is still inlined.
|
|
|
|
namespace nb {
|
|
|
|
class Bar {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
EXPECT_THAT(
|
|
|
|
getSymbols(FilePath),
|
2019-05-06 18:08:47 +08:00
|
|
|
ElementsAreArray<::testing::Matcher<DocumentSymbol>>(
|
2018-11-23 23:21:19 +08:00
|
|
|
{AllOf(WithName("ans1"),
|
|
|
|
Children(AllOf(WithName("ai1"), Children()),
|
|
|
|
AllOf(WithName("ans2"), Children(WithName("ai2"))))),
|
|
|
|
AllOf(WithName("(anonymous namespace)"), Children(WithName("test"))),
|
|
|
|
AllOf(WithName("na"),
|
|
|
|
Children(AllOf(WithName("nb"), Children(WithName("Foo"))))),
|
|
|
|
AllOf(WithName("na"),
|
|
|
|
Children(AllOf(WithName("nb"), Children(WithName("Bar")))))}));
|
2018-07-06 03:35:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DocumentSymbolsTest, Enums) {
|
|
|
|
std::string FilePath = testPath("foo.cpp");
|
|
|
|
addFile(FilePath, R"(
|
|
|
|
enum {
|
|
|
|
Red
|
|
|
|
};
|
|
|
|
enum Color {
|
|
|
|
Green
|
|
|
|
};
|
|
|
|
enum class Color2 {
|
|
|
|
Yellow
|
|
|
|
};
|
|
|
|
namespace ns {
|
|
|
|
enum {
|
|
|
|
Black
|
|
|
|
};
|
|
|
|
}
|
|
|
|
)");
|
2018-11-23 23:21:19 +08:00
|
|
|
EXPECT_THAT(
|
|
|
|
getSymbols(FilePath),
|
|
|
|
ElementsAre(
|
|
|
|
AllOf(WithName("(anonymous enum)"), Children(WithName("Red"))),
|
|
|
|
AllOf(WithName("Color"), Children(WithName("Green"))),
|
|
|
|
AllOf(WithName("Color2"), Children(WithName("Yellow"))),
|
|
|
|
AllOf(WithName("ns"), Children(AllOf(WithName("(anonymous enum)"),
|
|
|
|
Children(WithName("Black")))))));
|
2018-07-06 03:35:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DocumentSymbolsTest, FromMacro) {
|
|
|
|
std::string FilePath = testPath("foo.cpp");
|
|
|
|
Annotations Main(R"(
|
|
|
|
#define FF(name) \
|
|
|
|
class name##_Test {};
|
|
|
|
|
|
|
|
$expansion[[FF]](abc);
|
|
|
|
|
|
|
|
#define FF2() \
|
|
|
|
class $spelling[[Test]] {};
|
|
|
|
|
|
|
|
FF2();
|
|
|
|
)");
|
|
|
|
addFile(FilePath, Main.code());
|
|
|
|
EXPECT_THAT(
|
|
|
|
getSymbols(FilePath),
|
2018-11-23 23:21:19 +08:00
|
|
|
ElementsAre(
|
|
|
|
AllOf(WithName("abc_Test"), SymNameRange(Main.range("expansion"))),
|
|
|
|
AllOf(WithName("Test"), SymNameRange(Main.range("spelling")))));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DocumentSymbolsTest, FuncTemplates) {
|
|
|
|
std::string FilePath = testPath("foo.cpp");
|
|
|
|
Annotations Source(R"cpp(
|
|
|
|
template <class T>
|
|
|
|
T foo() {}
|
|
|
|
|
|
|
|
auto x = foo<int>();
|
|
|
|
auto y = foo<double>()
|
|
|
|
)cpp");
|
|
|
|
addFile(FilePath, Source.code());
|
|
|
|
// Make sure we only see the template declaration, not instantiations.
|
|
|
|
EXPECT_THAT(getSymbols(FilePath),
|
|
|
|
ElementsAre(WithName("foo"), WithName("x"), WithName("y")));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DocumentSymbolsTest, UsingDirectives) {
|
|
|
|
std::string FilePath = testPath("foo.cpp");
|
|
|
|
Annotations Source(R"cpp(
|
|
|
|
namespace ns {
|
|
|
|
int foo;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace ns_alias = ns;
|
|
|
|
|
|
|
|
using namespace ::ns; // check we don't loose qualifiers.
|
|
|
|
using namespace ns_alias; // and namespace aliases.
|
|
|
|
)cpp");
|
|
|
|
addFile(FilePath, Source.code());
|
|
|
|
EXPECT_THAT(getSymbols(FilePath),
|
|
|
|
ElementsAre(WithName("ns"), WithName("ns_alias"),
|
|
|
|
WithName("using namespace ::ns"),
|
|
|
|
WithName("using namespace ns_alias")));
|
2018-07-06 03:35:01 +08:00
|
|
|
}
|
|
|
|
|
2019-04-12 18:09:37 +08:00
|
|
|
TEST_F(DocumentSymbolsTest, TempSpecs) {
|
|
|
|
addFile("foo.cpp", R"cpp(
|
|
|
|
template <typename T, typename U, int X = 5> class Foo {};
|
|
|
|
template <typename T> class Foo<int, T> {};
|
|
|
|
template <> class Foo<bool, int> {};
|
|
|
|
template <> class Foo<bool, int, 3> {};
|
|
|
|
)cpp");
|
|
|
|
// Foo is higher ranked because of exact name match.
|
|
|
|
EXPECT_THAT(
|
|
|
|
getSymbols("foo.cpp"),
|
|
|
|
UnorderedElementsAre(
|
|
|
|
AllOf(WithName("Foo"), WithKind(SymbolKind::Class)),
|
|
|
|
AllOf(WithName("Foo<int, T>"), WithKind(SymbolKind::Class)),
|
|
|
|
AllOf(WithName("Foo<bool, int>"), WithKind(SymbolKind::Class)),
|
|
|
|
AllOf(WithName("Foo<bool, int, 3>"), WithKind(SymbolKind::Class))));
|
|
|
|
}
|
|
|
|
|
2019-08-14 20:51:04 +08:00
|
|
|
TEST_F(DocumentSymbolsTest, Qualifiers) {
|
|
|
|
addFile("foo.cpp", R"cpp(
|
|
|
|
namespace foo { namespace bar {
|
|
|
|
struct Cls;
|
|
|
|
|
|
|
|
int func1();
|
|
|
|
int func2();
|
|
|
|
int func3();
|
|
|
|
int func4();
|
|
|
|
}}
|
|
|
|
|
|
|
|
struct foo::bar::Cls { };
|
|
|
|
|
|
|
|
int foo::bar::func1() { return 10; }
|
|
|
|
int ::foo::bar::func2() { return 20; }
|
|
|
|
|
|
|
|
using namespace foo;
|
|
|
|
int bar::func3() { return 30; }
|
|
|
|
|
|
|
|
namespace alias = foo::bar;
|
|
|
|
int ::alias::func4() { return 40; }
|
|
|
|
)cpp");
|
|
|
|
|
|
|
|
// All the qualifiers should be preserved exactly as written.
|
|
|
|
EXPECT_THAT(getSymbols("foo.cpp"),
|
|
|
|
UnorderedElementsAre(
|
|
|
|
WithName("foo"), WithName("foo::bar::Cls"),
|
|
|
|
WithName("foo::bar::func1"), WithName("::foo::bar::func2"),
|
|
|
|
WithName("using namespace foo"), WithName("bar::func3"),
|
|
|
|
WithName("alias"), WithName("::alias::func4")));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DocumentSymbolsTest, QualifiersWithTemplateArgs) {
|
|
|
|
addFile("foo.cpp", R"cpp(
|
|
|
|
template <typename T, typename U = double> class Foo;
|
|
|
|
|
|
|
|
template <>
|
|
|
|
class Foo<int, double> {
|
|
|
|
int method1();
|
|
|
|
int method2();
|
|
|
|
int method3();
|
|
|
|
};
|
|
|
|
|
|
|
|
using int_type = int;
|
|
|
|
|
|
|
|
// Typedefs should be preserved!
|
|
|
|
int Foo<int_type, double>::method1() { return 10; }
|
|
|
|
|
|
|
|
// Default arguments should not be shown!
|
|
|
|
int Foo<int>::method2() { return 20; }
|
|
|
|
|
|
|
|
using Foo_type = Foo<int>;
|
|
|
|
// If the whole type is aliased, this should be preserved too!
|
|
|
|
int Foo_type::method3() { return 30; }
|
|
|
|
)cpp");
|
|
|
|
EXPECT_THAT(
|
|
|
|
getSymbols("foo.cpp"),
|
|
|
|
UnorderedElementsAre(WithName("Foo"), WithName("Foo<int, double>"),
|
|
|
|
WithName("int_type"),
|
|
|
|
WithName("Foo<int_type, double>::method1"),
|
|
|
|
WithName("Foo<int>::method2"), WithName("Foo_type"),
|
|
|
|
WithName("Foo_type::method3")));
|
|
|
|
}
|
|
|
|
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
} // namespace clangd
|
|
|
|
} // namespace clang
|