Index: clangd/ClangdLSPServer.cpp =================================================================== --- clangd/ClangdLSPServer.cpp +++ clangd/ClangdLSPServer.cpp @@ -116,8 +116,8 @@ {"commands", {ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND}}, }}, }}}}); - if (Params.rootUri && !Params.rootUri->file.empty()) - Server.setRootPath(Params.rootUri->file); + if (Params.rootUri && *Params.rootUri) + Server.setRootPath(Params.rootUri->getFile()); else if (Params.rootPath && !Params.rootPath->empty()) Server.setRootPath(*Params.rootPath); } @@ -132,9 +132,10 @@ void ClangdLSPServer::onDocumentDidOpen(DidOpenTextDocumentParams &Params) { if (Params.metadata && !Params.metadata->extraFlags.empty()) - CDB.setExtraFlagsForFile(Params.textDocument.uri.file, + CDB.setExtraFlagsForFile(Params.textDocument.uri.getFile(), std::move(Params.metadata->extraFlags)); - Server.addDocument(Params.textDocument.uri.file, Params.textDocument.text); + Server.addDocument(Params.textDocument.uri.getFile(), + Params.textDocument.text); } void ClangdLSPServer::onDocumentDidChange(DidChangeTextDocumentParams &Params) { @@ -142,7 +143,7 @@ return replyError(ErrorCode::InvalidParams, "can only apply one change at a time"); // We only support full syncing right now. - Server.addDocument(Params.textDocument.uri.file, + Server.addDocument(Params.textDocument.uri.getFile(), Params.contentChanges[0].text); } @@ -180,7 +181,7 @@ } void ClangdLSPServer::onRename(RenameParams &Params) { - auto File = Params.textDocument.uri.file; + auto File = Params.textDocument.uri.getFile(); auto Code = Server.getDocument(File); if (!Code) return replyError(ErrorCode::InvalidParams, @@ -200,12 +201,12 @@ } void ClangdLSPServer::onDocumentDidClose(DidCloseTextDocumentParams &Params) { - Server.removeDocument(Params.textDocument.uri.file); + Server.removeDocument(Params.textDocument.uri.getFile()); } void ClangdLSPServer::onDocumentOnTypeFormatting( DocumentOnTypeFormattingParams &Params) { - auto File = Params.textDocument.uri.file; + auto File = Params.textDocument.uri.getFile(); auto Code = Server.getDocument(File); if (!Code) return replyError(ErrorCode::InvalidParams, @@ -221,7 +222,7 @@ void ClangdLSPServer::onDocumentRangeFormatting( DocumentRangeFormattingParams &Params) { - auto File = Params.textDocument.uri.file; + auto File = Params.textDocument.uri.getFile(); auto Code = Server.getDocument(File); if (!Code) return replyError(ErrorCode::InvalidParams, @@ -236,7 +237,7 @@ } void ClangdLSPServer::onDocumentFormatting(DocumentFormattingParams &Params) { - auto File = Params.textDocument.uri.file; + auto File = Params.textDocument.uri.getFile(); auto Code = Server.getDocument(File); if (!Code) return replyError(ErrorCode::InvalidParams, @@ -253,14 +254,14 @@ void ClangdLSPServer::onCodeAction(CodeActionParams &Params) { // We provide a code action for each diagnostic at the requested location // which has FixIts available. - auto Code = Server.getDocument(Params.textDocument.uri.file); + auto Code = Server.getDocument(Params.textDocument.uri.getFile()); if (!Code) return replyError(ErrorCode::InvalidParams, "onCodeAction called for non-added file"); json::ary Commands; for (Diagnostic &D : Params.context.diagnostics) { - auto Edits = getFixIts(Params.textDocument.uri.file, D); + auto Edits = getFixIts(Params.textDocument.uri.getFile(), D); if (!Edits.empty()) { WorkspaceEdit WE; WE.changes = {{Params.textDocument.uri.uri(), std::move(Edits)}}; @@ -275,13 +276,14 @@ } void ClangdLSPServer::onCompletion(TextDocumentPositionParams &Params) { - Server.codeComplete(Params.textDocument.uri.file, Params.position, CCOpts, + Server.codeComplete(Params.textDocument.uri.getFile(), Params.position, + CCOpts, [](Tagged List) { reply(List.Value); }); } void ClangdLSPServer::onSignatureHelp(TextDocumentPositionParams &Params) { auto SignatureHelp = - Server.signatureHelp(Params.textDocument.uri.file, Params.position); + Server.signatureHelp(Params.textDocument.uri.getFile(), Params.position); if (!SignatureHelp) return replyError(ErrorCode::InvalidParams, llvm::toString(SignatureHelp.takeError())); @@ -289,8 +291,8 @@ } void ClangdLSPServer::onGoToDefinition(TextDocumentPositionParams &Params) { - auto Items = - Server.findDefinitions(Params.textDocument.uri.file, Params.position); + auto Items = Server.findDefinitions(Params.textDocument.uri.getFile(), + Params.position); if (!Items) return replyError(ErrorCode::InvalidParams, llvm::toString(Items.takeError())); @@ -298,13 +300,13 @@ } void ClangdLSPServer::onSwitchSourceHeader(TextDocumentIdentifier &Params) { - llvm::Optional Result = Server.switchSourceHeader(Params.uri.file); + llvm::Optional Result = Server.switchSourceHeader(Params.uri.getFile()); reply(Result ? URI::createFile(*Result).toString() : ""); } void ClangdLSPServer::onDocumentHighlight(TextDocumentPositionParams &Params) { - auto Highlights = Server.findDocumentHighlights(Params.textDocument.uri.file, - Params.position); + auto Highlights = Server.findDocumentHighlights( + Params.textDocument.uri.getFile(), Params.position); if (!Highlights) { replyError(ErrorCode::InternalError, Index: clangd/Protocol.h =================================================================== --- clangd/Protocol.h +++ clangd/Protocol.h @@ -25,6 +25,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PROTOCOL_H #include "JSONExpr.h" +#include "Path.h" #include "URI.h" #include "llvm/ADT/Optional.h" #include @@ -49,12 +50,17 @@ }; struct URIForFile { - std::string file; + URIForFile() = default; + explicit URIForFile(Path AbsPath); - std::string uri() const { return URI::createFile(file).toString(); } + /// Retrieves absolute path to the file. + PathRef getFile() const { return File; } + + explicit operator bool() const { return !File.empty(); } + std::string uri() const { return URI::createFile(File).toString(); } friend bool operator==(const URIForFile &LHS, const URIForFile &RHS) { - return LHS.file == RHS.file; + return LHS.File == RHS.File; } friend bool operator!=(const URIForFile &LHS, const URIForFile &RHS) { @@ -62,8 +68,11 @@ } friend bool operator<(const URIForFile &LHS, const URIForFile &RHS) { - return LHS.file < RHS.file; + return LHS.File < RHS.File; } + +private: + Path File; }; /// Serialize/deserialize \p URIForFile to/from a string URI. Index: clangd/Protocol.cpp =================================================================== --- clangd/Protocol.cpp +++ clangd/Protocol.cpp @@ -12,8 +12,8 @@ //===----------------------------------------------------------------------===// #include "Protocol.h" -#include "URI.h" #include "Logger.h" +#include "URI.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Format.h" @@ -24,6 +24,11 @@ namespace clang { namespace clangd { +URIForFile::URIForFile(Path AbsPath) { + assert(llvm::sys::path::is_absolute(AbsPath) && "the path is relative"); + File = std::move(AbsPath); +} + bool fromJSON(const json::Expr &E, URIForFile &R) { if (auto S = E.asString()) { auto U = URI::parse(*S); @@ -40,15 +45,13 @@ log(llvm::toString(Path.takeError())); return false; } - R.file = *Path; + R = URIForFile(*Path); return true; } return false; } -json::Expr toJSON(const URIForFile &U) { - return U.uri(); -} +json::Expr toJSON(const URIForFile &U) { return U.uri(); } llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const URIForFile &U) { return OS << U.uri(); Index: clangd/XRefs.cpp =================================================================== --- clangd/XRefs.cpp +++ clangd/XRefs.cpp @@ -149,7 +149,7 @@ } } - L.uri.file = FilePath.str(); + L.uri = URIForFile(FilePath.str()); L.range = R; return L; }