Implement SourceConverter (#26)

This commit is contained in:
Shiyu
2025-01-10 19:26:41 +08:00
committed by GitHub
parent b7d58d03f4
commit c1c1930757
20 changed files with 343 additions and 348 deletions

View File

@@ -21,7 +21,4 @@ using array = std::vector<T>;
using DocumentUri = std::string;
// TODO: figure out URI.
using URI = std::string;
} // namespace clice::proto

View File

@@ -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

View 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

View File

@@ -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