mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-29 11:01:57 +00:00
Added diagnostics.
This commit is contained in:
parent
1083a10a66
commit
202ab60ede
@ -990,6 +990,14 @@ void ParseFile(IndexerConfig* config,
|
|||||||
for (std::unique_ptr<IndexedFile>& new_index : indexes) {
|
for (std::unique_ptr<IndexedFile>& new_index : indexes) {
|
||||||
std::cerr << "Got index for " << new_index->path << std::endl;
|
std::cerr << "Got index for " << new_index->path << std::endl;
|
||||||
|
|
||||||
|
// Publish diagnostics.
|
||||||
|
if (!new_index->diagnostics.empty()) {
|
||||||
|
Out_TextDocumentPublishDiagnostics diag;
|
||||||
|
diag.params.uri = lsDocumentUri::FromPath(new_index->path);
|
||||||
|
diag.params.diagnostics = new_index->diagnostics;
|
||||||
|
IpcManager::instance()->SendOutMessageToClient(IpcId::TextDocumentPublishDiagnostics, diag);
|
||||||
|
}
|
||||||
|
|
||||||
// Load the cached index.
|
// Load the cached index.
|
||||||
std::unique_ptr<IndexedFile> cached_index;
|
std::unique_ptr<IndexedFile> cached_index;
|
||||||
if (cache_for_args && new_index->path == cache_for_args->path)
|
if (cache_for_args && new_index->path == cache_for_args->path)
|
||||||
|
151
src/indexer.cc
151
src/indexer.cc
@ -20,6 +20,31 @@ void AddFuncRef(std::vector<IndexFuncRef>* result, IndexFuncRef ref) {
|
|||||||
result->push_back(ref);
|
result->push_back(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Range Resolve(const CXSourceRange& range) {
|
||||||
|
CXSourceLocation start = clang_getRangeStart(range);
|
||||||
|
CXSourceLocation end = clang_getRangeEnd(range);
|
||||||
|
|
||||||
|
unsigned int start_line, start_column;
|
||||||
|
clang_getSpellingLocation(start, nullptr, &start_line, &start_column, nullptr);
|
||||||
|
unsigned int end_line, end_column;
|
||||||
|
clang_getSpellingLocation(end, nullptr, &end_line, &end_column, nullptr);
|
||||||
|
|
||||||
|
return Range(
|
||||||
|
Position(start_line, start_column) /*start*/,
|
||||||
|
Position(end_line, end_column) /*end*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
Range ResolveSpelling(const CXCursor& cx_cursor) {
|
||||||
|
CXSourceRange cx_range = clang_Cursor_getSpellingNameRange(cx_cursor, 0, 0);
|
||||||
|
return Resolve(cx_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
Range ResolveExtent(const CXCursor& cx_cursor) {
|
||||||
|
CXSourceRange cx_range = clang_getCursorExtent(cx_cursor);
|
||||||
|
return Resolve(cx_range);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
@ -120,30 +145,6 @@ void UniqueAdd(std::vector<Range>& uses, Range loc) {
|
|||||||
IdCache::IdCache(const std::string& primary_file)
|
IdCache::IdCache(const std::string& primary_file)
|
||||||
: primary_file(primary_file) {}
|
: primary_file(primary_file) {}
|
||||||
|
|
||||||
Range IdCache::Resolve(const CXSourceRange& range) {
|
|
||||||
CXSourceLocation start = clang_getRangeStart(range);
|
|
||||||
CXSourceLocation end = clang_getRangeEnd(range);
|
|
||||||
|
|
||||||
unsigned int start_line, start_column;
|
|
||||||
clang_getSpellingLocation(start, nullptr, &start_line, &start_column, nullptr);
|
|
||||||
unsigned int end_line, end_column;
|
|
||||||
clang_getSpellingLocation(end, nullptr, &end_line, &end_column, nullptr);
|
|
||||||
|
|
||||||
return Range(
|
|
||||||
Position(start_line, start_column) /*start*/,
|
|
||||||
Position(end_line, end_column) /*end*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
Range IdCache::ResolveSpelling(const CXCursor& cx_cursor) {
|
|
||||||
CXSourceRange cx_range = clang_Cursor_getSpellingNameRange(cx_cursor, 0, 0);
|
|
||||||
return Resolve(cx_range);
|
|
||||||
}
|
|
||||||
|
|
||||||
Range IdCache::ResolveExtent(const CXCursor& cx_cursor) {
|
|
||||||
CXSourceRange cx_range = clang_getCursorExtent(cx_cursor);
|
|
||||||
return Resolve(cx_range);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool Contains(const std::vector<T>& vec, const T& element) {
|
bool Contains(const std::vector<T>& vec, const T& element) {
|
||||||
for (const T& entry : vec) {
|
for (const T& entry : vec) {
|
||||||
@ -220,25 +221,59 @@ void diagnostic(CXClientData client_data,
|
|||||||
for (unsigned i = 0; i < clang_getNumDiagnosticsInSet(diagnostics); ++i) {
|
for (unsigned i = 0; i < clang_getNumDiagnosticsInSet(diagnostics); ++i) {
|
||||||
CXDiagnostic diagnostic = clang_getDiagnosticInSet(diagnostics, i);
|
CXDiagnostic diagnostic = clang_getDiagnosticInSet(diagnostics, i);
|
||||||
|
|
||||||
std::string spelling =
|
// Skip diagnostics in system headers.
|
||||||
clang::ToString(clang_getDiagnosticSpelling(diagnostic));
|
CXSourceLocation diag_loc = clang_getDiagnosticLocation(diagnostic);
|
||||||
|
if (clang_Location_isInSystemHeader(diag_loc))
|
||||||
|
continue;
|
||||||
|
|
||||||
// Fetch location
|
// Get db so we can attribute diagnostic to the right indexed file.
|
||||||
CXFile file;
|
CXFile file;
|
||||||
unsigned int line, column;
|
unsigned int line, column;
|
||||||
CXSourceLocation location = clang_getDiagnosticLocation(diagnostic);
|
clang_getSpellingLocation(diag_loc, &file, &line, &column, nullptr);
|
||||||
if (!clang_Location_isInSystemHeader(location)) {
|
bool is_first_time_visiting_file = false;
|
||||||
clang_getSpellingLocation(location, &file, &line, &column, nullptr);
|
IndexedFile* db = param->file_consumer->TryConsumeFile(file, &is_first_time_visiting_file);
|
||||||
|
if (!db)
|
||||||
|
continue;
|
||||||
|
if (is_first_time_visiting_file && param->primary_file)
|
||||||
|
param->primary_file->dependencies.push_back(db->path);
|
||||||
|
|
||||||
// Fetch path, print.
|
// Build diagnostic.
|
||||||
if (file != nullptr) {
|
|
||||||
std::string path = clang::ToString(clang_getFileName(file));
|
lsDiagnostic ls_diagnostic;
|
||||||
std::cerr << NormalizePath(path) << ':';
|
|
||||||
}
|
// TODO: ls_diagnostic.range is lsRange, we have Range. We should only be
|
||||||
std::cerr << line << ':' << column << ": " << spelling << std::endl;
|
// storing Range types when inside the indexer so that index <-> buffer
|
||||||
|
// remapping logic is applied.
|
||||||
|
ls_diagnostic.range = lsRange(lsPosition(line - 1, column), lsPosition(line - 1, column));
|
||||||
|
|
||||||
|
ls_diagnostic.message = clang::ToString(clang_getDiagnosticSpelling(diagnostic));
|
||||||
|
|
||||||
|
// Append the flag that enables this diagnostic, ie, [-Wswitch]
|
||||||
|
std::string enabling_flag = clang::ToString(clang_getDiagnosticOption(diagnostic, nullptr));
|
||||||
|
if (!enabling_flag.empty())
|
||||||
|
ls_diagnostic.message += " [" + enabling_flag + "]";
|
||||||
|
|
||||||
|
ls_diagnostic.code = clang_getDiagnosticCategory(diagnostic);
|
||||||
|
|
||||||
|
switch (clang_getDiagnosticSeverity(diagnostic)) {
|
||||||
|
case CXDiagnostic_Ignored:
|
||||||
|
case CXDiagnostic_Note:
|
||||||
|
ls_diagnostic.severity = lsDiagnosticSeverity::Information;
|
||||||
|
break;
|
||||||
|
case CXDiagnostic_Warning:
|
||||||
|
ls_diagnostic.severity = lsDiagnosticSeverity::Warning;
|
||||||
|
break;
|
||||||
|
case CXDiagnostic_Error:
|
||||||
|
case CXDiagnostic_Fatal:
|
||||||
|
ls_diagnostic.severity = lsDiagnosticSeverity::Error;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: integrate FixIts (ie, textDocument/codeAction)
|
||||||
|
|
||||||
clang_disposeDiagnostic(diagnostic);
|
clang_disposeDiagnostic(diagnostic);
|
||||||
|
|
||||||
|
db->diagnostics.push_back(ls_diagnostic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,7 +409,7 @@ void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor,
|
|||||||
IndexedTypeDef* ref_type_def = db->Resolve(ref_type_id);
|
IndexedTypeDef* ref_type_def = db->Resolve(ref_type_id);
|
||||||
// TODO: Should we even be visiting this if the file is not from the main
|
// TODO: Should we even be visiting this if the file is not from the main
|
||||||
// def? Try adding assert on |loc| later.
|
// def? Try adding assert on |loc| later.
|
||||||
Range loc = db->id_cache.ResolveSpelling(cursor.cx_cursor);
|
Range loc = ResolveSpelling(cursor.cx_cursor);
|
||||||
UniqueAdd(ref_type_def->uses, loc);
|
UniqueAdd(ref_type_def->uses, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,7 +646,7 @@ clang::VisiterResult AddDeclInitializerUsagesVisitor(clang::Cursor cursor,
|
|||||||
if (ref_usr == "")
|
if (ref_usr == "")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Range loc = db->id_cache.ResolveSpelling(cursor.cx_cursor);
|
Range loc = ResolveSpelling(cursor.cx_cursor);
|
||||||
// std::cerr << "Adding usage to id=" << ref_id.id << " usr=" << ref_usr
|
// std::cerr << "Adding usage to id=" << ref_id.id << " usr=" << ref_usr
|
||||||
// << " at " << loc.ToString() << std::endl;
|
// << " at " << loc.ToString() << std::endl;
|
||||||
IndexVarId ref_id = db->ToVarId(ref_usr);
|
IndexVarId ref_id = db->ToVarId(ref_usr);
|
||||||
@ -726,7 +761,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
case CXIdxEntity_Field:
|
case CXIdxEntity_Field:
|
||||||
case CXIdxEntity_Variable:
|
case CXIdxEntity_Variable:
|
||||||
case CXIdxEntity_CXXStaticVariable: {
|
case CXIdxEntity_CXXStaticVariable: {
|
||||||
Range decl_loc_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
Range decl_loc_spelling = ResolveSpelling(decl->cursor);
|
||||||
|
|
||||||
clang::Cursor decl_cursor = decl->cursor;
|
clang::Cursor decl_cursor = decl->cursor;
|
||||||
|
|
||||||
@ -751,11 +786,11 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
if (decl->isDefinition) {
|
if (decl->isDefinition) {
|
||||||
var_def->def.definition_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
var_def->def.definition_spelling = ResolveSpelling(decl->cursor);
|
||||||
var_def->def.definition_extent = db->id_cache.ResolveExtent(decl->cursor);;
|
var_def->def.definition_extent = ResolveExtent(decl->cursor);;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var_def->def.declaration = db->id_cache.ResolveSpelling(decl->cursor);
|
var_def->def.declaration = ResolveSpelling(decl->cursor);
|
||||||
}
|
}
|
||||||
UniqueAdd(var_def->uses, decl_loc_spelling);
|
UniqueAdd(var_def->uses, decl_loc_spelling);
|
||||||
|
|
||||||
@ -806,7 +841,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
case CXIdxEntity_CXXInstanceMethod:
|
case CXIdxEntity_CXXInstanceMethod:
|
||||||
case CXIdxEntity_CXXStaticMethod:
|
case CXIdxEntity_CXXStaticMethod:
|
||||||
case CXIdxEntity_CXXConversionFunction: {
|
case CXIdxEntity_CXXConversionFunction: {
|
||||||
Range decl_loc_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
Range decl_loc_spelling = ResolveSpelling(decl->cursor);
|
||||||
|
|
||||||
clang::Cursor decl_cursor = decl->cursor;
|
clang::Cursor decl_cursor = decl->cursor;
|
||||||
clang::Cursor resolved =
|
clang::Cursor resolved =
|
||||||
@ -824,13 +859,13 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
// hacking the 'declarations' field by
|
// hacking the 'declarations' field by
|
||||||
// adding a definition when we really don't have one.
|
// adding a definition when we really don't have one.
|
||||||
if (decl->isDefinition && !func_def->def.definition_extent.has_value()) {
|
if (decl->isDefinition && !func_def->def.definition_extent.has_value()) {
|
||||||
func_def->def.definition_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
func_def->def.definition_spelling = ResolveSpelling(decl->cursor);
|
||||||
func_def->def.definition_extent = db->id_cache.ResolveExtent(decl->cursor);
|
func_def->def.definition_extent = ResolveExtent(decl->cursor);
|
||||||
|
|
||||||
RemoveItem(func_def->declarations, *func_def->def.definition_spelling);
|
RemoveItem(func_def->declarations, *func_def->def.definition_spelling);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Range decl_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
Range decl_spelling = ResolveSpelling(decl->cursor);
|
||||||
// Only add the declaration if it's not already a definition.
|
// Only add the declaration if it's not already a definition.
|
||||||
if (!func_def->def.definition_spelling || *func_def->def.definition_spelling != decl_spelling)
|
if (!func_def->def.definition_spelling || *func_def->def.definition_spelling != decl_spelling)
|
||||||
UniqueAdd(func_def->declarations, decl_spelling);
|
UniqueAdd(func_def->declarations, decl_spelling);
|
||||||
@ -962,7 +997,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
|
|
||||||
case CXIdxEntity_Typedef:
|
case CXIdxEntity_Typedef:
|
||||||
case CXIdxEntity_CXXTypeAlias: {
|
case CXIdxEntity_CXXTypeAlias: {
|
||||||
Range decl_loc_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
Range decl_loc_spelling = ResolveSpelling(decl->cursor);
|
||||||
|
|
||||||
// Note we want to fetch the first TypeRef. Running
|
// Note we want to fetch the first TypeRef. Running
|
||||||
// ResolveCursorType(decl->cursor) would return
|
// ResolveCursorType(decl->cursor) would return
|
||||||
@ -981,8 +1016,8 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
type_def->def.detailed_name =
|
type_def->def.detailed_name =
|
||||||
ns->QualifiedName(decl->semanticContainer, type_def->def.short_name);
|
ns->QualifiedName(decl->semanticContainer, type_def->def.short_name);
|
||||||
|
|
||||||
type_def->def.definition_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
type_def->def.definition_spelling = ResolveSpelling(decl->cursor);
|
||||||
type_def->def.definition_extent = db->id_cache.ResolveExtent(decl->cursor);
|
type_def->def.definition_extent = ResolveExtent(decl->cursor);
|
||||||
UniqueAdd(type_def->uses, decl_loc_spelling);
|
UniqueAdd(type_def->uses, decl_loc_spelling);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -991,7 +1026,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
case CXIdxEntity_Union:
|
case CXIdxEntity_Union:
|
||||||
case CXIdxEntity_Struct:
|
case CXIdxEntity_Struct:
|
||||||
case CXIdxEntity_CXXClass: {
|
case CXIdxEntity_CXXClass: {
|
||||||
Range decl_loc_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
Range decl_loc_spelling = ResolveSpelling(decl->cursor);
|
||||||
|
|
||||||
IndexTypeId type_id = db->ToTypeId(decl->entityInfo->USR);
|
IndexTypeId type_id = db->ToTypeId(decl->entityInfo->USR);
|
||||||
IndexedTypeDef* type_def = db->Resolve(type_id);
|
IndexedTypeDef* type_def = db->Resolve(type_id);
|
||||||
@ -1018,8 +1053,8 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
assert(decl->isDefinition);
|
assert(decl->isDefinition);
|
||||||
type_def->def.definition_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
type_def->def.definition_spelling = ResolveSpelling(decl->cursor);
|
||||||
type_def->def.definition_extent = db->id_cache.ResolveExtent(decl->cursor);
|
type_def->def.definition_extent = ResolveExtent(decl->cursor);
|
||||||
UniqueAdd(type_def->uses, decl_loc_spelling);
|
UniqueAdd(type_def->uses, decl_loc_spelling);
|
||||||
|
|
||||||
// type_def->alias_of
|
// type_def->alias_of
|
||||||
@ -1056,7 +1091,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
std::cerr
|
std::cerr
|
||||||
<< "!! Unhandled indexDeclaration: "
|
<< "!! Unhandled indexDeclaration: "
|
||||||
<< clang::Cursor(decl->cursor).ToString() << " at "
|
<< clang::Cursor(decl->cursor).ToString() << " at "
|
||||||
<< db->id_cache.ResolveSpelling(decl->cursor).start.ToString()
|
<< ResolveSpelling(decl->cursor).start.ToString()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
std::cerr << " entityInfo->kind = " << decl->entityInfo->kind
|
std::cerr << " entityInfo->kind = " << decl->entityInfo->kind
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
@ -1199,7 +1234,7 @@ void indexEntityReference(CXClientData client_data,
|
|||||||
case CXIdxEntity_CXXStaticVariable:
|
case CXIdxEntity_CXXStaticVariable:
|
||||||
case CXIdxEntity_Variable:
|
case CXIdxEntity_Variable:
|
||||||
case CXIdxEntity_Field: {
|
case CXIdxEntity_Field: {
|
||||||
Range loc_spelling = db->id_cache.ResolveSpelling(ref->cursor);
|
Range loc_spelling = ResolveSpelling(ref->cursor);
|
||||||
|
|
||||||
clang::Cursor referenced = ref->referencedEntity->cursor;
|
clang::Cursor referenced = ref->referencedEntity->cursor;
|
||||||
referenced = referenced.template_specialization_to_template_definition();
|
referenced = referenced.template_specialization_to_template_definition();
|
||||||
@ -1226,7 +1261,7 @@ void indexEntityReference(CXClientData client_data,
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// TODO: search full history?
|
// TODO: search full history?
|
||||||
Range loc_spelling = db->id_cache.ResolveSpelling(ref->cursor);
|
Range loc_spelling = ResolveSpelling(ref->cursor);
|
||||||
|
|
||||||
// Note: be careful, calling db->ToFuncId invalidates the FuncDef* ptrs.
|
// Note: be careful, calling db->ToFuncId invalidates the FuncDef* ptrs.
|
||||||
IndexFuncId called_id = db->ToFuncId(ref->referencedEntity->USR);
|
IndexFuncId called_id = db->ToFuncId(ref->referencedEntity->USR);
|
||||||
@ -1251,7 +1286,7 @@ void indexEntityReference(CXClientData client_data,
|
|||||||
case CXIdxEntity_Union:
|
case CXIdxEntity_Union:
|
||||||
case CXIdxEntity_Struct:
|
case CXIdxEntity_Struct:
|
||||||
case CXIdxEntity_CXXClass: {
|
case CXIdxEntity_CXXClass: {
|
||||||
Range loc_spelling = db->id_cache.ResolveSpelling(ref->cursor);
|
Range loc_spelling = ResolveSpelling(ref->cursor);
|
||||||
|
|
||||||
clang::Cursor referenced = ref->referencedEntity->cursor;
|
clang::Cursor referenced = ref->referencedEntity->cursor;
|
||||||
referenced = referenced.template_specialization_to_template_definition();
|
referenced = referenced.template_specialization_to_template_definition();
|
||||||
@ -1283,7 +1318,7 @@ void indexEntityReference(CXClientData client_data,
|
|||||||
std::cerr
|
std::cerr
|
||||||
<< "!! Unhandled indexEntityReference: " << cursor.ToString()
|
<< "!! Unhandled indexEntityReference: " << cursor.ToString()
|
||||||
<< " at "
|
<< " at "
|
||||||
<< db->id_cache.ResolveSpelling(ref->cursor).start.ToString()
|
<< ResolveSpelling(ref->cursor).start.ToString()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
std::cerr << " ref->referencedEntity->kind = "
|
std::cerr << " ref->referencedEntity->kind = "
|
||||||
<< ref->referencedEntity->kind << std::endl;
|
<< ref->referencedEntity->kind << std::endl;
|
||||||
@ -1292,7 +1327,7 @@ void indexEntityReference(CXClientData client_data,
|
|||||||
<< ref->parentEntity->kind << std::endl;
|
<< ref->parentEntity->kind << std::endl;
|
||||||
std::cerr
|
std::cerr
|
||||||
<< " ref->loc = "
|
<< " ref->loc = "
|
||||||
<< db->id_cache.ResolveSpelling(ref->cursor).start.ToString()
|
<< ResolveSpelling(ref->cursor).start.ToString()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
std::cerr << " ref->kind = " << ref->kind << std::endl;
|
std::cerr << " ref->kind = " << ref->kind << std::endl;
|
||||||
if (ref->parentEntity)
|
if (ref->parentEntity)
|
||||||
|
@ -453,10 +453,6 @@ struct IdCache {
|
|||||||
std::unordered_map<IndexVarId, std::string> var_id_to_usr;
|
std::unordered_map<IndexVarId, std::string> var_id_to_usr;
|
||||||
|
|
||||||
IdCache(const std::string& primary_file);
|
IdCache(const std::string& primary_file);
|
||||||
|
|
||||||
Range Resolve(const CXSourceRange& range);
|
|
||||||
Range ResolveSpelling(const CXCursor& cx_cursor);
|
|
||||||
Range ResolveExtent(const CXCursor& cx_cursor);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexedFile {
|
struct IndexedFile {
|
||||||
@ -478,6 +474,9 @@ struct IndexedFile {
|
|||||||
// The content of |path| when it was indexed.
|
// The content of |path| when it was indexed.
|
||||||
//std::string content;
|
//std::string content;
|
||||||
|
|
||||||
|
// Diagnostics found when indexing the file. This is not saved.
|
||||||
|
NonElidedVector<lsDiagnostic> diagnostics;
|
||||||
|
|
||||||
std::vector<std::string> dependencies;
|
std::vector<std::string> dependencies;
|
||||||
std::vector<IndexedTypeDef> types;
|
std::vector<IndexedTypeDef> types;
|
||||||
std::vector<IndexedFuncDef> funcs;
|
std::vector<IndexedFuncDef> funcs;
|
||||||
|
@ -20,6 +20,8 @@ const char* IpcIdToString(IpcId id) {
|
|||||||
return "textDocument/didClose";
|
return "textDocument/didClose";
|
||||||
case IpcId::TextDocumentDidSave:
|
case IpcId::TextDocumentDidSave:
|
||||||
return "textDocument/didSave";
|
return "textDocument/didSave";
|
||||||
|
case IpcId::TextDocumentPublishDiagnostics:
|
||||||
|
return "textDocument/publishDiagnostics";
|
||||||
case IpcId::TextDocumentRename:
|
case IpcId::TextDocumentRename:
|
||||||
return "textDocument/rename";
|
return "textDocument/rename";
|
||||||
case IpcId::TextDocumentCompletion:
|
case IpcId::TextDocumentCompletion:
|
||||||
|
@ -15,6 +15,7 @@ enum class IpcId : int {
|
|||||||
TextDocumentDidChange,
|
TextDocumentDidChange,
|
||||||
TextDocumentDidClose,
|
TextDocumentDidClose,
|
||||||
TextDocumentDidSave,
|
TextDocumentDidSave,
|
||||||
|
TextDocumentPublishDiagnostics,
|
||||||
TextDocumentRename,
|
TextDocumentRename,
|
||||||
TextDocumentCompletion,
|
TextDocumentCompletion,
|
||||||
TextDocumentDefinition,
|
TextDocumentDefinition,
|
||||||
|
@ -555,6 +555,39 @@ struct lsDocumentHighlight {
|
|||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind);
|
MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind);
|
||||||
|
|
||||||
|
enum class lsDiagnosticSeverity {
|
||||||
|
// Reports an error.
|
||||||
|
Error = 1,
|
||||||
|
// Reports a warning.
|
||||||
|
Warning = 2,
|
||||||
|
// Reports an information.
|
||||||
|
Information = 3,
|
||||||
|
// Reports a hint.
|
||||||
|
Hint = 4
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_TYPE_PROXY(lsDiagnosticSeverity, int);
|
||||||
|
|
||||||
|
struct lsDiagnostic {
|
||||||
|
// The range at which the message applies.
|
||||||
|
lsRange range;
|
||||||
|
|
||||||
|
// The diagnostic's severity. Can be omitted. If omitted it is up to the
|
||||||
|
// client to interpret diagnostics as error, warning, info or hint.
|
||||||
|
optional<lsDiagnosticSeverity> severity;
|
||||||
|
|
||||||
|
// The diagnostic's code. Can be omitted.
|
||||||
|
int code = 0;
|
||||||
|
|
||||||
|
// A human-readable string describing the source of this
|
||||||
|
// diagnostic, e.g. 'typescript' or 'super lint'.
|
||||||
|
std::string source = "cquery";
|
||||||
|
|
||||||
|
// The diagnostic's message.
|
||||||
|
std::string message;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(lsDiagnostic, range, severity, source, message);
|
||||||
|
|
||||||
|
|
||||||
// TODO: DocumentFilter
|
// TODO: DocumentFilter
|
||||||
// TODO: DocumentSelector
|
// TODO: DocumentSelector
|
||||||
|
|
||||||
@ -1162,6 +1195,31 @@ MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidSave, params);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Diagnostics
|
||||||
|
struct Out_TextDocumentPublishDiagnostics : public lsOutMessage<Out_TextDocumentPublishDiagnostics> {
|
||||||
|
struct Params {
|
||||||
|
// The URI for which diagnostic information is reported.
|
||||||
|
lsDocumentUri uri;
|
||||||
|
|
||||||
|
// An array of diagnostic information items.
|
||||||
|
NonElidedVector<lsDiagnostic> diagnostics;
|
||||||
|
};
|
||||||
|
|
||||||
|
Params params;
|
||||||
|
};
|
||||||
|
template<typename TVisitor>
|
||||||
|
void Reflect(TVisitor& visitor, Out_TextDocumentPublishDiagnostics& value) {
|
||||||
|
std::string method = "textDocument/publishDiagnostics";
|
||||||
|
REFLECT_MEMBER_START();
|
||||||
|
REFLECT_MEMBER(jsonrpc);
|
||||||
|
REFLECT_MEMBER2("method", method);
|
||||||
|
REFLECT_MEMBER(params);
|
||||||
|
REFLECT_MEMBER_END();
|
||||||
|
}
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentPublishDiagnostics::Params, uri, diagnostics);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Rename
|
// Rename
|
||||||
struct Ipc_TextDocumentRename : public IpcMessage<Ipc_TextDocumentRename> {
|
struct Ipc_TextDocumentRename : public IpcMessage<Ipc_TextDocumentRename> {
|
||||||
struct Params {
|
struct Params {
|
||||||
|
Loading…
Reference in New Issue
Block a user