12 #include "clang/AST/ASTContext.h" 13 #include "clang/Basic/SourceManager.h" 14 #include "clang/Lex/Lexer.h" 15 #include "llvm/Support/Errc.h" 16 #include "llvm/Support/Error.h" 17 #include "llvm/Support/Path.h" 28 template <
typename Callback>
30 for (
size_t I = 0; I < U8.size();) {
31 unsigned char C =
static_cast<unsigned char>(U8[I]);
32 if (LLVM_LIKELY(!(C & 0x80))) {
39 size_t UTF8Length = llvm::countLeadingOnes(C);
42 assert((UTF8Length >= 2 && UTF8Length <= 4) &&
43 "Invalid UTF-8, or transcoding bug?");
47 if (CB(UTF8Length, UTF8Length == 4 ? 2 : 1))
56 static size_t measureUTF16(llvm::StringRef U8,
int U16Units,
bool &Valid) {
66 return std::min(Result, U8.size());
82 bool AllowColumnsBeyondLineLength) {
84 return llvm::make_error<llvm::StringError>(
85 llvm::formatv(
"Line value can't be negative ({0})", P.
line),
86 llvm::errc::invalid_argument);
88 return llvm::make_error<llvm::StringError>(
89 llvm::formatv(
"Character value can't be negative ({0})", P.
character),
90 llvm::errc::invalid_argument);
91 size_t StartOfLine = 0;
92 for (
int I = 0; I != P.
line; ++I) {
93 size_t NextNL = Code.find(
'\n', StartOfLine);
94 if (NextNL == llvm::StringRef::npos)
95 return llvm::make_error<llvm::StringError>(
96 llvm::formatv(
"Line value is out of range ({0})", P.
line),
97 llvm::errc::invalid_argument);
98 StartOfLine = NextNL + 1;
101 size_t NextNL = Code.find(
'\n', StartOfLine);
102 if (NextNL == llvm::StringRef::npos)
103 NextNL = Code.size();
107 Code.substr(StartOfLine, NextNL - StartOfLine), P.
character, Valid);
108 if (!Valid && !AllowColumnsBeyondLineLength)
109 return llvm::make_error<llvm::StringError>(
110 llvm::formatv(
"UTF-16 offset {0} is invalid for line {1}", P.
character,
112 llvm::errc::invalid_argument);
113 return StartOfLine + ByteOffsetInLine;
117 Offset = std::min(Code.size(), Offset);
118 llvm::StringRef Before = Code.substr(0, Offset);
119 int Lines = Before.count(
'\n');
120 size_t PrevNL = Before.rfind(
'\n');
121 size_t StartOfLine = (PrevNL == llvm::StringRef::npos) ? 0 : (PrevNL + 1);
132 std::tie(FID, Offset) = SM.getDecomposedSpellingLoc(Loc);
134 P.
line =
static_cast<int>(SM.getLineNumber(FID, Offset)) - 1;
135 bool Invalid =
false;
136 llvm::StringRef Code = SM.getBufferData(FID, &Invalid);
138 auto ColumnInBytes = SM.getColumnNumber(FID, Offset) - 1;
139 auto LineSoFar = Code.substr(Offset - ColumnInBytes, ColumnInBytes);
155 Offset = std::min(Code.size(), Offset);
156 llvm::StringRef Before = Code.substr(0, Offset);
157 int Lines = Before.count(
'\n');
158 size_t PrevNL = Before.rfind(
'\n');
159 size_t StartOfLine = (PrevNL == llvm::StringRef::npos) ? 0 : (PrevNL + 1);
160 return {Lines + 1, Offset - StartOfLine + 1};
163 std::pair<llvm::StringRef, llvm::StringRef>
165 size_t Pos = QName.rfind(
"::");
166 if (Pos == llvm::StringRef::npos)
167 return {llvm::StringRef(), QName};
168 return {QName.substr(0, Pos + 2), QName.substr(Pos + 2)};
172 const tooling::Replacement &R) {
173 Range ReplacementRange = {
176 return {ReplacementRange, R.getReplacementText()};
180 const tooling::Replacements &Repls) {
181 std::vector<TextEdit> Edits;
182 for (
const auto &R : Repls)
188 const SourceManager &SourceMgr) {
192 llvm::SmallString<128> FilePath = F->getName();
193 if (!llvm::sys::path::is_absolute(FilePath)) {
195 SourceMgr.getFileManager().getVirtualFileSystem()->makeAbsolute(
197 elog(
"Could not turn relative path '{0}' to absolute: {1}", FilePath,
214 if (
const DirectoryEntry *Dir = SourceMgr.getFileManager().getDirectory(
215 llvm::sys::path::parent_path(FilePath))) {
216 llvm::SmallString<128> RealPath;
217 llvm::StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
218 llvm::sys::path::append(RealPath, DirName,
219 llvm::sys::path::filename(FilePath));
220 return RealPath.str().str();
223 return FilePath.str().str();
227 const LangOptions &L) {
231 Result.
newText = FixIt.CodeToInsert;
241 return llvm::SHA1::hash({(
const uint8_t *)Content.data(), Content.size()});
244 llvm::Optional<FileDigest>
digestFile(
const SourceManager &SM, FileID FID) {
245 bool Invalid =
false;
246 llvm::StringRef Content = SM.getBufferData(FID, &Invalid);
SourceLocation Loc
'#' location in the include directive
Position start
The range's start position.
size_t lspLength(llvm::StringRef Code)
decltype(llvm::SHA1::hash({})) FileDigest
bool IsRangeConsecutive(const Range &Left, const Range &Right)
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
void elog(const char *Fmt, Ts &&... Vals)
std::pair< size_t, size_t > offsetToClangLineColumn(llvm::StringRef Code, size_t Offset)
TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M, const LangOptions &L)
std::string newText
The string to be inserted.
Position offsetToPosition(llvm::StringRef Code, size_t Offset)
Turn an offset in Code into a [line, column] pair.
llvm::Expected< size_t > positionToOffset(llvm::StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Turn a [line, column] pair into an offset in Code.
Range range
The range of the text document to be manipulated.
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
llvm::Optional< FileDigest > digestFile(const SourceManager &SM, FileID FID)
Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc)
Turn a SourceLocation into a [line, column] pair.
FileDigest digest(llvm::StringRef Content)
int line
Line position in a document (zero-based).
int character
Character offset on a line in a document (zero-based).
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
TextEdit replacementToEdit(llvm::StringRef Code, const tooling::Replacement &R)
std::pair< llvm::StringRef, llvm::StringRef > splitQualifiedName(llvm::StringRef QName)
From "a::b::c", return {"a::b::", "c"}.
llvm::Optional< std::string > getCanonicalPath(const FileEntry *F, const SourceManager &SourceMgr)
Get the canonical path of F.
std::vector< TextEdit > replacementsToEdits(llvm::StringRef Code, const tooling::Replacements &Repls)
llvm::Optional< FixItHint > FixIt
Position end
The range's end position.
static bool iterateCodepoints(llvm::StringRef U8, const Callback &CB)
static size_t measureUTF16(llvm::StringRef U8, int U16Units, bool &Valid)
Range halfOpenToRange(const SourceManager &SM, CharSourceRange R)