diff --git a/clang-tools-extra/clangd/CMakeLists.txt b/clang-tools-extra/clangd/CMakeLists.txt --- a/clang-tools-extra/clangd/CMakeLists.txt +++ b/clang-tools-extra/clangd/CMakeLists.txt @@ -75,6 +75,7 @@ IncludeFixer.cpp JSONTransport.cpp PathMapping.cpp + Plugin.cpp Protocol.cpp Quality.cpp ParsedAST.cpp diff --git a/clang-tools-extra/clangd/Plugin.h b/clang-tools-extra/clangd/Plugin.h new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clangd/Plugin.h @@ -0,0 +1,38 @@ +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PLUGIN_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PLUGIN_H +#include "Diagnostics.h" +#include "support/Path.h" +#include "clang/Basic/Diagnostic.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Registry.h" +#include + +namespace clang { +namespace clangd { + +/// Plugins enable augmenting clangd's behaviour in various places. +class Plugin { +public: + virtual ~Plugin() = default; + + /// Identifier for the plugin, should be unique. + virtual llvm::StringLiteral id() = 0; + + /// Returns an action that can be invoked to fix the diagnostic. + virtual llvm::Optional + actOnDiagnostic(DiagnosticsEngine::Level L, const clang::Diagnostic &Diag) { + return llvm::None; + } + + /// Convenience helper to collect fixes from all the plugins. + static std::vector collectFixes(DiagnosticsEngine::Level L, + const clang::Diagnostic &Diag); +}; +using PluginRegistry = llvm::Registry; + +} // namespace clangd +} // namespace clang +#endif diff --git a/clang-tools-extra/clangd/Plugin.cpp b/clang-tools-extra/clangd/Plugin.cpp new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clangd/Plugin.cpp @@ -0,0 +1,24 @@ +#include "Plugin.h" +#include "Diagnostics.h" +#include "Protocol.h" +#include "clang/Basic/Diagnostic.h" +#include "llvm/Support/Registry.h" +#include +#include + +namespace clang { +namespace clangd { + +std::vector Plugin::collectFixes(DiagnosticsEngine::Level L, + const clang::Diagnostic &Diag) { + std::vector Actions; + for (const auto &Entry : PluginRegistry::entries()) { + if (auto Action = Entry.instantiate()->actOnDiagnostic(L, Diag)) + Actions.emplace_back(std::move(*Action)); + } + return Actions; +} +} // namespace clangd +} // namespace clang + +LLVM_INSTANTIATE_REGISTRY(clang::clangd::PluginRegistry);