mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 07:35:08 +00:00
Backport and cleanup
This commit is contained in:
parent
4797401d55
commit
a385bffcbd
@ -252,7 +252,6 @@ target_sources(ccls PRIVATE
|
|||||||
src/messages/ccls_base.cc
|
src/messages/ccls_base.cc
|
||||||
src/messages/ccls_call_hierarchy.cc
|
src/messages/ccls_call_hierarchy.cc
|
||||||
src/messages/ccls_callers.cc
|
src/messages/ccls_callers.cc
|
||||||
src/messages/ccls_derived.cc
|
|
||||||
src/messages/ccls_file_info.cc
|
src/messages/ccls_file_info.cc
|
||||||
src/messages/ccls_freshen_index.cc
|
src/messages/ccls_freshen_index.cc
|
||||||
src/messages/ccls_inheritance_hierarchy.cc
|
src/messages/ccls_inheritance_hierarchy.cc
|
||||||
@ -272,6 +271,7 @@ target_sources(ccls PRIVATE
|
|||||||
src/messages/text_document_document_highlight.cc
|
src/messages/text_document_document_highlight.cc
|
||||||
src/messages/text_document_document_symbol.cc
|
src/messages/text_document_document_symbol.cc
|
||||||
src/messages/text_document_hover.cc
|
src/messages/text_document_hover.cc
|
||||||
|
src/messages/text_document_implementation.cc
|
||||||
src/messages/text_document_references.cc
|
src/messages/text_document_references.cc
|
||||||
src/messages/text_document_rename.cc
|
src/messages/text_document_rename.cc
|
||||||
src/messages/text_document_signature_help.cc
|
src/messages/text_document_signature_help.cc
|
||||||
|
@ -275,7 +275,7 @@ void BuildDetailString(CXCompletionString completion_string,
|
|||||||
int num_chunks = clang_getNumCompletionChunks(completion_string);
|
int num_chunks = clang_getNumCompletionChunks(completion_string);
|
||||||
auto append = [&](const char* text) {
|
auto append = [&](const char* text) {
|
||||||
detail += text;
|
detail += text;
|
||||||
if (do_insert)
|
if (do_insert && include_snippets)
|
||||||
insert += text;
|
insert += text;
|
||||||
};
|
};
|
||||||
for (int i = 0; i < num_chunks; ++i) {
|
for (int i = 0; i < num_chunks; ++i) {
|
||||||
@ -587,6 +587,8 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) {
|
|||||||
// Fetching the completion request blocks until we have a request.
|
// Fetching the completion request blocks until we have a request.
|
||||||
ClangCompleteManager::DiagnosticRequest request =
|
ClangCompleteManager::DiagnosticRequest request =
|
||||||
completion_manager->diagnostic_request_.Dequeue();
|
completion_manager->diagnostic_request_.Dequeue();
|
||||||
|
if (!g_config->diagnostics.onType)
|
||||||
|
continue;
|
||||||
std::string path = request.document.uri.GetPath();
|
std::string path = request.document.uri.GetPath();
|
||||||
|
|
||||||
std::shared_ptr<CompletionSession> session =
|
std::shared_ptr<CompletionSession> session =
|
||||||
|
@ -131,6 +131,18 @@ Usr ClangCursor::get_usr_hash() const {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<Usr> ClangCursor::get_opt_usr_hash() const {
|
||||||
|
CXString usr = clang_getCursorUSR(cx_cursor);
|
||||||
|
const char* str = clang_getCString(usr);
|
||||||
|
if (!str || str[0] == '\0') {
|
||||||
|
clang_disposeString(usr);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
Usr ret = HashUsr(str);
|
||||||
|
clang_disposeString(usr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool ClangCursor::is_definition() const {
|
bool ClangCursor::is_definition() const {
|
||||||
return clang_isCursorDefinition(cx_cursor);
|
return clang_isCursorDefinition(cx_cursor);
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,7 @@ class ClangCursor {
|
|||||||
std::string get_display_name() const;
|
std::string get_display_name() const;
|
||||||
std::string get_usr() const;
|
std::string get_usr() const;
|
||||||
Usr get_usr_hash() const;
|
Usr get_usr_hash() const;
|
||||||
|
std::optional<Usr> get_opt_usr_hash() const;
|
||||||
|
|
||||||
bool is_definition() const;
|
bool is_definition() const;
|
||||||
|
|
||||||
@ -108,15 +109,6 @@ class ClangCursor {
|
|||||||
CXCursor cx_cursor;
|
CXCursor cx_cursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace std {
|
|
||||||
template <>
|
|
||||||
struct hash<ClangCursor> {
|
|
||||||
size_t operator()(const ClangCursor& x) const {
|
|
||||||
return clang_hashCursor(x.cx_cursor);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
// Simple RAII wrapper about CXIndex.
|
// Simple RAII wrapper about CXIndex.
|
||||||
// Note: building a ClangIndex instance acquires a global lock, since libclang
|
// Note: building a ClangIndex instance acquires a global lock, since libclang
|
||||||
// API does not appear to be thread-safe here.
|
// API does not appear to be thread-safe here.
|
||||||
|
@ -557,15 +557,10 @@ IndexType* ResolveToDeclarationType(IndexFile* db,
|
|||||||
|
|
||||||
ClangCursor declaration =
|
ClangCursor declaration =
|
||||||
type.get_declaration().template_specialization_to_template_definition();
|
type.get_declaration().template_specialization_to_template_definition();
|
||||||
CXString cx_usr = clang_getCursorUSR(declaration.cx_cursor);
|
std::optional<Usr> usr = declaration.get_opt_usr_hash();
|
||||||
const char* str_usr = clang_getCString(cx_usr);
|
if (!usr)
|
||||||
if (!str_usr || str_usr[0] == '\0') {
|
|
||||||
clang_disposeString(cx_usr);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
IndexType& typ = db->ToType(*usr);
|
||||||
Usr usr = HashUsr(str_usr);
|
|
||||||
clang_disposeString(cx_usr);
|
|
||||||
IndexType& typ = db->ToType(usr);
|
|
||||||
if (typ.def.detailed_name.empty()) {
|
if (typ.def.detailed_name.empty()) {
|
||||||
std::string name = declaration.get_spell_name();
|
std::string name = declaration.get_spell_name();
|
||||||
SetTypeName(typ, declaration, nullptr, name.c_str(), param);
|
SetTypeName(typ, declaration, nullptr, name.c_str(), param);
|
||||||
@ -602,11 +597,12 @@ void SetVarDetail(IndexVar& var,
|
|||||||
param->ns.QualifiedName(semanticContainer, short_name);
|
param->ns.QualifiedName(semanticContainer, short_name);
|
||||||
|
|
||||||
if (cursor.get_kind() == CXCursor_EnumConstantDecl && semanticContainer) {
|
if (cursor.get_kind() == CXCursor_EnumConstantDecl && semanticContainer) {
|
||||||
CXType enum_type = clang_getCanonicalType(
|
CXTypeKind k = clang_getCanonicalType(
|
||||||
clang_getEnumDeclIntegerType(semanticContainer->cursor));
|
clang_getEnumDeclIntegerType(semanticContainer->cursor))
|
||||||
|
.kind;
|
||||||
std::string hover = qualified_name + " = ";
|
std::string hover = qualified_name + " = ";
|
||||||
if (enum_type.kind == CXType_UInt || enum_type.kind == CXType_ULong ||
|
if (k == CXType_Char_U || k == CXType_UChar || k == CXType_UShort ||
|
||||||
enum_type.kind == CXType_ULongLong)
|
k == CXType_UInt || k == CXType_ULong || k == CXType_ULongLong)
|
||||||
hover += std::to_string(
|
hover += std::to_string(
|
||||||
clang_getEnumConstantDeclUnsignedValue(cursor.cx_cursor));
|
clang_getEnumConstantDeclUnsignedValue(cursor.cx_cursor));
|
||||||
else
|
else
|
||||||
@ -896,15 +892,15 @@ void VisitDeclForTypeUsageVisitorHandler(ClangCursor cursor,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string referenced_usr =
|
std::optional<Usr> referenced_usr =
|
||||||
cursor.get_referenced()
|
cursor.get_referenced()
|
||||||
.template_specialization_to_template_definition()
|
.template_specialization_to_template_definition()
|
||||||
.get_usr();
|
.get_opt_usr_hash();
|
||||||
// TODO: things in STL cause this to be empty. Figure out why and document it.
|
// In STL this may be empty.
|
||||||
if (referenced_usr == "")
|
if (!referenced_usr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IndexType& ref_type = db->ToType(HashUsr(referenced_usr));
|
IndexType& ref_type = db->ToType(*referenced_usr);
|
||||||
|
|
||||||
if (!param->initial_type)
|
if (!param->initial_type)
|
||||||
param->initial_type = &ref_type;
|
param->initial_type = &ref_type;
|
||||||
@ -1129,12 +1125,10 @@ ClangCursor::VisitResult AddDeclInitializerUsagesVisitor(ClangCursor cursor,
|
|||||||
// cursor.get_referenced().template_specialization_to_template_definition().get_type().strip_qualifiers().get_usr_hash();
|
// cursor.get_referenced().template_specialization_to_template_definition().get_type().strip_qualifiers().get_usr_hash();
|
||||||
auto ref_usr = cursor.get_referenced()
|
auto ref_usr = cursor.get_referenced()
|
||||||
.template_specialization_to_template_definition()
|
.template_specialization_to_template_definition()
|
||||||
.get_usr();
|
.get_opt_usr_hash();
|
||||||
// std::string ref_usr = ref.get_usr_hash();
|
if (!ref_usr)
|
||||||
if (ref_usr.empty())
|
|
||||||
break;
|
break;
|
||||||
|
IndexVar& ref_var = db->ToVar(*ref_usr);
|
||||||
IndexVar& ref_var = db->ToVar(HashUsr(ref_usr));
|
|
||||||
AddUseSpell(db, ref_var.uses, cursor);
|
AddUseSpell(db, ref_var.uses, cursor);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1347,8 +1341,8 @@ std::tuple<std::string, int16_t, int16_t> NamespaceHelper::QualifiedName(
|
|||||||
std::string qualifier;
|
std::string qualifier;
|
||||||
while (cursor.get_kind() != CXCursor_TranslationUnit &&
|
while (cursor.get_kind() != CXCursor_TranslationUnit &&
|
||||||
GetSymbolKind(cursor.get_kind()) == SymbolKind::Type) {
|
GetSymbolKind(cursor.get_kind()) == SymbolKind::Type) {
|
||||||
auto it = container_cursor_to_qualified_name.find(cursor);
|
auto it = usr2qualified_name.find(cursor.get_usr_hash());
|
||||||
if (it != container_cursor_to_qualified_name.end()) {
|
if (it != usr2qualified_name.end()) {
|
||||||
qualifier = it->second;
|
qualifier = it->second;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1365,7 +1359,7 @@ std::tuple<std::string, int16_t, int16_t> NamespaceHelper::QualifiedName(
|
|||||||
else
|
else
|
||||||
qualifier += GetAnonName(namespaces[i].get_kind());
|
qualifier += GetAnonName(namespaces[i].get_kind());
|
||||||
qualifier += "::";
|
qualifier += "::";
|
||||||
container_cursor_to_qualified_name[namespaces[i]] = qualifier;
|
usr2qualified_name[namespaces[i].get_usr_hash()] = qualifier;
|
||||||
}
|
}
|
||||||
int16_t pos = qualifier.size();
|
int16_t pos = qualifier.size();
|
||||||
qualifier.append(unqualified_name);
|
qualifier.append(unqualified_name);
|
||||||
@ -2013,13 +2007,12 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<IndexFile>> Parse(
|
std::vector<std::unique_ptr<IndexFile>> ClangIndexer::Index(
|
||||||
VFS* vfs,
|
VFS* vfs,
|
||||||
std::string file,
|
std::string file,
|
||||||
const std::vector<std::string>& args,
|
const std::vector<std::string>& args,
|
||||||
const std::vector<FileContents>& file_contents,
|
const std::vector<FileContents>& file_contents,
|
||||||
PerformanceImportFile* perf,
|
PerformanceImportFile* perf) {
|
||||||
ClangIndex* index) {
|
|
||||||
if (!g_config->index.enabled)
|
if (!g_config->index.enabled)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
@ -2037,7 +2030,7 @@ std::vector<std::unique_ptr<IndexFile>> Parse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ClangTranslationUnit> tu = ClangTranslationUnit::Create(
|
std::unique_ptr<ClangTranslationUnit> tu = ClangTranslationUnit::Create(
|
||||||
index, file, args, unsaved_files,
|
&index, file, args, unsaved_files,
|
||||||
CXTranslationUnit_KeepGoing |
|
CXTranslationUnit_KeepGoing |
|
||||||
CXTranslationUnit_DetailedPreprocessingRecord);
|
CXTranslationUnit_DetailedPreprocessingRecord);
|
||||||
if (!tu)
|
if (!tu)
|
||||||
@ -2045,7 +2038,7 @@ std::vector<std::unique_ptr<IndexFile>> Parse(
|
|||||||
|
|
||||||
perf->index_parse = timer.ElapsedMicrosecondsAndReset();
|
perf->index_parse = timer.ElapsedMicrosecondsAndReset();
|
||||||
|
|
||||||
return ParseWithTu(vfs, perf, tu.get(), index, file, args, unsaved_files);
|
return ParseWithTu(vfs, perf, tu.get(), &index, file, args, unsaved_files);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<IndexFile>> ParseWithTu(
|
std::vector<std::unique_ptr<IndexFile>> ParseWithTu(
|
||||||
@ -2206,58 +2199,3 @@ void Reflect(Writer& visitor, Reference& value) {
|
|||||||
Reflect(visitor, value.role);
|
Reflect(visitor, value.role);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
struct TestIndexer : IIndexer {
|
|
||||||
static std::unique_ptr<TestIndexer> FromEntries(
|
|
||||||
const std::vector<TestEntry>& entries) {
|
|
||||||
auto result = std::make_unique<TestIndexer>();
|
|
||||||
|
|
||||||
for (const TestEntry& entry : entries) {
|
|
||||||
std::vector<std::unique_ptr<IndexFile>> indexes;
|
|
||||||
|
|
||||||
if (entry.num_indexes > 0)
|
|
||||||
indexes.push_back(std::make_unique<IndexFile>(entry.path, "<empty>"));
|
|
||||||
for (int i = 1; i < entry.num_indexes; ++i) {
|
|
||||||
indexes.push_back(std::make_unique<IndexFile>(
|
|
||||||
entry.path + "_extra_" + std::to_string(i) + ".h", "<empty>"));
|
|
||||||
}
|
|
||||||
|
|
||||||
result->indexes.insert(std::make_pair(entry.path, std::move(indexes)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<IndexFile>> Index(
|
|
||||||
VFS* vfs,
|
|
||||||
std::string file,
|
|
||||||
const std::vector<std::string>& args,
|
|
||||||
const std::vector<FileContents>& file_contents,
|
|
||||||
PerformanceImportFile* perf) override {
|
|
||||||
auto it = indexes.find(file);
|
|
||||||
if (it == indexes.end()) {
|
|
||||||
// Don't return any indexes for unexpected data.
|
|
||||||
assert(false && "no indexes");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: allow user to control how many times we return the index for a
|
|
||||||
// specific file (atm it is always 1)
|
|
||||||
auto result = std::move(it->second);
|
|
||||||
indexes.erase(it);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unordered_map<std::string, std::vector<std::unique_ptr<IndexFile>>>
|
|
||||||
indexes;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// static
|
|
||||||
std::unique_ptr<IIndexer> IIndexer::MakeTestIndexer(
|
|
||||||
std::initializer_list<TestEntry> entries) {
|
|
||||||
return TestIndexer::FromEntries(entries);
|
|
||||||
}
|
|
||||||
|
@ -137,6 +137,9 @@ struct Config {
|
|||||||
// If true, diagnostics from a full document parse will be reported.
|
// If true, diagnostics from a full document parse will be reported.
|
||||||
bool onParse = true;
|
bool onParse = true;
|
||||||
|
|
||||||
|
// If true, diagnostics from typing will be reported.
|
||||||
|
bool onType = true;
|
||||||
|
|
||||||
std::vector<std::string> whitelist;
|
std::vector<std::string> whitelist;
|
||||||
} diagnostics;
|
} diagnostics;
|
||||||
|
|
||||||
@ -211,6 +214,7 @@ MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport);
|
|||||||
MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables);
|
MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables);
|
||||||
MAKE_REFLECT_STRUCT(Config::Completion,
|
MAKE_REFLECT_STRUCT(Config::Completion,
|
||||||
caseSensitivity,
|
caseSensitivity,
|
||||||
|
dropOldRequests,
|
||||||
detailedLabel,
|
detailedLabel,
|
||||||
filterAndSort,
|
filterAndSort,
|
||||||
includeBlacklist,
|
includeBlacklist,
|
||||||
@ -221,6 +225,7 @@ MAKE_REFLECT_STRUCT(Config::Diagnostics,
|
|||||||
blacklist,
|
blacklist,
|
||||||
frequencyMs,
|
frequencyMs,
|
||||||
onParse,
|
onParse,
|
||||||
|
onType,
|
||||||
whitelist)
|
whitelist)
|
||||||
MAKE_REFLECT_STRUCT(Config::Highlight, blacklist, whitelist)
|
MAKE_REFLECT_STRUCT(Config::Highlight, blacklist, whitelist)
|
||||||
MAKE_REFLECT_STRUCT(Config::Index,
|
MAKE_REFLECT_STRUCT(Config::Index,
|
||||||
|
@ -63,7 +63,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine,
|
|||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
Project* project,
|
Project* project,
|
||||||
VFS* vfs,
|
VFS* vfs,
|
||||||
IIndexer* indexer) {
|
ClangIndexer* indexer) {
|
||||||
auto* queue = QueueManager::instance();
|
auto* queue = QueueManager::instance();
|
||||||
std::optional<Index_Request> opt_request = queue->index_request.TryPopFront();
|
std::optional<Index_Request> opt_request = queue->index_request.TryPopFront();
|
||||||
if (!opt_request)
|
if (!opt_request)
|
||||||
@ -211,10 +211,10 @@ void Indexer_Main(DiagnosticsEngine* diag_engine,
|
|||||||
MultiQueueWaiter* waiter) {
|
MultiQueueWaiter* waiter) {
|
||||||
auto* queue = QueueManager::instance();
|
auto* queue = QueueManager::instance();
|
||||||
// Build one index per-indexer, as building the index acquires a global lock.
|
// Build one index per-indexer, as building the index acquires a global lock.
|
||||||
auto indexer = std::make_unique<ClangIndexer>();
|
ClangIndexer indexer;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
if (!Indexer_Parse(diag_engine, working_files, project, vfs, indexer.get()))
|
if (!Indexer_Parse(diag_engine, working_files, project, vfs, &indexer))
|
||||||
waiter->Wait(&queue->index_request);
|
waiter->Wait(&queue->index_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,25 +321,13 @@ struct IndexFile {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct NamespaceHelper {
|
struct NamespaceHelper {
|
||||||
std::unordered_map<ClangCursor, std::string>
|
std::unordered_map<Usr, std::string> usr2qualified_name;
|
||||||
container_cursor_to_qualified_name;
|
|
||||||
|
|
||||||
std::tuple<std::string, int16_t, int16_t> QualifiedName(
|
std::tuple<std::string, int16_t, int16_t> QualifiedName(
|
||||||
const CXIdxContainerInfo* container,
|
const CXIdxContainerInfo* container,
|
||||||
std::string_view unqualified_name);
|
std::string_view unqualified_name);
|
||||||
};
|
};
|
||||||
|
|
||||||
// |import_file| is the cc file which is what gets passed to clang.
|
|
||||||
// |desired_index_file| is the (h or cc) file which has actually changed.
|
|
||||||
// |dependencies| are the existing dependencies of |import_file| if this is a
|
|
||||||
// reparse.
|
|
||||||
std::vector<std::unique_ptr<IndexFile>> Parse(
|
|
||||||
VFS* vfs,
|
|
||||||
std::string file,
|
|
||||||
const std::vector<std::string>& args,
|
|
||||||
const std::vector<FileContents>& file_contents,
|
|
||||||
PerformanceImportFile* perf,
|
|
||||||
ClangIndex* index);
|
|
||||||
std::vector<std::unique_ptr<IndexFile>> ParseWithTu(
|
std::vector<std::unique_ptr<IndexFile>> ParseWithTu(
|
||||||
VFS* vfs,
|
VFS* vfs,
|
||||||
PerformanceImportFile* perf,
|
PerformanceImportFile* perf,
|
||||||
@ -353,36 +341,13 @@ bool ConcatTypeAndName(std::string& type, const std::string& name);
|
|||||||
|
|
||||||
void IndexInit();
|
void IndexInit();
|
||||||
|
|
||||||
// Abstracts away the actual indexing process. Each IIndexer instance is
|
struct ClangIndexer {
|
||||||
// per-thread and constructing an instance may be extremely expensive (ie,
|
|
||||||
// acquire a lock) and should be done as rarely as possible.
|
|
||||||
struct IIndexer {
|
|
||||||
struct TestEntry {
|
|
||||||
std::string path;
|
|
||||||
int num_indexes = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::unique_ptr<IIndexer> MakeTestIndexer(
|
|
||||||
std::initializer_list<TestEntry> entries);
|
|
||||||
|
|
||||||
virtual ~IIndexer() = default;
|
|
||||||
virtual std::vector<std::unique_ptr<IndexFile>> Index(
|
|
||||||
VFS* vfs,
|
|
||||||
std::string file,
|
|
||||||
const std::vector<std::string>& args,
|
|
||||||
const std::vector<FileContents>& file_contents,
|
|
||||||
PerformanceImportFile* perf) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ClangIndexer : IIndexer {
|
|
||||||
std::vector<std::unique_ptr<IndexFile>> Index(
|
std::vector<std::unique_ptr<IndexFile>> Index(
|
||||||
VFS* vfs,
|
VFS* vfs,
|
||||||
std::string file,
|
std::string file,
|
||||||
const std::vector<std::string>& args,
|
const std::vector<std::string>& args,
|
||||||
const std::vector<FileContents>& file_contents,
|
const std::vector<FileContents>& file_contents,
|
||||||
PerformanceImportFile* perf) override {
|
PerformanceImportFile* perf);
|
||||||
return Parse(vfs, file, args, file_contents, perf, &index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: constructing this acquires a global lock
|
// Note: constructing this acquires a global lock
|
||||||
ClangIndex index;
|
ClangIndex index;
|
||||||
|
@ -3,18 +3,19 @@
|
|||||||
#include "queue_manager.h"
|
#include "queue_manager.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
MethodType kMethodType = "$ccls/derived";
|
MethodType kMethodType = "textDocument/implementation";
|
||||||
|
|
||||||
struct In_CclsDerived : public RequestInMessage {
|
struct In_TextDocumentImplementation : public RequestInMessage {
|
||||||
MethodType GetMethodType() const override { return kMethodType; }
|
MethodType GetMethodType() const override { return kMethodType; }
|
||||||
lsTextDocumentPositionParams params;
|
lsTextDocumentPositionParams params;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(In_CclsDerived, id, params);
|
MAKE_REFLECT_STRUCT(In_TextDocumentImplementation, id, params);
|
||||||
REGISTER_IN_MESSAGE(In_CclsDerived);
|
REGISTER_IN_MESSAGE(In_TextDocumentImplementation);
|
||||||
|
|
||||||
struct Handler_CclsDerived : BaseMessageHandler<In_CclsDerived> {
|
struct Handler_TextDocumentImplementation
|
||||||
|
: BaseMessageHandler<In_TextDocumentImplementation> {
|
||||||
MethodType GetMethodType() const override { return kMethodType; }
|
MethodType GetMethodType() const override { return kMethodType; }
|
||||||
void Run(In_CclsDerived* request) override {
|
void Run(In_TextDocumentImplementation* request) override {
|
||||||
QueryFile* file;
|
QueryFile* file;
|
||||||
if (!FindFileOrFail(db, project, request->id,
|
if (!FindFileOrFail(db, project, request->id,
|
||||||
request->params.textDocument.uri.GetPath(), &file)) {
|
request->params.textDocument.uri.GetPath(), &file)) {
|
||||||
@ -43,5 +44,5 @@ struct Handler_CclsDerived : BaseMessageHandler<In_CclsDerived> {
|
|||||||
QueueManager::WriteStdout(kMethodType, out);
|
QueueManager::WriteStdout(kMethodType, out);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
REGISTER_MESSAGE_HANDLER(Handler_CclsDerived);
|
REGISTER_MESSAGE_HANDLER(Handler_TextDocumentImplementation);
|
||||||
} // namespace
|
} // namespace
|
@ -247,7 +247,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) {
|
|||||||
bool update_all = false;
|
bool update_all = false;
|
||||||
// FIXME: show diagnostics in STL/headers when running tests. At the moment
|
// FIXME: show diagnostics in STL/headers when running tests. At the moment
|
||||||
// this can be done by constructing ClangIndex index(1, 1);
|
// this can be done by constructing ClangIndex index(1, 1);
|
||||||
ClangIndex index;
|
ClangIndexer index;
|
||||||
GetFilesInFolder(
|
GetFilesInFolder(
|
||||||
"index_tests", true /*recursive*/, true /*add_folder_to_path*/,
|
"index_tests", true /*recursive*/, true /*add_folder_to_path*/,
|
||||||
[&](const std::string& path) {
|
[&](const std::string& path) {
|
||||||
@ -294,7 +294,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) {
|
|||||||
g_config = std::make_unique<Config>();
|
g_config = std::make_unique<Config>();
|
||||||
VFS vfs;
|
VFS vfs;
|
||||||
PerformanceImportFile perf;
|
PerformanceImportFile perf;
|
||||||
auto dbs = Parse(&vfs, path, flags, {}, &perf, &index);
|
auto dbs = index.Index(&vfs, path, flags, {}, &perf);
|
||||||
|
|
||||||
for (const auto& entry : all_expected_output) {
|
for (const auto& entry : all_expected_output) {
|
||||||
const std::string& expected_path = entry.first;
|
const std::string& expected_path = entry.first;
|
||||||
|
@ -49,11 +49,6 @@ std::string StringJoin(const TValues& values, const std::string& sep = ", ") {
|
|||||||
sep);
|
sep);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TCollection, typename TValue>
|
|
||||||
bool ContainsValue(const TCollection& collection, const TValue& value) {
|
|
||||||
return collection.find(value) != collection.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensures that |path| ends in a slash.
|
// Ensures that |path| ends in a slash.
|
||||||
void EnsureEndsInSlash(std::string& path);
|
void EnsureEndsInSlash(std::string& path);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user