Index: clangd/ClangdLSPServer.cpp =================================================================== --- clangd/ClangdLSPServer.cpp +++ clangd/ClangdLSPServer.cpp @@ -87,8 +87,8 @@ } // namespace void ClangdLSPServer::onInitialize(InitializeParams &Params) { - if (Params.rootUri && !Params.rootUri->file.empty()) - Server.setRootPath(Params.rootUri->file); + if (Params.rootUri && *Params.rootUri) + Server.setRootPath(Params.rootUri->file()); else if (Params.rootPath && !Params.rootPath->empty()) Server.setRootPath(*Params.rootPath); @@ -136,9 +136,9 @@ void ClangdLSPServer::onDocumentDidOpen(DidOpenTextDocumentParams &Params) { if (Params.metadata && !Params.metadata->extraFlags.empty()) - CDB.setExtraFlagsForFile(Params.textDocument.uri.file, + CDB.setExtraFlagsForFile(Params.textDocument.uri.file(), std::move(Params.metadata->extraFlags)); - Server.addDocument(Params.textDocument.uri.file, Params.textDocument.text); + Server.addDocument(Params.textDocument.uri.file(), Params.textDocument.text); } void ClangdLSPServer::onDocumentDidChange(DidChangeTextDocumentParams &Params) { @@ -146,7 +146,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.file(), Params.contentChanges[0].text); } @@ -184,7 +184,7 @@ } void ClangdLSPServer::onRename(RenameParams &Params) { - Path File = Params.textDocument.uri.file; + Path File = Params.textDocument.uri.file(); llvm::Optional Code = Server.getDocument(File); if (!Code) return replyError(ErrorCode::InvalidParams, @@ -206,12 +206,12 @@ } void ClangdLSPServer::onDocumentDidClose(DidCloseTextDocumentParams &Params) { - Server.removeDocument(Params.textDocument.uri.file); + Server.removeDocument(Params.textDocument.uri.file()); } void ClangdLSPServer::onDocumentOnTypeFormatting( DocumentOnTypeFormattingParams &Params) { - auto File = Params.textDocument.uri.file; + auto File = Params.textDocument.uri.file(); auto Code = Server.getDocument(File); if (!Code) return replyError(ErrorCode::InvalidParams, @@ -227,7 +227,7 @@ void ClangdLSPServer::onDocumentRangeFormatting( DocumentRangeFormattingParams &Params) { - auto File = Params.textDocument.uri.file; + auto File = Params.textDocument.uri.file(); auto Code = Server.getDocument(File); if (!Code) return replyError(ErrorCode::InvalidParams, @@ -242,7 +242,7 @@ } void ClangdLSPServer::onDocumentFormatting(DocumentFormattingParams &Params) { - auto File = Params.textDocument.uri.file; + auto File = Params.textDocument.uri.file(); auto Code = Server.getDocument(File); if (!Code) return replyError(ErrorCode::InvalidParams, @@ -259,14 +259,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.file()); 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.file(), D); if (!Edits.empty()) { WorkspaceEdit WE; WE.changes = {{Params.textDocument.uri.uri(), std::move(Edits)}}; @@ -281,12 +281,12 @@ } void ClangdLSPServer::onCompletion(TextDocumentPositionParams &Params) { - Server.codeComplete(Params.textDocument.uri.file, Params.position, CCOpts, + Server.codeComplete(Params.textDocument.uri.file(), Params.position, CCOpts, [](Tagged List) { reply(List.Value); }); } void ClangdLSPServer::onSignatureHelp(TextDocumentPositionParams &Params) { - Server.signatureHelp(Params.textDocument.uri.file, Params.position, + Server.signatureHelp(Params.textDocument.uri.file(), Params.position, [](llvm::Expected> SignatureHelp) { if (!SignatureHelp) return replyError( @@ -298,7 +298,7 @@ void ClangdLSPServer::onGoToDefinition(TextDocumentPositionParams &Params) { Server.findDefinitions( - Params.textDocument.uri.file, Params.position, + Params.textDocument.uri.file(), Params.position, [](llvm::Expected>> Items) { if (!Items) return replyError(ErrorCode::InvalidParams, @@ -308,13 +308,13 @@ } void ClangdLSPServer::onSwitchSourceHeader(TextDocumentIdentifier &Params) { - llvm::Optional Result = Server.switchSourceHeader(Params.uri.file); + llvm::Optional Result = Server.switchSourceHeader(Params.uri.file()); reply(Result ? URI::createFile(*Result).toString() : ""); } void ClangdLSPServer::onDocumentHighlight(TextDocumentPositionParams &Params) { Server.findDocumentHighlights( - Params.textDocument.uri.file, Params.position, + Params.textDocument.uri.file(), Params.position, [](llvm::Expected>> Highlights) { if (!Highlights) return replyError(ErrorCode::InternalError, Index: clangd/Protocol.h =================================================================== --- clangd/Protocol.h +++ clangd/Protocol.h @@ -49,12 +49,17 @@ }; struct URIForFile { - std::string file; + URIForFile() = default; + explicit URIForFile(std::string AbsPath); - std::string uri() const { return URI::createFile(file).toString(); } + /// Retrieves absolute path to the file. + llvm::StringRef file() 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 +67,11 @@ } friend bool operator<(const URIForFile &LHS, const URIForFile &RHS) { - return LHS.file < RHS.file; + return LHS.File < RHS.File; } + +private: + std::string 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(std::string 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; }