clang-tools  10.0.0git
TweakTests.cpp
Go to the documentation of this file.
1 //===-- TweakTests.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 
9 #include "Annotations.h"
10 #include "SourceCode.h"
11 #include "TestFS.h"
12 #include "TestTU.h"
13 #include "TweakTesting.h"
14 #include "refactor/Tweak.h"
15 #include "clang/AST/Expr.h"
16 #include "clang/Basic/Diagnostic.h"
17 #include "clang/Basic/DiagnosticIDs.h"
18 #include "clang/Basic/DiagnosticOptions.h"
19 #include "clang/Basic/FileManager.h"
20 #include "clang/Basic/FileSystemOptions.h"
21 #include "clang/Basic/LLVM.h"
22 #include "clang/Basic/SourceLocation.h"
23 #include "clang/Basic/SourceManager.h"
24 #include "clang/Rewrite/Core/Rewriter.h"
25 #include "clang/Tooling/Core/Replacement.h"
26 #include "llvm/ADT/IntrusiveRefCntPtr.h"
27 #include "llvm/ADT/StringExtras.h"
28 #include "llvm/ADT/StringMap.h"
29 #include "llvm/ADT/StringRef.h"
30 #include "llvm/Support/Error.h"
31 #include "llvm/Support/MemoryBuffer.h"
32 #include "llvm/Support/VirtualFileSystem.h"
33 #include "llvm/Testing/Support/Error.h"
34 #include "gmock/gmock-matchers.h"
35 #include "gmock/gmock.h"
36 #include "gtest/gtest.h"
37 #include <cassert>
38 #include <string>
39 #include <utility>
40 #include <vector>
41 
42 using ::testing::AllOf;
43 using ::testing::ElementsAre;
44 using ::testing::HasSubstr;
45 using ::testing::StartsWith;
46 
47 namespace clang {
48 namespace clangd {
49 namespace {
50 
51 MATCHER_P2(FileWithContents, FileName, Contents, "") {
52  return arg.first() == FileName && arg.second == Contents;
53 }
54 
55 TEST(FileEdits, AbsolutePath) {
56  auto RelPaths = {"a.h", "foo.cpp", "test/test.cpp"};
57 
58  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> MemFS(
60  MemFS->setCurrentWorkingDirectory(testRoot());
61  for (auto Path : RelPaths)
62  MemFS->addFile(Path, 0, llvm::MemoryBuffer::getMemBuffer("", Path));
63  FileManager FM(FileSystemOptions(), MemFS);
64  DiagnosticsEngine DE(new DiagnosticIDs, new DiagnosticOptions);
65  SourceManager SM(DE, FM);
66 
67  for (auto Path : RelPaths) {
68  auto FID = SM.createFileID(*FM.getFile(Path), SourceLocation(),
69  clang::SrcMgr::C_User);
70  auto Res = Tweak::Effect::fileEdit(SM, FID, tooling::Replacements());
71  ASSERT_THAT_EXPECTED(Res, llvm::Succeeded());
72  EXPECT_EQ(Res->first, testPath(Path));
73  }
74 }
75 
76 TWEAK_TEST(SwapIfBranches);
77 TEST_F(SwapIfBranchesTest, Test) {
78  Context = Function;
79  EXPECT_EQ(apply("^if (true) {return 100;} else {continue;}"),
80  "if (true) {continue;} else {return 100;}");
81  EXPECT_EQ(apply("^if () {return 100;} else {continue;}"),
82  "if () {continue;} else {return 100;}")
83  << "broken condition";
84  EXPECT_AVAILABLE("^i^f^^(^t^r^u^e^) { return 100; } ^e^l^s^e^ { continue; }");
85  EXPECT_UNAVAILABLE("if (true) {^return ^100;^ } else { ^continue^;^ }");
86  // Available in subexpressions of the condition;
87  EXPECT_THAT("if(2 + [[2]] + 2) { return 2 + 2 + 2; } else {continue;}",
88  isAvailable());
89  // But not as part of the branches.
90  EXPECT_THAT("if(2 + 2 + 2) { return 2 + [[2]] + 2; } else { continue; }",
91  Not(isAvailable()));
92  // Range covers the "else" token, so available.
93  EXPECT_THAT("if(2 + 2 + 2) { return 2 + [[2 + 2; } else {continue;]]}",
94  isAvailable());
95  // Not available in compound statements in condition.
96  EXPECT_THAT(
97  "if([]{return [[true]];}()) { return 2 + 2 + 2; } else { continue; }",
98  Not(isAvailable()));
99  // Not available if both sides aren't braced.
100  EXPECT_THAT("^if (1) return; else { return; }", Not(isAvailable()));
101  // Only one if statement is supported!
102  EXPECT_THAT("[[if(1){}else{}if(2){}else{}]]", Not(isAvailable()));
103 }
104 
105 TWEAK_TEST(RawStringLiteral);
106 TEST_F(RawStringLiteralTest, Test) {
107  Context = Expression;
108  EXPECT_AVAILABLE(R"cpp(^"^f^o^o^\^n^")cpp");
109  EXPECT_AVAILABLE(R"cpp(R"(multi )" ^"token " "str\ning")cpp");
110  EXPECT_UNAVAILABLE(R"cpp(^"f^o^o^o")cpp"); // no chars need escaping
111  EXPECT_UNAVAILABLE(R"cpp(R"(multi )" ^"token " u8"str\ning")cpp"); // nonascii
112  EXPECT_UNAVAILABLE(R"cpp(^R^"^(^multi )" "token " "str\ning")cpp"); // raw
113  EXPECT_UNAVAILABLE(R"cpp(^"token\n" __FILE__)cpp"); // chunk is macro
114  EXPECT_UNAVAILABLE(R"cpp(^"a\r\n";)cpp"); // forbidden escape char
115 
116  const char *Input = R"cpp(R"(multi
117 token)" "\nst^ring\n" "literal")cpp";
118  const char *Output = R"cpp(R"(multi
119 token
120 string
121 literal)")cpp";
122  EXPECT_EQ(apply(Input), Output);
123 }
124 
125 TWEAK_TEST(ObjCLocalizeStringLiteral);
126 TEST_F(ObjCLocalizeStringLiteralTest, Test) {
127  ExtraArgs.push_back("-x");
128  ExtraArgs.push_back("objective-c");
129 
130  // Ensure the action can be initiated in the string literal.
131  EXPECT_AVAILABLE(R"(id x = ^[[@[[^"^t^est^"]]]];)");
132 
133  // Ensure that the action can't be initiated in other places.
134  EXPECT_UNAVAILABLE(R"([[i^d ^[[x]] ^= @"test";^]])");
135 
136  // Ensure that the action is not available for regular C strings.
137  EXPECT_UNAVAILABLE(R"(const char * x= "^test";)");
138 
139  const char *Input = R"(id x = [[@"test"]];)";
140  const char *Output = R"(id x = NSLocalizedString(@"test", @"");)";
141  EXPECT_EQ(apply(Input), Output);
142 }
143 
144 TWEAK_TEST(DumpAST);
145 TEST_F(DumpASTTest, Test) {
146  EXPECT_AVAILABLE("^int f^oo() { re^turn 2 ^+ 2; }");
147  EXPECT_UNAVAILABLE("/*c^omment*/ int foo() return 2 ^ + 2; }");
148  EXPECT_THAT(apply("int x = 2 ^+ 2;"),
149  AllOf(StartsWith("message:"), HasSubstr("BinaryOperator"),
150  HasSubstr("'+'"), HasSubstr("|-IntegerLiteral"),
151  HasSubstr("<col:9> 'int' 2\n`-IntegerLiteral"),
152  HasSubstr("<col:13> 'int' 2")));
153 }
154 
155 TWEAK_TEST(DumpSymbol);
156 TEST_F(DumpSymbolTest, Test) {
157  std::string ID = R"("id":"CA2EBE44A1D76D2A")";
158  std::string USR = R"("usr":"c:@F@foo#")";
159  EXPECT_THAT(apply("void f^oo();"),
160  AllOf(StartsWith("message:"), testing::HasSubstr(ID),
161  testing::HasSubstr(USR)));
162 }
163 
164 TWEAK_TEST(ShowSelectionTree);
165 TEST_F(ShowSelectionTreeTest, Test) {
166  EXPECT_AVAILABLE("^int f^oo() { re^turn 2 ^+ 2; }");
167  EXPECT_AVAILABLE("/*c^omment*/ int foo() return 2 ^ + 2; }");
168 
169  const char *Output = R"(message:
170  TranslationUnitDecl
171  VarDecl int x = fcall(2 + 2)
172  .CallExpr fcall(2 + 2)
173  ImplicitCastExpr fcall
174  .DeclRefExpr fcall
175  .BinaryOperator 2 + 2
176  *IntegerLiteral 2
177 )";
178  EXPECT_EQ(apply("int fcall(int); int x = fca[[ll(2 +]]2);"), Output);
179 }
180 
181 TWEAK_TEST(DumpRecordLayout);
182 TEST_F(DumpRecordLayoutTest, Test) {
183  EXPECT_AVAILABLE("^s^truct ^X ^{ int x; ^};");
184  EXPECT_THAT("struct X { int ^a; };", Not(isAvailable()));
185  EXPECT_THAT("struct ^X;", Not(isAvailable()));
186  EXPECT_THAT("template <typename T> struct ^X { T t; };", Not(isAvailable()));
187  EXPECT_THAT("enum ^X {};", Not(isAvailable()));
188 
189  EXPECT_THAT(apply("struct ^X { int x; int y; }"),
190  AllOf(StartsWith("message:"), HasSubstr("0 | int x")));
191 }
192 
193 TWEAK_TEST(ExtractVariable);
194 TEST_F(ExtractVariableTest, Test) {
195  const char *AvailableCases = R"cpp(
196  int xyz(int a = 1) {
197  struct T {
198  int bar(int a = 1);
199  int z;
200  } t;
201  // return statement
202  return [[[[t.b[[a]]r]](t.z)]];
203  }
204  void f() {
205  int a = [[5 +]] [[4 * [[[[xyz]]()]]]];
206  // multivariable initialization
207  if(1)
208  int x = [[1]], y = [[a + 1]], a = [[1]], z = a + 1;
209  // if without else
210  if([[1]])
211  a = [[1]];
212  // if with else
213  if(a < [[3]])
214  if(a == [[4]])
215  a = [[5]];
216  else
217  a = [[5]];
218  else if (a < [[4]])
219  a = [[4]];
220  else
221  a = [[5]];
222  // for loop
223  for(a = [[1]]; a > [[[[3]] + [[4]]]]; a++)
224  a = [[2]];
225  // while
226  while(a < [[1]])
227  a = [[1]];
228  // do while
229  do
230  a = [[1]];
231  while(a < [[3]]);
232  }
233  )cpp";
234  EXPECT_AVAILABLE(AvailableCases);
235 
236  const char *NoCrashCases = R"cpp(
237  template<typename T, typename ...Args>
238  struct Test<T, Args...> {
239  Test(const T &v) :val[[(^]]) {}
240  T val;
241  };
242  )cpp";
243  EXPECT_UNAVAILABLE(NoCrashCases);
244 
245  const char *UnavailableCases = R"cpp(
246  int xyz(int a = [[1]]) {
247  struct T {
248  int bar(int a = [[1]]);
249  int z = [[1]];
250  } t;
251  return [[t]].bar([[[[t]].z]]);
252  }
253  void v() { return; }
254  // function default argument
255  void f(int b = [[1]]) {
256  // empty selection
257  int a = ^1 ^+ ^2;
258  // void expressions
259  auto i = new int, j = new int;
260  [[[[delete i]], delete j]];
261  [[v]]();
262  // if
263  if(1)
264  int x = 1, y = a + 1, a = 1, z = [[a + 1]];
265  if(int a = 1)
266  if([[a + 1]] == 4)
267  a = [[[[a]] +]] 1;
268  // for loop
269  for(int a = 1, b = 2, c = 3; a > [[b + c]]; [[a++]])
270  a = [[a + 1]];
271  // lambda
272  auto lamb = [&[[a]], &[[b]]](int r = [[1]]) {return 1;}
273  // assignment
274  xyz([[a = 5]]);
275  xyz([[a *= 5]]);
276  // Variable DeclRefExpr
277  a = [[b]];
278  // statement expression
279  [[xyz()]];
280  while (a)
281  [[++a]];
282  // label statement
283  goto label;
284  label:
285  a = [[1]];
286  }
287  )cpp";
288  EXPECT_UNAVAILABLE(UnavailableCases);
289 
290  // vector of pairs of input and output strings
291  const std::vector<std::pair<std::string, std::string>>
292  InputOutputs = {
293  // extraction from variable declaration/assignment
294  {R"cpp(void varDecl() {
295  int a = 5 * (4 + (3 [[- 1)]]);
296  })cpp",
297  R"cpp(void varDecl() {
298  auto dummy = (3 - 1); int a = 5 * (4 + dummy);
299  })cpp"},
300  // FIXME: extraction from switch case
301  /*{R"cpp(void f(int a) {
302  if(1)
303  while(a < 1)
304  switch (1) {
305  case 1:
306  a = [[1 + 2]];
307  break;
308  default:
309  break;
310  }
311  })cpp",
312  R"cpp(void f(int a) {
313  auto dummy = 1 + 2; if(1)
314  while(a < 1)
315  switch (1) {
316  case 1:
317  a = dummy;
318  break;
319  default:
320  break;
321  }
322  })cpp"},*/
323  // Macros
324  {R"cpp(#define PLUS(x) x++
325  void f(int a) {
326  int y = PLUS([[1+a]]);
327  })cpp",
328  /*FIXME: It should be extracted like this.
329  R"cpp(#define PLUS(x) x++
330  void f(int a) {
331  auto dummy = 1+a; int y = PLUS(dummy);
332  })cpp"},*/
333  R"cpp(#define PLUS(x) x++
334  void f(int a) {
335  auto dummy = PLUS(1+a); int y = dummy;
336  })cpp"},
337  // ensure InsertionPoint isn't inside a macro
338  {R"cpp(#define LOOP(x) while (1) {a = x;}
339  void f(int a) {
340  if(1)
341  LOOP(5 + [[3]])
342  })cpp",
343  R"cpp(#define LOOP(x) while (1) {a = x;}
344  void f(int a) {
345  auto dummy = 3; if(1)
346  LOOP(5 + dummy)
347  })cpp"},
348  {R"cpp(#define LOOP(x) do {x;} while(1);
349  void f(int a) {
350  if(1)
351  LOOP(5 + [[3]])
352  })cpp",
353  R"cpp(#define LOOP(x) do {x;} while(1);
354  void f(int a) {
355  auto dummy = 3; if(1)
356  LOOP(5 + dummy)
357  })cpp"},
358  // attribute testing
359  {R"cpp(void f(int a) {
360  [ [gsl::suppress("type")] ] for (;;) a = [[1]];
361  })cpp",
362  R"cpp(void f(int a) {
363  auto dummy = 1; [ [gsl::suppress("type")] ] for (;;) a = dummy;
364  })cpp"},
365  // MemberExpr
366  {R"cpp(class T {
367  T f() {
368  return [[T().f()]].f();
369  }
370  };)cpp",
371  R"cpp(class T {
372  T f() {
373  auto dummy = T().f(); return dummy.f();
374  }
375  };)cpp"},
376  // Function DeclRefExpr
377  {R"cpp(int f() {
378  return [[f]]();
379  })cpp",
380  R"cpp(int f() {
381  auto dummy = f(); return dummy;
382  })cpp"},
383  // FIXME: Wrong result for \[\[clang::uninitialized\]\] int b = [[1]];
384  // since the attr is inside the DeclStmt and the bounds of
385  // DeclStmt don't cover the attribute.
386 
387  // Binary subexpressions
388  {R"cpp(void f() {
389  int x = 1 + [[2 + 3 + 4]] + 5;
390  })cpp",
391  R"cpp(void f() {
392  auto dummy = 2 + 3 + 4; int x = 1 + dummy + 5;
393  })cpp"},
394  {R"cpp(void f() {
395  int x = [[1 + 2 + 3]] + 4 + 5;
396  })cpp",
397  R"cpp(void f() {
398  auto dummy = 1 + 2 + 3; int x = dummy + 4 + 5;
399  })cpp"},
400  {R"cpp(void f() {
401  int x = 1 + 2 + [[3 + 4 + 5]];
402  })cpp",
403  R"cpp(void f() {
404  auto dummy = 3 + 4 + 5; int x = 1 + 2 + dummy;
405  })cpp"},
406  // Non-associative operations have no special support
407  {R"cpp(void f() {
408  int x = 1 - [[2 - 3 - 4]] - 5;
409  })cpp",
410  R"cpp(void f() {
411  auto dummy = 1 - 2 - 3 - 4; int x = dummy - 5;
412  })cpp"},
413  // A mix of associative operators isn't associative.
414  {R"cpp(void f() {
415  int x = 0 + 1 * [[2 + 3]] * 4 + 5;
416  })cpp",
417  R"cpp(void f() {
418  auto dummy = 1 * 2 + 3 * 4; int x = 0 + dummy + 5;
419  })cpp"},
420  // Overloaded operators are supported, we assume associativity
421  // as if they were built-in.
422  {R"cpp(struct S {
423  S(int);
424  };
425  S operator+(S, S);
426 
427  void f() {
428  S x = S(1) + [[S(2) + S(3) + S(4)]] + S(5);
429  })cpp",
430  R"cpp(struct S {
431  S(int);
432  };
433  S operator+(S, S);
434 
435  void f() {
436  auto dummy = S(2) + S(3) + S(4); S x = S(1) + dummy + S(5);
437  })cpp"},
438  // Don't try to analyze across macro boundaries
439  // FIXME: it'd be nice to do this someday (in a safe way)
440  {R"cpp(#define ECHO(X) X
441  void f() {
442  int x = 1 + [[ECHO(2 + 3) + 4]] + 5;
443  })cpp",
444  R"cpp(#define ECHO(X) X
445  void f() {
446  auto dummy = 1 + ECHO(2 + 3) + 4; int x = dummy + 5;
447  })cpp"},
448  {R"cpp(#define ECHO(X) X
449  void f() {
450  int x = 1 + [[ECHO(2) + ECHO(3) + 4]] + 5;
451  })cpp",
452  R"cpp(#define ECHO(X) X
453  void f() {
454  auto dummy = 1 + ECHO(2) + ECHO(3) + 4; int x = dummy + 5;
455  })cpp"},
456  };
457  for (const auto &IO : InputOutputs) {
458  EXPECT_EQ(IO.second, apply(IO.first)) << IO.first;
459  }
460 }
461 
462 TWEAK_TEST(AnnotateHighlightings);
463 TEST_F(AnnotateHighlightingsTest, Test) {
464  EXPECT_AVAILABLE("^vo^id^ ^f(^) {^}^"); // available everywhere.
465  EXPECT_AVAILABLE("[[int a; int b;]]");
466  EXPECT_EQ("void /* entity.name.function.cpp */f() {}", apply("void ^f() {}"));
467 
468  EXPECT_EQ(apply("[[void f1(); void f2();]]"),
469  "void /* entity.name.function.cpp */f1(); "
470  "void /* entity.name.function.cpp */f2();");
471 
472  EXPECT_EQ(apply("void f1(); void f2() {^}"),
473  "void f1(); "
474  "void /* entity.name.function.cpp */f2() {}");
475 }
476 
477 TWEAK_TEST(ExpandMacro);
478 TEST_F(ExpandMacroTest, Test) {
479  Header = R"cpp(
480  #define FOO 1 2 3
481  #define FUNC(X) X+X+X
482  #define EMPTY
483  #define EMPTY_FN(X)
484  )cpp";
485 
486  // Available on macro names, not available anywhere else.
487  EXPECT_AVAILABLE("^F^O^O^ BAR ^F^O^O^");
488  EXPECT_AVAILABLE("^F^U^N^C^(1)");
489  EXPECT_UNAVAILABLE("^#^d^efine^ ^XY^Z 1 ^2 ^3^");
490  EXPECT_UNAVAILABLE("FOO ^B^A^R^ FOO ^");
491  EXPECT_UNAVAILABLE("FUNC(^1^)^");
492 
493  // Works as expected on object-like macros.
494  EXPECT_EQ(apply("^FOO BAR FOO"), "1 2 3 BAR FOO");
495  EXPECT_EQ(apply("FOO BAR ^FOO"), "FOO BAR 1 2 3");
496  // And function-like macros.
497  EXPECT_EQ(apply("F^UNC(2)"), "2 + 2 + 2");
498 
499  // Works on empty macros.
500  EXPECT_EQ(apply("int a ^EMPTY;"), "int a ;");
501  EXPECT_EQ(apply("int a ^EMPTY_FN(1 2 3);"), "int a ;");
502  EXPECT_EQ(apply("int a = 123 ^EMPTY EMPTY_FN(1);"),
503  "int a = 123 EMPTY_FN(1);");
504  EXPECT_EQ(apply("int a = 123 ^EMPTY_FN(1) EMPTY;"), "int a = 123 EMPTY;");
505  EXPECT_EQ(apply("int a = 123 EMPTY_FN(1) ^EMPTY;"),
506  "int a = 123 EMPTY_FN(1) ;");
507 }
508 
509 TWEAK_TEST(ExpandAutoType);
510 TEST_F(ExpandAutoTypeTest, Test) {
511 
512  Header = R"cpp(
513  namespace ns {
514  struct Class {
515  struct Nested {};
516  }
517  void Func();
518  }
519  inline namespace inl_ns {
520  namespace {
521  struct Visible {};
522  }
523  }
524  )cpp";
525 
526  EXPECT_AVAILABLE("^a^u^t^o^ i = 0;");
527  EXPECT_UNAVAILABLE("auto ^i^ ^=^ ^0^;^");
528 
529  // check primitive type
530  EXPECT_EQ(apply("[[auto]] i = 0;"), "int i = 0;");
531  EXPECT_EQ(apply("au^to i = 0;"), "int i = 0;");
532  // check classes and namespaces
533  EXPECT_EQ(apply("^auto C = ns::Class::Nested();"),
534  "ns::Class::Nested C = ns::Class::Nested();");
535  // check that namespaces are shortened
536  EXPECT_EQ(apply("namespace ns { void f() { ^auto C = Class(); } }"),
537  "namespace ns { void f() { Class C = Class(); } }");
538  // undefined functions should not be replaced
539  EXPECT_THAT(apply("au^to x = doesnt_exist();"),
540  StartsWith("fail: Could not deduce type for 'auto' type"));
541  // function pointers should not be replaced
542  EXPECT_THAT(apply("au^to x = &ns::Func;"),
543  StartsWith("fail: Could not expand type of function pointer"));
544  // lambda types are not replaced
545  EXPECT_THAT(apply("au^to x = []{};"),
546  StartsWith("fail: Could not expand type of lambda expression"));
547  // inline namespaces
548  EXPECT_EQ(apply("au^to x = inl_ns::Visible();"),
549  "Visible x = inl_ns::Visible();");
550  // local class
551  EXPECT_EQ(apply("namespace x { void y() { struct S{}; ^auto z = S(); } }"),
552  "namespace x { void y() { struct S{}; S z = S(); } }");
553  // replace array types
554  EXPECT_EQ(apply(R"cpp(au^to x = "test")cpp"),
555  R"cpp(const char * x = "test")cpp");
556 
557  EXPECT_UNAVAILABLE("dec^ltype(au^to) x = 10;");
558 
559  // FIXME: Auto-completion in a template requires disabling delayed template
560  // parsing.
561  ExtraArgs.push_back("-fno-delayed-template-parsing");
562  // unknown types in a template should not be replaced
563  EXPECT_THAT(apply("template <typename T> void x() { ^auto y = T::z(); }"),
564  StartsWith("fail: Could not deduce type for 'auto' type"));
565 }
566 
567 TWEAK_TEST(ExtractFunction);
568 TEST_F(ExtractFunctionTest, FunctionTest) {
569  Context = Function;
570 
571  // Root statements should have common parent.
572  EXPECT_EQ(apply("for(;;) [[1+2; 1+2;]]"), "unavailable");
573  // Expressions aren't extracted.
574  EXPECT_EQ(apply("int x = 0; [[x++;]]"), "unavailable");
575  // We don't support extraction from lambdas.
576  EXPECT_EQ(apply("auto lam = [](){ [[int x;]] }; "), "unavailable");
577  // Partial statements aren't extracted.
578  EXPECT_THAT(apply("int [[x = 0]];"), "unavailable");
579 
580  // Ensure that end of Zone and Beginning of PostZone being adjacent doesn't
581  // lead to break being included in the extraction zone.
582  EXPECT_THAT(apply("for(;;) { [[int x;]]break; }"), HasSubstr("extracted"));
583  // FIXME: ExtractFunction should be unavailable inside loop construct
584  // initalizer/condition.
585  EXPECT_THAT(apply(" for([[int i = 0;]];);"), HasSubstr("extracted"));
586  // Don't extract because needs hoisting.
587  EXPECT_THAT(apply(" [[int a = 5;]] a++; "), StartsWith("fail"));
588  // Extract certain return
589  EXPECT_THAT(apply(" if(true) [[{ return; }]] "), HasSubstr("extracted"));
590  // Don't extract uncertain return
591  EXPECT_THAT(apply(" if(true) [[if (false) return;]] "), StartsWith("fail"));
592 }
593 
594 TEST_F(ExtractFunctionTest, FileTest) {
595  // Check all parameters are in order
596  std::string ParameterCheckInput = R"cpp(
597 struct Foo {
598  int x;
599 };
600 void f(int a) {
601  int b;
602  int *ptr = &a;
603  Foo foo;
604  [[a += foo.x + b;
605  *ptr++;]]
606 })cpp";
607  std::string ParameterCheckOutput = R"cpp(
608 struct Foo {
609  int x;
610 };
611 void extracted(int &a, int &b, int * &ptr, Foo &foo) {
612 a += foo.x + b;
613  *ptr++;
614 }
615 void f(int a) {
616  int b;
617  int *ptr = &a;
618  Foo foo;
619  extracted(a, b, ptr, foo);
620 })cpp";
621  EXPECT_EQ(apply(ParameterCheckInput), ParameterCheckOutput);
622 
623  // Check const qualifier
624  std::string ConstCheckInput = R"cpp(
625 void f(const int c) {
626  [[while(c) {}]]
627 })cpp";
628  std::string ConstCheckOutput = R"cpp(
629 void extracted(const int &c) {
630 while(c) {}
631 }
632 void f(const int c) {
633  extracted(c);
634 })cpp";
635  EXPECT_EQ(apply(ConstCheckInput), ConstCheckOutput);
636 
637  // Don't extract when we need to make a function as a parameter.
638  EXPECT_THAT(apply("void f() { [[int a; f();]] }"), StartsWith("fail"));
639 
640  // We don't extract from methods for now since they may involve multi-file
641  // edits
642  std::string MethodFailInput = R"cpp(
643  class T {
644  void f() {
645  [[int x;]]
646  }
647  };
648  )cpp";
649  EXPECT_EQ(apply(MethodFailInput), "unavailable");
650 
651  // We don't extract from templated functions for now as templates are hard
652  // to deal with.
653  std::string TemplateFailInput = R"cpp(
654  template<typename T>
655  void f() {
656  [[int x;]]
657  }
658  )cpp";
659  EXPECT_EQ(apply(TemplateFailInput), "unavailable");
660 
661  std::string MacroInput = R"cpp(
662  #define F(BODY) void f() { BODY }
663  F ([[int x = 0;]])
664  )cpp";
665  std::string MacroOutput = R"cpp(
666  #define F(BODY) void f() { BODY }
667  void extracted() {
668 int x = 0;
669 }
670 F (extracted();)
671  )cpp";
672  EXPECT_EQ(apply(MacroInput), MacroOutput);
673 
674  // Shouldn't crash.
675  EXPECT_EQ(apply("void f([[int a]]);"), "unavailable");
676  // Don't extract if we select the entire function body (CompoundStmt).
677  std::string CompoundFailInput = R"cpp(
678  void f() [[{
679  int a;
680  }]]
681  )cpp";
682  EXPECT_EQ(apply(CompoundFailInput), "unavailable");
683 }
684 
685 TEST_F(ExtractFunctionTest, ControlFlow) {
686  Context = Function;
687  // We should be able to extract break/continue with a parent loop/switch.
688  EXPECT_THAT(apply(" [[for(;;) if(1) break;]] "), HasSubstr("extracted"));
689  EXPECT_THAT(apply(" for(;;) [[while(1) break;]] "), HasSubstr("extracted"));
690  EXPECT_THAT(apply(" [[switch(1) { break; }]]"), HasSubstr("extracted"));
691  EXPECT_THAT(apply(" [[while(1) switch(1) { continue; }]]"),
692  HasSubstr("extracted"));
693  // Don't extract break and continue without a loop/switch parent.
694  EXPECT_THAT(apply(" for(;;) [[if(1) continue;]] "), StartsWith("fail"));
695  EXPECT_THAT(apply(" while(1) [[if(1) break;]] "), StartsWith("fail"));
696  EXPECT_THAT(apply(" switch(1) { [[break;]] }"), StartsWith("fail"));
697  EXPECT_THAT(apply(" for(;;) { [[while(1) break; break;]] }"),
698  StartsWith("fail"));
699 }
700 
701 TEST_F(ExtractFunctionTest, ExistingReturnStatement) {
702  Context = File;
703  const char* Before = R"cpp(
704  bool lucky(int N);
705  int getNum(bool Superstitious, int Min, int Max) {
706  if (Superstitious) [[{
707  for (int I = Min; I <= Max; ++I)
708  if (lucky(I))
709  return I;
710  return -1;
711  }]] else {
712  return (Min + Max) / 2;
713  }
714  }
715  )cpp";
716  // FIXME: min/max should be by value.
717  // FIXME: avoid emitting redundant braces
718  const char* After = R"cpp(
719  bool lucky(int N);
720  int extracted(int &Min, int &Max) {
721 {
722  for (int I = Min; I <= Max; ++I)
723  if (lucky(I))
724  return I;
725  return -1;
726  }
727 }
728 int getNum(bool Superstitious, int Min, int Max) {
729  if (Superstitious) return extracted(Min, Max); else {
730  return (Min + Max) / 2;
731  }
732  }
733  )cpp";
734  EXPECT_EQ(apply(Before), After);
735 }
736 
737 TWEAK_TEST(RemoveUsingNamespace);
738 TEST_F(RemoveUsingNamespaceTest, All) {
739  std::pair<llvm::StringRef /*Input*/, llvm::StringRef /*Expected*/> Cases[] = {
740  {// Remove all occurrences of ns. Qualify only unqualified.
741  R"cpp(
742  namespace ns1 { struct vector {}; }
743  namespace ns2 { struct map {}; }
744  using namespace n^s1;
745  using namespace ns2;
746  using namespace ns1;
747  int main() {
748  ns1::vector v1;
749  vector v2;
750  map m1;
751  }
752  )cpp",
753  R"cpp(
754  namespace ns1 { struct vector {}; }
755  namespace ns2 { struct map {}; }
756 
757  using namespace ns2;
758 
759  int main() {
760  ns1::vector v1;
761  ns1::vector v2;
762  map m1;
763  }
764  )cpp"},
765  {// Ident to be qualified is a macro arg.
766  R"cpp(
767  #define DECLARE(x, y) x y
768  namespace ns { struct vector {}; }
769  using namespace n^s;
770  int main() {
771  DECLARE(ns::vector, v1);
772  DECLARE(vector, v2);
773  }
774  )cpp",
775  R"cpp(
776  #define DECLARE(x, y) x y
777  namespace ns { struct vector {}; }
778 
779  int main() {
780  DECLARE(ns::vector, v1);
781  DECLARE(ns::vector, v2);
782  }
783  )cpp"},
784  {// Nested namespace: Fully qualify ident from inner ns.
785  R"cpp(
786  namespace aa { namespace bb { struct map {}; }}
787  using namespace aa::b^b;
788  int main() {
789  map m;
790  }
791  )cpp",
792  R"cpp(
793  namespace aa { namespace bb { struct map {}; }}
794 
795  int main() {
796  aa::bb::map m;
797  }
798  )cpp"},
799  {// Nested namespace: Fully qualify ident from inner ns.
800  R"cpp(
801  namespace aa { namespace bb { struct map {}; }}
802  using namespace a^a;
803  int main() {
804  bb::map m;
805  }
806  )cpp",
807  R"cpp(
808  namespace aa { namespace bb { struct map {}; }}
809 
810  int main() {
811  aa::bb::map m;
812  }
813  )cpp"},
814  {// Typedef.
815  R"cpp(
816  namespace aa { namespace bb { struct map {}; }}
817  using namespace a^a;
818  typedef bb::map map;
819  int main() { map M; }
820  )cpp",
821  R"cpp(
822  namespace aa { namespace bb { struct map {}; }}
823 
824  typedef aa::bb::map map;
825  int main() { map M; }
826  )cpp"},
827  {// FIXME: Nested namespaces: Not aware of using ns decl of outer ns.
828  R"cpp(
829  namespace aa { namespace bb { struct map {}; }}
830  using name[[space aa::b]]b;
831  using namespace aa;
832  int main() {
833  map m;
834  }
835  )cpp",
836  R"cpp(
837  namespace aa { namespace bb { struct map {}; }}
838 
839  using namespace aa;
840  int main() {
841  aa::bb::map m;
842  }
843  )cpp"},
844  {// Does not qualify ident from inner namespace.
845  R"cpp(
846  namespace aa { namespace bb { struct map {}; }}
847  using namespace aa::bb;
848  using namespace a^a;
849  int main() {
850  map m;
851  }
852  )cpp",
853  R"cpp(
854  namespace aa { namespace bb { struct map {}; }}
855  using namespace aa::bb;
856 
857  int main() {
858  map m;
859  }
860  )cpp"},
861  {// Available only for top level namespace decl.
862  R"cpp(
863  namespace aa {
864  namespace bb { struct map {}; }
865  using namespace b^b;
866  }
867  int main() { aa::map m; }
868  )cpp",
869  "unavailable"},
870  {// FIXME: Unavailable for namespaces containing using-namespace decl.
871  R"cpp(
872  namespace aa {
873  namespace bb { struct map {}; }
874  using namespace bb;
875  }
876  using namespace a^a;
877  int main() {
878  map m;
879  }
880  )cpp",
881  "unavailable"},
882  {R"cpp(
883  namespace a::b { struct Foo {}; }
884  using namespace a;
885  using namespace a::[[b]];
886  using namespace b;
887  int main() { Foo F;}
888  )cpp",
889  R"cpp(
890  namespace a::b { struct Foo {}; }
891  using namespace a;
892 
893 
894  int main() { a::b::Foo F;}
895  )cpp"},
896  {R"cpp(
897  namespace a::b { struct Foo {}; }
898  using namespace a;
899  using namespace a::b;
900  using namespace [[b]];
901  int main() { Foo F;}
902  )cpp",
903  R"cpp(
904  namespace a::b { struct Foo {}; }
905  using namespace a;
906 
907 
908  int main() { b::Foo F;}
909  )cpp"},
910  {// Enumerators.
911  R"cpp(
912  namespace tokens {
913  enum Token {
914  comma, identifier, numeric
915  };
916  }
917  using namespace tok^ens;
918  int main() {
919  auto x = comma;
920  }
921  )cpp",
922  R"cpp(
923  namespace tokens {
924  enum Token {
925  comma, identifier, numeric
926  };
927  }
928 
929  int main() {
930  auto x = tokens::comma;
931  }
932  )cpp"},
933  {// inline namespaces.
934  R"cpp(
935  namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
936  using namespace st^d;
937  int main() {
938  vector V;
939  }
940  )cpp",
941  R"cpp(
942  namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
943 
944  int main() {
945  std::vector V;
946  }
947  )cpp"}};
948  for (auto C : Cases)
949  EXPECT_EQ(C.second, apply(C.first)) << C.first;
950 }
951 
952 TWEAK_TEST(DefineInline);
953 TEST_F(DefineInlineTest, TriggersOnFunctionDecl) {
954  // Basic check for function body and signature.
955  EXPECT_AVAILABLE(R"cpp(
956  class Bar {
957  void baz();
958  };
959 
960  [[void [[Bar::[[b^a^z]]]]() [[{
961  return;
962  }]]]]
963 
964  void foo();
965  [[void [[f^o^o]]() [[{
966  return;
967  }]]]]
968  )cpp");
969 
970  EXPECT_UNAVAILABLE(R"cpp(
971  // Not a definition
972  vo^i[[d^ ^f]]^oo();
973 
974  [[vo^id ]]foo[[()]] {[[
975  [[(void)(5+3);
976  return;]]
977  }]]
978 
979  // Definition with no body.
980  class Bar { Bar() = def^ault; }
981  )cpp");
982 }
983 
984 TEST_F(DefineInlineTest, NoForwardDecl) {
985  Header = "void bar();";
986  EXPECT_UNAVAILABLE(R"cpp(
987  void bar() {
988  return;
989  }
990  // FIXME: Generate a decl in the header.
991  void fo^o() {
992  return;
993  })cpp");
994 }
995 
996 TEST_F(DefineInlineTest, ReferencedDecls) {
997  EXPECT_AVAILABLE(R"cpp(
998  void bar();
999  void foo(int test);
1000 
1001  void fo^o(int baz) {
1002  int x = 10;
1003  bar();
1004  })cpp");
1005 
1006  // Internal symbol usage.
1007  Header = "void foo(int test);";
1008  EXPECT_UNAVAILABLE(R"cpp(
1009  void bar();
1010  void fo^o(int baz) {
1011  int x = 10;
1012  bar();
1013  })cpp");
1014 
1015  // Becomes available after making symbol visible.
1016  Header = "void bar();" + Header;
1017  EXPECT_AVAILABLE(R"cpp(
1018  void fo^o(int baz) {
1019  int x = 10;
1020  bar();
1021  })cpp");
1022 
1023  // FIXME: Move declaration below bar to make it visible.
1024  Header.clear();
1025  EXPECT_UNAVAILABLE(R"cpp(
1026  void foo();
1027  void bar();
1028 
1029  void fo^o() {
1030  bar();
1031  })cpp");
1032 
1033  // Order doesn't matter within a class.
1034  EXPECT_AVAILABLE(R"cpp(
1035  class Bar {
1036  void foo();
1037  void bar();
1038  };
1039 
1040  void Bar::fo^o() {
1041  bar();
1042  })cpp");
1043 
1044  // FIXME: Perform include insertion to make symbol visible.
1045  ExtraFiles["a.h"] = "void bar();";
1046  Header = "void foo(int test);";
1047  EXPECT_UNAVAILABLE(R"cpp(
1048  #include "a.h"
1049  void fo^o(int baz) {
1050  int x = 10;
1051  bar();
1052  })cpp");
1053 }
1054 
1055 TEST_F(DefineInlineTest, TemplateSpec) {
1056  EXPECT_UNAVAILABLE(R"cpp(
1057  template <typename T> void foo();
1058  template<> void foo<char>();
1059 
1060  template<> void f^oo<int>() {
1061  })cpp");
1062  EXPECT_UNAVAILABLE(R"cpp(
1063  template <typename T> void foo();
1064 
1065  template<> void f^oo<int>() {
1066  })cpp");
1067  EXPECT_UNAVAILABLE(R"cpp(
1068  template <typename T> struct Foo { void foo(); };
1069 
1070  template <typename T> void Foo<T>::f^oo() {
1071  })cpp");
1072  EXPECT_AVAILABLE(R"cpp(
1073  template <typename T> void foo();
1074  void bar();
1075  template <> void foo<int>();
1076 
1077  template<> void f^oo<int>() {
1078  bar();
1079  })cpp");
1080 }
1081 
1082 TEST_F(DefineInlineTest, CheckForCanonDecl) {
1083  EXPECT_UNAVAILABLE(R"cpp(
1084  void foo();
1085 
1086  void bar() {}
1087  void f^oo() {
1088  // This bar normally refers to the definition just above, but it is not
1089  // visible from the forward declaration of foo.
1090  bar();
1091  })cpp");
1092  // Make it available with a forward decl.
1093  EXPECT_AVAILABLE(R"cpp(
1094  void bar();
1095  void foo();
1096 
1097  void bar() {}
1098  void f^oo() {
1099  bar();
1100  })cpp");
1101 }
1102 
1103 TEST_F(DefineInlineTest, UsingShadowDecls) {
1104  // Template body is not parsed until instantiation time on windows, which
1105  // results in arbitrary failures as function body becomes NULL.
1106  ExtraArgs.push_back("-fno-delayed-template-parsing");
1107  EXPECT_UNAVAILABLE(R"cpp(
1108  namespace ns1 { void foo(int); }
1109  namespace ns2 { void foo(int*); }
1110  template <typename T>
1111  void bar();
1112 
1113  using ns1::foo;
1114  using ns2::foo;
1115 
1116  template <typename T>
1117  void b^ar() {
1118  foo(T());
1119  })cpp");
1120 }
1121 
1122 TEST_F(DefineInlineTest, TransformNestedNamespaces) {
1123  auto Test = R"cpp(
1124  namespace a {
1125  void bar();
1126  namespace b {
1127  void baz();
1128  namespace c {
1129  void aux();
1130  }
1131  }
1132  }
1133 
1134  void foo();
1135  using namespace a;
1136  using namespace b;
1137  using namespace c;
1138  void f^oo() {
1139  bar();
1140  a::bar();
1141 
1142  baz();
1143  b::baz();
1144  a::b::baz();
1145 
1146  aux();
1147  c::aux();
1148  b::c::aux();
1149  a::b::c::aux();
1150  })cpp";
1151  auto Expected = R"cpp(
1152  namespace a {
1153  void bar();
1154  namespace b {
1155  void baz();
1156  namespace c {
1157  void aux();
1158  }
1159  }
1160  }
1161 
1162  void foo(){
1163  a::bar();
1164  a::bar();
1165 
1166  a::b::baz();
1167  a::b::baz();
1168  a::b::baz();
1169 
1170  a::b::c::aux();
1171  a::b::c::aux();
1172  a::b::c::aux();
1173  a::b::c::aux();
1174  }
1175  using namespace a;
1176  using namespace b;
1177  using namespace c;
1178  )cpp";
1179  EXPECT_EQ(apply(Test), Expected);
1180 }
1181 
1182 TEST_F(DefineInlineTest, TransformUsings) {
1183  auto Test = R"cpp(
1184  namespace a { namespace b { namespace c { void aux(); } } }
1185 
1186  void foo();
1187  void f^oo() {
1188  using namespace a;
1189  using namespace b;
1190  using namespace c;
1191  using c::aux;
1192  namespace d = c;
1193  })cpp";
1194  auto Expected = R"cpp(
1195  namespace a { namespace b { namespace c { void aux(); } } }
1196 
1197  void foo(){
1198  using namespace a;
1199  using namespace a::b;
1200  using namespace a::b::c;
1201  using a::b::c::aux;
1202  namespace d = a::b::c;
1203  }
1204  )cpp";
1205  EXPECT_EQ(apply(Test), Expected);
1206 }
1207 
1208 TEST_F(DefineInlineTest, TransformDecls) {
1209  auto Test = R"cpp(
1210  void foo();
1211  void f^oo() {
1212  class Foo {
1213  public:
1214  void foo();
1215  int x;
1216  static int y;
1217  };
1218  Foo::y = 0;
1219 
1220  enum En { Zero, One };
1221  En x = Zero;
1222 
1223  enum class EnClass { Zero, One };
1224  EnClass y = EnClass::Zero;
1225  })cpp";
1226  auto Expected = R"cpp(
1227  void foo(){
1228  class Foo {
1229  public:
1230  void foo();
1231  int x;
1232  static int y;
1233  };
1234  Foo::y = 0;
1235 
1236  enum En { Zero, One };
1237  En x = Zero;
1238 
1239  enum class EnClass { Zero, One };
1240  EnClass y = EnClass::Zero;
1241  }
1242  )cpp";
1243  EXPECT_EQ(apply(Test), Expected);
1244 }
1245 
1246 TEST_F(DefineInlineTest, TransformTemplDecls) {
1247  auto Test = R"cpp(
1248  namespace a {
1249  template <typename T> class Bar {
1250  public:
1251  void bar();
1252  };
1253  template <typename T> T bar;
1254  template <typename T> void aux() {}
1255  }
1256 
1257  void foo();
1258 
1259  using namespace a;
1260  void f^oo() {
1261  bar<Bar<int>>.bar();
1262  aux<Bar<int>>();
1263  })cpp";
1264  auto Expected = R"cpp(
1265  namespace a {
1266  template <typename T> class Bar {
1267  public:
1268  void bar();
1269  };
1270  template <typename T> T bar;
1271  template <typename T> void aux() {}
1272  }
1273 
1274  void foo(){
1275  a::bar<a::Bar<int>>.bar();
1276  a::aux<a::Bar<int>>();
1277  }
1278 
1279  using namespace a;
1280  )cpp";
1281  EXPECT_EQ(apply(Test), Expected);
1282 }
1283 
1284 TEST_F(DefineInlineTest, TransformMembers) {
1285  auto Test = R"cpp(
1286  class Foo {
1287  void foo();
1288  };
1289 
1290  void Foo::f^oo() {
1291  return;
1292  })cpp";
1293  auto Expected = R"cpp(
1294  class Foo {
1295  void foo(){
1296  return;
1297  }
1298  };
1299 
1300  )cpp";
1301  EXPECT_EQ(apply(Test), Expected);
1302 
1303  ExtraFiles["a.h"] = R"cpp(
1304  class Foo {
1305  void foo();
1306  };)cpp";
1307 
1308  llvm::StringMap<std::string> EditedFiles;
1309  Test = R"cpp(
1310  #include "a.h"
1311  void Foo::f^oo() {
1312  return;
1313  })cpp";
1314  Expected = R"cpp(
1315  #include "a.h"
1316  )cpp";
1317  EXPECT_EQ(apply(Test, &EditedFiles), Expected);
1318 
1319  Expected = R"cpp(
1320  class Foo {
1321  void foo(){
1322  return;
1323  }
1324  };)cpp";
1325  EXPECT_THAT(EditedFiles,
1326  ElementsAre(FileWithContents(testPath("a.h"), Expected)));
1327 }
1328 
1329 TEST_F(DefineInlineTest, TransformDependentTypes) {
1330  auto Test = R"cpp(
1331  namespace a {
1332  template <typename T> class Bar {};
1333  }
1334 
1335  template <typename T>
1336  void foo();
1337 
1338  using namespace a;
1339  template <typename T>
1340  void f^oo() {
1341  Bar<T> B;
1342  Bar<Bar<T>> q;
1343  })cpp";
1344  auto Expected = R"cpp(
1345  namespace a {
1346  template <typename T> class Bar {};
1347  }
1348 
1349  template <typename T>
1350  void foo(){
1351  a::Bar<T> B;
1352  a::Bar<a::Bar<T>> q;
1353  }
1354 
1355  using namespace a;
1356  )cpp";
1357 
1358  // Template body is not parsed until instantiation time on windows, which
1359  // results in arbitrary failures as function body becomes NULL.
1360  ExtraArgs.push_back("-fno-delayed-template-parsing");
1361  EXPECT_EQ(apply(Test), Expected);
1362 }
1363 
1364 TEST_F(DefineInlineTest, TransformFunctionTempls) {
1365  // Check we select correct specialization decl.
1366  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
1367  {R"cpp(
1368  template <typename T>
1369  void foo(T p);
1370 
1371  template <>
1372  void foo<int>(int p);
1373 
1374  template <>
1375  void foo<char>(char p);
1376 
1377  template <>
1378  void fo^o<int>(int p) {
1379  return;
1380  })cpp",
1381  R"cpp(
1382  template <typename T>
1383  void foo(T p);
1384 
1385  template <>
1386  void foo<int>(int p){
1387  return;
1388  }
1389 
1390  template <>
1391  void foo<char>(char p);
1392 
1393  )cpp"},
1394  {// Make sure we are not selecting the first specialization all the time.
1395  R"cpp(
1396  template <typename T>
1397  void foo(T p);
1398 
1399  template <>
1400  void foo<int>(int p);
1401 
1402  template <>
1403  void foo<char>(char p);
1404 
1405  template <>
1406  void fo^o<char>(char p) {
1407  return;
1408  })cpp",
1409  R"cpp(
1410  template <typename T>
1411  void foo(T p);
1412 
1413  template <>
1414  void foo<int>(int p);
1415 
1416  template <>
1417  void foo<char>(char p){
1418  return;
1419  }
1420 
1421  )cpp"},
1422  {R"cpp(
1423  template <typename T>
1424  void foo(T p);
1425 
1426  template <>
1427  void foo<int>(int p);
1428 
1429  template <typename T>
1430  void fo^o(T p) {
1431  return;
1432  })cpp",
1433  R"cpp(
1434  template <typename T>
1435  void foo(T p){
1436  return;
1437  }
1438 
1439  template <>
1440  void foo<int>(int p);
1441 
1442  )cpp"},
1443  };
1444  // Template body is not parsed until instantiation time on windows, which
1445  // results in arbitrary failures as function body becomes NULL.
1446  ExtraArgs.push_back("-fno-delayed-template-parsing");
1447  for (const auto &Case : Cases)
1448  EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1449 }
1450 
1451 TEST_F(DefineInlineTest, TransformTypeLocs) {
1452  auto Test = R"cpp(
1453  namespace a {
1454  template <typename T> class Bar {
1455  public:
1456  template <typename Q> class Baz {};
1457  };
1458  class Foo{};
1459  }
1460 
1461  void foo();
1462 
1463  using namespace a;
1464  void f^oo() {
1465  Bar<int> B;
1466  Foo foo;
1467  a::Bar<Bar<int>>::Baz<Bar<int>> q;
1468  })cpp";
1469  auto Expected = R"cpp(
1470  namespace a {
1471  template <typename T> class Bar {
1472  public:
1473  template <typename Q> class Baz {};
1474  };
1475  class Foo{};
1476  }
1477 
1478  void foo(){
1479  a::Bar<int> B;
1480  a::Foo foo;
1481  a::Bar<a::Bar<int>>::Baz<a::Bar<int>> q;
1482  }
1483 
1484  using namespace a;
1485  )cpp";
1486  EXPECT_EQ(apply(Test), Expected);
1487 }
1488 
1489 TEST_F(DefineInlineTest, TransformDeclRefs) {
1490  auto Test = R"cpp(
1491  namespace a {
1492  template <typename T> class Bar {
1493  public:
1494  void foo();
1495  static void bar();
1496  int x;
1497  static int y;
1498  };
1499  void bar();
1500  void test();
1501  }
1502 
1503  void foo();
1504  using namespace a;
1505  void f^oo() {
1506  a::Bar<int> B;
1507  B.foo();
1508  a::bar();
1509  Bar<Bar<int>>::bar();
1510  a::Bar<int>::bar();
1511  B.x = Bar<int>::y;
1512  Bar<int>::y = 3;
1513  bar();
1514  a::test();
1515  })cpp";
1516  auto Expected = R"cpp(
1517  namespace a {
1518  template <typename T> class Bar {
1519  public:
1520  void foo();
1521  static void bar();
1522  int x;
1523  static int y;
1524  };
1525  void bar();
1526  void test();
1527  }
1528 
1529  void foo(){
1530  a::Bar<int> B;
1531  B.foo();
1532  a::bar();
1533  a::Bar<a::Bar<int>>::bar();
1534  a::Bar<int>::bar();
1535  B.x = a::Bar<int>::y;
1536  a::Bar<int>::y = 3;
1537  a::bar();
1538  a::test();
1539  }
1540  using namespace a;
1541  )cpp";
1542  EXPECT_EQ(apply(Test), Expected);
1543 }
1544 
1545 TEST_F(DefineInlineTest, StaticMembers) {
1546  auto Test = R"cpp(
1547  namespace ns { class X { static void foo(); void bar(); }; }
1548  void ns::X::b^ar() {
1549  foo();
1550  })cpp";
1551  auto Expected = R"cpp(
1552  namespace ns { class X { static void foo(); void bar(){
1553  foo();
1554  } }; }
1555  )cpp";
1556  EXPECT_EQ(apply(Test), Expected);
1557 }
1558 
1559 TEST_F(DefineInlineTest, TransformParamNames) {
1560  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
1561  {R"cpp(
1562  void foo(int, bool b, int T\
1563 est);
1564  void ^foo(int f, bool x, int z) {})cpp",
1565  R"cpp(
1566  void foo(int f, bool x, int z){}
1567  )cpp"},
1568  {R"cpp(
1569  #define PARAM int Z
1570  void foo(PARAM);
1571 
1572  void ^foo(int X) {})cpp",
1573  "fail: Cant rename parameter inside macro body."},
1574  {R"cpp(
1575  #define TYPE int
1576  #define PARAM TYPE Z
1577  #define BODY(x) 5 * (x) + 2
1578  template <int P>
1579  void foo(PARAM, TYPE Q, TYPE, TYPE W = BODY(P));
1580  template <int x>
1581  void ^foo(int Z, int b, int c, int d) {})cpp",
1582  R"cpp(
1583  #define TYPE int
1584  #define PARAM TYPE Z
1585  #define BODY(x) 5 * (x) + 2
1586  template <int x>
1587  void foo(PARAM, TYPE b, TYPE c, TYPE d = BODY(x)){}
1588  )cpp"},
1589  };
1590  ExtraArgs.push_back("-fno-delayed-template-parsing");
1591  for (const auto &Case : Cases)
1592  EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1593 }
1594 
1595 TEST_F(DefineInlineTest, TransformTemplParamNames) {
1596  auto Test = R"cpp(
1597  struct Foo {
1598  struct Bar {
1599  template <class, class X,
1600  template<typename> class, template<typename> class Y,
1601  int, int Z>
1602  void foo(X, Y<X>, int W = 5 * Z + 2);
1603  };
1604  };
1605 
1606  template <class T, class U,
1607  template<typename> class V, template<typename> class W,
1608  int X, int Y>
1609  void Foo::Bar::f^oo(U, W<U>, int Q) {})cpp";
1610  auto Expected = R"cpp(
1611  struct Foo {
1612  struct Bar {
1613  template <class T, class U,
1614  template<typename> class V, template<typename> class W,
1615  int X, int Y>
1616  void foo(U, W<U>, int Q = 5 * Y + 2){}
1617  };
1618  };
1619 
1620  )cpp";
1621  ExtraArgs.push_back("-fno-delayed-template-parsing");
1622  EXPECT_EQ(apply(Test), Expected);
1623 }
1624 
1625 TEST_F(DefineInlineTest, TransformInlineNamespaces) {
1626  auto Test = R"cpp(
1627  namespace a { inline namespace b { namespace { struct Foo{}; } } }
1628  void foo();
1629 
1630  using namespace a;
1631  void ^foo() {Foo foo;})cpp";
1632  auto Expected = R"cpp(
1633  namespace a { inline namespace b { namespace { struct Foo{}; } } }
1634  void foo(){a::Foo foo;}
1635 
1636  using namespace a;
1637  )cpp";
1638  EXPECT_EQ(apply(Test), Expected);
1639 }
1640 
1641 TEST_F(DefineInlineTest, TokensBeforeSemicolon) {
1642  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
1643  {R"cpp(
1644  void foo() /*Comment -_-*/ /*Com 2*/ ;
1645  void fo^o() { return ; })cpp",
1646  R"cpp(
1647  void foo() /*Comment -_-*/ /*Com 2*/ { return ; }
1648  )cpp"},
1649 
1650  {R"cpp(
1651  void foo();
1652  void fo^o() { return ; })cpp",
1653  R"cpp(
1654  void foo(){ return ; }
1655  )cpp"},
1656 
1657  {R"cpp(
1658  #define SEMI ;
1659  void foo() SEMI
1660  void fo^o() { return ; })cpp",
1661  "fail: Couldn't find semicolon for target declaration."},
1662  };
1663  for (const auto &Case : Cases)
1664  EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1665 }
1666 
1667 TEST_F(DefineInlineTest, HandleMacros) {
1668  EXPECT_UNAVAILABLE(R"cpp(
1669  #define BODY { return; }
1670  void foo();
1671  void f^oo()BODY)cpp");
1672 
1673  EXPECT_UNAVAILABLE(R"cpp(
1674  #define BODY void foo(){ return; }
1675  void foo();
1676  [[BODY]])cpp");
1677 
1678  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
1679  // We don't qualify declarations coming from macros.
1680  {R"cpp(
1681  #define BODY Foo
1682  namespace a { class Foo{}; }
1683  void foo();
1684  using namespace a;
1685  void f^oo(){BODY})cpp",
1686  R"cpp(
1687  #define BODY Foo
1688  namespace a { class Foo{}; }
1689  void foo(){BODY}
1690  using namespace a;
1691  )cpp"},
1692 
1693  // Macro is not visible at declaration location, but we proceed.
1694  {R"cpp(
1695  void foo();
1696  #define BODY return;
1697  void f^oo(){BODY})cpp",
1698  R"cpp(
1699  void foo(){BODY}
1700  #define BODY return;
1701  )cpp"},
1702 
1703  {R"cpp(
1704  #define TARGET void foo()
1705  TARGET;
1706  void f^oo(){ return; })cpp",
1707  R"cpp(
1708  #define TARGET void foo()
1709  TARGET{ return; }
1710  )cpp"},
1711 
1712  {R"cpp(
1713  #define TARGET foo
1714  void TARGET();
1715  void f^oo(){ return; })cpp",
1716  R"cpp(
1717  #define TARGET foo
1718  void TARGET(){ return; }
1719  )cpp"},
1720  };
1721  for (const auto &Case : Cases)
1722  EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1723 }
1724 
1725 TEST_F(DefineInlineTest, DropCommonNameSpecifiers) {
1726  struct {
1727  llvm::StringRef Test;
1728  llvm::StringRef Expected;
1729  } Cases[] = {
1730  {R"cpp(
1731  namespace a { namespace b { void aux(); } }
1732  namespace ns1 {
1733  void foo();
1734  namespace qq { void test(); }
1735  namespace ns2 {
1736  void bar();
1737  namespace ns3 { void baz(); }
1738  }
1739  }
1740 
1741  using namespace a;
1742  using namespace a::b;
1743  using namespace ns1::qq;
1744  void ns1::ns2::ns3::b^az() {
1745  foo();
1746  bar();
1747  baz();
1748  ns1::ns2::ns3::baz();
1749  aux();
1750  test();
1751  })cpp",
1752  R"cpp(
1753  namespace a { namespace b { void aux(); } }
1754  namespace ns1 {
1755  void foo();
1756  namespace qq { void test(); }
1757  namespace ns2 {
1758  void bar();
1759  namespace ns3 { void baz(){
1760  foo();
1761  bar();
1762  baz();
1763  ns1::ns2::ns3::baz();
1764  a::b::aux();
1765  qq::test();
1766  } }
1767  }
1768  }
1769 
1770  using namespace a;
1771  using namespace a::b;
1772  using namespace ns1::qq;
1773  )cpp"},
1774  {R"cpp(
1775  namespace ns1 {
1776  namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
1777  namespace ns2 { void baz(); }
1778  }
1779 
1780  using namespace ns1::qq;
1781  void ns1::ns2::b^az() { Foo f; B b; })cpp",
1782  R"cpp(
1783  namespace ns1 {
1784  namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
1785  namespace ns2 { void baz(){ qq::Foo f; qq::B b; } }
1786  }
1787 
1788  using namespace ns1::qq;
1789  )cpp"},
1790  {R"cpp(
1791  namespace ns1 {
1792  namespace qq {
1793  template<class T> struct Foo { template <class U> struct Bar {}; };
1794  template<class T, class U>
1795  using B = typename Foo<T>::template Bar<U>;
1796  }
1797  namespace ns2 { void baz(); }
1798  }
1799 
1800  using namespace ns1::qq;
1801  void ns1::ns2::b^az() { B<int, bool> b; })cpp",
1802  R"cpp(
1803  namespace ns1 {
1804  namespace qq {
1805  template<class T> struct Foo { template <class U> struct Bar {}; };
1806  template<class T, class U>
1807  using B = typename Foo<T>::template Bar<U>;
1808  }
1809  namespace ns2 { void baz(){ qq::B<int, bool> b; } }
1810  }
1811 
1812  using namespace ns1::qq;
1813  )cpp"},
1814  };
1815  for (const auto &Case : Cases)
1816  EXPECT_EQ(apply(Case.Test), Case.Expected) << Case.Test;
1817 }
1818 
1819 TEST_F(DefineInlineTest, QualifyWithUsingDirectives) {
1820  llvm::StringRef Test = R"cpp(
1821  namespace a {
1822  void bar();
1823  namespace b { struct Foo{}; void aux(); }
1824  namespace c { void cux(); }
1825  }
1826  using namespace a;
1827  using X = b::Foo;
1828  void foo();
1829 
1830  using namespace b;
1831  using namespace c;
1832  void ^foo() {
1833  cux();
1834  bar();
1835  X x;
1836  aux();
1837  using namespace c;
1838  // FIXME: The last reference to cux() in body of foo should not be
1839  // qualified, since there is a using directive inside the function body.
1840  cux();
1841  })cpp";
1842  llvm::StringRef Expected = R"cpp(
1843  namespace a {
1844  void bar();
1845  namespace b { struct Foo{}; void aux(); }
1846  namespace c { void cux(); }
1847  }
1848  using namespace a;
1849  using X = b::Foo;
1850  void foo(){
1851  c::cux();
1852  bar();
1853  X x;
1854  b::aux();
1855  using namespace c;
1856  // FIXME: The last reference to cux() in body of foo should not be
1857  // qualified, since there is a using directive inside the function body.
1858  c::cux();
1859  }
1860 
1861  using namespace b;
1862  using namespace c;
1863  )cpp";
1864  EXPECT_EQ(apply(Test), Expected) << Test;
1865 }
1866 
1867 TEST_F(DefineInlineTest, AddInline) {
1868  ExtraArgs.push_back("-fno-delayed-template-parsing");
1869  llvm::StringMap<std::string> EditedFiles;
1870  ExtraFiles["a.h"] = "void foo();";
1871  apply(R"cpp(#include "a.h"
1872  void fo^o() {})cpp",
1873  &EditedFiles);
1874  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
1875  testPath("a.h"), "inline void foo(){}")));
1876 
1877  // Check we put inline before cv-qualifiers.
1878  ExtraFiles["a.h"] = "const int foo();";
1879  apply(R"cpp(#include "a.h"
1880  const int fo^o() {})cpp",
1881  &EditedFiles);
1882  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
1883  testPath("a.h"), "inline const int foo(){}")));
1884 
1885  // No double inline.
1886  ExtraFiles["a.h"] = "inline void foo();";
1887  apply(R"cpp(#include "a.h"
1888  inline void fo^o() {})cpp",
1889  &EditedFiles);
1890  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
1891  testPath("a.h"), "inline void foo(){}")));
1892 
1893  // Constexprs don't need "inline".
1894  ExtraFiles["a.h"] = "constexpr void foo();";
1895  apply(R"cpp(#include "a.h"
1896  constexpr void fo^o() {})cpp",
1897  &EditedFiles);
1898  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
1899  testPath("a.h"), "constexpr void foo(){}")));
1900 
1901  // Class members don't need "inline".
1902  ExtraFiles["a.h"] = "struct Foo { void foo(); }";
1903  apply(R"cpp(#include "a.h"
1904  void Foo::fo^o() {})cpp",
1905  &EditedFiles);
1906  EXPECT_THAT(EditedFiles,
1907  testing::ElementsAre(FileWithContents(
1908  testPath("a.h"), "struct Foo { void foo(){} }")));
1909 
1910  // Function template doesn't need to be "inline"d.
1911  ExtraFiles["a.h"] = "template <typename T> void foo();";
1912  apply(R"cpp(#include "a.h"
1913  template <typename T>
1914  void fo^o() {})cpp",
1915  &EditedFiles);
1916  EXPECT_THAT(EditedFiles,
1917  testing::ElementsAre(FileWithContents(
1918  testPath("a.h"), "template <typename T> void foo(){}")));
1919 
1920  // Specializations needs to be marked "inline".
1921  ExtraFiles["a.h"] = R"cpp(
1922  template <typename T> void foo();
1923  template <> void foo<int>();)cpp";
1924  apply(R"cpp(#include "a.h"
1925  template <>
1926  void fo^o<int>() {})cpp",
1927  &EditedFiles);
1928  EXPECT_THAT(EditedFiles,
1929  testing::ElementsAre(FileWithContents(testPath("a.h"),
1930  R"cpp(
1931  template <typename T> void foo();
1932  template <> inline void foo<int>(){})cpp")));
1933 }
1934 
1935 TWEAK_TEST(DefineOutline);
1936 TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
1937  FileName = "Test.cpp";
1938  // Not available unless in a header file.
1939  EXPECT_UNAVAILABLE(R"cpp(
1940  [[void [[f^o^o]]() [[{
1941  return;
1942  }]]]])cpp");
1943 
1944  FileName = "Test.hpp";
1945  // Not available unless function name or fully body is selected.
1946  EXPECT_UNAVAILABLE(R"cpp(
1947  // Not a definition
1948  vo^i[[d^ ^f]]^oo();
1949 
1950  [[vo^id ]]foo[[()]] {[[
1951  [[(void)(5+3);
1952  return;]]
1953  }]])cpp");
1954 
1955  // Available even if there are no implementation files.
1956  EXPECT_AVAILABLE(R"cpp(
1957  [[void [[f^o^o]]() [[{
1958  return;
1959  }]]]])cpp");
1960 
1961  // Not available for out-of-line methods.
1962  EXPECT_UNAVAILABLE(R"cpp(
1963  class Bar {
1964  void baz();
1965  };
1966 
1967  [[void [[Bar::[[b^a^z]]]]() [[{
1968  return;
1969  }]]]])cpp");
1970 
1971  // Basic check for function body and signature.
1972  EXPECT_AVAILABLE(R"cpp(
1973  class Bar {
1974  [[void [[f^o^o]]() [[{ return; }]]]]
1975  };
1976 
1977  void foo();
1978  [[void [[f^o^o]]() [[{
1979  return;
1980  }]]]])cpp");
1981 
1982  // Not available on defaulted/deleted members.
1983  EXPECT_UNAVAILABLE(R"cpp(
1984  class Foo {
1985  Fo^o() = default;
1986  F^oo(const Foo&) = delete;
1987  };)cpp");
1988 
1989  // Not available within templated classes, as it is hard to spell class name
1990  // out-of-line in such cases.
1991  EXPECT_UNAVAILABLE(R"cpp(
1992  template <typename> struct Foo { void fo^o(){} };
1993  })cpp");
1994 }
1995 
1996 TEST_F(DefineOutlineTest, FailsWithoutSource) {
1997  FileName = "Test.hpp";
1998  llvm::StringRef Test = "void fo^o() { return; }";
1999  llvm::StringRef Expected =
2000  "fail: Couldn't find a suitable implementation file.";
2001  EXPECT_EQ(apply(Test), Expected);
2002 }
2003 
2004 TEST_F(DefineOutlineTest, ApplyTest) {
2005  llvm::StringMap<std::string> EditedFiles;
2006  ExtraFiles["Test.cpp"] = "";
2007  FileName = "Test.hpp";
2008  // Template body is not parsed until instantiation time on windows, which
2009  // results in arbitrary failures as function body becomes NULL.
2010  ExtraArgs.push_back("-fno-delayed-template-parsing");
2011 
2012  struct {
2013  llvm::StringRef Test;
2014  llvm::StringRef ExpectedHeader;
2015  llvm::StringRef ExpectedSource;
2016  } Cases[] = {
2017  // Simple check
2018  {
2019  "void fo^o() { return; }",
2020  "void foo() ;",
2021  "void foo() { return; }",
2022  },
2023  // Templated function.
2024  {
2025  "template <typename T> void fo^o(T, T x) { return; }",
2026  "template <typename T> void foo(T, T x) ;",
2027  "template <typename T> void foo(T, T x) { return; }",
2028  },
2029  {
2030  "template <typename> void fo^o() { return; }",
2031  "template <typename> void foo() ;",
2032  "template <typename> void foo() { return; }",
2033  },
2034  // Template specialization.
2035  {
2036  R"cpp(
2037  template <typename> void foo();
2038  template <> void fo^o<int>() { return; })cpp",
2039  R"cpp(
2040  template <typename> void foo();
2041  template <> void foo<int>() ;)cpp",
2042  "template <> void foo<int>() { return; }",
2043  },
2044  // Default args.
2045  {
2046  "void fo^o(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) {}",
2047  "void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;",
2048  "void foo(int x, int y , int , int (*foo)(int) ) {}",
2049  },
2050  // Ctor initializers.
2051  {
2052  R"cpp(
2053  class Foo {
2054  int y = 2;
2055  F^oo(int z) __attribute__((weak)) : bar(2){}
2056  int bar;
2057  int z = 2;
2058  };)cpp",
2059  R"cpp(
2060  class Foo {
2061  int y = 2;
2062  Foo(int z) __attribute__((weak)) ;
2063  int bar;
2064  int z = 2;
2065  };)cpp",
2066  "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
2067  },
2068  };
2069  for (const auto &Case : Cases) {
2070  SCOPED_TRACE(Case.Test);
2071  EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
2072  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2073  testPath("Test.cpp"), Case.ExpectedSource)));
2074  }
2075 }
2076 
2077 TEST_F(DefineOutlineTest, HandleMacros) {
2078  llvm::StringMap<std::string> EditedFiles;
2079  ExtraFiles["Test.cpp"] = "";
2080  FileName = "Test.hpp";
2081 
2082  struct {
2083  llvm::StringRef Test;
2084  llvm::StringRef ExpectedHeader;
2085  llvm::StringRef ExpectedSource;
2086  } Cases[] = {
2087  {R"cpp(
2088  #define BODY { return; }
2089  void f^oo()BODY)cpp",
2090  R"cpp(
2091  #define BODY { return; }
2092  void foo();)cpp",
2093  "void foo()BODY"},
2094 
2095  {R"cpp(
2096  #define BODY return;
2097  void f^oo(){BODY})cpp",
2098  R"cpp(
2099  #define BODY return;
2100  void foo();)cpp",
2101  "void foo(){BODY}"},
2102 
2103  {R"cpp(
2104  #define TARGET void foo()
2105  [[TARGET]]{ return; })cpp",
2106  R"cpp(
2107  #define TARGET void foo()
2108  TARGET;)cpp",
2109  "TARGET{ return; }"},
2110 
2111  {R"cpp(
2112  #define TARGET foo
2113  void [[TARGET]](){ return; })cpp",
2114  R"cpp(
2115  #define TARGET foo
2116  void TARGET();)cpp",
2117  "void TARGET(){ return; }"},
2118  };
2119  for (const auto &Case : Cases) {
2120  SCOPED_TRACE(Case.Test);
2121  EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
2122  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2123  testPath("Test.cpp"), Case.ExpectedSource)));
2124  }
2125 }
2126 
2127 TEST_F(DefineOutlineTest, QualifyReturnValue) {
2128  FileName = "Test.hpp";
2129  ExtraFiles["Test.cpp"] = "";
2130 
2131  struct {
2132  llvm::StringRef Test;
2133  llvm::StringRef ExpectedHeader;
2134  llvm::StringRef ExpectedSource;
2135  } Cases[] = {
2136  {R"cpp(
2137  namespace a { class Foo; }
2138  using namespace a;
2139  Foo fo^o() { return; })cpp",
2140  R"cpp(
2141  namespace a { class Foo; }
2142  using namespace a;
2143  Foo foo() ;)cpp",
2144  "a::Foo foo() { return; }"},
2145  {R"cpp(
2146  namespace a {
2147  class Foo {
2148  class Bar {};
2149  Bar fo^o() { return {}; }
2150  };
2151  })cpp",
2152  R"cpp(
2153  namespace a {
2154  class Foo {
2155  class Bar {};
2156  Bar foo() ;
2157  };
2158  })cpp",
2159  "a::Foo::Bar a::Foo::foo() { return {}; }\n"},
2160  {R"cpp(
2161  class Foo;
2162  Foo fo^o() { return; })cpp",
2163  R"cpp(
2164  class Foo;
2165  Foo foo() ;)cpp",
2166  "Foo foo() { return; }"},
2167  };
2168  llvm::StringMap<std::string> EditedFiles;
2169  for (auto &Case : Cases) {
2170  apply(Case.Test, &EditedFiles);
2171  EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
2172  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2173  testPath("Test.cpp"), Case.ExpectedSource)));
2174  }
2175 }
2176 
2177 TEST_F(DefineOutlineTest, QualifyFunctionName) {
2178  FileName = "Test.hpp";
2179  struct {
2180  llvm::StringRef TestHeader;
2181  llvm::StringRef TestSource;
2182  llvm::StringRef ExpectedHeader;
2183  llvm::StringRef ExpectedSource;
2184  } Cases[] = {
2185  {
2186  R"cpp(
2187  namespace a {
2188  namespace b {
2189  class Foo {
2190  void fo^o() {}
2191  };
2192  }
2193  })cpp",
2194  "",
2195  R"cpp(
2196  namespace a {
2197  namespace b {
2198  class Foo {
2199  void foo() ;
2200  };
2201  }
2202  })cpp",
2203  "void a::b::Foo::foo() {}\n",
2204  },
2205  {
2206  "namespace a { namespace b { void f^oo() {} } }",
2207  "namespace a{}",
2208  "namespace a { namespace b { void foo() ; } }",
2209  "namespace a{void b::foo() {} }",
2210  },
2211  {
2212  "namespace a { namespace b { void f^oo() {} } }",
2213  "using namespace a;",
2214  "namespace a { namespace b { void foo() ; } }",
2215  // FIXME: Take using namespace directives in the source file into
2216  // account. This can be spelled as b::foo instead.
2217  "using namespace a;void a::b::foo() {} ",
2218  },
2219  };
2220  llvm::StringMap<std::string> EditedFiles;
2221  for (auto &Case : Cases) {
2222  ExtraFiles["Test.cpp"] = Case.TestSource;
2223  EXPECT_EQ(apply(Case.TestHeader, &EditedFiles), Case.ExpectedHeader);
2224  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2225  testPath("Test.cpp"), Case.ExpectedSource)))
2226  << Case.TestHeader;
2227  }
2228 }
2229 } // namespace
2230 } // namespace clangd
2231 } // namespace clang
llvm::StringRef Contents
llvm::IntrusiveRefCntPtr< llvm::vfs::InMemoryFileSystem > InMemoryFileSystem
#define TWEAK_TEST(TweakID)
Definition: TweakTesting.h:103
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
#define EXPECT_UNAVAILABLE(MarkedCode)
Definition: TweakTesting.h:115
TEST(BackgroundQueueTest, Priority)
std::string testPath(PathRef File)
Definition: TestFS.cpp:82
std::string Path
A typedef to represent a file path.
Definition: Path.h:20
const char * testRoot()
Definition: TestFS.cpp:74
PathRef FileName
llvm::StringMap< Edit > FileEdits
A mapping from absolute file path (the one used for accessing the underlying VFS) to edits...
Definition: SourceCode.h:222
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static llvm::Expected< std::pair< Path, Edit > > fileEdit(const SourceManager &SM, FileID FID, tooling::Replacements Replacements)
Path is the absolute, symlink-resolved path for the file pointed by FID in SM.
Definition: Tweak.cpp:93
std::vector< const char * > Expected
#define EXPECT_AVAILABLE(MarkedCode)
Definition: TweakTesting.h:109