Author: hokein Date: Tue Jan 22 01:39:05 2019 New Revision: 351792 URL: http://llvm.org/viewvc/llvm-project?rev=351792&view=rev Log: [clangd] Support clang-tidy configuration in clangd.
Summary: This patch adds some basic supports for clang-tidy configurations in clangd: - clangd will respect .clang-tidy configurations for each file - we don't aim to support all clang-tidy options in clangd, only a small subset of condfigurations (options related to which checks will be enabled) are supported. - add a `clang-tidy-checks` CLI option that can override options from .clang-tidy file Reviewers: ilya-biryukov, sammccall Reviewed By: sammccall Subscribers: javed.absar, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D55256 Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp clang-tools-extra/trunk/clangd/ClangdLSPServer.h clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/clangd/ClangdUnit.cpp clang-tools-extra/trunk/clangd/ClangdUnit.h clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp clang-tools-extra/trunk/unittests/clangd/ClangdUnitTests.cpp clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp clang-tools-extra/trunk/unittests/clangd/TestTU.cpp clang-tools-extra/trunk/unittests/clangd/TestTU.h Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=351792&r1=351791&r2=351792&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Tue Jan 22 01:39:05 2019 @@ -720,11 +720,13 @@ void ClangdLSPServer::onSymbolInfo(const } ClangdLSPServer::ClangdLSPServer(class Transport &Transp, + const FileSystemProvider &FSProvider, const clangd::CodeCompleteOptions &CCOpts, llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB, const ClangdServer::Options &Opts) - : Transp(Transp), MsgHandler(new MessageHandler(*this)), CCOpts(CCOpts), + : Transp(Transp), MsgHandler(new MessageHandler(*this)), + FSProvider(FSProvider), CCOpts(CCOpts), SupportedSymbolKinds(defaultSymbolKinds()), SupportedCompletionItemKinds(defaultCompletionItemKinds()), UseDirBasedCDB(UseDirBasedCDB), Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.h?rev=351792&r1=351791&r2=351792&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdLSPServer.h (original) +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.h Tue Jan 22 01:39:05 2019 @@ -37,7 +37,8 @@ public: /// for compile_commands.json in all parent directories of each file. /// If UseDirBasedCDB is false, compile commands are not read from disk. // FIXME: Clean up signature around CDBs. - ClangdLSPServer(Transport &Transp, const clangd::CodeCompleteOptions &CCOpts, + ClangdLSPServer(Transport &Transp, const FileSystemProvider &FSProvider, + const clangd::CodeCompleteOptions &CCOpts, llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB, const ClangdServer::Options &Opts); ~ClangdLSPServer(); @@ -128,7 +129,7 @@ private: void call(StringRef Method, llvm::json::Value Params); void notify(StringRef Method, llvm::json::Value Params); - RealFileSystemProvider FSProvider; + const FileSystemProvider &FSProvider; /// Options used for code completion clangd::CodeCompleteOptions CCOpts; /// Options used for diagnostics. Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=351792&r1=351791&r2=351792&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Tue Jan 22 01:39:05 2019 @@ -105,6 +105,7 @@ ClangdServer::ClangdServer(const GlobalC DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex(Opts.HeavyweightDynamicSymbolIndex) : nullptr), + ClangTidyOptProvider(Opts.ClangTidyOptProvider), WorkspaceRoot(Opts.WorkspaceRoot), PCHs(std::make_shared<PCHContainerOperations>()), // Pass a callback into `WorkScheduler` to extract symbols from a newly @@ -140,13 +141,16 @@ ClangdServer::ClangdServer(const GlobalC void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents, WantDiagnostics WantDiags) { + tidy::ClangTidyOptions Options = tidy::ClangTidyOptions::getDefaults(); + if (ClangTidyOptProvider) + Options = ClangTidyOptProvider->getOptions(File); // FIXME: some build systems like Bazel will take time to preparing // environment to build the file, it would be nice if we could emit a // "PreparingBuild" status to inform users, it is non-trivial given the // current implementation. - WorkScheduler.update(File, - ParseInputs{getCompileCommand(File), - FSProvider.getFileSystem(), Contents.str()}, + WorkScheduler.update(File, ParseInputs{getCompileCommand(File), + FSProvider.getFileSystem(), + Contents.str(), Options}, WantDiags); } Modified: clang-tools-extra/trunk/clangd/ClangdServer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=351792&r1=351791&r2=351792&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdServer.h (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.h Tue Jan 22 01:39:05 2019 @@ -9,6 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDSERVER_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDSERVER_H +#include "../clang-tidy/ClangTidyOptions.h" #include "Cancellation.h" #include "ClangdUnit.h" #include "CodeComplete.h" @@ -92,6 +93,13 @@ public: /// If set, use this index to augment code completion results. SymbolIndex *StaticIndex = nullptr; + /// If set, enable clang-tidy in clangd, used to get clang-tidy + /// configurations for a particular file. + /// Clangd supports only a small subset of ClangTidyOptions, these options + /// (Checks, CheckOptions) are about which clang-tidy checks will be + /// enabled. + tidy::ClangTidyOptionsProvider *ClangTidyOptProvider = nullptr; + /// Clangd's workspace root. Relevant for "workspace" operations not bound /// to a particular file. /// FIXME: If not set, should use the current working directory. @@ -257,6 +265,9 @@ private: // Storage for merged views of the various indexes. std::vector<std::unique_ptr<SymbolIndex>> MergedIdx; + // The provider used to provide a clang-tidy option for a specific file. + tidy::ClangTidyOptionsProvider *ClangTidyOptProvider = nullptr; + // GUARDED_BY(CachedCompletionFuzzyFindRequestMutex) llvm::StringMap<llvm::Optional<FuzzyFindRequest>> CachedCompletionFuzzyFindRequestByFile; Modified: clang-tools-extra/trunk/clangd/ClangdUnit.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.cpp?rev=351792&r1=351791&r2=351792&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdUnit.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdUnit.cpp Tue Jan 22 01:39:05 2019 @@ -132,6 +132,9 @@ public: CompilerInstance &Clang) { auto &PP = Clang.getPreprocessor(); auto *ExistingCallbacks = PP.getPPCallbacks(); + // No need to replay events if nobody is listening. + if (!ExistingCallbacks) + return; PP.addPPCallbacks(std::unique_ptr<PPCallbacks>( new ReplayPreamble(Includes, ExistingCallbacks, Clang.getSourceManager(), PP, Clang.getLangOpts()))); @@ -227,7 +230,8 @@ ParsedAST::build(std::unique_ptr<Compile std::shared_ptr<const PreambleData> Preamble, std::unique_ptr<llvm::MemoryBuffer> Buffer, std::shared_ptr<PCHContainerOperations> PCHs, - llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, + const tidy::ClangTidyOptions &ClangTidyOpts) { assert(CI); // Command-line parsing sets DisableFree to true by default, but we don't want // to leak memory in clangd. @@ -264,15 +268,8 @@ ParsedAST::build(std::unique_ptr<Compile tidy::ClangTidyCheckFactories CTFactories; for (const auto &E : tidy::ClangTidyModuleRegistry::entries()) E.instantiate()->addCheckFactories(CTFactories); - auto CTOpts = tidy::ClangTidyOptions::getDefaults(); - // FIXME: this needs to be configurable, and we need to support .clang-tidy - // files and other options providers. - // These checks exercise the matcher- and preprocessor-based hooks. - CTOpts.Checks = "bugprone-sizeof-expression," - "bugprone-macro-repeated-side-effects," - "modernize-deprecated-headers"; CTContext.emplace(llvm::make_unique<tidy::DefaultOptionsProvider>( - tidy::ClangTidyGlobalOptions(), CTOpts)); + tidy::ClangTidyGlobalOptions(), ClangTidyOpts)); CTContext->setDiagnosticsEngine(&Clang->getDiagnostics()); CTContext->setASTContext(&Clang->getASTContext()); CTContext->setCurrentFile(MainInput.getFile()); @@ -538,7 +535,7 @@ buildAST(PathRef FileName, std::unique_p return ParsedAST::build(llvm::make_unique<CompilerInvocation>(*Invocation), Preamble, llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents), - PCHs, std::move(VFS)); + PCHs, std::move(VFS), Inputs.ClangTidyOpts); } SourceLocation getBeginningOfIdentifier(ParsedAST &Unit, const Position &Pos, Modified: clang-tools-extra/trunk/clangd/ClangdUnit.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.h?rev=351792&r1=351791&r2=351792&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdUnit.h (original) +++ clang-tools-extra/trunk/clangd/ClangdUnit.h Tue Jan 22 01:39:05 2019 @@ -9,6 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H +#include "../clang-tidy/ClangTidyOptions.h" #include "Diagnostics.h" #include "FS.h" #include "Function.h" @@ -64,6 +65,7 @@ struct ParseInputs { tooling::CompileCommand CompileCommand; IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; std::string Contents; + tidy::ClangTidyOptions ClangTidyOpts; }; /// Stores and provides access to parsed AST. @@ -76,7 +78,8 @@ public: std::shared_ptr<const PreambleData> Preamble, std::unique_ptr<llvm::MemoryBuffer> Buffer, std::shared_ptr<PCHContainerOperations> PCHs, - IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS); + IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, + const tidy::ClangTidyOptions &ClangTidyOpts); ParsedAST(ParsedAST &&Other); ParsedAST &operator=(ParsedAST &&Other); Modified: clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp?rev=351792&r1=351791&r2=351792&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp (original) +++ clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp Tue Jan 22 01:39:05 2019 @@ -201,6 +201,12 @@ static llvm::cl::opt<bool> EnableFunctio "placeholders for method parameters."), llvm::cl::init(CodeCompleteOptions().EnableFunctionArgSnippets)); +static llvm::cl::opt<std::string> ClangTidyChecks( + "clang-tidy-checks", + llvm::cl::desc("List of clang-tidy checks to run (this will overrides " + ".clang-tidy files)"), + llvm::cl::init(""), llvm::cl::Hidden); + namespace { /// \brief Supports a test URI scheme with relaxed constraints for lit tests. @@ -408,6 +414,7 @@ int main(int argc, char *argv[]) { CCOpts.EnableFunctionArgSnippets = EnableFunctionArgSnippets; CCOpts.AllScopes = AllScopesCompletion; + RealFileSystemProvider FSProvider; // Initialize and run ClangdLSPServer. // Change stdin to binary to not lose \r\n on windows. llvm::sys::ChangeStdinToBinary(); @@ -427,8 +434,16 @@ int main(int argc, char *argv[]) { PrettyPrint, InputStyle); } + // Create an empty clang-tidy option. + auto OverrideClangTidyOptions = tidy::ClangTidyOptions::getDefaults(); + OverrideClangTidyOptions.Checks = ClangTidyChecks; + tidy::FileOptionsProvider ClangTidyOptProvider( + tidy::ClangTidyGlobalOptions(), + /* Default */ tidy::ClangTidyOptions::getDefaults(), + /* Override */ OverrideClangTidyOptions, FSProvider.getFileSystem()); + Opts.ClangTidyOptProvider = &ClangTidyOptProvider; ClangdLSPServer LSPServer( - *TransportLayer, CCOpts, CompileCommandsDirPath, + *TransportLayer, FSProvider, CCOpts, CompileCommandsDirPath, /*UseDirBasedCDB=*/CompileArgsFrom == FilesystemCompileArgs, Opts); llvm::set_thread_name("clangd.main"); return LSPServer.run() ? 0 Modified: clang-tools-extra/trunk/unittests/clangd/ClangdUnitTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdUnitTests.cpp?rev=351792&r1=351791&r2=351792&view=diff ============================================================================== --- clang-tools-extra/trunk/unittests/clangd/ClangdUnitTests.cpp (original) +++ clang-tools-extra/trunk/unittests/clangd/ClangdUnitTests.cpp Tue Jan 22 01:39:05 2019 @@ -141,6 +141,9 @@ TEST(DiagnosticsTest, ClangTidy) { )cpp"); auto TU = TestTU::withCode(Test.code()); TU.HeaderFilename = "assert.h"; // Suppress "not found" error. + TU.ClangTidyChecks = + "-*, bugprone-sizeof-expression, bugprone-macro-repeated-side-effects, " + "modernize-deprecated-headers"; EXPECT_THAT( TU.build().getDiagnostics(), UnorderedElementsAre( Modified: clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp?rev=351792&r1=351791&r2=351792&view=diff ============================================================================== --- clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp (original) +++ clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp Tue Jan 22 01:39:05 2019 @@ -363,7 +363,8 @@ TEST(FileIndexTest, ReferencesInMainFile auto AST = ParsedAST::build(createInvocationFromCommandLine(Cmd), PreambleData, llvm::MemoryBuffer::getMemBufferCopy(Main.code()), - std::make_shared<PCHContainerOperations>(), PI.FS); + std::make_shared<PCHContainerOperations>(), PI.FS, + tidy::ClangTidyOptions::getDefaults()); ASSERT_TRUE(AST); FileIndex Index; Index.updateMain(MainFile, *AST); Modified: clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp?rev=351792&r1=351791&r2=351792&view=diff ============================================================================== --- clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp (original) +++ clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp Tue Jan 22 01:39:05 2019 @@ -38,7 +38,8 @@ class TUSchedulerTests : public ::testin protected: ParseInputs getInputs(PathRef File, std::string Contents) { return ParseInputs{*CDB.getCompileCommand(File), - buildTestFS(Files, Timestamps), std::move(Contents)}; + buildTestFS(Files, Timestamps), std::move(Contents), + tidy::ClangTidyOptions::getDefaults()}; } void updateWithCallback(TUScheduler &S, PathRef File, Modified: clang-tools-extra/trunk/unittests/clangd/TestTU.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/TestTU.cpp?rev=351792&r1=351791&r2=351792&view=diff ============================================================================== --- clang-tools-extra/trunk/unittests/clangd/TestTU.cpp (original) +++ clang-tools-extra/trunk/unittests/clangd/TestTU.cpp Tue Jan 22 01:39:05 2019 @@ -35,6 +35,8 @@ ParsedAST TestTU::build() const { Inputs.CompileCommand.Directory = testRoot(); Inputs.Contents = Code; Inputs.FS = buildTestFS({{FullFilename, Code}, {FullHeaderName, HeaderCode}}); + Inputs.ClangTidyOpts = tidy::ClangTidyOptions::getDefaults(); + Inputs.ClangTidyOpts.Checks = ClangTidyChecks; auto PCHs = std::make_shared<PCHContainerOperations>(); auto CI = buildCompilerInvocation(Inputs); assert(CI && "Failed to build compilation invocation."); Modified: clang-tools-extra/trunk/unittests/clangd/TestTU.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/TestTU.h?rev=351792&r1=351791&r2=351792&view=diff ============================================================================== --- clang-tools-extra/trunk/unittests/clangd/TestTU.h (original) +++ clang-tools-extra/trunk/unittests/clangd/TestTU.h Tue Jan 22 01:39:05 2019 @@ -48,6 +48,8 @@ struct TestTU { // Extra arguments for the compiler invocation. std::vector<const char *> ExtraArgs; + llvm::Optional<std::string> ClangTidyChecks; + ParsedAST build() const; SymbolSlab headerSymbols() const; std::unique_ptr<SymbolIndex> index() const; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits