mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-10-31 20:53:01 +00:00 
			
		
		
		
	First pass at semantic highlighting.
It is disabled by default.
This commit is contained in:
		
							parent
							
								
									9d376a47d5
								
							
						
					
					
						commit
						8145a06534
					
				| @ -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; | ||||
|  | ||||
| @ -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"; | ||||
|  | ||||
| @ -32,6 +32,7 @@ enum class IpcId : int { | ||||
| 
 | ||||
|   // Custom notifications
 | ||||
|   CqueryPublishInactiveRegions, | ||||
|   CqueryPublishSemanticHighlighting, | ||||
| 
 | ||||
|   // Custom messages
 | ||||
|   CqueryFreshenIndex, | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -74,6 +74,7 @@ struct SymbolIdx { | ||||
|   } | ||||
| }; | ||||
| MAKE_REFLECT_STRUCT(SymbolIdx, kind, idx); | ||||
| MAKE_HASHABLE(SymbolIdx, t.kind, t.idx); | ||||
| 
 | ||||
| struct SymbolRef { | ||||
|   SymbolIdx idx; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user