Implement SourceConverter (#26)
This commit is contained in:
@@ -21,7 +21,4 @@ using array = std::vector<T>;
|
||||
|
||||
using DocumentUri = std::string;
|
||||
|
||||
// TODO: figure out URI.
|
||||
using URI = std::string;
|
||||
|
||||
} // namespace clice::proto
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <Basic/Location.h>
|
||||
#include <clang/Basic/SourceLocation.h>
|
||||
|
||||
namespace clice {
|
||||
|
||||
/// Measure the length of the content with the specified encoding kind.
|
||||
std::size_t remeasure(llvm::StringRef content, proto::PositionEncodingKind kind);
|
||||
|
||||
/// Convert a clang::SourceLocation to a proto::Position according to the
|
||||
/// specified encoding kind. Note that `SourceLocation` in clang is 1-based and
|
||||
/// is always encoded in UTF-8.
|
||||
proto::Position toPosition(llvm::StringRef content,
|
||||
clang::SourceLocation location,
|
||||
proto::PositionEncodingKind kind,
|
||||
const clang::SourceManager& SM);
|
||||
|
||||
/// Same as above, but content is retrieved from the `SourceManager`.
|
||||
proto::Position toPosition(clang::SourceLocation location,
|
||||
proto::PositionEncodingKind kind,
|
||||
const clang::SourceManager& SM);
|
||||
|
||||
/// Convert a proto::Position to a file offset in the content with the specified
|
||||
/// encoding kind.
|
||||
std::size_t toOffset(llvm::StringRef content,
|
||||
proto::Position position,
|
||||
proto::PositionEncodingKind kind);
|
||||
|
||||
} // namespace clice
|
||||
68
include/Basic/SourceConverter.h
Normal file
68
include/Basic/SourceConverter.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
#include <Basic/Location.h>
|
||||
#include <clang/Basic/SourceLocation.h>
|
||||
|
||||
namespace clice {
|
||||
|
||||
/// A helper class to convert `Position, Range, Location` between 1-1 encoding based clang and 0-0
|
||||
/// encoding based LSP. The conversion of DocumentUri is also supported.
|
||||
class SourceConverter {
|
||||
public:
|
||||
/// [(origin, new)], map origin header directory to another source directory.
|
||||
using SourceDirMapping = std::vector<std::pair<std::string, std::string>>;
|
||||
|
||||
/// Construct a `SourceConverter` with the specified encoding kind and empty source map.
|
||||
explicit SourceConverter(proto::PositionEncodingKind kind) : kind(kind), sourceMap() {}
|
||||
|
||||
SourceConverter(proto::PositionEncodingKind kind, SourceDirMapping sourceMap) :
|
||||
kind(kind), sourceMap(std::move(sourceMap)) {}
|
||||
|
||||
SourceConverter(const SourceConverter&) = delete;
|
||||
|
||||
SourceConverter(SourceConverter&&) = default;
|
||||
|
||||
/// Measure the length (character count) of the content with the specified encoding kind.
|
||||
std::size_t remeasure(llvm::StringRef content) const;
|
||||
|
||||
/// Convert a clang::SourceLocation to a proto::Position according to the
|
||||
/// specified encoding kind. Note that `SourceLocation` in clang is 1-based and
|
||||
/// is always encoded in UTF-8.
|
||||
proto::Position toPosition(llvm::StringRef content, clang::SourceLocation location,
|
||||
const clang::SourceManager& SM) const;
|
||||
|
||||
/// Same as above, but content is retrieved from the `SourceManager`.
|
||||
proto::Position toPosition(clang::SourceLocation location,
|
||||
const clang::SourceManager& SM) const;
|
||||
|
||||
/// Convert a clang::SourceRange to a proto::Range according to the specified encoding kind.
|
||||
proto::Range toRange(clang::SourceRange range, const clang::SourceManager& SM) const {
|
||||
return {toPosition(range.getBegin(), SM), toPosition(range.getEnd(), SM)};
|
||||
}
|
||||
|
||||
/// Convert a proto::Position to a file offset in the content with the specified
|
||||
/// encoding kind.
|
||||
std::size_t toOffset(llvm::StringRef content, proto::Position position) const;
|
||||
|
||||
/// Get the encoding kind of the content in LSP protocol.
|
||||
proto::PositionEncodingKind encodingKind() const {
|
||||
return kind;
|
||||
}
|
||||
|
||||
/// Convert a real path of a file to URI. Crash if failed.
|
||||
static proto::DocumentUri toURI(llvm::StringRef fspath);
|
||||
|
||||
/// Convert a file URI to real path with `clice::fs::real_path`. Crash if failed.
|
||||
static std::string toPath(llvm::StringRef uri);
|
||||
|
||||
private:
|
||||
/// The encoding kind of the content in LSP protocol.
|
||||
proto::PositionEncodingKind kind;
|
||||
|
||||
/// A user-defined map from header file to its source directory.
|
||||
SourceDirMapping sourceMap;
|
||||
};
|
||||
|
||||
} // namespace clice
|
||||
@@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Support/Support.h"
|
||||
|
||||
namespace clice {
|
||||
|
||||
class URI {
|
||||
public:
|
||||
URI(llvm::StringRef scheme, llvm::StringRef authority, llvm::StringRef path) :
|
||||
m_scheme(scheme), m_authority(authority), m_body(path) {}
|
||||
|
||||
URI(const URI&) = default;
|
||||
|
||||
bool operator== (const URI&) const = default;
|
||||
|
||||
/// Construct a URI object from the given file path.
|
||||
static URI from(llvm::StringRef file);
|
||||
|
||||
/// Parse the given URI string to create a URI object.
|
||||
static llvm::Expected<URI> parse(llvm::StringRef content);
|
||||
|
||||
/// Same as `parse`, but will crash if failed.
|
||||
static std::string resolve(llvm::StringRef content);
|
||||
|
||||
/// Returns decoded scheme e.g. "https"
|
||||
llvm::StringRef scheme() const {
|
||||
return m_scheme;
|
||||
}
|
||||
|
||||
/// Returns decoded authority e.g. "reviews.llvm.org"
|
||||
llvm::StringRef authority() const {
|
||||
return m_authority;
|
||||
}
|
||||
|
||||
/// Returns decoded body e.g. "/D41946"
|
||||
llvm::StringRef body() const {
|
||||
return m_body;
|
||||
}
|
||||
|
||||
std::string toString() const {
|
||||
return std::format("{}://{}{}", m_scheme, m_authority, m_body);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_scheme;
|
||||
std::string m_authority;
|
||||
std::string m_body;
|
||||
};
|
||||
|
||||
} // namespace clice
|
||||
Reference in New Issue
Block a user