Fix inactive region after closing/reopening a document.

Also make it a bit more robust.
This commit is contained in:
Jacob Dufault 2017-10-28 15:09:14 -07:00
parent 98c701b217
commit 4156be09c1
3 changed files with 42 additions and 39 deletions

View File

@ -99,10 +99,12 @@ void PushBack(NonElidedVector<lsLocation>* result,
} }
bool FindFileOrFail(QueryDatabase* db, bool FindFileOrFail(QueryDatabase* db,
lsRequestId id, optional<lsRequestId> id,
const std::string& absolute_path, const std::string& absolute_path,
QueryFile** out_query_file, QueryFile** out_query_file,
QueryFileId* out_file_id = nullptr) { QueryFileId* out_file_id = nullptr) {
*out_query_file = nullptr;
auto it = db->usr_to_file.find(LowerPathIfCaseInsensitive(absolute_path)); auto it = db->usr_to_file.find(LowerPathIfCaseInsensitive(absolute_path));
if (it != db->usr_to_file.end()) { if (it != db->usr_to_file.end()) {
QueryFile& file = db->files[it->second.id]; QueryFile& file = db->files[it->second.id];
@ -119,30 +121,25 @@ bool FindFileOrFail(QueryDatabase* db,
LOG_S(INFO) << "Unable to find file \"" << absolute_path << "\""; LOG_S(INFO) << "Unable to find file \"" << absolute_path << "\"";
Out_Error out; if (id) {
out.id = id; Out_Error out;
out.error.code = lsErrorCodes::InternalError; out.id = *id;
out.error.message = "Unable to find file " + absolute_path; out.error.code = lsErrorCodes::InternalError;
IpcManager::instance()->SendOutMessageToClient(IpcId::Cout, out); out.error.message = "Unable to find file " + absolute_path;
IpcManager::instance()->SendOutMessageToClient(IpcId::Cout, out);
}
return false; return false;
} }
void PublishInactiveLines(WorkingFile* working_file, void EmitInactiveLines(WorkingFile* working_file,
const std::vector<Range>& inactive, const std::vector<Range>& inactive_regions) {
bool remap_index_lines) {
Out_CquerySetInactiveRegion out; Out_CquerySetInactiveRegion out;
out.params.uri = lsDocumentUri::FromPath(working_file->filename); out.params.uri = lsDocumentUri::FromPath(working_file->filename);
for (Range skipped : inactive) { for (Range skipped : inactive_regions) {
if (remap_index_lines) { optional<lsRange> ls_skipped = GetLsRange(working_file, skipped);
optional<lsRange> ls_skipped = GetLsRange(working_file, skipped); if (ls_skipped)
if (ls_skipped) out.params.inactiveRegions.push_back(*ls_skipped);
out.params.inactiveRegions.push_back(*ls_skipped);
} else {
out.params.inactiveRegions.push_back(
lsRange(lsPosition(skipped.start.line - 1, skipped.start.column),
lsPosition(skipped.end.line - 1, skipped.end.column)));
}
} }
IpcManager::instance()->SendOutMessageToClient( IpcManager::instance()->SendOutMessageToClient(
IpcId::CqueryPublishInactiveRegions, out); IpcId::CqueryPublishInactiveRegions, out);
@ -938,20 +935,7 @@ std::vector<Index_DoIdMap> DoParseFile(
// handled by code completion. // handled by code completion.
if (!is_interactive) if (!is_interactive)
EmitDiagnostics(working_files, new_index->path, new_index->diagnostics_); EmitDiagnostics(working_files, new_index->path, new_index->diagnostics_);
// Emit regions disabled by the preprocessor. Checking |is_interactive| is
// an optimization so we can avoid locking as much in WorkingFiles, but it
// will likely generate invalid results if the index request was created
// and then the user opened the file.
if (is_interactive) {
// Since |is_interactive| is true |working_file| should ideally never be
// null, but the user may have closed the document after the index
// request was generated.
WorkingFile* working_file =
working_files->GetFileByFilename(new_index->path);
if (working_file)
PublishInactiveLines(working_file, new_index->skipped_by_preprocessor,
false /*remap_index_lines*/);
}
// 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;
@ -1290,6 +1274,9 @@ bool QueryDb_ImportMain(Config* config,
time.ResetAndPrint( time.ResetAndPrint(
"Update WorkingFile index contents (via disk load) for " + "Update WorkingFile index contents (via disk load) for " +
updated_file.path); updated_file.path);
// Update inactive region.
EmitInactiveLines(working_file, updated_file.inactive_regions);
} }
} }
@ -1787,10 +1774,10 @@ bool QueryDbMainLoop(Config* config,
else else
working_file->SetIndexContent(working_file->buffer_content); working_file->SetIndexContent(working_file->buffer_content);
std::unique_ptr<IndexFile> cache = LoadCachedIndex(config, path); QueryFile* file = nullptr;
if (cache && !cache->skipped_by_preprocessor.empty()) FindFileOrFail(db, nullopt, path, &file);
PublishInactiveLines(working_file, cache->skipped_by_preprocessor, if (file && file->def)
true /*remap_index_lines*/); EmitInactiveLines(working_file, file->def->inactive_regions);
time.ResetAndPrint( time.ResetAndPrint(
"[querydb] Loading cached index file for DidOpen (blocks " "[querydb] Loading cached index file for DidOpen (blocks "
@ -2754,6 +2741,14 @@ bool QueryDbMainLoop(Config* config,
} }
ipc->SendOutMessageToClient(IpcId::TextDocumentCodeLens, response); ipc->SendOutMessageToClient(IpcId::TextDocumentCodeLens, response);
// TODO: We need to move this to a separate request, as the user may
// have turned code lens off (ie, a custom DidView notification).
if (file && file->def) {
EmitInactiveLines(working_files->GetFileByFilename(file->def->path),
file->def->inactive_regions);
}
break; break;
} }
@ -3098,7 +3093,8 @@ void LanguageServerMain(const std::string& bin_name,
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int main(int argc, char** argv) { int main(int argc, char** argv) {
loguru::init(argc, argv); loguru::init(argc, argv);
loguru::add_file("cquery_diagnostics.log", loguru::Truncate, loguru::Verbosity_MAX); loguru::add_file("cquery_diagnostics.log", loguru::Truncate,
loguru::Verbosity_MAX);
loguru::g_flush_interval_ms = 0; loguru::g_flush_interval_ms = 0;
loguru::g_stderr_verbosity = 1; loguru::g_stderr_verbosity = 1;

View File

@ -172,6 +172,7 @@ QueryFile::Def BuildFileDef(const IdMap& id_map, const IndexFile& indexed) {
QueryFile::Def def; QueryFile::Def def;
def.path = indexed.path; def.path = indexed.path;
def.includes = indexed.includes; def.includes = indexed.includes;
def.inactive_regions = indexed.skipped_by_preprocessor;
auto add_outline = [&def, &id_map](SymbolIdx idx, Range range) { auto add_outline = [&def, &id_map](SymbolIdx idx, Range range) {
def.outline.push_back(SymbolRef(idx, id_map.ToQuery(range))); def.outline.push_back(SymbolRef(idx, id_map.ToQuery(range)));

View File

@ -165,6 +165,8 @@ struct QueryFile {
std::vector<SymbolRef> outline; std::vector<SymbolRef> outline;
// Every symbol found in the file (ie, for goto definition) // Every symbol found in the file (ie, for goto definition)
std::vector<SymbolRef> all_symbols; std::vector<SymbolRef> all_symbols;
// Parts of the file which are disabled.
std::vector<Range> inactive_regions;
}; };
using DefUpdate = Def; using DefUpdate = Def;
@ -177,7 +179,11 @@ struct QueryFile {
def->path = path; def->path = path;
} }
}; };
MAKE_REFLECT_STRUCT(QueryFile::Def, path, outline, all_symbols); MAKE_REFLECT_STRUCT(QueryFile::Def,
path,
outline,
all_symbols,
inactive_regions);
struct QueryType { struct QueryType {
using DefUpdate = TypeDefDefinitionData<QueryTypeId, using DefUpdate = TypeDefDefinitionData<QueryTypeId,