Nebiroth updated this revision to Diff 113895.
Nebiroth added a comment.
Added function to avoid code reuse and extra nesting.
https://reviews.llvm.org/D37150
Files:
clangd/ClangdLSPServer.cpp
clangd/ClangdLSPServer.h
clangd/ClangdServer.cpp
clangd/ClangdServer.h
clangd/GlobalCompilationDatabase.cpp
clangd/GlobalCompilationDatabase.h
clangd/tool/ClangdMain.cpp
test/clangd/hover.test
Index: test/clangd/hover.test
===================================================================
--- /dev/null
+++ test/clangd/hover.test
@@ -0,0 +1,26 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 172
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"int main() {\nint a;\na;\n}\n"}}}
+
+Content-Length: 143
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":0,"character":5}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":{"contents": {"language": "C++", "value": "int main() {\nint a;\na;\n}"}, "range": {"start": {"line": 0, "character": 0}, "end": {"line": 3, "character": 1}}}}
+
+Content-Length: 143
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":1,"character":5}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":{"contents": {"language": "C++", "value": "int a"}, "range": {"start": {"line": 1, "character": 0}, "end": {"line": 1, "character": 5}}}}
+
+Content-Length: 44
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
Index: clangd/tool/ClangdMain.cpp
===================================================================
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -12,6 +12,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Program.h"
+#include "llvm/Support/Path.h"
#include <iostream>
#include <memory>
@@ -25,16 +26,29 @@
llvm::cl::desc("parse on main thread"),
llvm::cl::init(false), llvm::cl::Hidden);
+static llvm::cl::opt<std::string>
+ CompileCommands("compile-commands-dir",
+ llvm::cl::desc("Specify a path to look for compile_commands.json. If path is invalid, clangd will look in the current directory and parent paths of each source file."));
+
+
int main(int argc, char *argv[]) {
llvm::cl::ParseCommandLineOptions(argc, argv, "clangd");
llvm::raw_ostream &Outs = llvm::outs();
llvm::raw_ostream &Logs = llvm::errs();
JSONOutput Out(Outs, Logs);
+ // If --compileCommands arg was invoked, check value and override default path.
+ namespace path = llvm::sys::path;
+ if (!llvm::sys::path::is_absolute(CompileCommands) || CompileCommands.empty())
+ Logs << "Path specified for compilation database must be absolute. Verifying current folder instead.";
+
+ if (!llvm::sys::fs::exists(CompileCommands))
+ Logs << "File does not exist. Verifying current folder instead.";
+
// Change stdin to binary to not lose \r\n on windows.
llvm::sys::ChangeStdinToBinary();
- ClangdLSPServer LSPServer(Out, RunSynchronously);
+ ClangdLSPServer LSPServer(Out, RunSynchronously, CompileCommands);
LSPServer.run(std::cin);
}
Index: clangd/GlobalCompilationDatabase.h
===================================================================
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -33,8 +33,9 @@
public:
virtual ~GlobalCompilationDatabase() = default;
- virtual std::vector<tooling::CompileCommand>
+ virtual std::vector<tooling::CompileCommand>
getCompileCommands(PathRef File) = 0;
+ std::string CompileCommands;
/// FIXME(ibiryukov): add facilities to track changes to compilation flags of
/// existing targets.
@@ -49,6 +50,7 @@
getCompileCommands(PathRef File) override;
void setExtraFlagsForFile(PathRef File, std::vector<std::string> ExtraFlags);
+ tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File, std::string &Error);
private:
tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
Index: clangd/GlobalCompilationDatabase.cpp
===================================================================
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -11,6 +11,16 @@
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/YAMLTraits.h"
namespace clang {
namespace clangd {
@@ -61,37 +71,44 @@
ExtraFlagsForFile[File] = std::move(ExtraFlags);
}
+tooling::CompilationDatabase * DirectoryBasedGlobalCompilationDatabase::tryLoadDatabaseFromPath(PathRef File, std::string &Error)
+{
+ auto CachedIt = CompilationDatabases.find(File);
+ if (CachedIt != CompilationDatabases.end())
+ return (CachedIt->second.get());
+ auto CDB = tooling::CompilationDatabase::loadFromDirectory(File, Error);
+ if (CDB && Error.empty())
+ {
+ auto result = CDB.get();
+ CompilationDatabases.insert(std::make_pair(File, std::move(CDB)));
+ return result;
+ }
+ return nullptr;
+}
+
tooling::CompilationDatabase *
DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
std::lock_guard<std::mutex> Lock(Mutex);
-
- namespace path = llvm::sys::path;
-
- assert((path::is_absolute(File, path::Style::posix) ||
- path::is_absolute(File, path::Style::windows)) &&
- "path must be absolute");
+ namespace path = llvm::sys::path;
+ if (llvm::sys::fs::exists(CompileCommands))
+ File = CompileCommands;
+
+ std::string Error;
+ File = path::parent_path(File);
+ auto CDB = tryLoadDatabaseFromPath(File, Error);
+
+ if (CDB && Error.empty())
+ return CDB;
for (auto Path = path::parent_path(File); !Path.empty();
- Path = path::parent_path(Path)) {
-
- auto CachedIt = CompilationDatabases.find(Path);
- if (CachedIt != CompilationDatabases.end())
- return CachedIt->second.get();
- std::string Error;
- auto CDB = tooling::CompilationDatabase::loadFromDirectory(Path, Error);
- if (!CDB) {
- if (!Error.empty()) {
- // FIXME(ibiryukov): logging
- // Output.log("Error when trying to load compilation database from " +
- // Twine(Path) + ": " + Twine(Error) + "\n");
- }
- continue;
- }
-
- // FIXME(ibiryukov): Invalidate cached compilation databases on changes
- auto result = CDB.get();
- CompilationDatabases.insert(std::make_pair(Path, std::move(CDB)));
- return result;
+ Path = path::parent_path(Path)) {
+ Error = "";
+ CDB = tryLoadDatabaseFromPath(Path, Error);
+ if (!CDB || !Error.empty())
+ continue;
+
+ // FIXME(ibiryukov): Invalidate cached compilation databases on changes
+ return CDB;
}
// FIXME(ibiryukov): logging
Index: clangd/ClangdServer.h
===================================================================
--- clangd/ClangdServer.h
+++ clangd/ClangdServer.h
@@ -156,7 +156,7 @@
/// location, obtained via CompilerInvocation::GetResourcePath.
ClangdServer(GlobalCompilationDatabase &CDB,
DiagnosticsConsumer &DiagConsumer,
- FileSystemProvider &FSProvider, bool RunSynchronously,
+ FileSystemProvider &FSProvider, bool RunSynchronously, std::string CompileCommands,
llvm::Optional<StringRef> ResourceDir = llvm::None);
/// Add a \p File to the list of tracked C++ files or update the contents if
Index: clangd/ClangdServer.cpp
===================================================================
--- clangd/ClangdServer.cpp
+++ clangd/ClangdServer.cpp
@@ -147,11 +147,16 @@
DiagnosticsConsumer &DiagConsumer,
FileSystemProvider &FSProvider,
bool RunSynchronously,
+ std::string CompileCommands,
llvm::Optional<StringRef> ResourceDir)
: CDB(CDB), DiagConsumer(DiagConsumer), FSProvider(FSProvider),
ResourceDir(ResourceDir ? ResourceDir->str() : getStandardResourceDir()),
PCHs(std::make_shared<PCHContainerOperations>()),
- WorkScheduler(RunSynchronously) {}
+ WorkScheduler(RunSynchronously) {
+
+ if (CompileCommands != "")
+ CDB.CompileCommands = CompileCommands;
+ }
void ClangdServer::addDocument(PathRef File, StringRef Contents) {
DocVersion Version = DraftMgr.updateDraft(File, Contents);
Index: clangd/ClangdLSPServer.h
===================================================================
--- clangd/ClangdLSPServer.h
+++ clangd/ClangdLSPServer.h
@@ -25,7 +25,7 @@
/// dispatch and ClangdServer together.
class ClangdLSPServer {
public:
- ClangdLSPServer(JSONOutput &Out, bool RunSynchronously);
+ ClangdLSPServer(JSONOutput &Out, bool RunSynchronously, std::string CompileCommands);
/// Run LSP server loop, receiving input for it from \p In. \p In must be
/// opened in binary mode. Output will be written using Out variable passed to
Index: clangd/ClangdLSPServer.cpp
===================================================================
--- clangd/ClangdLSPServer.cpp
+++ clangd/ClangdLSPServer.cpp
@@ -216,9 +216,9 @@
R"(,"result":[)" + Locations + R"(]})");
}
-ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, bool RunSynchronously)
+ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, bool RunSynchronously, std::string CompileCommands)
: Out(Out), DiagConsumer(*this),
- Server(CDB, DiagConsumer, FSProvider, RunSynchronously) {}
+ Server(CDB, DiagConsumer, FSProvider, RunSynchronously, CompileCommands) {}
void ClangdLSPServer::run(std::istream &In) {
assert(!IsDone && "Run was called before");
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits