diff --git a/clang-tools-extra/clangd/BuildSystem.h b/clang-tools-extra/clangd/BuildSystem.h new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clangd/BuildSystem.h @@ -0,0 +1,55 @@ +//===--- BuildSystem.h -------------------------------------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_BUILD_SYSTEM_H_ +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_BUILD_SYSTEM_H_ + +#include "Protocol.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include +#include +#include +#include + +namespace clang { +namespace clangd { + +class BuildSystem { +public: + virtual ~BuildSystem() = default; + + virtual llvm::Expected> + getOwningTarget(llvm::StringRef FilePath) const = 0; + + virtual llvm::Expected + addDependency(llvm::StringRef FromTarget, llvm::StringRef ToTarget) const = 0; +}; + +class BuildSystemPlugin { +public: + virtual ~BuildSystemPlugin() = default; + + virtual std::unique_ptr + createForDirectory(llvm::StringRef Dir) const = 0; +}; +using BuildSystemRegistry = llvm::Registry; + +class BuildSystemProvider { +public: + const BuildSystem *get(llvm::StringRef Path); + +private: + // Keyed by absolute paths. + // We can hand out pointers as they're stable and entries are never removed. + mutable llvm::StringMap> DirCaches; + mutable std::mutex DirCachesMutex; +}; +} // namespace clangd +} // namespace clang +#endif diff --git a/clang-tools-extra/clangd/BuildSystem.cpp b/clang-tools-extra/clangd/BuildSystem.cpp new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clangd/BuildSystem.cpp @@ -0,0 +1,43 @@ +//===--- BuildSystem.cpp -----------------------------------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include "BuildSystem.h" +#include "support/Path.h" +#include "llvm/ADT/StringRef.h" +#include +#include + +namespace clang { +namespace clangd { + +const BuildSystem *BuildSystemProvider::get(llvm::StringRef Path) { + std::vector SearchDirs; + actOnAllParentDirectories(Path, [&](PathRef Dir) { + SearchDirs.push_back(Dir); + return false; + }); + std::lock_guard Lock(DirCachesMutex); + for (PathRef Dir : SearchDirs) { + auto Entry = DirCaches.try_emplace(Dir, nullptr); + auto &Value = Entry.first->getValue(); + if (Entry.second) { + for (const auto &BSP : BuildSystemRegistry::entries()) { + Value = BSP.instantiate()->createForDirectory(Dir); + if (Value) + break; + } + } + if (Value) + return Value.get(); + } + return nullptr; +} + +} // namespace clangd +} // namespace clang + +LLVM_INSTANTIATE_REGISTRY(clang::clangd::BuildSystemRegistry); 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 @@ -47,6 +47,7 @@ add_clang_library(clangDaemon AST.cpp ASTSignals.cpp + BuildSystem.cpp ClangdLSPServer.cpp ClangdServer.cpp CodeComplete.cpp