[clangd] Support textEdit in addition to insertText.
Summary:
Completion replies contains textEdits as well. Note that this change
relies on https://reviews.llvm.org/D50443.
Reviewers: ilya-biryukov
Reviewed By: ilya-biryukov
Subscribers: mgrang, ioeric, MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D50449
llvm-svn: 339543
diff --git a/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp b/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
index 350d47d..67f54eb 100644
--- a/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
+++ b/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
@@ -1439,6 +1439,82 @@
}
}
+TEST(CompletionTest, RenderWithFixItMerged) {
+ TextEdit FixIt;
+ FixIt.range.end.character = 5;
+ FixIt.newText = "->";
+
+ CodeCompletion C;
+ C.Name = "x";
+ C.RequiredQualifier = "Foo::";
+ C.FixIts = {FixIt};
+ C.CompletionTokenRange.start.character = 5;
+
+ CodeCompleteOptions Opts;
+ Opts.IncludeFixIts = true;
+
+ auto R = C.render(Opts);
+ EXPECT_TRUE(R.textEdit);
+ EXPECT_EQ(R.textEdit->newText, "->Foo::x");
+ EXPECT_TRUE(R.additionalTextEdits.empty());
+}
+
+TEST(CompletionTest, RenderWithFixItNonMerged) {
+ TextEdit FixIt;
+ FixIt.range.end.character = 4;
+ FixIt.newText = "->";
+
+ CodeCompletion C;
+ C.Name = "x";
+ C.RequiredQualifier = "Foo::";
+ C.FixIts = {FixIt};
+ C.CompletionTokenRange.start.character = 5;
+
+ CodeCompleteOptions Opts;
+ Opts.IncludeFixIts = true;
+
+ auto R = C.render(Opts);
+ EXPECT_TRUE(R.textEdit);
+ EXPECT_EQ(R.textEdit->newText, "Foo::x");
+ EXPECT_THAT(R.additionalTextEdits, UnorderedElementsAre(FixIt));
+}
+
+TEST(CompletionTest, CompletionTokenRange) {
+ MockFSProvider FS;
+ MockCompilationDatabase CDB;
+ IgnoreDiagnostics DiagConsumer;
+ ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
+
+ constexpr const char *TestCodes[] = {
+ R"cpp(
+ class Auxilary {
+ public:
+ void AuxFunction();
+ };
+ void f() {
+ Auxilary x;
+ x.[[Aux]]^;
+ }
+ )cpp",
+ R"cpp(
+ class Auxilary {
+ public:
+ void AuxFunction();
+ };
+ void f() {
+ Auxilary x;
+ x.[[]]^;
+ }
+ )cpp"};
+ for (const auto &Text : TestCodes) {
+ Annotations TestCode(Text);
+ auto Results = completions(Server, TestCode.code(), TestCode.point());
+
+ EXPECT_EQ(Results.Completions.size(), 1u);
+ EXPECT_THAT(Results.Completions.front().CompletionTokenRange, TestCode.range());
+ }
+}
+
} // namespace
} // namespace clangd
} // namespace clang
diff --git a/clang-tools-extra/unittests/clangd/SourceCodeTests.cpp b/clang-tools-extra/unittests/clangd/SourceCodeTests.cpp
index 57276af..4a97fa0 100644
--- a/clang-tools-extra/unittests/clangd/SourceCodeTests.cpp
+++ b/clang-tools-extra/unittests/clangd/SourceCodeTests.cpp
@@ -37,6 +37,13 @@
return Pos;
}
+Range range(const std::pair<int, int> p1, const std::pair<int, int> p2) {
+ Range range;
+ range.start = position(p1.first, p1.second);
+ range.end = position(p2.first, p2.second);
+ return range;
+}
+
TEST(SourceCodeTests, PositionToOffset) {
// line out of bounds
EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), Failed());
@@ -119,6 +126,14 @@
EXPECT_THAT(offsetToPosition(File, 30), Pos(2, 9)) << "out of bounds";
}
+TEST(SourceCodeTests, IsRangeConsecutive) {
+ EXPECT_TRUE(IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 3}, {2, 4})));
+ EXPECT_FALSE(
+ IsRangeConsecutive(range({0, 2}, {0, 3}), range({2, 3}, {2, 4})));
+ EXPECT_FALSE(
+ IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 4}, {2, 5})));
+}
+
} // namespace
} // namespace clangd
} // namespace clang