2017-12-19 20:23:48 +08:00
|
|
|
//===--- SourceCode.h - Manipulating source code as strings -----*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "SourceCode.h"
|
|
|
|
|
2018-02-21 10:39:08 +08:00
|
|
|
#include "clang/Basic/SourceManager.h"
|
Make positionToOffset return llvm::Expected<size_t>
Summary:
To implement incremental document syncing, we want to verify that the
ranges provided by the front-end are valid. Currently, positionToOffset
deals with invalid Positions by returning 0 or Code.size(), which are
two valid offsets. Instead, return an llvm:Expected<size_t> with an
error if the position is invalid.
According to the LSP, if the character value exceeds the number of
characters of the given line, it should default back to the end of the
line. It makes sense in some contexts to have this behavior, and does
not in other contexts. The AllowColumnsBeyondLineLength parameter
allows to decide what to do in that case, default back to the end of the
line, or return an error.
Reviewers: ilya-biryukov
Subscribers: klimek, ilya-biryukov, jkorous-apple, ioeric, cfe-commits
Differential Revision: https://reviews.llvm.org/D44673
llvm-svn: 328100
2018-03-21 22:36:46 +08:00
|
|
|
#include "llvm/Support/Errc.h"
|
|
|
|
#include "llvm/Support/Error.h"
|
2018-02-21 10:39:08 +08:00
|
|
|
|
2017-12-19 20:23:48 +08:00
|
|
|
namespace clang {
|
|
|
|
namespace clangd {
|
|
|
|
using namespace llvm;
|
|
|
|
|
Make positionToOffset return llvm::Expected<size_t>
Summary:
To implement incremental document syncing, we want to verify that the
ranges provided by the front-end are valid. Currently, positionToOffset
deals with invalid Positions by returning 0 or Code.size(), which are
two valid offsets. Instead, return an llvm:Expected<size_t> with an
error if the position is invalid.
According to the LSP, if the character value exceeds the number of
characters of the given line, it should default back to the end of the
line. It makes sense in some contexts to have this behavior, and does
not in other contexts. The AllowColumnsBeyondLineLength parameter
allows to decide what to do in that case, default back to the end of the
line, or return an error.
Reviewers: ilya-biryukov
Subscribers: klimek, ilya-biryukov, jkorous-apple, ioeric, cfe-commits
Differential Revision: https://reviews.llvm.org/D44673
llvm-svn: 328100
2018-03-21 22:36:46 +08:00
|
|
|
llvm::Expected<size_t> positionToOffset(StringRef Code, Position P,
|
|
|
|
bool AllowColumnsBeyondLineLength) {
|
2017-12-19 20:23:48 +08:00
|
|
|
if (P.line < 0)
|
Make positionToOffset return llvm::Expected<size_t>
Summary:
To implement incremental document syncing, we want to verify that the
ranges provided by the front-end are valid. Currently, positionToOffset
deals with invalid Positions by returning 0 or Code.size(), which are
two valid offsets. Instead, return an llvm:Expected<size_t> with an
error if the position is invalid.
According to the LSP, if the character value exceeds the number of
characters of the given line, it should default back to the end of the
line. It makes sense in some contexts to have this behavior, and does
not in other contexts. The AllowColumnsBeyondLineLength parameter
allows to decide what to do in that case, default back to the end of the
line, or return an error.
Reviewers: ilya-biryukov
Subscribers: klimek, ilya-biryukov, jkorous-apple, ioeric, cfe-commits
Differential Revision: https://reviews.llvm.org/D44673
llvm-svn: 328100
2018-03-21 22:36:46 +08:00
|
|
|
return llvm::make_error<llvm::StringError>(
|
|
|
|
llvm::formatv("Line value can't be negative ({0})", P.line),
|
|
|
|
llvm::errc::invalid_argument);
|
|
|
|
if (P.character < 0)
|
|
|
|
return llvm::make_error<llvm::StringError>(
|
|
|
|
llvm::formatv("Character value can't be negative ({0})", P.character),
|
|
|
|
llvm::errc::invalid_argument);
|
2017-12-19 20:23:48 +08:00
|
|
|
size_t StartOfLine = 0;
|
|
|
|
for (int I = 0; I != P.line; ++I) {
|
|
|
|
size_t NextNL = Code.find('\n', StartOfLine);
|
|
|
|
if (NextNL == StringRef::npos)
|
Make positionToOffset return llvm::Expected<size_t>
Summary:
To implement incremental document syncing, we want to verify that the
ranges provided by the front-end are valid. Currently, positionToOffset
deals with invalid Positions by returning 0 or Code.size(), which are
two valid offsets. Instead, return an llvm:Expected<size_t> with an
error if the position is invalid.
According to the LSP, if the character value exceeds the number of
characters of the given line, it should default back to the end of the
line. It makes sense in some contexts to have this behavior, and does
not in other contexts. The AllowColumnsBeyondLineLength parameter
allows to decide what to do in that case, default back to the end of the
line, or return an error.
Reviewers: ilya-biryukov
Subscribers: klimek, ilya-biryukov, jkorous-apple, ioeric, cfe-commits
Differential Revision: https://reviews.llvm.org/D44673
llvm-svn: 328100
2018-03-21 22:36:46 +08:00
|
|
|
return llvm::make_error<llvm::StringError>(
|
|
|
|
llvm::formatv("Line value is out of range ({0})", P.line),
|
|
|
|
llvm::errc::invalid_argument);
|
2017-12-19 20:23:48 +08:00
|
|
|
StartOfLine = NextNL + 1;
|
|
|
|
}
|
Make positionToOffset return llvm::Expected<size_t>
Summary:
To implement incremental document syncing, we want to verify that the
ranges provided by the front-end are valid. Currently, positionToOffset
deals with invalid Positions by returning 0 or Code.size(), which are
two valid offsets. Instead, return an llvm:Expected<size_t> with an
error if the position is invalid.
According to the LSP, if the character value exceeds the number of
characters of the given line, it should default back to the end of the
line. It makes sense in some contexts to have this behavior, and does
not in other contexts. The AllowColumnsBeyondLineLength parameter
allows to decide what to do in that case, default back to the end of the
line, or return an error.
Reviewers: ilya-biryukov
Subscribers: klimek, ilya-biryukov, jkorous-apple, ioeric, cfe-commits
Differential Revision: https://reviews.llvm.org/D44673
llvm-svn: 328100
2018-03-21 22:36:46 +08:00
|
|
|
|
|
|
|
size_t NextNL = Code.find('\n', StartOfLine);
|
|
|
|
if (NextNL == StringRef::npos)
|
|
|
|
NextNL = Code.size();
|
|
|
|
|
|
|
|
if (StartOfLine + P.character > NextNL && !AllowColumnsBeyondLineLength)
|
|
|
|
return llvm::make_error<llvm::StringError>(
|
|
|
|
llvm::formatv("Character value is out of range ({0})", P.character),
|
|
|
|
llvm::errc::invalid_argument);
|
2017-12-19 20:23:48 +08:00
|
|
|
// FIXME: officially P.character counts UTF-16 code units, not UTF-8 bytes!
|
Make positionToOffset return llvm::Expected<size_t>
Summary:
To implement incremental document syncing, we want to verify that the
ranges provided by the front-end are valid. Currently, positionToOffset
deals with invalid Positions by returning 0 or Code.size(), which are
two valid offsets. Instead, return an llvm:Expected<size_t> with an
error if the position is invalid.
According to the LSP, if the character value exceeds the number of
characters of the given line, it should default back to the end of the
line. It makes sense in some contexts to have this behavior, and does
not in other contexts. The AllowColumnsBeyondLineLength parameter
allows to decide what to do in that case, default back to the end of the
line, or return an error.
Reviewers: ilya-biryukov
Subscribers: klimek, ilya-biryukov, jkorous-apple, ioeric, cfe-commits
Differential Revision: https://reviews.llvm.org/D44673
llvm-svn: 328100
2018-03-21 22:36:46 +08:00
|
|
|
return std::min(NextNL, StartOfLine + P.character);
|
2017-12-19 20:23:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Position offsetToPosition(StringRef Code, size_t Offset) {
|
|
|
|
Offset = std::min(Code.size(), Offset);
|
|
|
|
StringRef Before = Code.substr(0, Offset);
|
|
|
|
int Lines = Before.count('\n');
|
|
|
|
size_t PrevNL = Before.rfind('\n');
|
|
|
|
size_t StartOfLine = (PrevNL == StringRef::npos) ? 0 : (PrevNL + 1);
|
|
|
|
// FIXME: officially character counts UTF-16 code units, not UTF-8 bytes!
|
2018-02-14 18:52:04 +08:00
|
|
|
Position Pos;
|
|
|
|
Pos.line = Lines;
|
|
|
|
Pos.character = static_cast<int>(Offset - StartOfLine);
|
|
|
|
return Pos;
|
2017-12-19 20:23:48 +08:00
|
|
|
}
|
|
|
|
|
2018-02-21 10:39:08 +08:00
|
|
|
Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc) {
|
|
|
|
Position P;
|
|
|
|
P.line = static_cast<int>(SM.getSpellingLineNumber(Loc)) - 1;
|
|
|
|
P.character = static_cast<int>(SM.getSpellingColumnNumber(Loc)) - 1;
|
|
|
|
return P;
|
|
|
|
}
|
|
|
|
|
2018-03-12 23:28:22 +08:00
|
|
|
Range halfOpenToRange(const SourceManager &SM, CharSourceRange R) {
|
|
|
|
// Clang is 1-based, LSP uses 0-based indexes.
|
|
|
|
Position Begin = sourceLocToPosition(SM, R.getBegin());
|
|
|
|
Position End = sourceLocToPosition(SM, R.getEnd());
|
|
|
|
|
|
|
|
return {Begin, End};
|
|
|
|
}
|
|
|
|
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
std::pair<llvm::StringRef, llvm::StringRef>
|
|
|
|
splitQualifiedName(llvm::StringRef QName) {
|
|
|
|
size_t Pos = QName.rfind("::");
|
|
|
|
if (Pos == llvm::StringRef::npos)
|
|
|
|
return {StringRef(), QName};
|
|
|
|
return {QName.substr(0, Pos + 2), QName.substr(Pos + 2)};
|
|
|
|
}
|
|
|
|
|
2017-12-19 20:23:48 +08:00
|
|
|
} // namespace clangd
|
|
|
|
} // namespace clang
|