stanionascu created this revision.
rfc8089#appendix-E.2 specifies that paths can begin with a drive letter e.g. as
file:///c:/.
In this case just consuming front file:// is not enough and the 3rd slash must
be consumed to produce a valid path on windows.
The patch introduce a generic way of converting an uri to a filesystem path and
back.
https://reviews.llvm.org/D31401
Files:
clangd/ASTManager.cpp
clangd/Protocol.cpp
clangd/Protocol.h
clangd/clients/clangd-vscode/src/extension.ts
Index: clangd/clients/clangd-vscode/src/extension.ts
===================================================================
--- clangd/clients/clangd-vscode/src/extension.ts
+++ clangd/clients/clangd-vscode/src/extension.ts
@@ -23,7 +23,12 @@
const clientOptions: vscodelc.LanguageClientOptions = {
// Register the server for C/C++ files
- documentSelector: ['c', 'cc', 'cpp', 'h', 'hh', 'hpp']
+ documentSelector: ['c', 'cc', 'cpp', 'h', 'hh', 'hpp'],
+ uriConverters: {
+ // FIXME: implement percent decoding in clangd
+ code2Protocol: (uri: vscode.Uri) : string => uri.toString(true),
+ protocol2Code: (file: string) : vscode.Uri => vscode.Uri.file(file)
+ }
};
const clangdClient = new vscodelc.LanguageClient('Clang Language Server', serverOptions, clientOptions);
Index: clangd/Protocol.h
===================================================================
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -29,6 +29,11 @@
namespace clang {
namespace clangd {
+struct Uri {
+ static std::string parse(llvm::StringRef uri);
+ static std::string unparse(llvm::StringRef file);
+};
+
struct TextDocumentIdentifier {
/// The text document's URI.
std::string uri;
Index: clangd/Protocol.cpp
===================================================================
--- clangd/Protocol.cpp
+++ clangd/Protocol.cpp
@@ -17,8 +17,30 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Path.h"
using namespace clang::clangd;
+std::string Uri::parse(llvm::StringRef uri) {
+ uri.consume_front("file://");
+ // For Windows paths e.g. /X:
+ if (uri.size() > 2 && uri[0] == '/' && uri[2] == ':')
+ uri.consume_front("/");
+ // Make sure that file paths are in native separators
+ std::string Result = llvm::sys::path::convert_to_slash(uri);
+ return Result;
+}
+
+std::string Uri::unparse(llvm::StringRef file) {
+ using namespace llvm::sys;
+ std::string Result = "file://";
+ // For Windows paths e.g. X:
+ if (file.size() > 1 && file[1] == ':')
+ Result += "/";
+ // Make sure that uri paths are with posix separators
+ Result += path::convert_to_slash(file, path::Style::posix);
+ return Result;
+}
+
llvm::Optional<TextDocumentIdentifier>
TextDocumentIdentifier::parse(llvm::yaml::MappingNode *Params) {
TextDocumentIdentifier Result;
@@ -36,7 +58,7 @@
llvm::SmallString<10> Storage;
if (KeyValue == "uri") {
- Result.uri = Value->getValue(Storage);
+ Result.uri = Uri::parse(Value->getValue(Storage));
} else if (KeyValue == "version") {
// FIXME: parse version, but only for VersionedTextDocumentIdentifiers.
} else {
@@ -142,7 +164,7 @@
llvm::SmallString<10> Storage;
if (KeyValue == "uri") {
- Result.uri = Value->getValue(Storage);
+ Result.uri = Uri::parse(Value->getValue(Storage));
} else if (KeyValue == "languageId") {
Result.languageId = Value->getValue(Storage);
} else if (KeyValue == "version") {
Index: clangd/ASTManager.cpp
===================================================================
--- clangd/ASTManager.cpp
+++ clangd/ASTManager.cpp
@@ -28,7 +28,6 @@
std::vector<ASTUnit::RemappedFile> RemappedFiles;
for (const auto &P : Docs.getAllDocuments()) {
StringRef FileName = P.first;
- FileName.consume_front("file://");
RemappedFiles.push_back(ASTUnit::RemappedFile(
FileName,
llvm::MemoryBuffer::getMemBufferCopy(P.second, FileName).release()));
@@ -138,7 +137,7 @@
Diagnostics.pop_back(); // Drop trailing comma.
Output.writeMessage(
R"({"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":")" +
- File + R"(","diagnostics":[)" + Diagnostics + R"(]}})");
+ Uri::unparse(File) + R"(","diagnostics":[)" + Diagnostics + R"(]}})");
}
ASTManager::~ASTManager() {
@@ -169,8 +168,6 @@
if (I)
return I.get();
- Uri.consume_front("file://");
-
std::string Error;
I = tooling::CompilationDatabase::autoDetectFromSource(Uri, Error);
Output.log("Failed to load compilation database: " + Twine(Error) + "\n");
@@ -182,7 +179,6 @@
tooling::CompilationDatabase *CDB =
getOrCreateCompilationDatabaseForFile(Uri);
- Uri.consume_front("file://");
std::vector<tooling::CompileCommand> Commands;
if (CDB) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits