16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/Support/Error.h"
18#include "gmock/gmock.h"
19#include "gtest/gtest.h"
26using ::testing::ElementsAre;
27using ::testing::ElementsAreArray;
28using ::testing::UnorderedElementsAreArray;
31std::vector<Range> gatherRanges(
const SelectionRange &SR) {
32 std::vector<Range> Ranges;
33 for (
const SelectionRange *S = &SR; S; S = S->parent.get())
34 Ranges.push_back(S->range);
39gatherFoldingRanges(llvm::ArrayRef<FoldingRange> FoldingRanges) {
40 std::vector<Range> Ranges;
42 for (
const auto &R : FoldingRanges) {
43 NextRange.start.line = R.startLine;
44 NextRange.start.character = R.startCharacter;
45 NextRange.end.line = R.endLine;
46 NextRange.end.character = R.endCharacter;
47 Ranges.push_back(NextRange);
53 const char *Tests[] = {
54 R
"cpp( // Single statement in a function body.
56 [[[[int v = [[1^00]]]];]]
62 // int v = (10 + 2) * (a + a);
63 [[[[int v = [[[[([[[[10^]] + 2]])]] * (a + a)]]]];]]
66 R"cpp( // Function call.
67 int add(int x, int y) { return x + y; }
69 // int res = add(11, 22);
70 [[[[int res = [[add([[1^1]], 22)]]]];]]
73 R"cpp( // Tricky macros.
76 // int var = (4 + 15 MUL 6 + 10);
77 [[[[int var = [[[[([[4 + [[1^5]]]] MUL]] 6 + 10)]]]];]]
80 R"cpp( // Cursor inside a macro.
81 #define HASH(x) ((x) % 10)
83 [[[[int a = [[HASH([[[[2^3]] + 34]])]]]];]]
86 R"cpp( // Cursor on a macro.
87 #define HASH(x) ((x) % 10)
89 [[[[int a = [[HA^SH(23)]]]];]]
92 R"cpp( // Multiple declaration.
94 [[[[int var1, var^2]], var3;]]
97 R"cpp( // Before comment.
100 [[[[int var2 = [[[[var1]]^ /*some comment*/ + 41]]]];]]
106 R
"cpp( // Single statement in TU.
107 [[int v = [[1^00]]]];
109 R"cpp( // Cursor at end of VarDecl.
110 [[int v = [[100]]^]];
113 R
"cpp( // Cursor in between spaces.
115 int v = 100 + [[^]] 100;
120 struct AAA { struct BBB { static int ccc(); };};
122 // int x = AAA::BBB::ccc();
123 [[[[int x = [[[[AAA::BBB::c^cc]]()]]]];]]
127 struct AAA { struct BBB { static int ccc(); };};
129 // int x = AAA::BBB::ccc();
130 [[[[int x = [[[[[[[[[[AA^A]]::]]BBB::]]ccc]]()]]]];]]
133 R"cpp( // Inside struct.
134 struct A { static int a(); };
137 [[return [[[[1^1]] + 2]]]];
147 // int x = nsa::nsb::ccc();
148 [[[[int x = [[[[nsa::nsb::cc^c]]()]]]];]]
156 for (
const char *Test : Tests) {
157 auto T = Annotations(Test);
160 ElementsAreArray(
T.ranges()))
165TEST(SemanticSelection, RunViaClangdServer) {
167 MockCompilationDatabase CDB;
171 FS.Files[FooH] = R
"cpp(
173 #define HASH(x) ((x) % 10)
177 const char *SourceContents = R
"cpp(
179 [[void bar(int& inp) [[{
180 // inp = HASH(foo(inp));
181 [[inp = [[HASH([[foo([[in^p]])]])]]]];
185 Annotations SourceAnnotations(SourceContents);
186 FS.Files[FooCpp] = std::string(SourceAnnotations.code());
187 Server.addDocument(FooCpp, SourceAnnotations.code());
190 ASSERT_TRUE(
bool(Ranges))
191 <<
"getSemanticRange returned an error: " << Ranges.takeError();
192 ASSERT_EQ(Ranges->size(), SourceAnnotations.points().size());
193 EXPECT_THAT(gatherRanges(Ranges->front()),
194 ElementsAreArray(SourceAnnotations.ranges()));
195 EXPECT_THAT(gatherRanges(Ranges->back()),
196 ElementsAre(SourceAnnotations.range(
"empty")));
199TEST(FoldingRanges, ASTAll) {
200 const char *Tests[] = {
202 #define FOO int foo() {\
206 // Do not generate folding range for braces within macro expansion.
209 // Do not generate folding range within macro arguments.
210 #define FUNCTOR(functor) functor
215 // Do not generate folding range with a brace coming from macro.
225 if (Variable > 5) {[[
227 ]]} else if (Variable++)
233 // Do not generate FoldingRange for empty CompoundStmts.
236 // If there are newlines between {}, we should generate one.
254 // Braces are located at the same line: no folding range here.
259 for (
const char *Test : Tests) {
260 auto T = Annotations(Test);
263 UnorderedElementsAreArray(
T.ranges()))
268TEST(FoldingRanges, PseudoParserWithoutLineFoldings) {
269 const char *Tests[] = {
271 #define FOO int foo() {\
275 // Do not generate folding range for braces within macro expansion.
278 // Do not generate folding range within macro arguments.
279 #define FUNCTOR(functor) functor
284 // Do not generate folding range with a brace coming from macro.
294 if (Variable > 5) {[[
296 ]]} else if (Variable++)
302 // Do not generate FoldingRange for empty CompoundStmts.
305 // If there are newlines between {}, we should generate one.
323 // Braces are located at the same line: no folding range here.
328 // Range boundaries on escaped newlines.
351 // No folding for single line comment.
374 for (
const char *Test : Tests) {
375 auto T = Annotations(Test);
377 T.code().str(),
false))),
378 UnorderedElementsAreArray(
T.ranges()))
383TEST(FoldingRanges, PseudoParserLineFoldingsOnly) {
384 const char *Tests[] = {
391 // Always exclude last line for brackets.
395 } else if (a == 2){[[
397 } else { // No folding for 2 line bracketed ranges.
406 /* No folding for this comment.
409 // No folding for this comment.
411 //[[ 2 single line comment.
412 // 2 single line comment.]]
414 //[[ >=2 line comments.
415 // >=2 line comments.
416 // >=2 line comments.]]
428 * This does not fold me */
439 auto StripColumns = [](
const std::vector<Range> &Ranges) {
440 std::vector<Range> Res;
441 for (Range R : Ranges) {
442 R.start.character = R.end.character = 0;
447 for (
const char *Test : Tests) {
448 auto T = Annotations(Test);
450 StripColumns(gatherFoldingRanges(llvm::cantFail(
452 UnorderedElementsAreArray(StripColumns(
T.ranges())))
CharSourceRange Range
SourceRange for the file name.
static Options optsForTest()
llvm::Expected< std::vector< FoldingRange > > getFoldingRanges(ParsedAST &AST)
Returns a list of ranges whose contents might be collapsible in an editor.
llvm::Expected< std::vector< SelectionRange > > runSemanticRanges(ClangdServer &Server, PathRef File, const std::vector< Position > &Pos)
std::string testPath(PathRef File, llvm::sys::path::Style Style)
llvm::Expected< SelectionRange > getSemanticRanges(ParsedAST &AST, Position Pos)
Returns the list of all interesting ranges around the Position Pos.
TEST(BackgroundQueueTest, Priority)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static TestTU withCode(llvm::StringRef Code)