mirror of
https://github.com/MaskRay/ccls.git
synced 2025-02-07 17:32:14 +00:00
Response on index error. (#319)
This commit is contained in:
parent
57e95590e8
commit
b8a3e089ce
@ -6,7 +6,7 @@ namespace {
|
|||||||
struct ClangIndexer : IIndexer {
|
struct ClangIndexer : IIndexer {
|
||||||
~ClangIndexer() override = default;
|
~ClangIndexer() override = default;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<IndexFile>> Index(
|
optional<std::vector<std::unique_ptr<IndexFile>>> Index(
|
||||||
Config* config,
|
Config* config,
|
||||||
FileConsumerSharedState* file_consumer_shared,
|
FileConsumerSharedState* file_consumer_shared,
|
||||||
std::string file,
|
std::string file,
|
||||||
@ -50,7 +50,7 @@ struct TestIndexer : IIndexer {
|
|||||||
|
|
||||||
~TestIndexer() override = default;
|
~TestIndexer() override = default;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<IndexFile>> Index(
|
optional<std::vector<std::unique_ptr<IndexFile>>> Index(
|
||||||
Config* config,
|
Config* config,
|
||||||
FileConsumerSharedState* file_consumer_shared,
|
FileConsumerSharedState* file_consumer_shared,
|
||||||
std::string file,
|
std::string file,
|
||||||
@ -61,7 +61,7 @@ struct TestIndexer : IIndexer {
|
|||||||
if (it == indexes.end()) {
|
if (it == indexes.end()) {
|
||||||
// Don't return any indexes for unexpected data.
|
// Don't return any indexes for unexpected data.
|
||||||
assert(false && "no indexes");
|
assert(false && "no indexes");
|
||||||
return {};
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: allow user to control how many times we return the index for a
|
// FIXME: allow user to control how many times we return the index for a
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional.h>
|
||||||
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -32,7 +34,7 @@ struct IIndexer {
|
|||||||
std::initializer_list<TestEntry> entries);
|
std::initializer_list<TestEntry> entries);
|
||||||
|
|
||||||
virtual ~IIndexer() = default;
|
virtual ~IIndexer() = default;
|
||||||
virtual std::vector<std::unique_ptr<IndexFile>> Index(
|
virtual optional<std::vector<std::unique_ptr<IndexFile>>> Index(
|
||||||
Config* config,
|
Config* config,
|
||||||
FileConsumerSharedState* file_consumer_shared,
|
FileConsumerSharedState* file_consumer_shared,
|
||||||
std::string file,
|
std::string file,
|
||||||
|
@ -321,9 +321,8 @@ void ParseFile(Config* config,
|
|||||||
ImportManager* import_manager,
|
ImportManager* import_manager,
|
||||||
ICacheManager* cache_manager,
|
ICacheManager* cache_manager,
|
||||||
IIndexer* indexer,
|
IIndexer* indexer,
|
||||||
bool is_interactive,
|
const Index_Request& request,
|
||||||
const Project::Entry& entry,
|
const Project::Entry& entry) {
|
||||||
const std::string& entry_contents) {
|
|
||||||
// If the file is inferred, we may not actually be able to parse that file
|
// If the file is inferred, we may not actually be able to parse that file
|
||||||
// directly (ie, a header file, which are not listed in the project). If this
|
// directly (ie, a header file, which are not listed in the project). If this
|
||||||
// file is inferred, then try to use the file which originally imported it.
|
// file is inferred, then try to use the file which originally imported it.
|
||||||
@ -337,33 +336,46 @@ void ParseFile(Config* config,
|
|||||||
// Try to load the file from cache.
|
// Try to load the file from cache.
|
||||||
if (TryLoadFromCache(file_consumer_shared, timestamp_manager,
|
if (TryLoadFromCache(file_consumer_shared, timestamp_manager,
|
||||||
modification_timestamp_fetcher, import_manager,
|
modification_timestamp_fetcher, import_manager,
|
||||||
cache_manager, is_interactive, entry,
|
cache_manager, request.is_interactive, entry,
|
||||||
path_to_index) == CacheLoadResult::DoNotParse) {
|
path_to_index) == CacheLoadResult::DoNotParse) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_S(INFO) << "Parsing " << path_to_index;
|
LOG_S(INFO) << "Parsing " << path_to_index;
|
||||||
std::vector<FileContents> file_contents =
|
std::vector<FileContents> file_contents = PreloadFileContents(
|
||||||
PreloadFileContents(cache_manager, entry, entry_contents, path_to_index);
|
cache_manager, entry, request.contents, path_to_index);
|
||||||
|
|
||||||
std::vector<Index_DoIdMap> result;
|
std::vector<Index_DoIdMap> result;
|
||||||
PerformanceImportFile perf;
|
PerformanceImportFile perf;
|
||||||
std::vector<std::unique_ptr<IndexFile>> indexes =
|
auto indexes = indexer->Index(config, file_consumer_shared, path_to_index,
|
||||||
indexer->Index(config, file_consumer_shared, path_to_index, entry.args,
|
entry.args, file_contents, &perf);
|
||||||
file_contents, &perf);
|
|
||||||
for (std::unique_ptr<IndexFile>& new_index : indexes) {
|
if (!indexes) {
|
||||||
|
if (config->enableIndexing &&
|
||||||
|
std::holds_alternative<int64_t>(request.id)) {
|
||||||
|
Out_Error out;
|
||||||
|
out.id = request.id;
|
||||||
|
out.error.code = lsErrorCodes::InternalError;
|
||||||
|
out.error.message = "Failed to index " + path_to_index;
|
||||||
|
QueueManager::WriteStdout(IpcId::Unknown, out);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::unique_ptr<IndexFile>& new_index : *indexes) {
|
||||||
Timer time;
|
Timer time;
|
||||||
|
|
||||||
// Only emit diagnostics for non-interactive sessions, which makes it easier
|
// Only emit diagnostics for non-interactive sessions, which makes it easier
|
||||||
// to identify indexing problems. For interactive sessions, diagnostics are
|
// to identify indexing problems. For interactive sessions, diagnostics are
|
||||||
// handled by code completion.
|
// handled by code completion.
|
||||||
if (!is_interactive)
|
if (!request.is_interactive)
|
||||||
EmitDiagnostics(working_files, new_index->path, new_index->diagnostics_);
|
EmitDiagnostics(working_files, new_index->path, new_index->diagnostics_);
|
||||||
|
|
||||||
// When main thread does IdMap request it will request the previous index if
|
// When main thread does IdMap request it will request the previous index if
|
||||||
// needed.
|
// needed.
|
||||||
LOG_S(INFO) << "Emitting index result for " << new_index->path;
|
LOG_S(INFO) << "Emitting index result for " << new_index->path;
|
||||||
result.push_back(Index_DoIdMap(std::move(new_index), perf, is_interactive,
|
result.push_back(Index_DoIdMap(std::move(new_index), perf,
|
||||||
|
request.is_interactive,
|
||||||
true /*write_to_disk*/));
|
true /*write_to_disk*/));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,7 +401,7 @@ bool IndexMain_DoParse(
|
|||||||
entry.args = request->args;
|
entry.args = request->args;
|
||||||
ParseFile(config, working_files, file_consumer_shared, timestamp_manager,
|
ParseFile(config, working_files, file_consumer_shared, timestamp_manager,
|
||||||
modification_timestamp_fetcher, import_manager, cache_manager,
|
modification_timestamp_fetcher, import_manager, cache_manager,
|
||||||
indexer, request->is_interactive, entry, request->contents);
|
indexer, request.value(), entry);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,11 +530,13 @@ void IndexWithTuFromCodeCompletion(
|
|||||||
|
|
||||||
PerformanceImportFile perf;
|
PerformanceImportFile perf;
|
||||||
ClangIndex index;
|
ClangIndex index;
|
||||||
std::vector<std::unique_ptr<IndexFile>> indexes = ParseWithTu(
|
auto indexes = ParseWithTu(
|
||||||
file_consumer_shared, &perf, tu, &index, path, args, file_contents);
|
file_consumer_shared, &perf, tu, &index, path, args, file_contents);
|
||||||
|
if (!indexes)
|
||||||
|
return;
|
||||||
|
|
||||||
std::vector<Index_DoIdMap> result;
|
std::vector<Index_DoIdMap> result;
|
||||||
for (std::unique_ptr<IndexFile>& new_index : indexes) {
|
for (std::unique_ptr<IndexFile>& new_index : *indexes) {
|
||||||
Timer time;
|
Timer time;
|
||||||
|
|
||||||
// When main thread does IdMap request it will request the previous index if
|
// When main thread does IdMap request it will request the previous index if
|
||||||
|
@ -1894,7 +1894,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<IndexFile>> Parse(
|
optional<std::vector<std::unique_ptr<IndexFile>>> Parse(
|
||||||
Config* config,
|
Config* config,
|
||||||
FileConsumerSharedState* file_consumer_shared,
|
FileConsumerSharedState* file_consumer_shared,
|
||||||
std::string file,
|
std::string file,
|
||||||
@ -1924,7 +1924,7 @@ std::vector<std::unique_ptr<IndexFile>> Parse(
|
|||||||
CXTranslationUnit_KeepGoing |
|
CXTranslationUnit_KeepGoing |
|
||||||
CXTranslationUnit_DetailedPreprocessingRecord);
|
CXTranslationUnit_DetailedPreprocessingRecord);
|
||||||
if (!tu)
|
if (!tu)
|
||||||
return {};
|
return nullopt;
|
||||||
|
|
||||||
perf->index_parse = timer.ElapsedMicrosecondsAndReset();
|
perf->index_parse = timer.ElapsedMicrosecondsAndReset();
|
||||||
|
|
||||||
@ -1935,7 +1935,7 @@ std::vector<std::unique_ptr<IndexFile>> Parse(
|
|||||||
unsaved_files);
|
unsaved_files);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<IndexFile>> ParseWithTu(
|
optional<std::vector<std::unique_ptr<IndexFile>>> ParseWithTu(
|
||||||
FileConsumerSharedState* file_consumer_shared,
|
FileConsumerSharedState* file_consumer_shared,
|
||||||
PerformanceImportFile* perf,
|
PerformanceImportFile* perf,
|
||||||
ClangTranslationUnit* tu,
|
ClangTranslationUnit* tu,
|
||||||
@ -1982,8 +1982,9 @@ std::vector<std::unique_ptr<IndexFile>> ParseWithTu(
|
|||||||
CXIndexOpt_IndexImplicitTemplateInstantiations,
|
CXIndexOpt_IndexImplicitTemplateInstantiations,
|
||||||
tu->cx_tu);
|
tu->cx_tu);
|
||||||
if (index_result != CXError_Success) {
|
if (index_result != CXError_Success) {
|
||||||
LOG_S(WARNING) << "Indexing " << file
|
LOG_S(ERROR) << "Indexing " << file
|
||||||
<< " failed with errno=" << index_result;
|
<< " failed with errno=" << index_result;
|
||||||
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
clang_IndexAction_dispose(index_action);
|
clang_IndexAction_dispose(index_action);
|
||||||
|
@ -539,7 +539,7 @@ struct NamespaceHelper {
|
|||||||
// |desired_index_file| is the (h or cc) file which has actually changed.
|
// |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
|
// |dependencies| are the existing dependencies of |import_file| if this is a
|
||||||
// reparse.
|
// reparse.
|
||||||
std::vector<std::unique_ptr<IndexFile>> Parse(
|
optional<std::vector<std::unique_ptr<IndexFile>>> Parse(
|
||||||
Config* config,
|
Config* config,
|
||||||
FileConsumerSharedState* file_consumer_shared,
|
FileConsumerSharedState* file_consumer_shared,
|
||||||
std::string file,
|
std::string file,
|
||||||
@ -548,7 +548,7 @@ std::vector<std::unique_ptr<IndexFile>> Parse(
|
|||||||
PerformanceImportFile* perf,
|
PerformanceImportFile* perf,
|
||||||
ClangIndex* index,
|
ClangIndex* index,
|
||||||
bool dump_ast = false);
|
bool dump_ast = false);
|
||||||
std::vector<std::unique_ptr<IndexFile>> ParseWithTu(
|
optional<std::vector<std::unique_ptr<IndexFile>>> ParseWithTu(
|
||||||
FileConsumerSharedState* file_consumer_shared,
|
FileConsumerSharedState* file_consumer_shared,
|
||||||
PerformanceImportFile* perf,
|
PerformanceImportFile* perf,
|
||||||
ClangTranslationUnit* tu,
|
ClangTranslationUnit* tu,
|
||||||
|
@ -221,8 +221,9 @@ struct InitializeHandler : BaseMessageHandler<Ipc_InitializeRequest> {
|
|||||||
}
|
}
|
||||||
bool is_interactive =
|
bool is_interactive =
|
||||||
working_files->GetFileByFilename(entry.filename) != nullptr;
|
working_files->GetFileByFilename(entry.filename) != nullptr;
|
||||||
queue->index_request.Enqueue(Index_Request(
|
queue->index_request.Enqueue(
|
||||||
entry.filename, entry.args, is_interactive, *content));
|
Index_Request(entry.filename, entry.args, is_interactive,
|
||||||
|
*content, request->id));
|
||||||
});
|
});
|
||||||
|
|
||||||
// We need to support multiple concurrent index processes.
|
// We need to support multiple concurrent index processes.
|
||||||
|
@ -8,11 +8,13 @@
|
|||||||
Index_Request::Index_Request(const std::string& path,
|
Index_Request::Index_Request(const std::string& path,
|
||||||
const std::vector<std::string>& args,
|
const std::vector<std::string>& args,
|
||||||
bool is_interactive,
|
bool is_interactive,
|
||||||
const std::string& contents)
|
const std::string& contents,
|
||||||
|
lsRequestId id)
|
||||||
: path(path),
|
: path(path),
|
||||||
args(args),
|
args(args),
|
||||||
is_interactive(is_interactive),
|
is_interactive(is_interactive),
|
||||||
contents(contents) {}
|
contents(contents),
|
||||||
|
id(id) {}
|
||||||
|
|
||||||
Index_DoIdMap::Index_DoIdMap(std::unique_ptr<IndexFile> current,
|
Index_DoIdMap::Index_DoIdMap(std::unique_ptr<IndexFile> current,
|
||||||
PerformanceImportFile perf,
|
PerformanceImportFile perf,
|
||||||
|
@ -20,11 +20,13 @@ struct Index_Request {
|
|||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
bool is_interactive;
|
bool is_interactive;
|
||||||
std::string contents; // Preloaded contents. Useful for tests.
|
std::string contents; // Preloaded contents. Useful for tests.
|
||||||
|
lsRequestId id;
|
||||||
|
|
||||||
Index_Request(const std::string& path,
|
Index_Request(const std::string& path,
|
||||||
const std::vector<std::string>& args,
|
const std::vector<std::string>& args,
|
||||||
bool is_interactive,
|
bool is_interactive,
|
||||||
const std::string& contents);
|
const std::string& contents,
|
||||||
|
lsRequestId id={});
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Index_DoIdMap {
|
struct Index_DoIdMap {
|
||||||
|
@ -170,9 +170,9 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) {
|
|||||||
Config config;
|
Config config;
|
||||||
FileConsumerSharedState file_consumer_shared;
|
FileConsumerSharedState file_consumer_shared;
|
||||||
PerformanceImportFile perf;
|
PerformanceImportFile perf;
|
||||||
std::vector<std::unique_ptr<IndexFile>> dbs =
|
auto dbs = Parse(&config, &file_consumer_shared, path, flags, {}, &perf,
|
||||||
Parse(&config, &file_consumer_shared, path, flags, {}, &perf, &index,
|
&index, false /*dump_ast*/);
|
||||||
false /*dump_ast*/);
|
assert(dbs);
|
||||||
|
|
||||||
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;
|
||||||
@ -203,7 +203,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Get output from index operation.
|
// Get output from index operation.
|
||||||
IndexFile* db = FindDbForPathEnding(expected_path, dbs);
|
IndexFile* db = FindDbForPathEnding(expected_path, *dbs);
|
||||||
assert(db);
|
assert(db);
|
||||||
if (!db->diagnostics_.empty()) {
|
if (!db->diagnostics_.empty()) {
|
||||||
std::cout << "For " << path << std::endl;
|
std::cout << "For " << path << std::endl;
|
||||||
|
Loading…
Reference in New Issue
Block a user