Line data Source code
1 : //===--- URI.h - File URIs with schemes --------------------------*- C++-*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PATHURI_H
11 : #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PATHURI_H
12 :
13 : #include "llvm/ADT/StringRef.h"
14 : #include "llvm/Support/Error.h"
15 : #include "llvm/Support/Registry.h"
16 :
17 : namespace clang {
18 : namespace clangd {
19 :
20 : /// A URI describes the location of a source file.
21 : /// In the simplest case, this is a "file" URI that directly encodes the
22 : /// absolute path to a file. More abstract cases are possible: a shared index
23 : /// service might expose repo:// URIs that are relative to the source control
24 : /// root.
25 : ///
26 : /// Clangd handles URIs of the form <scheme>:[//<authority>]<body>. It doesn't
27 : /// further split the authority or body into constituent parts (e.g. query
28 : /// strings is included in the body).
29 : class URI {
30 : public:
31 : URI(llvm::StringRef Scheme, llvm::StringRef Authority, llvm::StringRef Body);
32 :
33 : /// Returns decoded scheme e.g. "https"
34 : llvm::StringRef scheme() const { return Scheme; }
35 : /// Returns decoded authority e.g. "reviews.lvm.org"
36 : llvm::StringRef authority() const { return Authority; }
37 : /// Returns decoded body e.g. "/D41946"
38 : llvm::StringRef body() const { return Body; }
39 :
40 : /// Returns a string URI with all components percent-encoded.
41 : std::string toString() const;
42 :
43 : /// Creates a URI for a file in the given scheme. \p Scheme must be
44 : /// registered. The URI is percent-encoded.
45 : static llvm::Expected<URI> create(llvm::StringRef AbsolutePath,
46 : llvm::StringRef Scheme);
47 :
48 : // Similar to above except this uses the first scheme in \p Schemes that
49 : // works.
50 : static llvm::Expected<URI> create(llvm::StringRef AbsolutePath,
51 : const std::vector<std::string> &Schemes);
52 :
53 : /// This creates a file:// URI for \p AbsolutePath. The path must be absolute.
54 : static URI createFile(llvm::StringRef AbsolutePath);
55 :
56 : /// Parse a URI string "<scheme>:[//<authority>/]<path>". Percent-encoded
57 : /// characters in the URI will be decoded.
58 : static llvm::Expected<URI> parse(llvm::StringRef Uri);
59 :
60 : /// Resolves the absolute path of \p U. If there is no matching scheme, or the
61 : /// URI is invalid in the scheme, this returns an error.
62 : ///
63 : /// \p HintPath A related path, such as the current file or working directory,
64 : /// which can help disambiguate when the same file exists in many workspaces.
65 : static llvm::Expected<std::string> resolve(const URI &U,
66 : llvm::StringRef HintPath = "");
67 :
68 : /// Gets the preferred spelling of this file for #include, if there is one,
69 : /// e.g. <system_header.h>, "path/to/x.h".
70 : ///
71 : /// This allows URI schemas to provide their customized include paths.
72 : ///
73 : /// Returns an empty string if normal include-shortening based on the absolute
74 : /// path should be used.
75 : /// Fails if the URI is not valid in the schema.
76 : static llvm::Expected<std::string> includeSpelling(const URI &U);
77 :
78 : friend bool operator==(const URI &LHS, const URI &RHS) {
79 : return std::tie(LHS.Scheme, LHS.Authority, LHS.Body) ==
80 : std::tie(RHS.Scheme, RHS.Authority, RHS.Body);
81 : }
82 :
83 : friend bool operator<(const URI &LHS, const URI &RHS) {
84 : return std::tie(LHS.Scheme, LHS.Authority, LHS.Body) <
85 : std::tie(RHS.Scheme, RHS.Authority, RHS.Body);
86 : }
87 :
88 : private:
89 : URI() = default;
90 :
91 : std::string Scheme;
92 : std::string Authority;
93 : std::string Body;
94 : };
95 :
96 : /// URIScheme is an extension point for teaching clangd to recognize a custom
97 : /// URI scheme. This is expected to be implemented and exposed via the
98 : /// URISchemeRegistry.
99 : class URIScheme {
100 : public:
101 0 : virtual ~URIScheme() = default;
102 :
103 : /// Returns the absolute path of the file corresponding to the URI
104 : /// authority+body in the file system. See URI::resolve for semantics of
105 : /// \p HintPath.
106 : virtual llvm::Expected<std::string>
107 : getAbsolutePath(llvm::StringRef Authority, llvm::StringRef Body,
108 : llvm::StringRef HintPath) const = 0;
109 :
110 : virtual llvm::Expected<URI>
111 : uriFromAbsolutePath(llvm::StringRef AbsolutePath) const = 0;
112 :
113 : /// Returns the include path of the file (e.g. <path>, "path"), which can be
114 : /// #included directly. See URI::includeSpelling for details.
115 0 : virtual llvm::Expected<std::string> getIncludeSpelling(const URI &U) const {
116 0 : return ""; // no customized include path for this scheme.
117 : }
118 : };
119 :
120 : /// By default, a "file" scheme is supported where URI paths are always absolute
121 : /// in the file system.
122 : typedef llvm::Registry<URIScheme> URISchemeRegistry;
123 :
124 : } // namespace clangd
125 : } // namespace clang
126 :
127 : #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_PATHURI_H
|