diff options
| author | Eric Liu <ioeric@google.com> | 2018-11-28 10:30:42 +0000 |
|---|---|---|
| committer | Eric Liu <ioeric@google.com> | 2018-11-28 10:30:42 +0000 |
| commit | 4d814a93e5b9d130097413bc027efca9524b36ce (patch) | |
| tree | fca975e18d42da20bf4d863182031186674084d0 /clang-tools-extra/clangd/Protocol.cpp | |
| parent | 613c80d22f2428fb7e70754340c6a515e8e8d9c9 (diff) | |
| download | bcm5719-llvm-4d814a93e5b9d130097413bc027efca9524b36ce.tar.gz bcm5719-llvm-4d814a93e5b9d130097413bc027efca9524b36ce.zip | |
[clangd] Canonicalize file path in URIForFile.
Summary:
File paths in URIForFile can come from index or local AST. Path from
index goes through URI transformation and the final path is resolved by URI
scheme and could be potentially different from the original path. Hence, we
should do the same transformation for all paths. We do this in URIForFile, which
now converts a path to URI and back to a canonicalized path.
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D54845
llvm-svn: 347739
Diffstat (limited to 'clang-tools-extra/clangd/Protocol.cpp')
| -rw-r--r-- | clang-tools-extra/clangd/Protocol.cpp | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp index 7687693f62c..550789548cd 100644 --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -30,29 +30,44 @@ namespace clangd { char LSPError::ID; -URIForFile::URIForFile(std::string AbsPath) { +URIForFile URIForFile::canonicalize(StringRef AbsPath, StringRef TUPath) { assert(sys::path::is_absolute(AbsPath) && "the path is relative"); - File = std::move(AbsPath); + auto Resolved = URI::resolvePath(AbsPath, TUPath); + if (!Resolved) { + elog("URIForFile: failed to resolve path {0} with TU path {1}: " + "{2}.\nUsing unresolved path.", + AbsPath, TUPath, Resolved.takeError()); + return URIForFile(AbsPath); + } + return URIForFile(std::move(*Resolved)); +} + +Expected<URIForFile> URIForFile::fromURI(const URI &U, StringRef HintPath) { + auto Resolved = URI::resolve(U, HintPath); + if (!Resolved) + return Resolved.takeError(); + return URIForFile(std::move(*Resolved)); } bool fromJSON(const json::Value &E, URIForFile &R) { if (auto S = E.getAsString()) { - auto U = URI::parse(*S); - if (!U) { - elog("Failed to parse URI {0}: {1}", *S, U.takeError()); + auto Parsed = URI::parse(*S); + if (!Parsed) { + elog("Failed to parse URI {0}: {1}", *S, Parsed.takeError()); return false; } - if (U->scheme() != "file" && U->scheme() != "test") { + if (Parsed->scheme() != "file" && Parsed->scheme() != "test") { elog("Clangd only supports 'file' URI scheme for workspace files: {0}", *S); return false; } - auto Path = URI::resolve(*U); - if (!Path) { - log("{0}", Path.takeError()); + // "file" and "test" schemes do not require hint path. + auto U = URIForFile::fromURI(*Parsed, /*HintPath=*/""); + if (!U) { + elog("{0}", U.takeError()); return false; } - R = URIForFile(*Path); + R = std::move(*U); return true; } return false; |

