Reuse preamble (built by "comp-preload") in indexer

This commit is contained in:
Fangrui Song 2018-09-08 12:07:43 -07:00
parent 58191fd335
commit da982a6506
19 changed files with 121 additions and 102 deletions

View File

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "clang_complete.h" #include "clang_complete.hh"
#include "clang_utils.h" #include "clang_utils.h"
#include "filesystem.hh" #include "filesystem.hh"
@ -525,7 +525,7 @@ bool Parse(CompilerInstance &Clang) {
return true; return true;
} }
void CompletionPreloadMain(ClangCompleteManager *completion_manager) { void CompletionPreloadMain(CompletionManager *completion_manager) {
while (true) { while (true) {
// Fetching the completion request blocks until we have a request. // Fetching the completion request blocks until we have a request.
auto request = completion_manager->preload_requests_.Dequeue(); auto request = completion_manager->preload_requests_.Dequeue();
@ -550,10 +550,10 @@ void CompletionPreloadMain(ClangCompleteManager *completion_manager) {
} }
} }
void CompletionMain(ClangCompleteManager *completion_manager) { void CompletionMain(CompletionManager *completion_manager) {
while (true) { while (true) {
// Fetching the completion request blocks until we have a request. // Fetching the completion request blocks until we have a request.
std::unique_ptr<ClangCompleteManager::CompletionRequest> request = std::unique_ptr<CompletionManager::CompletionRequest> request =
completion_manager->completion_request_.Dequeue(); completion_manager->completion_request_.Dequeue();
// Drop older requests if we're not buffering. // Drop older requests if we're not buffering.
@ -606,10 +606,10 @@ void CompletionMain(ClangCompleteManager *completion_manager) {
} }
} }
void DiagnosticMain(ClangCompleteManager *manager) { void DiagnosticMain(CompletionManager *manager) {
while (true) { while (true) {
// Fetching the completion request blocks until we have a request. // Fetching the completion request blocks until we have a request.
ClangCompleteManager::DiagnosticRequest request = CompletionManager::DiagnosticRequest request =
manager->diagnostic_request_.Dequeue(); manager->diagnostic_request_.Dequeue();
std::string path = request.document.uri.GetPath(); std::string path = request.document.uri.GetPath();
@ -699,7 +699,7 @@ void CompletionSession::BuildPreamble(CompilerInvocation &CI) {
} // namespace ccls } // namespace ccls
ClangCompleteManager::ClangCompleteManager(Project *project, CompletionManager::CompletionManager(Project *project,
WorkingFiles *working_files, WorkingFiles *working_files,
OnDiagnostic on_diagnostic, OnDiagnostic on_diagnostic,
OnDropped on_dropped) OnDropped on_dropped)
@ -725,7 +725,7 @@ ClangCompleteManager::ClangCompleteManager(Project *project,
.detach(); .detach();
} }
void ClangCompleteManager::CodeComplete( void CompletionManager::CodeComplete(
const lsRequestId &id, const lsRequestId &id,
const lsTextDocumentPositionParams &completion_location, const lsTextDocumentPositionParams &completion_location,
const OnComplete &on_complete) { const OnComplete &on_complete) {
@ -734,7 +734,7 @@ void ClangCompleteManager::CodeComplete(
on_complete)); on_complete));
} }
void ClangCompleteManager::DiagnosticsUpdate( void CompletionManager::DiagnosticsUpdate(
const lsTextDocumentIdentifier &document) { const lsTextDocumentIdentifier &document) {
bool has = false; bool has = false;
diagnostic_request_.Iterate([&](const DiagnosticRequest &request) { diagnostic_request_.Iterate([&](const DiagnosticRequest &request) {
@ -746,29 +746,13 @@ void ClangCompleteManager::DiagnosticsUpdate(
true /*priority*/); true /*priority*/);
} }
void ClangCompleteManager::NotifyView(const std::string &filename) { void CompletionManager::NotifyView(const std::string &path) {
//
// On view, we reparse only if the file has not been parsed. The existence of
// a CompletionSession instance implies the file is already parsed or will be
// parsed soon.
//
// Only reparse the file if we create a new CompletionSession. // Only reparse the file if we create a new CompletionSession.
if (EnsureCompletionOrCreatePreloadSession(filename)) if (EnsureCompletionOrCreatePreloadSession(path))
preload_requests_.PushBack(PreloadRequest(filename), true); preload_requests_.PushBack(PreloadRequest(path), true);
} }
void ClangCompleteManager::NotifyEdit(const std::string &filename) { void CompletionManager::NotifySave(const std::string &filename) {
//
// We treat an edit like a view, because the completion logic will handle
// moving the CompletionSession instance from preloaded to completion
// storage.
//
NotifyView(filename);
}
void ClangCompleteManager::NotifySave(const std::string &filename) {
// //
// On save, always reparse. // On save, always reparse.
// //
@ -777,7 +761,7 @@ void ClangCompleteManager::NotifySave(const std::string &filename) {
preload_requests_.PushBack(PreloadRequest(filename), true); preload_requests_.PushBack(PreloadRequest(filename), true);
} }
void ClangCompleteManager::NotifyClose(const std::string &filename) { void CompletionManager::NotifyClose(const std::string &filename) {
// //
// On close, we clear any existing CompletionSession instance. // On close, we clear any existing CompletionSession instance.
// //
@ -797,63 +781,63 @@ void ClangCompleteManager::NotifyClose(const std::string &filename) {
assert((preloaded_ptr && completion_ptr) == false); assert((preloaded_ptr && completion_ptr) == false);
} }
bool ClangCompleteManager::EnsureCompletionOrCreatePreloadSession( bool CompletionManager::EnsureCompletionOrCreatePreloadSession(
const std::string &filename) { const std::string &path) {
std::lock_guard<std::mutex> lock(sessions_lock_); std::lock_guard<std::mutex> lock(sessions_lock_);
// Check for an existing CompletionSession. // Check for an existing CompletionSession.
if (preloaded_sessions_.TryGet(filename) || if (preloaded_sessions_.TryGet(path) ||
completion_sessions_.TryGet(filename)) { completion_sessions_.TryGet(path)) {
return false; return false;
} }
// No CompletionSession, create new one. // No CompletionSession, create new one.
auto session = std::make_shared<ccls::CompletionSession>( auto session = std::make_shared<ccls::CompletionSession>(
project_->FindCompilationEntryForFile(filename), working_files_, PCH); project_->FindCompilationEntryForFile(path), working_files_, PCH);
preloaded_sessions_.Insert(session->file.filename, session); preloaded_sessions_.Insert(session->file.filename, session);
return true; return true;
} }
std::shared_ptr<ccls::CompletionSession> std::shared_ptr<ccls::CompletionSession>
ClangCompleteManager::TryGetSession(const std::string &filename, CompletionManager::TryGetSession(const std::string &path,
bool mark_as_completion, bool mark_as_completion,
bool create_if_needed) { bool create_if_needed) {
std::lock_guard<std::mutex> lock(sessions_lock_); std::lock_guard<std::mutex> lock(sessions_lock_);
// Try to find a preloaded session. // Try to find a preloaded session.
std::shared_ptr<ccls::CompletionSession> preloaded = std::shared_ptr<ccls::CompletionSession> preloaded =
preloaded_sessions_.TryGet(filename); preloaded_sessions_.TryGet(path);
if (preloaded) { if (preloaded) {
// If this request is for a completion, we should move it to // If this request is for a completion, we should move it to
// |completion_sessions|. // |completion_sessions|.
if (mark_as_completion) { if (mark_as_completion) {
preloaded_sessions_.TryTake(filename); preloaded_sessions_.TryTake(path);
completion_sessions_.Insert(filename, preloaded); completion_sessions_.Insert(path, preloaded);
} }
return preloaded; return preloaded;
} }
// Try to find a completion session. If none create one. // Try to find a completion session. If none create one.
std::shared_ptr<ccls::CompletionSession> session = std::shared_ptr<ccls::CompletionSession> session =
completion_sessions_.TryGet(filename); completion_sessions_.TryGet(path);
if (!session && create_if_needed) { if (!session && create_if_needed) {
session = std::make_shared<ccls::CompletionSession>( session = std::make_shared<ccls::CompletionSession>(
project_->FindCompilationEntryForFile(filename), working_files_, PCH); project_->FindCompilationEntryForFile(path), working_files_, PCH);
completion_sessions_.Insert(filename, session); completion_sessions_.Insert(path, session);
} }
return session; return session;
} }
void ClangCompleteManager::FlushSession(const std::string &filename) { void CompletionManager::FlushSession(const std::string &path) {
std::lock_guard<std::mutex> lock(sessions_lock_); std::lock_guard<std::mutex> lock(sessions_lock_);
preloaded_sessions_.TryTake(filename); preloaded_sessions_.TryTake(path);
completion_sessions_.TryTake(filename); completion_sessions_.TryTake(path);
} }
void ClangCompleteManager::FlushAllSessions() { void CompletionManager::FlushAllSessions() {
LOG_S(INFO) << "flush all clang complete sessions"; LOG_S(INFO) << "flush all clang complete sessions";
std::lock_guard<std::mutex> lock(sessions_lock_); std::lock_guard<std::mutex> lock(sessions_lock_);

View File

@ -76,7 +76,7 @@ struct CompletionSession
}; };
} }
struct ClangCompleteManager { struct CompletionManager {
using OnDiagnostic = std::function<void( using OnDiagnostic = std::function<void(
std::string path, std::vector<lsDiagnostic> diagnostics)>; std::string path, std::vector<lsDiagnostic> diagnostics)>;
using OnComplete = std::function<void( using OnComplete = std::function<void(
@ -106,7 +106,7 @@ struct ClangCompleteManager {
lsTextDocumentIdentifier document; lsTextDocumentIdentifier document;
}; };
ClangCompleteManager(Project *project, WorkingFiles *working_files, CompletionManager(Project *project, WorkingFiles *working_files,
OnDiagnostic on_diagnostic, OnDropped on_dropped); OnDiagnostic on_diagnostic, OnDropped on_dropped);
// Start a code completion at the given location. |on_complete| will run when // Start a code completion at the given location. |on_complete| will run when
@ -119,27 +119,25 @@ struct ClangCompleteManager {
// Notify the completion manager that |filename| has been viewed and we // Notify the completion manager that |filename| has been viewed and we
// should begin preloading completion data. // should begin preloading completion data.
void NotifyView(const std::string &filename); void NotifyView(const std::string &path);
// Notify the completion manager that |filename| has been edited.
void NotifyEdit(const std::string &filename);
// Notify the completion manager that |filename| has been saved. This // Notify the completion manager that |filename| has been saved. This
// triggers a reparse. // triggers a reparse.
void NotifySave(const std::string &filename); void NotifySave(const std::string &path);
// Notify the completion manager that |filename| has been closed. Any existing // Notify the completion manager that |filename| has been closed. Any existing
// completion session will be dropped. // completion session will be dropped.
void NotifyClose(const std::string &filename); void NotifyClose(const std::string &path);
// Ensures there is a completion or preloaded session. Returns true if a new // Ensures there is a completion or preloaded session. Returns true if a new
// session was created. // session was created.
bool EnsureCompletionOrCreatePreloadSession(const std::string &filename); bool EnsureCompletionOrCreatePreloadSession(const std::string &path);
// Tries to find an edit session for |filename|. This will move the session // Tries to find an edit session for |filename|. This will move the session
// from view to edit. // from view to edit.
std::shared_ptr<ccls::CompletionSession> std::shared_ptr<ccls::CompletionSession>
TryGetSession(const std::string &filename, bool mark_as_completion, TryGetSession(const std::string &path, bool mark_as_completion,
bool create_if_needed); bool create_if_needed);
// Flushes all saved sessions with the supplied filename // Flushes all saved sessions with the supplied filename
void FlushSession(const std::string &filename); void FlushSession(const std::string &path);
// Flushes all saved sessions // Flushes all saved sessions
void FlushAllSessions(void); void FlushAllSessions(void);

View File

@ -154,6 +154,8 @@ struct Config {
// If true, diagnostics will be reported for textDocument/didOpen. // If true, diagnostics will be reported for textDocument/didOpen.
bool onOpen = true; bool onOpen = true;
bool spellChecking = true;
std::vector<std::string> whitelist; std::vector<std::string> whitelist;
} diagnostics; } diagnostics;
@ -238,7 +240,7 @@ MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, dropOldRequests,
includeMaxPathSize, includeSuffixWhitelist, includeMaxPathSize, includeSuffixWhitelist,
includeWhitelist); includeWhitelist);
MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onChange, MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onChange,
onOpen, whitelist) onOpen, spellChecking, whitelist)
MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist)
MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, multiVersion, MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, multiVersion,
multiVersionBlacklist, multiVersionWhitelist, onChange, multiVersionBlacklist, multiVersionWhitelist, onChange,

View File

@ -15,12 +15,13 @@ limitations under the License.
#include "indexer.h" #include "indexer.h"
#include "clang_complete.hh"
#include "clang_tu.h" #include "clang_tu.h"
#include "log.hh" #include "log.hh"
#include "match.h" #include "match.h"
#include "platform.h" #include "platform.h"
#include "serializer.h" #include "serializer.h"
using ccls::Intern; using namespace ccls;
#include <clang/AST/AST.h> #include <clang/AST/AST.h>
#include <clang/Frontend/FrontendAction.h> #include <clang/Frontend/FrontendAction.h>
@ -1195,7 +1196,8 @@ void Init() {
} }
std::vector<std::unique_ptr<IndexFile>> std::vector<std::unique_ptr<IndexFile>>
Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs,
const std::string &opt_wdir, const std::string &file,
const std::vector<std::string> &args, const std::vector<std::string> &args,
const std::vector<std::pair<std::string, std::string>> &remapped) { const std::vector<std::pair<std::string, std::string>> &remapped) {
if (!g_config->index.enabled) if (!g_config->index.enabled)
@ -1221,14 +1223,33 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
// HSOpts.UseBuiltinIncludes) // HSOpts.UseBuiltinIncludes)
// HSOpts.ResourceDir = g_config->clang.resourceDir; // HSOpts.ResourceDir = g_config->clang.resourceDir;
} }
std::string buf = wfiles->GetContent(file);
std::vector<std::unique_ptr<llvm::MemoryBuffer>> Bufs; std::vector<std::unique_ptr<llvm::MemoryBuffer>> Bufs;
if (buf.size()) {
// If there is a completion session, reuse its preamble if exists.
bool done_remap = false;
std::shared_ptr<CompletionSession> session =
completion->TryGetSession(file, false, false);
if (session)
if (auto preamble = session->GetPreamble()) {
Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(buf));
auto Bounds = ComputePreambleBounds(*CI->getLangOpts(), Bufs.back().get(), 0);
if (preamble->Preamble.CanReuse(*CI, Bufs.back().get(), Bounds,
FS.get())) {
preamble->Preamble.AddImplicitPreamble(*CI, FS, Bufs.back().get());
done_remap = true;
}
}
for (auto &[filename, content] : remapped) { for (auto &[filename, content] : remapped) {
if (filename == file && done_remap)
continue;
Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(content)); Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(content));
CI->getPreprocessorOpts().addRemappedFile( CI->getPreprocessorOpts().addRemappedFile(
filename == file ? CI->getFrontendOpts().Inputs[0].getFile() filename == file ? CI->getFrontendOpts().Inputs[0].getFile()
: StringRef(filename), : StringRef(filename),
Bufs.back().get()); Bufs.back().get());
} }
}
DiagnosticConsumer DC; DiagnosticConsumer DC;
auto Clang = std::make_unique<CompilerInstance>(PCH); auto Clang = std::make_unique<CompilerInstance>(PCH);

View File

@ -284,10 +284,14 @@ struct IndexFile {
std::string ToString(); std::string ToString();
}; };
struct CompletionManager;
struct WorkingFiles;
namespace ccls::idx { namespace ccls::idx {
void Init(); void Init();
std::vector<std::unique_ptr<IndexFile>> std::vector<std::unique_ptr<IndexFile>>
Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, Index(CompletionManager *complete, WorkingFiles *wfiles, VFS *vfs,
const std::string &opt_wdir, const std::string &file,
const std::vector<std::string> &args, const std::vector<std::string> &args,
const std::vector<std::pair<std::string, std::string>> &remapped); const std::vector<std::pair<std::string, std::string>> &remapped);
} // namespace ccls::idx }

View File

@ -26,7 +26,7 @@ limitations under the License.
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
struct ClangCompleteManager; struct CompletionManager;
struct CodeCompleteCache; struct CodeCompleteCache;
struct Config; struct Config;
class DiagnosticsPublisher; class DiagnosticsPublisher;
@ -119,7 +119,7 @@ struct MessageHandler {
ImportManager *import_manager = nullptr; ImportManager *import_manager = nullptr;
SemanticHighlightSymbolCache *semantic_cache = nullptr; SemanticHighlightSymbolCache *semantic_cache = nullptr;
WorkingFiles *working_files = nullptr; WorkingFiles *working_files = nullptr;
ClangCompleteManager *clang_complete = nullptr; CompletionManager *clang_complete = nullptr;
IncludeComplete *include_complete = nullptr; IncludeComplete *include_complete = nullptr;
CodeCompleteCache *global_code_complete_cache = nullptr; CodeCompleteCache *global_code_complete_cache = nullptr;
CodeCompleteCache *non_global_code_complete_cache = nullptr; CodeCompleteCache *non_global_code_complete_cache = nullptr;

View File

@ -13,6 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "clang_complete.hh"
#include "filesystem.hh" #include "filesystem.hh"
#include "include_complete.h" #include "include_complete.h"
#include "log.hh" #include "log.hh"
@ -495,7 +496,8 @@ struct Handler_Initialize : BaseMessageHandler<In_InitializeRequest> {
g_thread_id = i + 1; g_thread_id = i + 1;
std::string name = "indexer" + std::to_string(i); std::string name = "indexer" + std::to_string(i);
set_thread_name(name.c_str()); set_thread_name(name.c_str());
pipeline::Indexer_Main(diag_pub, vfs, project, working_files); pipeline::Indexer_Main(clang_complete, diag_pub, vfs, project,
working_files);
}) })
.detach(); .detach();
} }

View File

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "clang_complete.h" #include "clang_complete.hh"
#include "lsp_code_action.h" #include "lsp_code_action.h"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh" #include "pipeline.hh"

View File

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "clang_complete.h" #include "clang_complete.hh"
#include "fuzzy_match.h" #include "fuzzy_match.h"
#include "include_complete.h" #include "include_complete.h"
#include "message_handler.h" #include "message_handler.h"
@ -380,7 +380,7 @@ struct Handler_TextDocumentCompletion : MessageHandler {
pipeline::WriteStdout(kMethodType, out); pipeline::WriteStdout(kMethodType, out);
} else { } else {
ClangCompleteManager::OnComplete callback = std::bind( CompletionManager::OnComplete callback = std::bind(
[this, request, params, is_global_completion, existing_completion, [this, request, params, is_global_completion, existing_completion,
has_open_paren](const std::vector<lsCompletionItem> &results, has_open_paren](const std::vector<lsCompletionItem> &results,
bool is_cached_result) { bool is_cached_result) {
@ -420,7 +420,7 @@ struct Handler_TextDocumentCompletion : MessageHandler {
!global_code_complete_cache->cached_results_.empty(); !global_code_complete_cache->cached_results_.empty();
}); });
if (is_cache_match) { if (is_cache_match) {
ClangCompleteManager::OnComplete freshen_global = CompletionManager::OnComplete freshen_global =
[this](std::vector<lsCompletionItem> results, [this](std::vector<lsCompletionItem> results,
bool is_cached_result) { bool is_cached_result) {
assert(!is_cached_result); assert(!is_cached_result);

View File

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "clang_complete.h" #include "clang_complete.hh"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "project.h" #include "project.h"

View File

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "clang_complete.h" #include "clang_complete.hh"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "working_files.h" #include "working_files.h"

View File

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "clang_complete.h" #include "clang_complete.hh"
#include "include_complete.h" #include "include_complete.h"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh" #include "pipeline.hh"

View File

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "clang_complete.h" #include "clang_complete.hh"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "project.h" #include "project.h"

View File

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "clang_complete.h" #include "clang_complete.hh"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh" #include "pipeline.hh"
using namespace ccls; using namespace ccls;
@ -114,7 +114,7 @@ struct Handler_TextDocumentSignatureHelp : MessageHandler {
if (search.empty()) if (search.empty())
return; return;
ClangCompleteManager::OnComplete callback = std::bind( CompletionManager::OnComplete callback = std::bind(
[this](InMessage *message, std::string search, int active_param, [this](InMessage *message, std::string search, int active_param,
const std::vector<lsCompletionItem> &results, const std::vector<lsCompletionItem> &results,
bool is_cached_result) { bool is_cached_result) {

View File

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "clang_complete.h" #include "clang_complete.hh"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "project.h" #include "project.h"

View File

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "clang_complete.h" #include "clang_complete.hh"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "project.h" #include "project.h"

View File

@ -15,7 +15,7 @@ limitations under the License.
#include "pipeline.hh" #include "pipeline.hh"
#include "clang_complete.h" #include "clang_complete.hh"
#include "config.h" #include "config.h"
#include "include_complete.h" #include "include_complete.h"
#include "log.hh" #include "log.hh"
@ -165,7 +165,8 @@ std::unique_ptr<IndexFile> RawCacheLoad(const std::string &path) {
IndexFile::kMajorVersion); IndexFile::kMajorVersion);
} }
bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, bool Indexer_Parse(CompletionManager *completion,
DiagnosticsPublisher *diag_pub, WorkingFiles *wfiles,
Project *project, VFS *vfs, const GroupMatch &matcher) { Project *project, VFS *vfs, const GroupMatch &matcher) {
std::optional<Index_Request> opt_request = index_request->TryPopFront(); std::optional<Index_Request> opt_request = index_request->TryPopFront();
if (!opt_request) if (!opt_request)
@ -259,12 +260,12 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files,
std::vector<std::pair<std::string, std::string>> remapped; std::vector<std::pair<std::string, std::string>> remapped;
if (g_config->index.onChange) { if (g_config->index.onChange) {
std::string content = working_files->GetContent(request.path); std::string content = wfiles->GetContent(request.path);
if (content.size()) if (content.size())
remapped.emplace_back(request.path, content); remapped.emplace_back(request.path, content);
} }
auto indexes = auto indexes = idx::Index(completion, wfiles, vfs, entry.directory,
idx::Index(vfs, entry.directory, path_to_index, entry.args, remapped); path_to_index, entry.args, remapped);
if (indexes.empty()) { if (indexes.empty()) {
if (g_config->index.enabled && request.id.Valid()) { if (g_config->index.enabled && request.id.Valid()) {
@ -348,11 +349,13 @@ void Init() {
for_stdout = new ThreadedQueue<Stdout_Request>(stdout_waiter); for_stdout = new ThreadedQueue<Stdout_Request>(stdout_waiter);
} }
void Indexer_Main(DiagnosticsPublisher *diag_pub, VFS *vfs, Project *project, void Indexer_Main(CompletionManager *completion,
DiagnosticsPublisher *diag_pub, VFS *vfs, Project *project,
WorkingFiles *working_files) { WorkingFiles *working_files) {
GroupMatch matcher(g_config->index.whitelist, g_config->index.blacklist); GroupMatch matcher(g_config->index.whitelist, g_config->index.blacklist);
while (true) while (true)
if (!Indexer_Parse(diag_pub, working_files, project, vfs, matcher)) if (!Indexer_Parse(completion, diag_pub, working_files, project, vfs,
matcher))
indexer_waiter->Wait(index_request); indexer_waiter->Wait(index_request);
} }
@ -464,7 +467,7 @@ void MainLoop() {
VFS vfs; VFS vfs;
DiagnosticsPublisher diag_pub; DiagnosticsPublisher diag_pub;
ClangCompleteManager clang_complete( CompletionManager clang_complete(
&project, &working_files, &project, &working_files,
[&](std::string path, std::vector<lsDiagnostic> diagnostics) { [&](std::string path, std::vector<lsDiagnostic> diagnostics) {
diag_pub.Publish(&working_files, path, diagnostics); diag_pub.Publish(&working_files, path, diagnostics);

View File

@ -8,6 +8,7 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
struct CompletionManager;
struct GroupMatch; struct GroupMatch;
struct VFS; struct VFS;
struct Project; struct Project;
@ -37,9 +38,8 @@ namespace pipeline {
void Init(); void Init();
void LaunchStdin(); void LaunchStdin();
void LaunchStdout(); void LaunchStdout();
void Indexer_Main(DiagnosticsPublisher* diag_pub, void Indexer_Main(CompletionManager *complete,
VFS* vfs, DiagnosticsPublisher *diag_pub, VFS *vfs, Project *project,
Project* project,
WorkingFiles *working_files); WorkingFiles *working_files);
void MainLoop(); void MainLoop();

View File

@ -15,6 +15,7 @@ limitations under the License.
#include "test.h" #include "test.h"
#include "clang_complete.hh"
#include "filesystem.hh" #include "filesystem.hh"
#include "indexer.h" #include "indexer.h"
#include "platform.h" #include "platform.h"
@ -301,7 +302,11 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) {
// Run test. // Run test.
g_config = new Config; g_config = new Config;
VFS vfs; VFS vfs;
auto dbs = ccls::idx::Index(&vfs, "", path, flags, {}); CompletionManager completion(
nullptr, nullptr, [&](std::string, std::vector<lsDiagnostic>) {},
[](lsRequestId id) {});
WorkingFiles wfiles;
auto dbs = ccls::idx::Index(&completion, &wfiles, &vfs, "", path, flags, {});
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;