ccls/src/file_consumer.cc

106 lines
3.0 KiB
C++
Raw Normal View History

#include "file_consumer.h"
2017-05-21 03:46:15 +00:00
#include "clang_utils.h"
2017-04-08 22:54:36 +00:00
#include "indexer.h"
#include "platform.h"
2017-04-08 22:54:36 +00:00
#include "utils.h"
#include <loguru.hpp>
namespace {
optional<std::string> GetFileContents(const std::string& path,
FileContentsMap* file_contents) {
auto it = file_contents->find(path);
if (it == file_contents->end()) {
optional<std::string> content = ReadContent(path);
if (content)
(*file_contents)[path] = FileContents(path, *content);
return content;
}
return it->second.content;
}
} // namespace
bool operator==(const CXFileUniqueID& a, const CXFileUniqueID& b) {
2017-09-22 01:14:57 +00:00
return a.data[0] == b.data[0] && a.data[1] == b.data[1] &&
a.data[2] == b.data[2];
}
2017-12-29 16:29:47 +00:00
bool FileConsumerSharedState::Mark(const std::string& file) {
std::lock_guard<std::mutex> lock(mutex);
return used_files.insert(file).second;
}
2017-12-29 16:29:47 +00:00
void FileConsumerSharedState::Reset(const std::string& file) {
std::lock_guard<std::mutex> lock(mutex);
auto it = used_files.find(file);
if (it != used_files.end())
used_files.erase(it);
}
2017-12-29 16:29:47 +00:00
FileConsumer::FileConsumer(FileConsumerSharedState* shared_state,
2017-09-22 01:14:57 +00:00
const std::string& parse_file)
: shared_(shared_state), parse_file_(parse_file) {}
IndexFile* FileConsumer::TryConsumeFile(CXFile file,
bool* is_first_ownership,
FileContentsMap* file_contents_map) {
assert(is_first_ownership);
CXFileUniqueID file_id;
if (clang_getFileUniqueID(file, &file_id) != 0) {
EmitError(file);
return nullptr;
}
// Try to find cached local result.
auto it = local_.find(file_id);
if (it != local_.end()) {
*is_first_ownership = false;
2017-04-08 22:54:36 +00:00
return it->second.get();
}
std::string file_name = FileName(file);
// No result in local; we need to query global.
bool did_insert = shared_->Mark(file_name);
// We did not take the file from global. Cache that we failed so we don't try
// again and return nullptr.
if (!did_insert) {
local_[file_id] = nullptr;
return nullptr;
}
// Read the file contents, if we fail then we cannot index the file.
optional<std::string> contents = GetFileContents(file_name, file_contents_map);
if (!contents) {
*is_first_ownership = false;
return nullptr;
}
// Build IndexFile instance.
*is_first_ownership = true;
local_[file_id] = MakeUnique<IndexFile>(file_name, *contents);
return local_[file_id].get();
}
std::vector<std::unique_ptr<IndexFile>> FileConsumer::TakeLocalState() {
std::vector<std::unique_ptr<IndexFile>> result;
for (auto& entry : local_) {
if (entry.second)
result.push_back(std::move(entry.second));
}
return result;
}
void FileConsumer::EmitError(CXFile file) const {
std::string file_name = ToString(clang_getFileName(file));
// TODO: Investigate this more, why can we get an empty file name?
if (!file_name.empty()) {
LOG_S(ERROR) << "Could not get unique file id for " << file_name
<< " when parsing " << parse_file_;
}
}