[clangd] Expose offset <-> LSP position functions, and fix bugs
Summary:
- Moved these functions to SourceCode.h
- added unit tests
- fix off by one in positionToOffset: Offset - 1 in final calculation was wrong
- fixed formatOnType which had an equal and opposite off-by-one
- positionToOffset and offsetToPosition both consistently clamp to beginning/end
of file when input is out of range
- gave variables more descriptive names
- removed windows line ending fixmes where there is nothing to fix
- elaborated on UTF-8 fixmes
This will conflict with Eric's D41281, but in a pretty easy-to-resolve way.
Reviewers: ioeric
Subscribers: klimek, mgorny, ilya-biryukov, cfe-commits
Differential Revision: https://reviews.llvm.org/D41351
llvm-svn: 321073
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp
index 7e48d68..4a9ee69 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -8,6 +8,7 @@
//===-------------------------------------------------------------------===//
#include "ClangdServer.h"
+#include "SourceCode.h"
#include "clang/Format/Format.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
@@ -57,29 +58,6 @@
} // namespace
-size_t clangd::positionToOffset(StringRef Code, Position P) {
- size_t Offset = 0;
- for (int I = 0; I != P.line; ++I) {
- // FIXME: \r\n
- // FIXME: UTF-8
- size_t F = Code.find('\n', Offset);
- if (F == StringRef::npos)
- return 0; // FIXME: Is this reasonable?
- Offset = F + 1;
- }
- return (Offset == 0 ? 0 : (Offset - 1)) + P.character;
-}
-
-/// Turn an offset in Code into a [line, column] pair.
-Position clangd::offsetToPosition(StringRef Code, size_t Offset) {
- StringRef JustBefore = Code.substr(0, Offset);
- // FIXME: \r\n
- // FIXME: UTF-8
- int Lines = JustBefore.count('\n');
- int Cols = JustBefore.size() - JustBefore.rfind('\n') - 1;
- return {Lines, Cols};
-}
-
Tagged<IntrusiveRefCntPtr<vfs::FileSystem>>
RealFileSystemProvider::getTaggedFileSystem(PathRef File) {
return make_tagged(vfs::getRealFileSystem(), VFSTag());
@@ -337,7 +315,7 @@
size_t PreviousLBracePos = StringRef(Code).find_last_of('{', CursorPos);
if (PreviousLBracePos == StringRef::npos)
PreviousLBracePos = CursorPos;
- size_t Len = 1 + CursorPos - PreviousLBracePos;
+ size_t Len = CursorPos - PreviousLBracePos;
return formatCode(Code, File, {tooling::Range(PreviousLBracePos, Len)});
}