mirror of
https://github.com/MaskRay/ccls.git
synced 2025-02-16 13:48:04 +00:00
Make sure file exists before importing it.
This commit is contained in:
parent
49aca3038b
commit
7901653698
@ -818,6 +818,12 @@ struct IndexManager {
|
||||
|
||||
//} // namespace
|
||||
|
||||
enum class FileParseState {
|
||||
NeedsParse,
|
||||
DoesNotNeedParse,
|
||||
BadFile
|
||||
};
|
||||
|
||||
std::vector<Index_DoIdMap> DoParseFile(
|
||||
Config* config,
|
||||
clang::Index* index,
|
||||
@ -832,22 +838,31 @@ std::vector<Index_DoIdMap> DoParseFile(
|
||||
if (previous_index) {
|
||||
// If none of the dependencies have changed, skip parsing and just load from cache.
|
||||
auto file_needs_parse = [&](const std::string& path) {
|
||||
int64_t modification_timestamp = GetLastModificationTime(path);
|
||||
optional<int64_t> modification_timestamp = GetLastModificationTime(path);
|
||||
if (!modification_timestamp)
|
||||
return FileParseState::BadFile;
|
||||
|
||||
optional<int64_t> last_cached_modification = timestamp_manager->GetLastCachedModificationTime(cache_loader, path);
|
||||
|
||||
if (!last_cached_modification || modification_timestamp != *last_cached_modification) {
|
||||
file_consumer_shared->Reset(path);
|
||||
return true;
|
||||
return FileParseState::NeedsParse;
|
||||
}
|
||||
return false;
|
||||
return FileParseState::DoesNotNeedParse;
|
||||
};
|
||||
|
||||
// Check timestamps and update |file_consumer_shared|.
|
||||
bool needs_reparse = file_needs_parse(path);
|
||||
bool needs_reparse = false;
|
||||
FileParseState path_state = file_needs_parse(path);
|
||||
if (path_state == FileParseState::BadFile)
|
||||
return result;
|
||||
if (path_state == FileParseState::NeedsParse)
|
||||
needs_reparse = true;
|
||||
|
||||
for (const std::string& dependency : previous_index->dependencies) {
|
||||
assert(!dependency.empty());
|
||||
|
||||
if (file_needs_parse(dependency)) {
|
||||
if (file_needs_parse(dependency) == FileParseState::NeedsParse) {
|
||||
LOG_S(INFO) << "Timestamp has changed for " << dependency;
|
||||
needs_reparse = true;
|
||||
// SUBTLE: Do not break here, as |file_consumer_shared| is updated
|
||||
@ -890,6 +905,7 @@ std::vector<Index_DoIdMap> DoParseFile(
|
||||
// TODO: We might be able to optimize perf by only copying for files in
|
||||
// working_files. We can pass that same set of files to the indexer as
|
||||
// well. We then default to a fast file-copy if not in working set.
|
||||
bool loaded_primary = false;
|
||||
std::vector<FileContents> file_contents;
|
||||
for (const auto& it : cache_loader->caches) {
|
||||
const std::unique_ptr<IndexFile>& index = it.second;
|
||||
@ -900,6 +916,16 @@ std::vector<Index_DoIdMap> DoParseFile(
|
||||
continue;
|
||||
}
|
||||
file_contents.push_back(FileContents(index->path, *index_content));
|
||||
|
||||
loaded_primary = loaded_primary || index->path == path;
|
||||
}
|
||||
if (!loaded_primary) {
|
||||
optional<std::string> content = ReadContent(path);
|
||||
if (!content) {
|
||||
LOG_S(ERROR) << "Skipping index (file cannot be found): " << path;
|
||||
return result;
|
||||
}
|
||||
file_contents.push_back(FileContents(path, *content));
|
||||
}
|
||||
|
||||
PerformanceImportFile perf;
|
||||
|
@ -128,7 +128,10 @@ IndexFile* ConsumeFile(IndexParam* param, CXFile file) {
|
||||
param->seen_files.push_back(file_name);
|
||||
|
||||
// Set modification time.
|
||||
param->file_modification_times[file_name] = GetLastModificationTime(file_name);
|
||||
optional<int64_t> modification_time = GetLastModificationTime(file_name);
|
||||
LOG_IF_S(ERROR, !modification_time) << "Failed fetching modification time for " << file_name;
|
||||
if (modification_time)
|
||||
param->file_modification_times[file_name] = *modification_time;
|
||||
|
||||
// Capture file contents in |param->file_contents| if it was not specified
|
||||
// at the start of indexing.
|
||||
|
@ -1,9 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using std::experimental::optional;
|
||||
using std::experimental::nullopt;
|
||||
|
||||
struct PlatformMutex {
|
||||
virtual ~PlatformMutex();
|
||||
};
|
||||
@ -37,7 +42,7 @@ bool TryMakeDirectory(const std::string& absolute_path);
|
||||
|
||||
void SetCurrentThreadName(const std::string& thread_name);
|
||||
|
||||
int64_t GetLastModificationTime(const std::string& absolute_path);
|
||||
optional<int64_t> GetLastModificationTime(const std::string& absolute_path);
|
||||
|
||||
void MoveFileTo(const std::string& destination, const std::string& source);
|
||||
void CopyFileTo(const std::string& destination, const std::string& source);
|
||||
|
@ -166,20 +166,20 @@ void SetCurrentThreadName(const std::string& thread_name) {
|
||||
#endif
|
||||
}
|
||||
|
||||
int64_t GetLastModificationTime(const std::string& absolute_path) {
|
||||
optional<int64_t> GetLastModificationTime(const std::string& absolute_path) {
|
||||
struct stat buf;
|
||||
if (stat(absolute_path.c_str(), &buf) != 0) {
|
||||
switch (errno) {
|
||||
case ENOENT:
|
||||
std::cerr << "GetLastModificationTime: unable to find file " << absolute_path << std::endl;
|
||||
break;
|
||||
//std::cerr << "GetLastModificationTime: unable to find file " << absolute_path << std::endl;
|
||||
return nullopt;
|
||||
case EINVAL:
|
||||
std::cerr << "GetLastModificationTime: invalid param to _stat for file file " << absolute_path << std::endl;
|
||||
break;
|
||||
//std::cerr << "GetLastModificationTime: invalid param to _stat for file file " << absolute_path << std::endl;
|
||||
return nullopt;
|
||||
default:
|
||||
std::cerr << "GetLastModificationTime: unhandled for " << absolute_path << std::endl;
|
||||
exit(1);
|
||||
break;
|
||||
//std::cerr << "GetLastModificationTime: unhandled for " << absolute_path << std::endl;
|
||||
//exit(1);
|
||||
return nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,20 +184,20 @@ void SetCurrentThreadName(const std::string& thread_name) {
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {}
|
||||
}
|
||||
|
||||
int64_t GetLastModificationTime(const std::string& absolute_path) {
|
||||
optional<int64_t> GetLastModificationTime(const std::string& absolute_path) {
|
||||
struct _stat buf;
|
||||
if (_stat(absolute_path.c_str(), &buf) != 0) {
|
||||
switch (errno) {
|
||||
case ENOENT:
|
||||
std::cerr << "GetLastModificationTime: unable to find file " << absolute_path << std::endl;
|
||||
break;
|
||||
//std::cerr << "GetLastModificationTime: unable to find file " << absolute_path << std::endl;
|
||||
return nullopt;
|
||||
case EINVAL:
|
||||
std::cerr << "GetLastModificationTime: invalid param to _stat for file file " << absolute_path << std::endl;
|
||||
break;
|
||||
//std::cerr << "GetLastModificationTime: invalid param to _stat for file file " << absolute_path << std::endl;
|
||||
return nullopt;
|
||||
default:
|
||||
std::cerr << "GetLastModificationTime: unhandled for " << absolute_path << std::endl;
|
||||
exit(1);
|
||||
break;
|
||||
//std::cerr << "GetLastModificationTime: unhandled for " << absolute_path << std::endl;
|
||||
//exit(1);
|
||||
return nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,7 +305,7 @@ QueryVarId GetQueryVarIdFromUsr(QueryDatabase* query_db, const Usr& usr) {
|
||||
|
||||
IdMap::IdMap(QueryDatabase* query_db, const IdCache& local_ids)
|
||||
: local_ids(local_ids) {
|
||||
LOG_S(INFO) << "Creating IdMap for " << local_ids.primary_file;
|
||||
//LOG_S(INFO) << "Creating IdMap for " << local_ids.primary_file;
|
||||
primary_file = GetQueryFileIdFromPath(query_db, local_ids.primary_file);
|
||||
|
||||
cached_type_ids_.resize(local_ids.type_id_to_usr.size());
|
||||
|
Loading…
Reference in New Issue
Block a user