mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-28 02:21:57 +00:00
Use DiagnosticRelatedInformation if client supports publishDiagnostics.relatedInformation (#276)
In clients that support DiagnosticRelatedInformation, display clang notes as these nested diagnostics rather than appending them to the parent diagnostic's message. Behaviour for clients that don't support related information should be unchanged.
This commit is contained in:
parent
ea774dadf5
commit
3a252fc0ad
@ -102,6 +102,8 @@ struct Config {
|
|||||||
} clang;
|
} clang;
|
||||||
|
|
||||||
struct ClientCapability {
|
struct ClientCapability {
|
||||||
|
// TextDocumentClientCapabilities.publishDiagnostics.relatedInformation
|
||||||
|
bool diagnosticsRelatedInformation = true;
|
||||||
// TextDocumentClientCapabilities.documentSymbol.hierarchicalDocumentSymbolSupport
|
// TextDocumentClientCapabilities.documentSymbol.hierarchicalDocumentSymbolSupport
|
||||||
bool hierarchicalDocumentSymbolSupport = true;
|
bool hierarchicalDocumentSymbolSupport = true;
|
||||||
// TextDocumentClientCapabilities.definition.linkSupport
|
// TextDocumentClientCapabilities.definition.linkSupport
|
||||||
@ -299,8 +301,8 @@ REFLECT_STRUCT(Config::ServerCap, documentOnTypeFormattingProvider,
|
|||||||
foldingRangeProvider, workspace);
|
foldingRangeProvider, workspace);
|
||||||
REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings,
|
REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings,
|
||||||
resourceDir);
|
resourceDir);
|
||||||
REFLECT_STRUCT(Config::ClientCapability, hierarchicalDocumentSymbolSupport,
|
REFLECT_STRUCT(Config::ClientCapability, diagnosticsRelatedInformation,
|
||||||
linkSupport, snippetSupport);
|
hierarchicalDocumentSymbolSupport, linkSupport, snippetSupport);
|
||||||
REFLECT_STRUCT(Config::CodeLens, localVariables);
|
REFLECT_STRUCT(Config::CodeLens, localVariables);
|
||||||
REFLECT_STRUCT(Config::Completion::Include, blacklist, maxPathSize,
|
REFLECT_STRUCT(Config::Completion::Include, blacklist, maxPathSize,
|
||||||
suffixWhitelist, whitelist);
|
suffixWhitelist, whitelist);
|
||||||
|
@ -238,12 +238,18 @@ struct WorkspaceFolder {
|
|||||||
enum class MessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 };
|
enum class MessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 };
|
||||||
REFLECT_UNDERLYING(MessageType)
|
REFLECT_UNDERLYING(MessageType)
|
||||||
|
|
||||||
|
struct DiagnosticRelatedInformation {
|
||||||
|
Location location;
|
||||||
|
std::string message;
|
||||||
|
};
|
||||||
|
|
||||||
struct Diagnostic {
|
struct Diagnostic {
|
||||||
lsRange range;
|
lsRange range;
|
||||||
int severity = 0;
|
int severity = 0;
|
||||||
int code = 0;
|
int code = 0;
|
||||||
std::string source = "ccls";
|
std::string source = "ccls";
|
||||||
std::string message;
|
std::string message;
|
||||||
|
std::vector<DiagnosticRelatedInformation> relatedInformation;
|
||||||
std::vector<TextEdit> fixits_;
|
std::vector<TextEdit> fixits_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -195,7 +195,8 @@ REFLECT_STRUCT(TextDocumentIdentifier, uri);
|
|||||||
REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text);
|
REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text);
|
||||||
REFLECT_STRUCT(TextEdit, range, newText);
|
REFLECT_STRUCT(TextEdit, range, newText);
|
||||||
REFLECT_STRUCT(VersionedTextDocumentIdentifier, uri, version);
|
REFLECT_STRUCT(VersionedTextDocumentIdentifier, uri, version);
|
||||||
REFLECT_STRUCT(Diagnostic, range, severity, code, source, message);
|
REFLECT_STRUCT(DiagnosticRelatedInformation, location, message);
|
||||||
|
REFLECT_STRUCT(Diagnostic, range, severity, code, source, message, relatedInformation);
|
||||||
REFLECT_STRUCT(ShowMessageParam, type, message);
|
REFLECT_STRUCT(ShowMessageParam, type, message);
|
||||||
REFLECT_UNDERLYING_B(LanguageId);
|
REFLECT_UNDERLYING_B(LanguageId);
|
||||||
|
|
||||||
|
@ -171,6 +171,10 @@ struct TextDocumentClientCap {
|
|||||||
struct DocumentSymbol {
|
struct DocumentSymbol {
|
||||||
bool hierarchicalDocumentSymbolSupport = false;
|
bool hierarchicalDocumentSymbolSupport = false;
|
||||||
} documentSymbol;
|
} documentSymbol;
|
||||||
|
|
||||||
|
struct PublishDiagnostics {
|
||||||
|
bool relatedInformation = false;
|
||||||
|
} publishDiagnostics;
|
||||||
};
|
};
|
||||||
|
|
||||||
REFLECT_STRUCT(TextDocumentClientCap::Completion::CompletionItem,
|
REFLECT_STRUCT(TextDocumentClientCap::Completion::CompletionItem,
|
||||||
@ -179,7 +183,8 @@ REFLECT_STRUCT(TextDocumentClientCap::Completion, completionItem);
|
|||||||
REFLECT_STRUCT(TextDocumentClientCap::DocumentSymbol,
|
REFLECT_STRUCT(TextDocumentClientCap::DocumentSymbol,
|
||||||
hierarchicalDocumentSymbolSupport);
|
hierarchicalDocumentSymbolSupport);
|
||||||
REFLECT_STRUCT(TextDocumentClientCap::LinkSupport, linkSupport);
|
REFLECT_STRUCT(TextDocumentClientCap::LinkSupport, linkSupport);
|
||||||
REFLECT_STRUCT(TextDocumentClientCap, completion, definition, documentSymbol);
|
REFLECT_STRUCT(TextDocumentClientCap::PublishDiagnostics, relatedInformation);
|
||||||
|
REFLECT_STRUCT(TextDocumentClientCap, completion, definition, documentSymbol, publishDiagnostics);
|
||||||
|
|
||||||
struct ClientCap {
|
struct ClientCap {
|
||||||
WorkspaceClientCap workspace;
|
WorkspaceClientCap workspace;
|
||||||
@ -306,6 +311,8 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) {
|
|||||||
capabilities.textDocument.definition.linkSupport;
|
capabilities.textDocument.definition.linkSupport;
|
||||||
g_config->client.snippetSupport &=
|
g_config->client.snippetSupport &=
|
||||||
capabilities.textDocument.completion.completionItem.snippetSupport;
|
capabilities.textDocument.completion.completionItem.snippetSupport;
|
||||||
|
g_config->client.diagnosticsRelatedInformation &=
|
||||||
|
capabilities.textDocument.publishDiagnostics.relatedInformation;
|
||||||
didChangeWatchedFiles =
|
didChangeWatchedFiles =
|
||||||
capabilities.workspace.didChangeWatchedFiles.dynamicRegistration;
|
capabilities.workspace.didChangeWatchedFiles.dynamicRegistration;
|
||||||
|
|
||||||
|
@ -514,7 +514,7 @@ llvm::StringRef diagLeveltoString(DiagnosticsEngine::Level Lvl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printDiag(llvm::raw_string_ostream &OS, const DiagBase &d) {
|
void PrintDiag(llvm::raw_string_ostream &OS, const DiagBase &d) {
|
||||||
if (d.concerned)
|
if (d.concerned)
|
||||||
OS << llvm::sys::path::filename(d.file);
|
OS << llvm::sys::path::filename(d.file);
|
||||||
else
|
else
|
||||||
@ -612,29 +612,42 @@ void *DiagnosticMain(void *manager_) {
|
|||||||
for (auto &d : diags) {
|
for (auto &d : diags) {
|
||||||
if (!d.concerned)
|
if (!d.concerned)
|
||||||
continue;
|
continue;
|
||||||
std::string buf;
|
|
||||||
llvm::raw_string_ostream OS(buf);
|
|
||||||
Diagnostic &ls_diag = ls_diags.emplace_back();
|
Diagnostic &ls_diag = ls_diags.emplace_back();
|
||||||
Fill(d, ls_diag);
|
Fill(d, ls_diag);
|
||||||
ls_diag.fixits_ = d.edits;
|
ls_diag.fixits_ = d.edits;
|
||||||
|
if (g_config->client.diagnosticsRelatedInformation) {
|
||||||
|
ls_diag.message = d.message;
|
||||||
|
for (const Note &n : d.notes) {
|
||||||
|
SmallString<256> Str(n.file);
|
||||||
|
llvm::sys::path::remove_dots(Str, true);
|
||||||
|
Location loc{DocumentUri::FromPath(Str.str()),
|
||||||
|
lsRange{{n.range.start.line, n.range.start.column},
|
||||||
|
{n.range.end.line, n.range.end.column}}};
|
||||||
|
ls_diag.relatedInformation.push_back({loc, n.message});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::string buf;
|
||||||
|
llvm::raw_string_ostream OS(buf);
|
||||||
OS << d.message;
|
OS << d.message;
|
||||||
for (auto &n : d.notes) {
|
for (const Note &n : d.notes) {
|
||||||
OS << "\n\n";
|
OS << "\n\n";
|
||||||
printDiag(OS, n);
|
PrintDiag(OS, n);
|
||||||
}
|
}
|
||||||
OS.flush();
|
OS.flush();
|
||||||
ls_diag.message = std::move(buf);
|
ls_diag.message = std::move(buf);
|
||||||
for (auto &n : d.notes) {
|
for (const Note &n : d.notes) {
|
||||||
if (!n.concerned)
|
if (!n.concerned)
|
||||||
continue;
|
continue;
|
||||||
Diagnostic &ls_diag1 = ls_diags.emplace_back();
|
Diagnostic &ls_diag1 = ls_diags.emplace_back();
|
||||||
Fill(n, ls_diag1);
|
Fill(n, ls_diag1);
|
||||||
|
buf.clear();
|
||||||
OS << n.message << "\n\n";
|
OS << n.message << "\n\n";
|
||||||
printDiag(OS, d);
|
PrintDiag(OS, d);
|
||||||
OS.flush();
|
OS.flush();
|
||||||
ls_diag1.message = std::move(buf);
|
ls_diag1.message = std::move(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard lock(manager->wfiles->mutex);
|
std::lock_guard lock(manager->wfiles->mutex);
|
||||||
|
Loading…
Reference in New Issue
Block a user