clang-tools  9.0.0
SourceCodeTests.cpp
Go to the documentation of this file.
1 //===-- SourceCodeTests.cpp ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #include "Annotations.h"
9 #include "Context.h"
10 #include "Protocol.h"
11 #include "SourceCode.h"
12 #include "TestTU.h"
13 #include "clang/Basic/LangOptions.h"
14 #include "clang/Format/Format.h"
15 #include "llvm/Support/Error.h"
16 #include "llvm/Support/raw_os_ostream.h"
17 #include "llvm/Testing/Support/Error.h"
18 #include "gmock/gmock.h"
19 #include "gtest/gtest.h"
20 
21 namespace clang {
22 namespace clangd {
23 namespace {
24 
25 using llvm::Failed;
26 using llvm::HasValue;
27 using ::testing::UnorderedElementsAreArray;
28 
29 MATCHER_P2(Pos, Line, Col, "") {
30  return arg.line == int(Line) && arg.character == int(Col);
31 }
32 
33 MATCHER_P(MacroName, Name, "") { return arg.Name == Name; }
34 
35 /// A helper to make tests easier to read.
36 Position position(int line, int character) {
37  Position Pos;
38  Pos.line = line;
39  Pos.character = character;
40  return Pos;
41 }
42 
43 Range range(const std::pair<int, int> p1, const std::pair<int, int> p2) {
44  Range range;
45  range.start = position(p1.first, p1.second);
46  range.end = position(p2.first, p2.second);
47  return range;
48 }
49 
50 TEST(SourceCodeTests, lspLength) {
51  EXPECT_EQ(lspLength(""), 0UL);
52  EXPECT_EQ(lspLength("ascii"), 5UL);
53  // BMP
54  EXPECT_EQ(lspLength("↓"), 1UL);
55  EXPECT_EQ(lspLength("¥"), 1UL);
56  // astral
57  EXPECT_EQ(lspLength("😂"), 2UL);
58 
60  EXPECT_EQ(lspLength(""), 0UL);
61  EXPECT_EQ(lspLength("ascii"), 5UL);
62  // BMP
63  EXPECT_EQ(lspLength("↓"), 3UL);
64  EXPECT_EQ(lspLength("¥"), 2UL);
65  // astral
66  EXPECT_EQ(lspLength("😂"), 4UL);
67 
69  EXPECT_EQ(lspLength(""), 0UL);
70  EXPECT_EQ(lspLength("ascii"), 5UL);
71  // BMP
72  EXPECT_EQ(lspLength("↓"), 1UL);
73  EXPECT_EQ(lspLength("¥"), 1UL);
74  // astral
75  EXPECT_EQ(lspLength("😂"), 1UL);
76 }
77 
78 // The = → 🡆 below are ASCII (1 byte), BMP (3 bytes), and astral (4 bytes).
79 const char File[] = R"(0:0 = 0
80 1:0 → 8
81 2:0 🡆 18)";
82 struct Line {
83  unsigned Number;
84  unsigned Offset;
85  unsigned Length;
86 };
87 Line FileLines[] = {Line{0, 0, 7}, Line{1, 8, 9}, Line{2, 18, 11}};
88 
89 TEST(SourceCodeTests, PositionToOffset) {
90  // line out of bounds
91  EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), llvm::Failed());
92  // first line
93  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, -1)),
94  llvm::Failed()); // out of range
95  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 0)),
96  llvm::HasValue(0)); // first character
97  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 3)),
98  llvm::HasValue(3)); // middle character
99  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 6)),
100  llvm::HasValue(6)); // last character
101  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7)),
102  llvm::HasValue(7)); // the newline itself
103  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7), false),
104  llvm::HasValue(7));
105  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8)),
106  llvm::HasValue(7)); // out of range
107  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8), false),
108  llvm::Failed()); // out of range
109  // middle line
110  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, -1)),
111  llvm::Failed()); // out of range
112  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 0)),
113  llvm::HasValue(8)); // first character
114  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3)),
115  llvm::HasValue(11)); // middle character
116  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3), false),
117  llvm::HasValue(11));
118  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 6)),
119  llvm::HasValue(16)); // last character
120  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 7)),
121  llvm::HasValue(17)); // the newline itself
122  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8)),
123  llvm::HasValue(17)); // out of range
124  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8), false),
125  llvm::Failed()); // out of range
126  // last line
127  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, -1)),
128  llvm::Failed()); // out of range
129  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 0)),
130  llvm::HasValue(18)); // first character
131  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 3)),
132  llvm::HasValue(21)); // middle character
133  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5), false),
134  llvm::Failed()); // middle of surrogate pair
135  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5)),
136  llvm::HasValue(26)); // middle of surrogate pair
137  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 6), false),
138  llvm::HasValue(26)); // end of surrogate pair
139  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 8)),
140  llvm::HasValue(28)); // last character
141  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 9)),
142  llvm::HasValue(29)); // EOF
143  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 10), false),
144  llvm::Failed()); // out of range
145  // line out of bounds
146  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), llvm::Failed());
147  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 1)), llvm::Failed());
148 
149  // Codepoints are similar, except near astral characters.
151  // line out of bounds
152  EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), llvm::Failed());
153  // first line
154  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, -1)),
155  llvm::Failed()); // out of range
156  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 0)),
157  llvm::HasValue(0)); // first character
158  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 3)),
159  llvm::HasValue(3)); // middle character
160  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 6)),
161  llvm::HasValue(6)); // last character
162  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7)),
163  llvm::HasValue(7)); // the newline itself
164  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7), false),
165  llvm::HasValue(7));
166  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8)),
167  llvm::HasValue(7)); // out of range
168  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8), false),
169  llvm::Failed()); // out of range
170  // middle line
171  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, -1)),
172  llvm::Failed()); // out of range
173  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 0)),
174  llvm::HasValue(8)); // first character
175  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3)),
176  llvm::HasValue(11)); // middle character
177  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3), false),
178  llvm::HasValue(11));
179  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 6)),
180  llvm::HasValue(16)); // last character
181  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 7)),
182  llvm::HasValue(17)); // the newline itself
183  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8)),
184  llvm::HasValue(17)); // out of range
185  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8), false),
186  llvm::Failed()); // out of range
187  // last line
188  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, -1)),
189  llvm::Failed()); // out of range
190  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 0)),
191  llvm::HasValue(18)); // first character
192  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 4)),
193  llvm::HasValue(22)); // Before astral character.
194  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5), false),
195  llvm::HasValue(26)); // after astral character
196  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 7)),
197  llvm::HasValue(28)); // last character
198  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 8)),
199  llvm::HasValue(29)); // EOF
200  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 9), false),
201  llvm::Failed()); // out of range
202  // line out of bounds
203  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), llvm::Failed());
204  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 1)), llvm::Failed());
205 
206  // Test UTF-8, where transformations are trivial.
208  EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), llvm::Failed());
209  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), llvm::Failed());
210  for (Line L : FileLines) {
211  EXPECT_THAT_EXPECTED(positionToOffset(File, position(L.Number, -1)),
212  llvm::Failed()); // out of range
213  for (unsigned I = 0; I <= L.Length; ++I)
214  EXPECT_THAT_EXPECTED(positionToOffset(File, position(L.Number, I)),
215  llvm::HasValue(L.Offset + I));
216  EXPECT_THAT_EXPECTED(positionToOffset(File, position(L.Number, L.Length+1)),
217  llvm::HasValue(L.Offset + L.Length));
218  EXPECT_THAT_EXPECTED(
219  positionToOffset(File, position(L.Number, L.Length + 1), false),
220  llvm::Failed()); // out of range
221  }
222 }
223 
224 TEST(SourceCodeTests, OffsetToPosition) {
225  EXPECT_THAT(offsetToPosition(File, 0), Pos(0, 0)) << "start of file";
226  EXPECT_THAT(offsetToPosition(File, 3), Pos(0, 3)) << "in first line";
227  EXPECT_THAT(offsetToPosition(File, 6), Pos(0, 6)) << "end of first line";
228  EXPECT_THAT(offsetToPosition(File, 7), Pos(0, 7)) << "first newline";
229  EXPECT_THAT(offsetToPosition(File, 8), Pos(1, 0)) << "start of second line";
230  EXPECT_THAT(offsetToPosition(File, 12), Pos(1, 4)) << "before BMP char";
231  EXPECT_THAT(offsetToPosition(File, 13), Pos(1, 5)) << "in BMP char";
232  EXPECT_THAT(offsetToPosition(File, 15), Pos(1, 5)) << "after BMP char";
233  EXPECT_THAT(offsetToPosition(File, 16), Pos(1, 6)) << "end of second line";
234  EXPECT_THAT(offsetToPosition(File, 17), Pos(1, 7)) << "second newline";
235  EXPECT_THAT(offsetToPosition(File, 18), Pos(2, 0)) << "start of last line";
236  EXPECT_THAT(offsetToPosition(File, 21), Pos(2, 3)) << "in last line";
237  EXPECT_THAT(offsetToPosition(File, 22), Pos(2, 4)) << "before astral char";
238  EXPECT_THAT(offsetToPosition(File, 24), Pos(2, 6)) << "in astral char";
239  EXPECT_THAT(offsetToPosition(File, 26), Pos(2, 6)) << "after astral char";
240  EXPECT_THAT(offsetToPosition(File, 28), Pos(2, 8)) << "end of last line";
241  EXPECT_THAT(offsetToPosition(File, 29), Pos(2, 9)) << "EOF";
242  EXPECT_THAT(offsetToPosition(File, 30), Pos(2, 9)) << "out of bounds";
243 
244  // Codepoints are similar, except near astral characters.
246  EXPECT_THAT(offsetToPosition(File, 0), Pos(0, 0)) << "start of file";
247  EXPECT_THAT(offsetToPosition(File, 3), Pos(0, 3)) << "in first line";
248  EXPECT_THAT(offsetToPosition(File, 6), Pos(0, 6)) << "end of first line";
249  EXPECT_THAT(offsetToPosition(File, 7), Pos(0, 7)) << "first newline";
250  EXPECT_THAT(offsetToPosition(File, 8), Pos(1, 0)) << "start of second line";
251  EXPECT_THAT(offsetToPosition(File, 12), Pos(1, 4)) << "before BMP char";
252  EXPECT_THAT(offsetToPosition(File, 13), Pos(1, 5)) << "in BMP char";
253  EXPECT_THAT(offsetToPosition(File, 15), Pos(1, 5)) << "after BMP char";
254  EXPECT_THAT(offsetToPosition(File, 16), Pos(1, 6)) << "end of second line";
255  EXPECT_THAT(offsetToPosition(File, 17), Pos(1, 7)) << "second newline";
256  EXPECT_THAT(offsetToPosition(File, 18), Pos(2, 0)) << "start of last line";
257  EXPECT_THAT(offsetToPosition(File, 21), Pos(2, 3)) << "in last line";
258  EXPECT_THAT(offsetToPosition(File, 22), Pos(2, 4)) << "before astral char";
259  EXPECT_THAT(offsetToPosition(File, 24), Pos(2, 5)) << "in astral char";
260  EXPECT_THAT(offsetToPosition(File, 26), Pos(2, 5)) << "after astral char";
261  EXPECT_THAT(offsetToPosition(File, 28), Pos(2, 7)) << "end of last line";
262  EXPECT_THAT(offsetToPosition(File, 29), Pos(2, 8)) << "EOF";
263  EXPECT_THAT(offsetToPosition(File, 30), Pos(2, 8)) << "out of bounds";
264 
266  for (Line L : FileLines) {
267  for (unsigned I = 0; I <= L.Length; ++I)
268  EXPECT_THAT(offsetToPosition(File, L.Offset + I), Pos(L.Number, I));
269  }
270  EXPECT_THAT(offsetToPosition(File, 30), Pos(2, 11)) << "out of bounds";
271 }
272 
273 TEST(SourceCodeTests, IsRangeConsecutive) {
274  EXPECT_TRUE(isRangeConsecutive(range({2, 2}, {2, 3}), range({2, 3}, {2, 4})));
275  EXPECT_FALSE(
276  isRangeConsecutive(range({0, 2}, {0, 3}), range({2, 3}, {2, 4})));
277  EXPECT_FALSE(
278  isRangeConsecutive(range({2, 2}, {2, 3}), range({2, 4}, {2, 5})));
279 }
280 
281 TEST(SourceCodeTests, SourceLocationInMainFile) {
282  Annotations Source(R"cpp(
283  ^in^t ^foo
284  ^bar
285  ^baz ^() {} {} {} {} { }^
286 )cpp");
287 
288  SourceManagerForFile Owner("foo.cpp", Source.code());
289  SourceManager &SM = Owner.get();
290 
291  SourceLocation StartOfFile = SM.getLocForStartOfFile(SM.getMainFileID());
292  EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(0, 0)),
293  HasValue(StartOfFile));
294  // End of file.
295  EXPECT_THAT_EXPECTED(
296  sourceLocationInMainFile(SM, position(4, 0)),
297  HasValue(StartOfFile.getLocWithOffset(Source.code().size())));
298  // Column number is too large.
299  EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(0, 1)), Failed());
300  EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(0, 100)),
301  Failed());
302  EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(4, 1)), Failed());
303  // Line number is too large.
304  EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(5, 0)), Failed());
305  // Check all positions mentioned in the test return valid results.
306  for (auto P : Source.points()) {
307  size_t Offset = llvm::cantFail(positionToOffset(Source.code(), P));
308  EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, P),
309  HasValue(StartOfFile.getLocWithOffset(Offset)));
310  }
311 }
312 
313 TEST(SourceCodeTests, CollectIdentifiers) {
314  auto Style = format::getLLVMStyle();
315  auto IDs = collectIdentifiers(R"cpp(
316  #include "a.h"
317  void foo() { int xyz; int abc = xyz; return foo(); }
318  )cpp",
319  Style);
320  EXPECT_EQ(IDs.size(), 7u);
321  EXPECT_EQ(IDs["include"], 1u);
322  EXPECT_EQ(IDs["void"], 1u);
323  EXPECT_EQ(IDs["int"], 2u);
324  EXPECT_EQ(IDs["xyz"], 2u);
325  EXPECT_EQ(IDs["abc"], 1u);
326  EXPECT_EQ(IDs["return"], 1u);
327  EXPECT_EQ(IDs["foo"], 2u);
328 }
329 
330 TEST(SourceCodeTests, CollectWords) {
331  auto Words = collectWords(R"cpp(
332  #define FIZZ_BUZZ
333  // this is a comment
334  std::string getSomeText() { return "magic word"; }
335  )cpp");
336  std::set<std::string> ActualWords(Words.keys().begin(), Words.keys().end());
337  std::set<std::string> ExpectedWords = {"define", "fizz", "buzz", "this",
338  "comment", "string", "some", "text",
339  "return", "magic", "word"};
340  EXPECT_EQ(ActualWords, ExpectedWords);
341 }
342 
343 TEST(SourceCodeTests, VisibleNamespaces) {
344  std::vector<std::pair<const char *, std::vector<std::string>>> Cases = {
345  {
346  R"cpp(
347  // Using directive resolved against enclosing namespaces.
348  using namespace foo;
349  namespace ns {
350  using namespace bar;
351  )cpp",
352  {"ns", "", "bar", "foo", "ns::bar"},
353  },
354  {
355  R"cpp(
356  // Don't include namespaces we've closed, ignore namespace aliases.
357  using namespace clang;
358  using std::swap;
359  namespace clang {
360  namespace clangd {}
361  namespace ll = ::llvm;
362  }
363  namespace clang {
364  )cpp",
365  {"clang", ""},
366  },
367  {
368  R"cpp(
369  // Using directives visible even if a namespace is reopened.
370  // Ignore anonymous namespaces.
371  namespace foo{ using namespace bar; }
372  namespace foo{ namespace {
373  )cpp",
374  {"foo", "", "bar", "foo::bar"},
375  },
376  {
377  R"cpp(
378  // Mismatched braces
379  namespace foo{}
380  }}}
381  namespace bar{
382  )cpp",
383  {"bar", ""},
384  },
385  {
386  R"cpp(
387  // Namespaces with multiple chunks.
388  namespace a::b {
389  using namespace c::d;
390  namespace e::f {
391  )cpp",
392  {
393  "a::b::e::f",
394  "",
395  "a",
396  "a::b",
397  "a::b::c::d",
398  "a::b::e",
399  "a::c::d",
400  "c::d",
401  },
402  },
403  };
404  for (const auto& Case : Cases) {
405  EXPECT_EQ(Case.second,
406  visibleNamespaces(Case.first, format::getLLVMStyle()))
407  << Case.first;
408  }
409 }
410 
411 TEST(SourceCodeTests, GetMacros) {
412  Annotations Code(R"cpp(
413  #define MACRO 123
414  int abc = MA^CRO;
415  )cpp");
416  TestTU TU = TestTU::withCode(Code.code());
417  auto AST = TU.build();
418  auto Loc = getBeginningOfIdentifier(AST, Code.point(),
419  AST.getSourceManager().getMainFileID());
420  auto Result = locateMacroAt(Loc, AST.getPreprocessor());
421  ASSERT_TRUE(Result);
422  EXPECT_THAT(*Result, MacroName("MACRO"));
423 }
424 
425 TEST(SourceCodeTests, IsInsideMainFile){
426  TestTU TU;
427  TU.HeaderCode = R"cpp(
428  #define DEFINE_CLASS(X) class X {};
429  #define DEFINE_YY DEFINE_CLASS(YY)
430 
431  class Header1 {};
432  DEFINE_CLASS(Header2)
433  class Header {};
434  )cpp";
435  TU.Code = R"cpp(
436  class Main1 {};
437  DEFINE_CLASS(Main2)
438  DEFINE_YY
439  class Main {};
440  )cpp";
441  TU.ExtraArgs.push_back("-DHeader=Header3");
442  TU.ExtraArgs.push_back("-DMain=Main3");
443  auto AST = TU.build();
444  const auto& SM = AST.getSourceManager();
445  auto DeclLoc = [&AST](llvm::StringRef Name) {
446  return findDecl(AST, Name).getLocation();
447  };
448  for (const auto *HeaderDecl : {"Header1", "Header2", "Header3"})
449  EXPECT_FALSE(isInsideMainFile(DeclLoc(HeaderDecl), SM));
450 
451  for (const auto *MainDecl : {"Main1", "Main2", "Main3", "YY"})
452  EXPECT_TRUE(isInsideMainFile(DeclLoc(MainDecl), SM));
453 }
454 
455 // Test for functions toHalfOpenFileRange and getHalfOpenFileRange
456 TEST(SourceCodeTests, HalfOpenFileRange) {
457  // Each marked range should be the file range of the decl with the same name
458  // and each name should be unique.
459  Annotations Test(R"cpp(
460  #define FOO(X, Y) int Y = ++X
461  #define BAR(X) X + 1
462  #define ECHO(X) X
463 
464  #define BUZZ BAZZ(ADD)
465  #define BAZZ(m) m(1)
466  #define ADD(a) int f = a + 1;
467  template<typename T>
468  class P {};
469 
470  int main() {
471  $a[[P<P<P<P<P<int>>>>> a]];
472  $b[[int b = 1]];
473  $c[[FOO(b, c)]];
474  $d[[FOO(BAR(BAR(b)), d)]];
475  // FIXME: We might want to select everything inside the outer ECHO.
476  ECHO(ECHO($e[[int) ECHO(e]]));
477  // Shouldn't crash.
478  $f[[BUZZ]];
479  }
480  )cpp");
481 
482  ParsedAST AST = TestTU::withCode(Test.code()).build();
483  llvm::errs() << Test.code();
484  const SourceManager &SM = AST.getSourceManager();
485  const LangOptions &LangOpts = AST.getASTContext().getLangOpts();
486  // Turn a SourceLocation into a pair of positions
487  auto SourceRangeToRange = [&SM](SourceRange SrcRange) {
488  return Range{sourceLocToPosition(SM, SrcRange.getBegin()),
489  sourceLocToPosition(SM, SrcRange.getEnd())};
490  };
491  auto CheckRange = [&](llvm::StringRef Name) {
492  const NamedDecl &Decl = findUnqualifiedDecl(AST, Name);
493  auto FileRange = toHalfOpenFileRange(SM, LangOpts, Decl.getSourceRange());
494  SCOPED_TRACE("Checking range: " + Name);
495  ASSERT_NE(FileRange, llvm::None);
496  Range HalfOpenRange = SourceRangeToRange(*FileRange);
497  EXPECT_EQ(HalfOpenRange, Test.ranges(Name)[0]);
498  };
499 
500  CheckRange("a");
501  CheckRange("b");
502  CheckRange("c");
503  CheckRange("d");
504  CheckRange("e");
505  CheckRange("f");
506 }
507 
508 } // namespace
509 } // namespace clangd
510 } // namespace clang
SourceLocation Loc
&#39;#&#39; location in the include directive
llvm::StringSet collectWords(llvm::StringRef Content)
Collects words from the source code.
Definition: SourceCode.cpp:758
OptionalMatcher< InnerMatcher > HasValue(const InnerMatcher &inner_matcher)
MATCHER_P(Named, N, "")
unsigned Offset
size_t lspLength(llvm::StringRef Code)
Definition: SourceCode.cpp:117
bool isInsideMainFile(SourceLocation Loc, const SourceManager &SM)
Returns true iff Loc is inside the main file.
Definition: SourceCode.cpp:372
Documents should not be synced at all.
const NamedDecl & findUnqualifiedDecl(ParsedAST &AST, llvm::StringRef Name)
Definition: TestTU.cpp:155
llvm::Expected< SourceLocation > sourceLocationInMainFile(const SourceManager &SM, Position P)
Return the file location, corresponding to P.
Definition: SourceCode.cpp:408
std::vector< std::string > visibleNamespaces(llvm::StringRef Code, const format::FormatStyle &Style)
Heuristically determine namespaces visible at a point, without parsing Code.
Definition: SourceCode.cpp:708
bool isRangeConsecutive(const Range &Left, const Range &Right)
Definition: SourceCode.cpp:507
SourceLocation getBeginningOfIdentifier(const ParsedAST &Unit, const Position &Pos, const FileID FID)
Get the beginning SourceLocation at a specified Pos.
Definition: ClangdUnit.cpp:659
Position offsetToPosition(llvm::StringRef Code, size_t Offset)
Turn an offset in Code into a [line, column] pair.
Definition: SourceCode.cpp:174
TEST(BackgroundQueueTest, Priority)
llvm::Expected< size_t > positionToOffset(llvm::StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Turn a [line, column] pair into an offset in Code.
Definition: SourceCode.cpp:141
static constexpr llvm::StringLiteral Name
Key< OffsetEncoding > kCurrentOffsetEncoding
Definition: SourceCode.cpp:110
Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc)
Turn a SourceLocation into a [line, column] pair.
Definition: SourceCode.cpp:186
static TestTU withCode(llvm::StringRef Code)
Definition: TestTU.h:33
llvm::Optional< SourceRange > toHalfOpenFileRange(const SourceManager &SM, const LangOptions &LangOpts, SourceRange R)
Turns a token range into a half-open range and checks its correctness.
Definition: SourceCode.cpp:376
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
CharSourceRange Range
SourceRange for the file name.
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
Definition: Rename.cpp:36
unsigned Length
llvm::StringMap< unsigned > collectIdentifiers(llvm::StringRef Content, const format::FormatStyle &Style)
Collects identifiers with counts in the source code.
Definition: SourceCode.cpp:567
llvm::Optional< DefinedMacro > locateMacroAt(SourceLocation Loc, Preprocessor &PP)
Definition: SourceCode.cpp:796
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
Definition: TestTU.cpp:114