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
diff --git a/clang-tools-extra/unittests/clangd/SourceCodeTests.cpp b/clang-tools-extra/unittests/clangd/SourceCodeTests.cpp
index 86c8a09..d787641 100644
--- a/clang-tools-extra/unittests/clangd/SourceCodeTests.cpp
+++ b/clang-tools-extra/unittests/clangd/SourceCodeTests.cpp
@@ -7,7 +7,9 @@
//
//===----------------------------------------------------------------------===//
#include "SourceCode.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/raw_os_ostream.h"
+#include "llvm/Testing/Support/Error.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -15,6 +17,9 @@
namespace clangd {
namespace {
+using llvm::Failed;
+using llvm::HasValue;
+
MATCHER_P2(Pos, Line, Col, "") {
return arg.line == Line && arg.character == Col;
}
@@ -33,30 +38,57 @@
TEST(SourceCodeTests, PositionToOffset) {
// line out of bounds
- EXPECT_EQ(0u, positionToOffset(File, position(-1, 2)));
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), Failed());
// first line
- EXPECT_EQ(0u, positionToOffset(File, position(0, -1))); // out of range
- EXPECT_EQ(0u, positionToOffset(File, position(0, 0))); // first character
- EXPECT_EQ(3u, positionToOffset(File, position(0, 3))); // middle character
- EXPECT_EQ(6u, positionToOffset(File, position(0, 6))); // last character
- EXPECT_EQ(7u, positionToOffset(File, position(0, 7))); // the newline itself
- EXPECT_EQ(8u, positionToOffset(File, position(0, 8))); // out of range
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, -1)),
+ Failed()); // out of range
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 0)),
+ HasValue(0)); // first character
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 3)),
+ HasValue(3)); // middle character
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 6)),
+ HasValue(6)); // last character
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7)),
+ HasValue(7)); // the newline itself
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7), false),
+ HasValue(7));
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8)),
+ HasValue(7)); // out of range
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8), false),
+ Failed()); // out of range
// middle line
- EXPECT_EQ(8u, positionToOffset(File, position(1, -1))); // out of range
- EXPECT_EQ(8u, positionToOffset(File, position(1, 0))); // first character
- EXPECT_EQ(11u, positionToOffset(File, position(1, 3))); // middle character
- EXPECT_EQ(14u, positionToOffset(File, position(1, 6))); // last character
- EXPECT_EQ(15u, positionToOffset(File, position(1, 7))); // the newline itself
- EXPECT_EQ(16u, positionToOffset(File, position(1, 8))); // out of range
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, -1)),
+ Failed()); // out of range
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 0)),
+ HasValue(8)); // first character
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3)),
+ HasValue(11)); // middle character
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3), false),
+ HasValue(11));
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 6)),
+ HasValue(14)); // last character
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 7)),
+ HasValue(15)); // the newline itself
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8)),
+ HasValue(15)); // out of range
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8), false),
+ Failed()); // out of range
// last line
- EXPECT_EQ(16u, positionToOffset(File, position(2, -1))); // out of range
- EXPECT_EQ(16u, positionToOffset(File, position(2, 0))); // first character
- EXPECT_EQ(19u, positionToOffset(File, position(2, 3))); // middle character
- EXPECT_EQ(23u, positionToOffset(File, position(2, 7))); // last character
- EXPECT_EQ(24u, positionToOffset(File, position(2, 8))); // EOF
- EXPECT_EQ(24u, positionToOffset(File, position(2, 9))); // out of range
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, -1)),
+ Failed()); // out of range
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 0)),
+ HasValue(16)); // first character
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 3)),
+ HasValue(19)); // middle character
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 7)),
+ HasValue(23)); // last character
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 8)),
+ HasValue(24)); // EOF
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 9), false),
+ Failed()); // out of range
// line out of bounds
- EXPECT_EQ(24u, positionToOffset(File, position(3, 1)));
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), Failed());
+ EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 1)), Failed());
}
TEST(SourceCodeTests, OffsetToPosition) {