First pass at semantic highlighting.

It is disabled by default.
This commit is contained in:
Jacob Dufault 2017-11-08 23:06:32 -08:00
parent 9d376a47d5
commit 8145a06534
5 changed files with 95 additions and 3 deletions

View File

@ -143,6 +143,51 @@ void EmitInactiveLines(WorkingFile* working_file,
IpcId::CqueryPublishInactiveRegions, out);
}
void EmitSemanticHighlighting(QueryDatabase* db,
WorkingFile* working_file,
QueryFile* file) {
auto map_symbol_kind_to_symbol_type = [](SymbolKind kind) {
switch (kind) {
case SymbolKind::Type:
return Out_CqueryPublishSemanticHighlighting::SymbolType::Type;
case SymbolKind::Func:
return Out_CqueryPublishSemanticHighlighting::SymbolType::Function;
case SymbolKind::Var:
return Out_CqueryPublishSemanticHighlighting::SymbolType::Variable;
default:
assert(false);
return Out_CqueryPublishSemanticHighlighting::SymbolType::Variable;
}
};
// Group symbols together.
std::unordered_map<SymbolIdx, NonElidedVector<lsRange>> grouped_symbols;
for (SymbolRef sym : file->def->all_symbols) {
if (sym.idx.kind == SymbolKind::Var) {
QueryVar* var = &db->vars[sym.idx.idx];
if (!var->def)
continue;
if (!var->def->is_local)
continue;
}
optional<lsRange> loc = GetLsRange(working_file, sym.loc.range);
if (loc)
grouped_symbols[sym.idx].push_back(*loc);
}
// Publish.
Out_CqueryPublishSemanticHighlighting out;
out.params.uri = lsDocumentUri::FromPath(working_file->filename);
for (auto& entry : grouped_symbols) {
Out_CqueryPublishSemanticHighlighting::Symbol symbol;
symbol.type = map_symbol_kind_to_symbol_type(entry.first.kind);
symbol.ranges = entry.second;
out.params.symbols.push_back(symbol);
}
IpcManager::instance()->SendOutMessageToClient(
IpcId::CqueryPublishSemanticHighlighting, out);
}
optional<int> FindIncludeLine(const std::vector<std::string>& lines,
const std::string& full_include_line) {
//
@ -1286,6 +1331,18 @@ bool QueryDb_ImportMain(Config* config,
return value.path;
}));
// Update semantic highlighting.
for (auto& updated_file : response->update.files_def_update) {
WorkingFile* working_file =
working_files->GetFileByFilename(updated_file.path);
if (working_file) {
QueryFileId file_id =
db->usr_to_file[LowerPathIfCaseInsensitive(working_file->filename)];
QueryFile* file = &db->files[file_id.id];
EmitSemanticHighlighting(db, working_file, file);
}
}
// Mark the files as being done in querydb stage after we apply the index
// update.
for (auto& updated_file : response->update.files_def_update)
@ -1774,8 +1831,10 @@ bool QueryDbMainLoop(Config* config,
QueryFile* file = nullptr;
FindFileOrFail(db, nullopt, path, &file);
if (file && file->def)
if (file && file->def) {
EmitInactiveLines(working_file, file->def->inactive_regions);
EmitSemanticHighlighting(db, working_file, file);
}
time.ResetAndPrint(
"[querydb] Loading cached index file for DidOpen (blocks "
@ -2743,8 +2802,11 @@ bool QueryDbMainLoop(Config* config,
// 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);
WorkingFile* working_file =
working_files->GetFileByFilename(file->def->path);
EmitInactiveLines(working_file, file->def->inactive_regions);
// Do not emit semantic highlighting information here, as it has not
// been updated.
}
break;

View File

@ -51,6 +51,8 @@ const char* IpcIdToString(IpcId id) {
case IpcId::CqueryPublishInactiveRegions:
return "$cquery/publishInactiveRegions";
case IpcId::CqueryPublishSemanticHighlighting:
return "$cquery/publishSemanticHighlighting";
case IpcId::CqueryFreshenIndex:
return "$cquery/freshenIndex";

View File

@ -32,6 +32,7 @@ enum class IpcId : int {
// Custom notifications
CqueryPublishInactiveRegions,
CqueryPublishSemanticHighlighting,
// Custom messages
CqueryFreshenIndex,

View File

@ -1480,6 +1480,32 @@ struct Out_CquerySetInactiveRegion
MAKE_REFLECT_STRUCT(Out_CquerySetInactiveRegion::Params, uri, inactiveRegions);
MAKE_REFLECT_STRUCT(Out_CquerySetInactiveRegion, jsonrpc, method, params);
struct Out_CqueryPublishSemanticHighlighting
: public lsOutMessage<Out_CqueryPublishSemanticHighlighting> {
enum class SymbolType { Type = 0, Function, Variable };
struct Symbol {
SymbolType type;
NonElidedVector<lsRange> ranges;
};
struct Params {
lsDocumentUri uri;
NonElidedVector<Symbol> symbols;
};
std::string method = "$cquery/publishSemanticHighlighting";
Params params;
};
MAKE_REFLECT_TYPE_PROXY(Out_CqueryPublishSemanticHighlighting::SymbolType, int);
MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting::Symbol,
type,
ranges);
MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting::Params,
uri,
symbols);
MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting,
jsonrpc,
method,
params);
struct Ipc_CqueryFreshenIndex : public IpcMessage<Ipc_CqueryFreshenIndex> {
const static IpcId kIpcId = IpcId::CqueryFreshenIndex;
lsRequestId id;

View File

@ -74,6 +74,7 @@ struct SymbolIdx {
}
};
MAKE_REFLECT_STRUCT(SymbolIdx, kind, idx);
MAKE_HASHABLE(SymbolIdx, t.kind, t.idx);
struct SymbolRef {
SymbolIdx idx;