Line data Source code
1 : //===--- Diagnostics.h -------------------------------------------*- C++-*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_DIAGNOSTICS_H
11 : #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_DIAGNOSTICS_H
12 :
13 : #include "Path.h"
14 : #include "Protocol.h"
15 : #include "clang/Basic/Diagnostic.h"
16 : #include "clang/Basic/LangOptions.h"
17 : #include "llvm/ADT/ArrayRef.h"
18 : #include "llvm/ADT/STLExtras.h"
19 : #include "llvm/ADT/StringSet.h"
20 : #include <cassert>
21 : #include <string>
22 :
23 : namespace clang {
24 : namespace clangd {
25 :
26 : struct ClangdDiagnosticOptions {
27 : /// If true, Clangd uses an LSP extension to embed the fixes with the
28 : /// diagnostics that are sent to the client.
29 : bool EmbedFixesInDiagnostics = false;
30 :
31 : /// If true, Clangd uses an LSP extension to send the diagnostic's
32 : /// category to the client. The category typically describes the compilation
33 : /// stage during which the issue was produced, e.g. "Semantic Issue" or "Parse
34 : /// Issue".
35 : bool SendDiagnosticCategory = false;
36 : };
37 :
38 : /// Contains basic information about a diagnostic.
39 0 : struct DiagBase {
40 : std::string Message;
41 : // Intended to be used only in error messages.
42 : // May be relative, absolute or even artifically constructed.
43 : std::string File;
44 : clangd::Range Range;
45 : DiagnosticsEngine::Level Severity = DiagnosticsEngine::Note;
46 : std::string Category;
47 : // Since File is only descriptive, we store a separate flag to distinguish
48 : // diags from the main file.
49 : bool InsideMainFile = false;
50 : };
51 : llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const DiagBase &D);
52 :
53 : /// Represents a single fix-it that editor can apply to fix the error.
54 : struct Fix {
55 : /// Message for the fix-it.
56 : std::string Message;
57 : /// TextEdits from clang's fix-its. Must be non-empty.
58 : llvm::SmallVector<TextEdit, 1> Edits;
59 : };
60 : llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Fix &F);
61 :
62 : /// Represents a note for the diagnostic. Severity of notes can only be 'note'
63 : /// or 'remark'.
64 0 : struct Note : DiagBase {};
65 :
66 : /// A top-level diagnostic that may have Notes and Fixes.
67 : struct Diag : DiagBase {
68 : /// Elaborate on the problem, usually pointing to a related piece of code.
69 : std::vector<Note> Notes;
70 : /// *Alternative* fixes for this diagnostic, one should be chosen.
71 : std::vector<Fix> Fixes;
72 : };
73 : llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Diag &D);
74 :
75 : /// Conversion to LSP diagnostics. Formats the error message of each diagnostic
76 : /// to include all its notes. Notes inside main file are also provided as
77 : /// separate diagnostics with their corresponding fixits. Notes outside main
78 : /// file do not have a corresponding LSP diagnostic, but can still be included
79 : /// as part of their main diagnostic's message.
80 : void toLSPDiags(
81 : const Diag &D,
82 : llvm::function_ref<void(clangd::Diagnostic, llvm::ArrayRef<Fix>)> OutFn);
83 :
84 : /// Convert from clang diagnostic level to LSP severity.
85 : int getSeverity(DiagnosticsEngine::Level L);
86 :
87 : /// StoreDiags collects the diagnostics that can later be reported by
88 : /// clangd. It groups all notes for a diagnostic into a single Diag
89 : /// and filters out diagnostics that don't mention the main file (i.e. neither
90 : /// the diag itself nor its notes are in the main file).
91 : class StoreDiags : public DiagnosticConsumer {
92 : public:
93 : std::vector<Diag> take();
94 :
95 : void BeginSourceFile(const LangOptions &Opts, const Preprocessor *) override;
96 : void EndSourceFile() override;
97 : void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
98 : const clang::Diagnostic &Info) override;
99 :
100 : private:
101 : void flushLastDiag();
102 :
103 : std::vector<Diag> Output;
104 : llvm::Optional<LangOptions> LangOpts;
105 : llvm::Optional<Diag> LastDiag;
106 : };
107 :
108 : } // namespace clangd
109 : } // namespace clang
110 :
111 : #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_DIAGNOSTICS_H
|