mirror of
https://github.com/MaskRay/ccls.git
synced 2025-01-31 09:50:26 +00:00
Response on index error. (#319)
This commit is contained in:
parent
57e95590e8
commit
b8a3e089ce
@ -6,7 +6,7 @@ namespace {
|
||||
struct ClangIndexer : IIndexer {
|
||||
~ClangIndexer() override = default;
|
||||
|
||||
std::vector<std::unique_ptr<IndexFile>> Index(
|
||||
optional<std::vector<std::unique_ptr<IndexFile>>> Index(
|
||||
Config* config,
|
||||
FileConsumerSharedState* file_consumer_shared,
|
||||
std::string file,
|
||||
@ -50,7 +50,7 @@ struct TestIndexer : IIndexer {
|
||||
|
||||
~TestIndexer() override = default;
|
||||
|
||||
std::vector<std::unique_ptr<IndexFile>> Index(
|
||||
optional<std::vector<std::unique_ptr<IndexFile>>> Index(
|
||||
Config* config,
|
||||
FileConsumerSharedState* file_consumer_shared,
|
||||
std::string file,
|
||||
@ -61,7 +61,7 @@ struct TestIndexer : IIndexer {
|
||||
if (it == indexes.end()) {
|
||||
// Don't return any indexes for unexpected data.
|
||||
assert(false && "no indexes");
|
||||
return {};
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
// FIXME: allow user to control how many times we return the index for a
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional.h>
|
||||
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@ -32,7 +34,7 @@ struct IIndexer {
|
||||
std::initializer_list<TestEntry> entries);
|
||||
|
||||
virtual ~IIndexer() = default;
|
||||
virtual std::vector<std::unique_ptr<IndexFile>> Index(
|
||||
virtual optional<std::vector<std::unique_ptr<IndexFile>>> Index(
|
||||
Config* config,
|
||||
FileConsumerSharedState* file_consumer_shared,
|
||||
std::string file,
|
||||
|
@ -321,9 +321,8 @@ void ParseFile(Config* config,
|
||||
ImportManager* import_manager,
|
||||
ICacheManager* cache_manager,
|
||||
IIndexer* indexer,
|
||||
bool is_interactive,
|
||||
const Project::Entry& entry,
|
||||
const std::string& entry_contents) {
|
||||
const Index_Request& request,
|
||||
const Project::Entry& entry) {
|
||||
// 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
|
||||
// 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.
|
||||
if (TryLoadFromCache(file_consumer_shared, timestamp_manager,
|
||||
modification_timestamp_fetcher, import_manager,
|
||||
cache_manager, is_interactive, entry,
|
||||
cache_manager, request.is_interactive, entry,
|
||||
path_to_index) == CacheLoadResult::DoNotParse) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_S(INFO) << "Parsing " << path_to_index;
|
||||
std::vector<FileContents> file_contents =
|
||||
PreloadFileContents(cache_manager, entry, entry_contents, path_to_index);
|
||||
std::vector<FileContents> file_contents = PreloadFileContents(
|
||||
cache_manager, entry, request.contents, path_to_index);
|
||||
|
||||
std::vector<Index_DoIdMap> result;
|
||||
PerformanceImportFile perf;
|
||||
std::vector<std::unique_ptr<IndexFile>> indexes =
|
||||
indexer->Index(config, file_consumer_shared, path_to_index, entry.args,
|
||||
file_contents, &perf);
|
||||
for (std::unique_ptr<IndexFile>& new_index : indexes) {
|
||||
auto indexes = indexer->Index(config, file_consumer_shared, path_to_index,
|
||||
entry.args, file_contents, &perf);
|
||||
|
||||
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;
|
||||
|
||||
// Only emit diagnostics for non-interactive sessions, which makes it easier
|
||||
// to identify indexing problems. For interactive sessions, diagnostics are
|
||||
// handled by code completion.
|
||||
if (!is_interactive)
|
||||
if (!request.is_interactive)
|
||||
EmitDiagnostics(working_files, new_index->path, new_index->diagnostics_);
|
||||
|
||||
// When main thread does IdMap request it will request the previous index if
|
||||
// needed.
|
||||
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*/));
|
||||
}
|
||||
|
||||
@ -389,7 +401,7 @@ bool IndexMain_DoParse(
|
||||
entry.args = request->args;
|
||||
ParseFile(config, working_files, file_consumer_shared, timestamp_manager,
|
||||
modification_timestamp_fetcher, import_manager, cache_manager,
|
||||
indexer, request->is_interactive, entry, request->contents);
|
||||
indexer, request.value(), entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -518,11 +530,13 @@ void IndexWithTuFromCodeCompletion(
|
||||
|
||||
PerformanceImportFile perf;
|
||||
ClangIndex index;
|
||||
std::vector<std::unique_ptr<IndexFile>> indexes = ParseWithTu(
|
||||
auto indexes = ParseWithTu(
|
||||
file_consumer_shared, &perf, tu, &index, path, args, file_contents);
|
||||
if (!indexes)
|
||||
return;
|
||||
|
||||
std::vector<Index_DoIdMap> result;
|
||||
for (std::unique_ptr<IndexFile>& new_index : indexes) {
|
||||
for (std::unique_ptr<IndexFile>& new_index : *indexes) {
|
||||
Timer time;
|
||||
|
||||
// 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,
|
||||
FileConsumerSharedState* file_consumer_shared,
|
||||
std::string file,
|
||||
@ -1924,7 +1924,7 @@ std::vector<std::unique_ptr<IndexFile>> Parse(
|
||||
CXTranslationUnit_KeepGoing |
|
||||
CXTranslationUnit_DetailedPreprocessingRecord);
|
||||
if (!tu)
|
||||
return {};
|
||||
return nullopt;
|
||||
|
||||
perf->index_parse = timer.ElapsedMicrosecondsAndReset();
|
||||
|
||||
@ -1935,7 +1935,7 @@ std::vector<std::unique_ptr<IndexFile>> Parse(
|
||||
unsaved_files);
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<IndexFile>> ParseWithTu(
|
||||
optional<std::vector<std::unique_ptr<IndexFile>>> ParseWithTu(
|
||||
FileConsumerSharedState* file_consumer_shared,
|
||||
PerformanceImportFile* perf,
|
||||
ClangTranslationUnit* tu,
|
||||
@ -1982,8 +1982,9 @@ std::vector<std::unique_ptr<IndexFile>> ParseWithTu(
|
||||
CXIndexOpt_IndexImplicitTemplateInstantiations,
|
||||
tu->cx_tu);
|
||||
if (index_result != CXError_Success) {
|
||||
LOG_S(WARNING) << "Indexing " << file
|
||||
<< " failed with errno=" << index_result;
|
||||
LOG_S(ERROR) << "Indexing " << file
|
||||
<< " failed with errno=" << index_result;
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
clang_IndexAction_dispose(index_action);
|
||||
|
@ -539,7 +539,7 @@ struct NamespaceHelper {
|
||||
// |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(
|
||||
optional<std::vector<std::unique_ptr<IndexFile>>> Parse(
|
||||
Config* config,
|
||||
FileConsumerSharedState* file_consumer_shared,
|
||||
std::string file,
|
||||
@ -548,7 +548,7 @@ std::vector<std::unique_ptr<IndexFile>> Parse(
|
||||
PerformanceImportFile* perf,
|
||||
ClangIndex* index,
|
||||
bool dump_ast = false);
|
||||
std::vector<std::unique_ptr<IndexFile>> ParseWithTu(
|
||||
optional<std::vector<std::unique_ptr<IndexFile>>> ParseWithTu(
|
||||
FileConsumerSharedState* file_consumer_shared,
|
||||
PerformanceImportFile* perf,
|
||||
ClangTranslationUnit* tu,
|
||||
|
@ -221,8 +221,9 @@ struct InitializeHandler : BaseMessageHandler<Ipc_InitializeRequest> {
|
||||
}
|
||||
bool is_interactive =
|
||||
working_files->GetFileByFilename(entry.filename) != nullptr;
|
||||
queue->index_request.Enqueue(Index_Request(
|
||||
entry.filename, entry.args, is_interactive, *content));
|
||||
queue->index_request.Enqueue(
|
||||
Index_Request(entry.filename, entry.args, is_interactive,
|
||||
*content, request->id));
|
||||
});
|
||||
|
||||
// We need to support multiple concurrent index processes.
|
||||
|
@ -8,11 +8,13 @@
|
||||
Index_Request::Index_Request(const std::string& path,
|
||||
const std::vector<std::string>& args,
|
||||
bool is_interactive,
|
||||
const std::string& contents)
|
||||
const std::string& contents,
|
||||
lsRequestId id)
|
||||
: path(path),
|
||||
args(args),
|
||||
is_interactive(is_interactive),
|
||||
contents(contents) {}
|
||||
contents(contents),
|
||||
id(id) {}
|
||||
|
||||
Index_DoIdMap::Index_DoIdMap(std::unique_ptr<IndexFile> current,
|
||||
PerformanceImportFile perf,
|
||||
|
@ -20,11 +20,13 @@ struct Index_Request {
|
||||
std::vector<std::string> args;
|
||||
bool is_interactive;
|
||||
std::string contents; // Preloaded contents. Useful for tests.
|
||||
lsRequestId id;
|
||||
|
||||
Index_Request(const std::string& path,
|
||||
const std::vector<std::string>& args,
|
||||
bool is_interactive,
|
||||
const std::string& contents);
|
||||
const std::string& contents,
|
||||
lsRequestId id={});
|
||||
};
|
||||
|
||||
struct Index_DoIdMap {
|
||||
|
@ -170,9 +170,9 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) {
|
||||
Config config;
|
||||
FileConsumerSharedState file_consumer_shared;
|
||||
PerformanceImportFile perf;
|
||||
std::vector<std::unique_ptr<IndexFile>> dbs =
|
||||
Parse(&config, &file_consumer_shared, path, flags, {}, &perf, &index,
|
||||
false /*dump_ast*/);
|
||||
auto dbs = Parse(&config, &file_consumer_shared, path, flags, {}, &perf,
|
||||
&index, false /*dump_ast*/);
|
||||
assert(dbs);
|
||||
|
||||
for (const auto& entry : all_expected_output) {
|
||||
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.
|
||||
IndexFile* db = FindDbForPathEnding(expected_path, dbs);
|
||||
IndexFile* db = FindDbForPathEnding(expected_path, *dbs);
|
||||
assert(db);
|
||||
if (!db->diagnostics_.empty()) {
|
||||
std::cout << "For " << path << std::endl;
|
||||
|
Loading…
Reference in New Issue
Block a user