clang-tools  11.0.0
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;} else {(void)0;}"),
80  "if (true) {(void)0;} else {return;}");
81  EXPECT_EQ(apply("^if (/*error-ok*/) {return;} else {(void)0;}"),
82  "if (/*error-ok*/) {(void)0;} else {return;}")
83  << "broken condition";
84  EXPECT_AVAILABLE("^i^f^^(^t^r^u^e^) { return; } ^e^l^s^e^ { return; }");
85  EXPECT_UNAVAILABLE("if (true) {^return ^;^ } else { ^return^;^ }");
86  // Available in subexpressions of the condition;
87  EXPECT_THAT("if(2 + [[2]] + 2) { return; } else {return;}", isAvailable());
88  // But not as part of the branches.
89  EXPECT_THAT("if(2 + 2 + 2) { [[return]]; } else { return; }",
90  Not(isAvailable()));
91  // Range covers the "else" token, so available.
92  EXPECT_THAT("if(2 + 2 + 2) { return[[; } else {return;]]}", isAvailable());
93  // Not available in compound statements in condition.
94  EXPECT_THAT("if([]{return [[true]];}()) { return; } else { return; }",
95  Not(isAvailable()));
96  // Not available if both sides aren't braced.
97  EXPECT_THAT("^if (1) return; else { return; }", Not(isAvailable()));
98  // Only one if statement is supported!
99  EXPECT_THAT("[[if(1){}else{}if(2){}else{}]]", Not(isAvailable()));
100 }
101 
102 TWEAK_TEST(RawStringLiteral);
103 TEST_F(RawStringLiteralTest, Test) {
104  Context = Expression;
105  EXPECT_AVAILABLE(R"cpp(^"^f^o^o^\^n^")cpp");
106  EXPECT_AVAILABLE(R"cpp(R"(multi )" ^"token " "str\ning")cpp");
107  EXPECT_UNAVAILABLE(R"cpp(^"f^o^o^o")cpp"); // no chars need escaping
108  EXPECT_UNAVAILABLE(R"cpp(R"(multi )" ^"token " u8"str\ning")cpp"); // nonascii
109  EXPECT_UNAVAILABLE(R"cpp(^R^"^(^multi )" "token " "str\ning")cpp"); // raw
110  EXPECT_UNAVAILABLE(R"cpp(^"token\n" __FILE__)cpp"); // chunk is macro
111  EXPECT_UNAVAILABLE(R"cpp(^"a\r\n";)cpp"); // forbidden escape char
112 
113  const char *Input = R"cpp(R"(multi
114 token)" "\nst^ring\n" "literal")cpp";
115  const char *Output = R"cpp(R"(multi
116 token
117 string
118 literal)")cpp";
119  EXPECT_EQ(apply(Input), Output);
120 }
121 
122 TWEAK_TEST(ObjCLocalizeStringLiteral);
123 TEST_F(ObjCLocalizeStringLiteralTest, Test) {
124  ExtraArgs.push_back("-x");
125  ExtraArgs.push_back("objective-c");
126 
127  // Ensure the action can be initiated in the string literal.
128  EXPECT_AVAILABLE(R"(id x = ^[[@[[^"^t^est^"]]]];)");
129 
130  // Ensure that the action can't be initiated in other places.
131  EXPECT_UNAVAILABLE(R"([[i^d ^[[x]] ^= @"test";^]])");
132 
133  // Ensure that the action is not available for regular C strings.
134  EXPECT_UNAVAILABLE(R"(const char * x= "^test";)");
135 
136  const char *Input = R"(id x = [[@"test"]];)";
137  const char *Output = R"(id x = NSLocalizedString(@"test", @"");)";
138  EXPECT_EQ(apply(Input), Output);
139 }
140 
141 TWEAK_TEST(DumpAST);
142 TEST_F(DumpASTTest, Test) {
143  EXPECT_AVAILABLE("^int f^oo() { re^turn 2 ^+ 2; }");
144  EXPECT_UNAVAILABLE("/*c^omment*/ int foo() { return 2 ^ + 2; }");
145  EXPECT_THAT(apply("int x = 2 ^+ 2;"),
146  AllOf(StartsWith("message:"), HasSubstr("BinaryOperator"),
147  HasSubstr("'+'"), HasSubstr("|-IntegerLiteral"),
148  HasSubstr("<col:9> 'int' 2\n`-IntegerLiteral"),
149  HasSubstr("<col:13> 'int' 2")));
150 }
151 
152 TWEAK_TEST(DumpSymbol);
153 TEST_F(DumpSymbolTest, Test) {
154  std::string ID = R"("id":"CA2EBE44A1D76D2A")";
155  std::string USR = R"("usr":"c:@F@foo#")";
156  EXPECT_THAT(apply("void f^oo();"),
157  AllOf(StartsWith("message:"), testing::HasSubstr(ID),
158  testing::HasSubstr(USR)));
159 }
160 
161 TWEAK_TEST(ShowSelectionTree);
162 TEST_F(ShowSelectionTreeTest, Test) {
163  EXPECT_AVAILABLE("^int f^oo() { re^turn 2 ^+ 2; }");
164  EXPECT_AVAILABLE("/*c^omment*/ int foo() { return 2 ^ + 2; }");
165 
166  const char *Output = R"(message:
167  TranslationUnitDecl
168  VarDecl int x = fcall(2 + 2)
169  .CallExpr fcall(2 + 2)
170  ImplicitCastExpr fcall
171  .DeclRefExpr fcall
172  .BinaryOperator 2 + 2
173  *IntegerLiteral 2
174 )";
175  EXPECT_EQ(apply("int fcall(int); int x = fca[[ll(2 +]]2);"), Output);
176 
177  Output = R"(message:
178  TranslationUnitDecl
179  FunctionDecl void x()
180  CompoundStmt { …
181  ForStmt for (;;) …
182  *BreakStmt break;
183 )";
184  EXPECT_EQ(apply("void x() { for (;;) br^eak; }"), Output);
185 }
186 
187 TWEAK_TEST(DumpRecordLayout);
188 TEST_F(DumpRecordLayoutTest, Test) {
189  EXPECT_AVAILABLE("^s^truct ^X ^{ int x; ^};");
190  EXPECT_THAT("struct X { int ^a; };", Not(isAvailable()));
191  EXPECT_THAT("struct ^X;", Not(isAvailable()));
192  EXPECT_THAT("template <typename T> struct ^X { T t; };", Not(isAvailable()));
193  EXPECT_THAT("enum ^X {};", Not(isAvailable()));
194 
195  EXPECT_THAT(apply("struct ^X { int x; int y; };"),
196  AllOf(StartsWith("message:"), HasSubstr("0 | int x")));
197 }
198 
199 TWEAK_TEST(ExtractVariable);
200 TEST_F(ExtractVariableTest, Test) {
201  const char *AvailableCases = R"cpp(
202  int xyz(int a = 1) {
203  struct T {
204  int bar(int a = 1);
205  int z;
206  } t;
207  // return statement
208  return [[[[t.b[[a]]r]](t.z)]];
209  }
210  void f() {
211  int a = [[5 +]] [[4 * [[[[xyz]]()]]]];
212  // multivariable initialization
213  if(1)
214  int x = [[1]], y = [[a + 1]], a = [[1]], z = a + 1;
215  // if without else
216  if([[1]])
217  a = [[1]];
218  // if with else
219  if(a < [[3]])
220  if(a == [[4]])
221  a = [[5]];
222  else
223  a = [[5]];
224  else if (a < [[4]])
225  a = [[4]];
226  else
227  a = [[5]];
228  // for loop
229  for(a = [[1]]; a > [[[[3]] + [[4]]]]; a++)
230  a = [[2]];
231  // while
232  while(a < [[1]])
233  a = [[1]];
234  // do while
235  do
236  a = [[1]];
237  while(a < [[3]]);
238  }
239  )cpp";
240  EXPECT_AVAILABLE(AvailableCases);
241 
242  ExtraArgs = {"-xc"};
243  const char *AvailableButC = R"cpp(
244  void foo() {
245  int x = [[1]];
246  })cpp";
247  EXPECT_UNAVAILABLE(AvailableButC);
248  ExtraArgs = {};
249 
250  const char *NoCrashCases = R"cpp(
251  // error-ok: broken code, but shouldn't crash
252  template<typename T, typename ...Args>
253  struct Test<T, Args...> {
254  Test(const T &v) :val[[(^]]) {}
255  T val;
256  };
257  )cpp";
258  EXPECT_UNAVAILABLE(NoCrashCases);
259 
260  const char *UnavailableCases = R"cpp(
261  int xyz(int a = [[1]]) {
262  struct T {
263  int bar(int a = [[1]]);
264  int z = [[1]];
265  } t;
266  return [[t]].bar([[[[t]].z]]);
267  }
268  void v() { return; }
269  // function default argument
270  void f(int b = [[1]]) {
271  // empty selection
272  int a = ^1 ^+ ^2;
273  // void expressions
274  auto i = new int, j = new int;
275  [[[[delete i]], delete j]];
276  [[v]]();
277  // if
278  if(1)
279  int x = 1, y = a + 1, a = 1, z = [[a + 1]];
280  if(int a = 1)
281  if([[a + 1]] == 4)
282  a = [[[[a]] +]] 1;
283  // for loop
284  for(int a = 1, b = 2, c = 3; a > [[b + c]]; [[a++]])
285  a = [[a + 1]];
286  // lambda
287  auto lamb = [&[[a]], &[[b]]](int r = [[1]]) {return 1;};
288  // assignment
289  xyz([[a = 5]]);
290  xyz([[a *= 5]]);
291  // Variable DeclRefExpr
292  a = [[b]];
293  // statement expression
294  [[xyz()]];
295  while (a)
296  [[++a]];
297  // label statement
298  goto label;
299  label:
300  a = [[1]];
301  }
302  )cpp";
303  EXPECT_UNAVAILABLE(UnavailableCases);
304 
305  // vector of pairs of input and output strings
306  const std::vector<std::pair<std::string, std::string>>
307  InputOutputs = {
308  // extraction from variable declaration/assignment
309  {R"cpp(void varDecl() {
310  int a = 5 * (4 + (3 [[- 1)]]);
311  })cpp",
312  R"cpp(void varDecl() {
313  auto dummy = (3 - 1); int a = 5 * (4 + dummy);
314  })cpp"},
315  // FIXME: extraction from switch case
316  /*{R"cpp(void f(int a) {
317  if(1)
318  while(a < 1)
319  switch (1) {
320  case 1:
321  a = [[1 + 2]];
322  break;
323  default:
324  break;
325  }
326  })cpp",
327  R"cpp(void f(int a) {
328  auto dummy = 1 + 2; if(1)
329  while(a < 1)
330  switch (1) {
331  case 1:
332  a = dummy;
333  break;
334  default:
335  break;
336  }
337  })cpp"},*/
338  // Macros
339  {R"cpp(#define PLUS(x) x++
340  void f(int a) {
341  int y = PLUS([[1+a]]);
342  })cpp",
343  /*FIXME: It should be extracted like this.
344  R"cpp(#define PLUS(x) x++
345  void f(int a) {
346  auto dummy = 1+a; int y = PLUS(dummy);
347  })cpp"},*/
348  R"cpp(#define PLUS(x) x++
349  void f(int a) {
350  auto dummy = PLUS(1+a); int y = dummy;
351  })cpp"},
352  // ensure InsertionPoint isn't inside a macro
353  {R"cpp(#define LOOP(x) while (1) {a = x;}
354  void f(int a) {
355  if(1)
356  LOOP(5 + [[3]])
357  })cpp",
358  R"cpp(#define LOOP(x) while (1) {a = x;}
359  void f(int a) {
360  auto dummy = 3; if(1)
361  LOOP(5 + dummy)
362  })cpp"},
363  {R"cpp(#define LOOP(x) do {x;} while(1);
364  void f(int a) {
365  if(1)
366  LOOP(5 + [[3]])
367  })cpp",
368  R"cpp(#define LOOP(x) do {x;} while(1);
369  void f(int a) {
370  auto dummy = 3; if(1)
371  LOOP(5 + dummy)
372  })cpp"},
373  // attribute testing
374  {R"cpp(void f(int a) {
375  [ [gsl::suppress("type")] ] for (;;) a = [[1]];
376  })cpp",
377  R"cpp(void f(int a) {
378  auto dummy = 1; [ [gsl::suppress("type")] ] for (;;) a = dummy;
379  })cpp"},
380  // MemberExpr
381  {R"cpp(class T {
382  T f() {
383  return [[T().f()]].f();
384  }
385  };)cpp",
386  R"cpp(class T {
387  T f() {
388  auto dummy = T().f(); return dummy.f();
389  }
390  };)cpp"},
391  // Function DeclRefExpr
392  {R"cpp(int f() {
393  return [[f]]();
394  })cpp",
395  R"cpp(int f() {
396  auto dummy = f(); return dummy;
397  })cpp"},
398  // FIXME: Wrong result for \[\[clang::uninitialized\]\] int b = [[1]];
399  // since the attr is inside the DeclStmt and the bounds of
400  // DeclStmt don't cover the attribute.
401 
402  // Binary subexpressions
403  {R"cpp(void f() {
404  int x = 1 + [[2 + 3 + 4]] + 5;
405  })cpp",
406  R"cpp(void f() {
407  auto dummy = 2 + 3 + 4; int x = 1 + dummy + 5;
408  })cpp"},
409  {R"cpp(void f() {
410  int x = [[1 + 2 + 3]] + 4 + 5;
411  })cpp",
412  R"cpp(void f() {
413  auto dummy = 1 + 2 + 3; int x = dummy + 4 + 5;
414  })cpp"},
415  {R"cpp(void f() {
416  int x = 1 + 2 + [[3 + 4 + 5]];
417  })cpp",
418  R"cpp(void f() {
419  auto dummy = 3 + 4 + 5; int x = 1 + 2 + dummy;
420  })cpp"},
421  // Non-associative operations have no special support
422  {R"cpp(void f() {
423  int x = 1 - [[2 - 3 - 4]] - 5;
424  })cpp",
425  R"cpp(void f() {
426  auto dummy = 1 - 2 - 3 - 4; int x = dummy - 5;
427  })cpp"},
428  // A mix of associative operators isn't associative.
429  {R"cpp(void f() {
430  int x = 0 + 1 * [[2 + 3]] * 4 + 5;
431  })cpp",
432  R"cpp(void f() {
433  auto dummy = 1 * 2 + 3 * 4; int x = 0 + dummy + 5;
434  })cpp"},
435  // Overloaded operators are supported, we assume associativity
436  // as if they were built-in.
437  {R"cpp(struct S {
438  S(int);
439  };
440  S operator+(S, S);
441 
442  void f() {
443  S x = S(1) + [[S(2) + S(3) + S(4)]] + S(5);
444  })cpp",
445  R"cpp(struct S {
446  S(int);
447  };
448  S operator+(S, S);
449 
450  void f() {
451  auto dummy = S(2) + S(3) + S(4); S x = S(1) + dummy + S(5);
452  })cpp"},
453  // Don't try to analyze across macro boundaries
454  // FIXME: it'd be nice to do this someday (in a safe way)
455  {R"cpp(#define ECHO(X) X
456  void f() {
457  int x = 1 + [[ECHO(2 + 3) + 4]] + 5;
458  })cpp",
459  R"cpp(#define ECHO(X) X
460  void f() {
461  auto dummy = 1 + ECHO(2 + 3) + 4; int x = dummy + 5;
462  })cpp"},
463  {R"cpp(#define ECHO(X) X
464  void f() {
465  int x = 1 + [[ECHO(2) + ECHO(3) + 4]] + 5;
466  })cpp",
467  R"cpp(#define ECHO(X) X
468  void f() {
469  auto dummy = 1 + ECHO(2) + ECHO(3) + 4; int x = dummy + 5;
470  })cpp"},
471  };
472  for (const auto &IO : InputOutputs) {
473  EXPECT_EQ(IO.second, apply(IO.first)) << IO.first;
474  }
475 }
476 
477 TWEAK_TEST(AnnotateHighlightings);
478 TEST_F(AnnotateHighlightingsTest, Test) {
479  EXPECT_AVAILABLE("^vo^id^ ^f(^) {^}^"); // available everywhere.
480  EXPECT_AVAILABLE("[[int a; int b;]]");
481  EXPECT_EQ("void /* entity.name.function.cpp */f() {}", apply("void ^f() {}"));
482 
483  EXPECT_EQ(apply("[[void f1(); void f2();]]"),
484  "void /* entity.name.function.cpp */f1(); "
485  "void /* entity.name.function.cpp */f2();");
486 
487  EXPECT_EQ(apply("void f1(); void f2() {^}"),
488  "void f1(); "
489  "void /* entity.name.function.cpp */f2() {}");
490 }
491 
492 TWEAK_TEST(ExpandMacro);
493 TEST_F(ExpandMacroTest, Test) {
494  Header = R"cpp(
495  // error-ok: not real c++, just token manipulation
496  #define FOO 1 2 3
497  #define FUNC(X) X+X+X
498  #define EMPTY
499  #define EMPTY_FN(X)
500  )cpp";
501 
502  // Available on macro names, not available anywhere else.
503  EXPECT_AVAILABLE("^F^O^O^ BAR ^F^O^O^");
504  EXPECT_AVAILABLE("^F^U^N^C^(1)");
505  EXPECT_UNAVAILABLE("^#^d^efine^ ^XY^Z 1 ^2 ^3^");
506  EXPECT_UNAVAILABLE("FOO ^B^A^R^ FOO ^");
507  EXPECT_UNAVAILABLE("FUNC(^1^)^");
508 
509  // Works as expected on object-like macros.
510  EXPECT_EQ(apply("^FOO BAR FOO"), "1 2 3 BAR FOO");
511  EXPECT_EQ(apply("FOO BAR ^FOO"), "FOO BAR 1 2 3");
512  // And function-like macros.
513  EXPECT_EQ(apply("F^UNC(2)"), "2 + 2 + 2");
514 
515  // Works on empty macros.
516  EXPECT_EQ(apply("int a ^EMPTY;"), "int a ;");
517  EXPECT_EQ(apply("int a ^EMPTY_FN(1 2 3);"), "int a ;");
518  EXPECT_EQ(apply("int a = 123 ^EMPTY EMPTY_FN(1);"),
519  "int a = 123 EMPTY_FN(1);");
520  EXPECT_EQ(apply("int a = 123 ^EMPTY_FN(1) EMPTY;"), "int a = 123 EMPTY;");
521  EXPECT_EQ(apply("int a = 123 EMPTY_FN(1) ^EMPTY;"),
522  "int a = 123 EMPTY_FN(1) ;");
523 }
524 
525 TWEAK_TEST(ExpandAutoType);
526 TEST_F(ExpandAutoTypeTest, Test) {
527 
528  Header = R"cpp(
529  namespace ns {
530  struct Class {
531  struct Nested {};
532  };
533  void Func();
534  }
535  inline namespace inl_ns {
536  namespace {
537  struct Visible {};
538  }
539  }
540  )cpp";
541 
542  EXPECT_AVAILABLE("^a^u^t^o^ i = 0;");
543  EXPECT_UNAVAILABLE("auto ^i^ ^=^ ^0^;^");
544 
545  // check primitive type
546  EXPECT_EQ(apply("[[auto]] i = 0;"), "int i = 0;");
547  EXPECT_EQ(apply("au^to i = 0;"), "int i = 0;");
548  // check classes and namespaces
549  EXPECT_EQ(apply("^auto C = ns::Class::Nested();"),
550  "ns::Class::Nested C = ns::Class::Nested();");
551  // check that namespaces are shortened
552  EXPECT_EQ(apply("namespace ns { void f() { ^auto C = Class(); } }"),
553  "namespace ns { void f() { Class C = Class(); } }");
554  // undefined functions should not be replaced
555  EXPECT_THAT(apply("au^to x = doesnt_exist(); // error-ok"),
556  StartsWith("fail: Could not deduce type for 'auto' type"));
557  // function pointers should not be replaced
558  EXPECT_THAT(apply("au^to x = &ns::Func;"),
559  StartsWith("fail: Could not expand type of function pointer"));
560  // lambda types are not replaced
561  EXPECT_THAT(apply("au^to x = []{};"),
562  StartsWith("fail: Could not expand type of lambda expression"));
563  // inline namespaces
564  EXPECT_EQ(apply("au^to x = inl_ns::Visible();"),
565  "Visible x = inl_ns::Visible();");
566  // local class
567  EXPECT_EQ(apply("namespace x { void y() { struct S{}; ^auto z = S(); } }"),
568  "namespace x { void y() { struct S{}; S z = S(); } }");
569  // replace array types
570  EXPECT_EQ(apply(R"cpp(au^to x = "test";)cpp"),
571  R"cpp(const char * x = "test";)cpp");
572 
573  EXPECT_UNAVAILABLE("dec^ltype(au^to) x = 10;");
574 
575  // FIXME: Auto-completion in a template requires disabling delayed template
576  // parsing.
577  ExtraArgs.push_back("-fno-delayed-template-parsing");
578  // unknown types in a template should not be replaced
579  EXPECT_THAT(apply("template <typename T> void x() { ^auto y = T::z(); }"),
580  StartsWith("fail: Could not deduce type for 'auto' type"));
581 }
582 
583 TWEAK_TEST(ExtractFunction);
584 TEST_F(ExtractFunctionTest, FunctionTest) {
585  Context = Function;
586 
587  // Root statements should have common parent.
588  EXPECT_EQ(apply("for(;;) [[1+2; 1+2;]]"), "unavailable");
589  // Expressions aren't extracted.
590  EXPECT_EQ(apply("int x = 0; [[x++;]]"), "unavailable");
591  // We don't support extraction from lambdas.
592  EXPECT_EQ(apply("auto lam = [](){ [[int x;]] }; "), "unavailable");
593  // Partial statements aren't extracted.
594  EXPECT_THAT(apply("int [[x = 0]];"), "unavailable");
595 
596  // Ensure that end of Zone and Beginning of PostZone being adjacent doesn't
597  // lead to break being included in the extraction zone.
598  EXPECT_THAT(apply("for(;;) { [[int x;]]break; }"), HasSubstr("extracted"));
599  // FIXME: ExtractFunction should be unavailable inside loop construct
600  // initializer/condition.
601  EXPECT_THAT(apply(" for([[int i = 0;]];);"), HasSubstr("extracted"));
602  // Don't extract because needs hoisting.
603  EXPECT_THAT(apply(" [[int a = 5;]] a++; "), StartsWith("fail"));
604  // Extract certain return
605  EXPECT_THAT(apply(" if(true) [[{ return; }]] "), HasSubstr("extracted"));
606  // Don't extract uncertain return
607  EXPECT_THAT(apply(" if(true) [[if (false) return;]] "), StartsWith("fail"));
608 }
609 
610 TEST_F(ExtractFunctionTest, FileTest) {
611  // Check all parameters are in order
612  std::string ParameterCheckInput = R"cpp(
613 struct Foo {
614  int x;
615 };
616 void f(int a) {
617  int b;
618  int *ptr = &a;
619  Foo foo;
620  [[a += foo.x + b;
621  *ptr++;]]
622 })cpp";
623  std::string ParameterCheckOutput = R"cpp(
624 struct Foo {
625  int x;
626 };
627 void extracted(int &a, int &b, int * &ptr, Foo &foo) {
628 a += foo.x + b;
629  *ptr++;
630 }
631 void f(int a) {
632  int b;
633  int *ptr = &a;
634  Foo foo;
635  extracted(a, b, ptr, foo);
636 })cpp";
637  EXPECT_EQ(apply(ParameterCheckInput), ParameterCheckOutput);
638 
639  // Check const qualifier
640  std::string ConstCheckInput = R"cpp(
641 void f(const int c) {
642  [[while(c) {}]]
643 })cpp";
644  std::string ConstCheckOutput = R"cpp(
645 void extracted(const int &c) {
646 while(c) {}
647 }
648 void f(const int c) {
649  extracted(c);
650 })cpp";
651  EXPECT_EQ(apply(ConstCheckInput), ConstCheckOutput);
652 
653  // Don't extract when we need to make a function as a parameter.
654  EXPECT_THAT(apply("void f() { [[int a; f();]] }"), StartsWith("fail"));
655 
656  // We don't extract from methods for now since they may involve multi-file
657  // edits
658  std::string MethodFailInput = R"cpp(
659  class T {
660  void f() {
661  [[int x;]]
662  }
663  };
664  )cpp";
665  EXPECT_EQ(apply(MethodFailInput), "unavailable");
666 
667  // We don't extract from templated functions for now as templates are hard
668  // to deal with.
669  std::string TemplateFailInput = R"cpp(
670  template<typename T>
671  void f() {
672  [[int x;]]
673  }
674  )cpp";
675  EXPECT_EQ(apply(TemplateFailInput), "unavailable");
676 
677  std::string MacroInput = R"cpp(
678  #define F(BODY) void f() { BODY }
679  F ([[int x = 0;]])
680  )cpp";
681  std::string MacroOutput = R"cpp(
682  #define F(BODY) void f() { BODY }
683  void extracted() {
684 int x = 0;
685 }
686 F (extracted();)
687  )cpp";
688  EXPECT_EQ(apply(MacroInput), MacroOutput);
689 
690  // Shouldn't crash.
691  EXPECT_EQ(apply("void f([[int a]]);"), "unavailable");
692  // Don't extract if we select the entire function body (CompoundStmt).
693  std::string CompoundFailInput = R"cpp(
694  void f() [[{
695  int a;
696  }]]
697  )cpp";
698  EXPECT_EQ(apply(CompoundFailInput), "unavailable");
699 }
700 
701 TEST_F(ExtractFunctionTest, ControlFlow) {
702  Context = Function;
703  // We should be able to extract break/continue with a parent loop/switch.
704  EXPECT_THAT(apply(" [[for(;;) if(1) break;]] "), HasSubstr("extracted"));
705  EXPECT_THAT(apply(" for(;;) [[while(1) break;]] "), HasSubstr("extracted"));
706  EXPECT_THAT(apply(" [[switch(1) { break; }]]"), HasSubstr("extracted"));
707  EXPECT_THAT(apply(" [[while(1) switch(1) { continue; }]]"),
708  HasSubstr("extracted"));
709  // Don't extract break and continue without a loop/switch parent.
710  EXPECT_THAT(apply(" for(;;) [[if(1) continue;]] "), StartsWith("fail"));
711  EXPECT_THAT(apply(" while(1) [[if(1) break;]] "), StartsWith("fail"));
712  EXPECT_THAT(apply(" switch(1) { [[break;]] }"), StartsWith("fail"));
713  EXPECT_THAT(apply(" for(;;) { [[while(1) break; break;]] }"),
714  StartsWith("fail"));
715 }
716 
717 TEST_F(ExtractFunctionTest, ExistingReturnStatement) {
718  Context = File;
719  const char* Before = R"cpp(
720  bool lucky(int N);
721  int getNum(bool Superstitious, int Min, int Max) {
722  if (Superstitious) [[{
723  for (int I = Min; I <= Max; ++I)
724  if (lucky(I))
725  return I;
726  return -1;
727  }]] else {
728  return (Min + Max) / 2;
729  }
730  }
731  )cpp";
732  // FIXME: min/max should be by value.
733  // FIXME: avoid emitting redundant braces
734  const char* After = R"cpp(
735  bool lucky(int N);
736  int extracted(int &Min, int &Max) {
737 {
738  for (int I = Min; I <= Max; ++I)
739  if (lucky(I))
740  return I;
741  return -1;
742  }
743 }
744 int getNum(bool Superstitious, int Min, int Max) {
745  if (Superstitious) return extracted(Min, Max); else {
746  return (Min + Max) / 2;
747  }
748  }
749  )cpp";
750  EXPECT_EQ(apply(Before), After);
751 }
752 
753 TWEAK_TEST(RemoveUsingNamespace);
754 TEST_F(RemoveUsingNamespaceTest, All) {
755  std::pair<llvm::StringRef /*Input*/, llvm::StringRef /*Expected*/> Cases[] = {
756  {// Remove all occurrences of ns. Qualify only unqualified.
757  R"cpp(
758  namespace ns1 { struct vector {}; }
759  namespace ns2 { struct map {}; }
760  using namespace n^s1;
761  using namespace ns2;
762  using namespace ns1;
763  int main() {
764  ns1::vector v1;
765  vector v2;
766  map m1;
767  }
768  )cpp",
769  R"cpp(
770  namespace ns1 { struct vector {}; }
771  namespace ns2 { struct map {}; }
772 
773  using namespace ns2;
774 
775  int main() {
776  ns1::vector v1;
777  ns1::vector v2;
778  map m1;
779  }
780  )cpp"},
781  {// Ident to be qualified is a macro arg.
782  R"cpp(
783  #define DECLARE(x, y) x y
784  namespace ns { struct vector {}; }
785  using namespace n^s;
786  int main() {
787  DECLARE(ns::vector, v1);
788  DECLARE(vector, v2);
789  }
790  )cpp",
791  R"cpp(
792  #define DECLARE(x, y) x y
793  namespace ns { struct vector {}; }
794 
795  int main() {
796  DECLARE(ns::vector, v1);
797  DECLARE(ns::vector, v2);
798  }
799  )cpp"},
800  {// Nested namespace: Fully qualify ident from inner ns.
801  R"cpp(
802  namespace aa { namespace bb { struct map {}; }}
803  using namespace aa::b^b;
804  int main() {
805  map m;
806  }
807  )cpp",
808  R"cpp(
809  namespace aa { namespace bb { struct map {}; }}
810 
811  int main() {
812  aa::bb::map m;
813  }
814  )cpp"},
815  {// Nested namespace: Fully qualify ident from inner ns.
816  R"cpp(
817  namespace aa { namespace bb { struct map {}; }}
818  using namespace a^a;
819  int main() {
820  bb::map m;
821  }
822  )cpp",
823  R"cpp(
824  namespace aa { namespace bb { struct map {}; }}
825 
826  int main() {
827  aa::bb::map m;
828  }
829  )cpp"},
830  {// Typedef.
831  R"cpp(
832  namespace aa { namespace bb { struct map {}; }}
833  using namespace a^a;
834  typedef bb::map map;
835  int main() { map M; }
836  )cpp",
837  R"cpp(
838  namespace aa { namespace bb { struct map {}; }}
839 
840  typedef aa::bb::map map;
841  int main() { map M; }
842  )cpp"},
843  {// FIXME: Nested namespaces: Not aware of using ns decl of outer ns.
844  R"cpp(
845  namespace aa { namespace bb { struct map {}; }}
846  using name[[space aa::b]]b;
847  using namespace aa;
848  int main() {
849  map m;
850  }
851  )cpp",
852  R"cpp(
853  namespace aa { namespace bb { struct map {}; }}
854 
855  using namespace aa;
856  int main() {
857  aa::bb::map m;
858  }
859  )cpp"},
860  {// Does not qualify ident from inner namespace.
861  R"cpp(
862  namespace aa { namespace bb { struct map {}; }}
863  using namespace aa::bb;
864  using namespace a^a;
865  int main() {
866  map m;
867  }
868  )cpp",
869  R"cpp(
870  namespace aa { namespace bb { struct map {}; }}
871  using namespace aa::bb;
872 
873  int main() {
874  map m;
875  }
876  )cpp"},
877  {// Available only for top level namespace decl.
878  R"cpp(
879  namespace aa {
880  namespace bb { struct map {}; }
881  using namespace b^b;
882  }
883  int main() { aa::map m; }
884  )cpp",
885  "unavailable"},
886  {// FIXME: Unavailable for namespaces containing using-namespace decl.
887  R"cpp(
888  namespace aa {
889  namespace bb { struct map {}; }
890  using namespace bb;
891  }
892  using namespace a^a;
893  int main() {
894  map m;
895  }
896  )cpp",
897  "unavailable"},
898  {R"cpp(
899  namespace a::b { struct Foo {}; }
900  using namespace a;
901  using namespace a::[[b]];
902  using namespace b;
903  int main() { Foo F;}
904  )cpp",
905  R"cpp(
906  namespace a::b { struct Foo {}; }
907  using namespace a;
908 
909 
910  int main() { a::b::Foo F;}
911  )cpp"},
912  {R"cpp(
913  namespace a::b { struct Foo {}; }
914  using namespace a;
915  using namespace a::b;
916  using namespace [[b]];
917  int main() { Foo F;}
918  )cpp",
919  R"cpp(
920  namespace a::b { struct Foo {}; }
921  using namespace a;
922 
923 
924  int main() { b::Foo F;}
925  )cpp"},
926  {// Enumerators.
927  R"cpp(
928  namespace tokens {
929  enum Token {
930  comma, identifier, numeric
931  };
932  }
933  using namespace tok^ens;
934  int main() {
935  auto x = comma;
936  }
937  )cpp",
938  R"cpp(
939  namespace tokens {
940  enum Token {
941  comma, identifier, numeric
942  };
943  }
944 
945  int main() {
946  auto x = tokens::comma;
947  }
948  )cpp"},
949  {// inline namespaces.
950  R"cpp(
951  namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
952  using namespace st^d;
953  int main() {
954  vector V;
955  }
956  )cpp",
957  R"cpp(
958  namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
959 
960  int main() {
961  std::vector V;
962  }
963  )cpp"}};
964  for (auto C : Cases)
965  EXPECT_EQ(C.second, apply(C.first)) << C.first;
966 }
967 
968 TWEAK_TEST(DefineInline);
969 TEST_F(DefineInlineTest, TriggersOnFunctionDecl) {
970  // Basic check for function body and signature.
971  EXPECT_AVAILABLE(R"cpp(
972  class Bar {
973  void baz();
974  };
975 
976  [[void [[Bar::[[b^a^z]]]]() [[{
977  return;
978  }]]]]
979 
980  void foo();
981  [[void [[f^o^o]]() [[{
982  return;
983  }]]]]
984  )cpp");
985 
986  EXPECT_UNAVAILABLE(R"cpp(
987  // Not a definition
988  vo^i[[d^ ^f]]^oo();
989 
990  [[vo^id ]]foo[[()]] {[[
991  [[(void)(5+3);
992  return;]]
993  }]]
994 
995  // Definition with no body.
996  class Bar { Bar() = def^ault; };
997  )cpp");
998 }
999 
1000 TEST_F(DefineInlineTest, NoForwardDecl) {
1001  Header = "void bar();";
1002  EXPECT_UNAVAILABLE(R"cpp(
1003  void bar() {
1004  return;
1005  }
1006  // FIXME: Generate a decl in the header.
1007  void fo^o() {
1008  return;
1009  })cpp");
1010 }
1011 
1012 TEST_F(DefineInlineTest, ReferencedDecls) {
1013  EXPECT_AVAILABLE(R"cpp(
1014  void bar();
1015  void foo(int test);
1016 
1017  void fo^o(int baz) {
1018  int x = 10;
1019  bar();
1020  })cpp");
1021 
1022  // Internal symbol usage.
1023  Header = "void foo(int test);";
1024  EXPECT_UNAVAILABLE(R"cpp(
1025  void bar();
1026  void fo^o(int baz) {
1027  int x = 10;
1028  bar();
1029  })cpp");
1030 
1031  // Becomes available after making symbol visible.
1032  Header = "void bar();" + Header;
1033  EXPECT_AVAILABLE(R"cpp(
1034  void fo^o(int baz) {
1035  int x = 10;
1036  bar();
1037  })cpp");
1038 
1039  // FIXME: Move declaration below bar to make it visible.
1040  Header.clear();
1041  EXPECT_UNAVAILABLE(R"cpp(
1042  void foo();
1043  void bar();
1044 
1045  void fo^o() {
1046  bar();
1047  })cpp");
1048 
1049  // Order doesn't matter within a class.
1050  EXPECT_AVAILABLE(R"cpp(
1051  class Bar {
1052  void foo();
1053  void bar();
1054  };
1055 
1056  void Bar::fo^o() {
1057  bar();
1058  })cpp");
1059 
1060  // FIXME: Perform include insertion to make symbol visible.
1061  ExtraFiles["a.h"] = "void bar();";
1062  Header = "void foo(int test);";
1063  EXPECT_UNAVAILABLE(R"cpp(
1064  #include "a.h"
1065  void fo^o(int baz) {
1066  int x = 10;
1067  bar();
1068  })cpp");
1069 }
1070 
1071 TEST_F(DefineInlineTest, TemplateSpec) {
1072  EXPECT_UNAVAILABLE(R"cpp(
1073  template <typename T> void foo();
1074  template<> void foo<char>();
1075 
1076  template<> void f^oo<int>() {
1077  })cpp");
1078  EXPECT_UNAVAILABLE(R"cpp(
1079  template <typename T> void foo();
1080 
1081  template<> void f^oo<int>() {
1082  })cpp");
1083  EXPECT_UNAVAILABLE(R"cpp(
1084  template <typename T> struct Foo { void foo(); };
1085 
1086  template <typename T> void Foo<T>::f^oo() {
1087  })cpp");
1088  EXPECT_AVAILABLE(R"cpp(
1089  template <typename T> void foo();
1090  void bar();
1091  template <> void foo<int>();
1092 
1093  template<> void f^oo<int>() {
1094  bar();
1095  })cpp");
1096 }
1097 
1098 TEST_F(DefineInlineTest, CheckForCanonDecl) {
1099  EXPECT_UNAVAILABLE(R"cpp(
1100  void foo();
1101 
1102  void bar() {}
1103  void f^oo() {
1104  // This bar normally refers to the definition just above, but it is not
1105  // visible from the forward declaration of foo.
1106  bar();
1107  })cpp");
1108  // Make it available with a forward decl.
1109  EXPECT_AVAILABLE(R"cpp(
1110  void bar();
1111  void foo();
1112 
1113  void bar() {}
1114  void f^oo() {
1115  bar();
1116  })cpp");
1117 }
1118 
1119 TEST_F(DefineInlineTest, UsingShadowDecls) {
1120  // Template body is not parsed until instantiation time on windows, which
1121  // results in arbitrary failures as function body becomes NULL.
1122  ExtraArgs.push_back("-fno-delayed-template-parsing");
1123  EXPECT_UNAVAILABLE(R"cpp(
1124  namespace ns1 { void foo(int); }
1125  namespace ns2 { void foo(int*); }
1126  template <typename T>
1127  void bar();
1128 
1129  using ns1::foo;
1130  using ns2::foo;
1131 
1132  template <typename T>
1133  void b^ar() {
1134  foo(T());
1135  })cpp");
1136 }
1137 
1138 TEST_F(DefineInlineTest, TransformNestedNamespaces) {
1139  auto Test = R"cpp(
1140  namespace a {
1141  void bar();
1142  namespace b {
1143  void baz();
1144  namespace c {
1145  void aux();
1146  }
1147  }
1148  }
1149 
1150  void foo();
1151  using namespace a;
1152  using namespace b;
1153  using namespace c;
1154  void f^oo() {
1155  bar();
1156  a::bar();
1157 
1158  baz();
1159  b::baz();
1160  a::b::baz();
1161 
1162  aux();
1163  c::aux();
1164  b::c::aux();
1165  a::b::c::aux();
1166  })cpp";
1167  auto Expected = R"cpp(
1168  namespace a {
1169  void bar();
1170  namespace b {
1171  void baz();
1172  namespace c {
1173  void aux();
1174  }
1175  }
1176  }
1177 
1178  void foo(){
1179  a::bar();
1180  a::bar();
1181 
1182  a::b::baz();
1183  a::b::baz();
1184  a::b::baz();
1185 
1186  a::b::c::aux();
1187  a::b::c::aux();
1188  a::b::c::aux();
1189  a::b::c::aux();
1190  }
1191  using namespace a;
1192  using namespace b;
1193  using namespace c;
1194  )cpp";
1195  EXPECT_EQ(apply(Test), Expected);
1196 }
1197 
1198 TEST_F(DefineInlineTest, TransformUsings) {
1199  auto Test = R"cpp(
1200  namespace a { namespace b { namespace c { void aux(); } } }
1201 
1202  void foo();
1203  void f^oo() {
1204  using namespace a;
1205  using namespace b;
1206  using namespace c;
1207  using c::aux;
1208  namespace d = c;
1209  })cpp";
1210  auto Expected = R"cpp(
1211  namespace a { namespace b { namespace c { void aux(); } } }
1212 
1213  void foo(){
1214  using namespace a;
1215  using namespace a::b;
1216  using namespace a::b::c;
1217  using a::b::c::aux;
1218  namespace d = a::b::c;
1219  }
1220  )cpp";
1221  EXPECT_EQ(apply(Test), Expected);
1222 }
1223 
1224 TEST_F(DefineInlineTest, TransformDecls) {
1225  auto Test = R"cpp(
1226  void foo();
1227  void f^oo() {
1228  class Foo {
1229  public:
1230  void foo();
1231  int x;
1232  };
1233 
1234  enum En { Zero, One };
1235  En x = Zero;
1236 
1237  enum class EnClass { Zero, One };
1238  EnClass y = EnClass::Zero;
1239  })cpp";
1240  auto Expected = R"cpp(
1241  void foo(){
1242  class Foo {
1243  public:
1244  void foo();
1245  int x;
1246  };
1247 
1248  enum En { Zero, One };
1249  En x = Zero;
1250 
1251  enum class EnClass { Zero, One };
1252  EnClass y = EnClass::Zero;
1253  }
1254  )cpp";
1255  EXPECT_EQ(apply(Test), Expected);
1256 }
1257 
1258 TEST_F(DefineInlineTest, TransformTemplDecls) {
1259  auto Test = R"cpp(
1260  namespace a {
1261  template <typename T> class Bar {
1262  public:
1263  void bar();
1264  };
1265  template <typename T> T bar;
1266  template <typename T> void aux() {}
1267  }
1268 
1269  void foo();
1270 
1271  using namespace a;
1272  void f^oo() {
1273  bar<Bar<int>>.bar();
1274  aux<Bar<int>>();
1275  })cpp";
1276  auto Expected = R"cpp(
1277  namespace a {
1278  template <typename T> class Bar {
1279  public:
1280  void bar();
1281  };
1282  template <typename T> T bar;
1283  template <typename T> void aux() {}
1284  }
1285 
1286  void foo(){
1287  a::bar<a::Bar<int>>.bar();
1288  a::aux<a::Bar<int>>();
1289  }
1290 
1291  using namespace a;
1292  )cpp";
1293  EXPECT_EQ(apply(Test), Expected);
1294 }
1295 
1296 TEST_F(DefineInlineTest, TransformMembers) {
1297  auto Test = R"cpp(
1298  class Foo {
1299  void foo();
1300  };
1301 
1302  void Foo::f^oo() {
1303  return;
1304  })cpp";
1305  auto Expected = R"cpp(
1306  class Foo {
1307  void foo(){
1308  return;
1309  }
1310  };
1311 
1312  )cpp";
1313  EXPECT_EQ(apply(Test), Expected);
1314 
1315  ExtraFiles["a.h"] = R"cpp(
1316  class Foo {
1317  void foo();
1318  };)cpp";
1319 
1320  llvm::StringMap<std::string> EditedFiles;
1321  Test = R"cpp(
1322  #include "a.h"
1323  void Foo::f^oo() {
1324  return;
1325  })cpp";
1326  Expected = R"cpp(
1327  #include "a.h"
1328  )cpp";
1329  EXPECT_EQ(apply(Test, &EditedFiles), Expected);
1330 
1331  Expected = R"cpp(
1332  class Foo {
1333  void foo(){
1334  return;
1335  }
1336  };)cpp";
1337  EXPECT_THAT(EditedFiles,
1338  ElementsAre(FileWithContents(testPath("a.h"), Expected)));
1339 }
1340 
1341 TEST_F(DefineInlineTest, TransformDependentTypes) {
1342  auto Test = R"cpp(
1343  namespace a {
1344  template <typename T> class Bar {};
1345  }
1346 
1347  template <typename T>
1348  void foo();
1349 
1350  using namespace a;
1351  template <typename T>
1352  void f^oo() {
1353  Bar<T> B;
1354  Bar<Bar<T>> q;
1355  })cpp";
1356  auto Expected = R"cpp(
1357  namespace a {
1358  template <typename T> class Bar {};
1359  }
1360 
1361  template <typename T>
1362  void foo(){
1363  a::Bar<T> B;
1364  a::Bar<a::Bar<T>> q;
1365  }
1366 
1367  using namespace a;
1368  )cpp";
1369 
1370  // Template body is not parsed until instantiation time on windows, which
1371  // results in arbitrary failures as function body becomes NULL.
1372  ExtraArgs.push_back("-fno-delayed-template-parsing");
1373  EXPECT_EQ(apply(Test), Expected);
1374 }
1375 
1376 TEST_F(DefineInlineTest, TransformFunctionTempls) {
1377  // Check we select correct specialization decl.
1378  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
1379  {R"cpp(
1380  template <typename T>
1381  void foo(T p);
1382 
1383  template <>
1384  void foo<int>(int p);
1385 
1386  template <>
1387  void foo<char>(char p);
1388 
1389  template <>
1390  void fo^o<int>(int p) {
1391  return;
1392  })cpp",
1393  R"cpp(
1394  template <typename T>
1395  void foo(T p);
1396 
1397  template <>
1398  void foo<int>(int p){
1399  return;
1400  }
1401 
1402  template <>
1403  void foo<char>(char p);
1404 
1405  )cpp"},
1406  {// Make sure we are not selecting the first specialization all the time.
1407  R"cpp(
1408  template <typename T>
1409  void foo(T p);
1410 
1411  template <>
1412  void foo<int>(int p);
1413 
1414  template <>
1415  void foo<char>(char p);
1416 
1417  template <>
1418  void fo^o<char>(char p) {
1419  return;
1420  })cpp",
1421  R"cpp(
1422  template <typename T>
1423  void foo(T p);
1424 
1425  template <>
1426  void foo<int>(int p);
1427 
1428  template <>
1429  void foo<char>(char p){
1430  return;
1431  }
1432 
1433  )cpp"},
1434  {R"cpp(
1435  template <typename T>
1436  void foo(T p);
1437 
1438  template <>
1439  void foo<int>(int p);
1440 
1441  template <typename T>
1442  void fo^o(T p) {
1443  return;
1444  })cpp",
1445  R"cpp(
1446  template <typename T>
1447  void foo(T p){
1448  return;
1449  }
1450 
1451  template <>
1452  void foo<int>(int p);
1453 
1454  )cpp"},
1455  };
1456  // Template body is not parsed until instantiation time on windows, which
1457  // results in arbitrary failures as function body becomes NULL.
1458  ExtraArgs.push_back("-fno-delayed-template-parsing");
1459  for (const auto &Case : Cases)
1460  EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1461 }
1462 
1463 TEST_F(DefineInlineTest, TransformTypeLocs) {
1464  auto Test = R"cpp(
1465  namespace a {
1466  template <typename T> class Bar {
1467  public:
1468  template <typename Q> class Baz {};
1469  };
1470  class Foo{};
1471  }
1472 
1473  void foo();
1474 
1475  using namespace a;
1476  void f^oo() {
1477  Bar<int> B;
1478  Foo foo;
1479  a::Bar<Bar<int>>::Baz<Bar<int>> q;
1480  })cpp";
1481  auto Expected = R"cpp(
1482  namespace a {
1483  template <typename T> class Bar {
1484  public:
1485  template <typename Q> class Baz {};
1486  };
1487  class Foo{};
1488  }
1489 
1490  void foo(){
1491  a::Bar<int> B;
1492  a::Foo foo;
1493  a::Bar<a::Bar<int>>::Baz<a::Bar<int>> q;
1494  }
1495 
1496  using namespace a;
1497  )cpp";
1498  EXPECT_EQ(apply(Test), Expected);
1499 }
1500 
1501 TEST_F(DefineInlineTest, TransformDeclRefs) {
1502  auto Test = R"cpp(
1503  namespace a {
1504  template <typename T> class Bar {
1505  public:
1506  void foo();
1507  static void bar();
1508  int x;
1509  static int y;
1510  };
1511  void bar();
1512  void test();
1513  }
1514 
1515  void foo();
1516  using namespace a;
1517  void f^oo() {
1518  a::Bar<int> B;
1519  B.foo();
1520  a::bar();
1521  Bar<Bar<int>>::bar();
1522  a::Bar<int>::bar();
1523  B.x = Bar<int>::y;
1524  Bar<int>::y = 3;
1525  bar();
1526  a::test();
1527  })cpp";
1528  auto Expected = R"cpp(
1529  namespace a {
1530  template <typename T> class Bar {
1531  public:
1532  void foo();
1533  static void bar();
1534  int x;
1535  static int y;
1536  };
1537  void bar();
1538  void test();
1539  }
1540 
1541  void foo(){
1542  a::Bar<int> B;
1543  B.foo();
1544  a::bar();
1545  a::Bar<a::Bar<int>>::bar();
1546  a::Bar<int>::bar();
1547  B.x = a::Bar<int>::y;
1548  a::Bar<int>::y = 3;
1549  a::bar();
1550  a::test();
1551  }
1552  using namespace a;
1553  )cpp";
1554  EXPECT_EQ(apply(Test), Expected);
1555 }
1556 
1557 TEST_F(DefineInlineTest, StaticMembers) {
1558  auto Test = R"cpp(
1559  namespace ns { class X { static void foo(); void bar(); }; }
1560  void ns::X::b^ar() {
1561  foo();
1562  })cpp";
1563  auto Expected = R"cpp(
1564  namespace ns { class X { static void foo(); void bar(){
1565  foo();
1566  } }; }
1567  )cpp";
1568  EXPECT_EQ(apply(Test), Expected);
1569 }
1570 
1571 TEST_F(DefineInlineTest, TransformParamNames) {
1572  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
1573  {R"cpp(
1574  void foo(int, bool b, int T\
1575 est);
1576  void ^foo(int f, bool x, int z) {})cpp",
1577  R"cpp(
1578  void foo(int f, bool x, int z){}
1579  )cpp"},
1580  {R"cpp(
1581  #define PARAM int Z
1582  void foo(PARAM);
1583 
1584  void ^foo(int X) {})cpp",
1585  "fail: Cant rename parameter inside macro body."},
1586  {R"cpp(
1587  #define TYPE int
1588  #define PARAM TYPE Z
1589  #define BODY(x) 5 * (x) + 2
1590  template <int P>
1591  void foo(PARAM, TYPE Q, TYPE, TYPE W = BODY(P));
1592  template <int x>
1593  void ^foo(int Z, int b, int c, int d) {})cpp",
1594  R"cpp(
1595  #define TYPE int
1596  #define PARAM TYPE Z
1597  #define BODY(x) 5 * (x) + 2
1598  template <int x>
1599  void foo(PARAM, TYPE b, TYPE c, TYPE d = BODY(x)){}
1600  )cpp"},
1601  };
1602  ExtraArgs.push_back("-fno-delayed-template-parsing");
1603  for (const auto &Case : Cases)
1604  EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1605 }
1606 
1607 TEST_F(DefineInlineTest, TransformTemplParamNames) {
1608  auto Test = R"cpp(
1609  struct Foo {
1610  struct Bar {
1611  template <class, class X,
1612  template<typename> class, template<typename> class Y,
1613  int, int Z>
1614  void foo(X, Y<X>, int W = 5 * Z + 2);
1615  };
1616  };
1617 
1618  template <class T, class U,
1619  template<typename> class V, template<typename> class W,
1620  int X, int Y>
1621  void Foo::Bar::f^oo(U, W<U>, int Q) {})cpp";
1622  auto Expected = R"cpp(
1623  struct Foo {
1624  struct Bar {
1625  template <class T, class U,
1626  template<typename> class V, template<typename> class W,
1627  int X, int Y>
1628  void foo(U, W<U>, int Q = 5 * Y + 2){}
1629  };
1630  };
1631 
1632  )cpp";
1633  ExtraArgs.push_back("-fno-delayed-template-parsing");
1634  EXPECT_EQ(apply(Test), Expected);
1635 }
1636 
1637 TEST_F(DefineInlineTest, TransformInlineNamespaces) {
1638  auto Test = R"cpp(
1639  namespace a { inline namespace b { namespace { struct Foo{}; } } }
1640  void foo();
1641 
1642  using namespace a;
1643  void ^foo() {Foo foo;})cpp";
1644  auto Expected = R"cpp(
1645  namespace a { inline namespace b { namespace { struct Foo{}; } } }
1646  void foo(){a::Foo foo;}
1647 
1648  using namespace a;
1649  )cpp";
1650  EXPECT_EQ(apply(Test), Expected);
1651 }
1652 
1653 TEST_F(DefineInlineTest, TokensBeforeSemicolon) {
1654  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
1655  {R"cpp(
1656  void foo() /*Comment -_-*/ /*Com 2*/ ;
1657  void fo^o() { return ; })cpp",
1658  R"cpp(
1659  void foo() /*Comment -_-*/ /*Com 2*/ { return ; }
1660  )cpp"},
1661 
1662  {R"cpp(
1663  void foo();
1664  void fo^o() { return ; })cpp",
1665  R"cpp(
1666  void foo(){ return ; }
1667  )cpp"},
1668 
1669  {R"cpp(
1670  #define SEMI ;
1671  void foo() SEMI
1672  void fo^o() { return ; })cpp",
1673  "fail: Couldn't find semicolon for target declaration."},
1674  };
1675  for (const auto &Case : Cases)
1676  EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1677 }
1678 
1679 TEST_F(DefineInlineTest, HandleMacros) {
1680  EXPECT_UNAVAILABLE(R"cpp(
1681  #define BODY { return; }
1682  void foo();
1683  void f^oo()BODY)cpp");
1684 
1685  EXPECT_UNAVAILABLE(R"cpp(
1686  #define BODY void foo(){ return; }
1687  void foo();
1688  [[BODY]])cpp");
1689 
1690  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
1691  // We don't qualify declarations coming from macros.
1692  {R"cpp(
1693  #define BODY Foo
1694  namespace a { class Foo{}; }
1695  void foo();
1696  using namespace a;
1697  void f^oo(){BODY();})cpp",
1698  R"cpp(
1699  #define BODY Foo
1700  namespace a { class Foo{}; }
1701  void foo(){BODY();}
1702  using namespace a;
1703  )cpp"},
1704 
1705  // Macro is not visible at declaration location, but we proceed.
1706  {R"cpp(
1707  void foo();
1708  #define BODY return;
1709  void f^oo(){BODY})cpp",
1710  R"cpp(
1711  void foo(){BODY}
1712  #define BODY return;
1713  )cpp"},
1714 
1715  {R"cpp(
1716  #define TARGET void foo()
1717  TARGET;
1718  void f^oo(){ return; })cpp",
1719  R"cpp(
1720  #define TARGET void foo()
1721  TARGET{ return; }
1722  )cpp"},
1723 
1724  {R"cpp(
1725  #define TARGET foo
1726  void TARGET();
1727  void f^oo(){ return; })cpp",
1728  R"cpp(
1729  #define TARGET foo
1730  void TARGET(){ return; }
1731  )cpp"},
1732  };
1733  for (const auto &Case : Cases)
1734  EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1735 }
1736 
1737 TEST_F(DefineInlineTest, DropCommonNameSpecifiers) {
1738  struct {
1739  llvm::StringRef Test;
1740  llvm::StringRef Expected;
1741  } Cases[] = {
1742  {R"cpp(
1743  namespace a { namespace b { void aux(); } }
1744  namespace ns1 {
1745  void foo();
1746  namespace qq { void test(); }
1747  namespace ns2 {
1748  void bar();
1749  namespace ns3 { void baz(); }
1750  }
1751  }
1752 
1753  using namespace a;
1754  using namespace a::b;
1755  using namespace ns1::qq;
1756  void ns1::ns2::ns3::b^az() {
1757  foo();
1758  bar();
1759  baz();
1760  ns1::ns2::ns3::baz();
1761  aux();
1762  test();
1763  })cpp",
1764  R"cpp(
1765  namespace a { namespace b { void aux(); } }
1766  namespace ns1 {
1767  void foo();
1768  namespace qq { void test(); }
1769  namespace ns2 {
1770  void bar();
1771  namespace ns3 { void baz(){
1772  foo();
1773  bar();
1774  baz();
1775  ns1::ns2::ns3::baz();
1776  a::b::aux();
1777  qq::test();
1778  } }
1779  }
1780  }
1781 
1782  using namespace a;
1783  using namespace a::b;
1784  using namespace ns1::qq;
1785  )cpp"},
1786  {R"cpp(
1787  namespace ns1 {
1788  namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
1789  namespace ns2 { void baz(); }
1790  }
1791 
1792  using namespace ns1::qq;
1793  void ns1::ns2::b^az() { Foo f; B b; })cpp",
1794  R"cpp(
1795  namespace ns1 {
1796  namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
1797  namespace ns2 { void baz(){ qq::Foo f; qq::B b; } }
1798  }
1799 
1800  using namespace ns1::qq;
1801  )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(); }
1810  }
1811 
1812  using namespace ns1::qq;
1813  void ns1::ns2::b^az() { B<int, bool> b; })cpp",
1814  R"cpp(
1815  namespace ns1 {
1816  namespace qq {
1817  template<class T> struct Foo { template <class U> struct Bar {}; };
1818  template<class T, class U>
1819  using B = typename Foo<T>::template Bar<U>;
1820  }
1821  namespace ns2 { void baz(){ qq::B<int, bool> b; } }
1822  }
1823 
1824  using namespace ns1::qq;
1825  )cpp"},
1826  };
1827  for (const auto &Case : Cases)
1828  EXPECT_EQ(apply(Case.Test), Case.Expected) << Case.Test;
1829 }
1830 
1831 TEST_F(DefineInlineTest, QualifyWithUsingDirectives) {
1832  llvm::StringRef Test = R"cpp(
1833  namespace a {
1834  void bar();
1835  namespace b { struct Foo{}; void aux(); }
1836  namespace c { void cux(); }
1837  }
1838  using namespace a;
1839  using X = b::Foo;
1840  void foo();
1841 
1842  using namespace b;
1843  using namespace c;
1844  void ^foo() {
1845  cux();
1846  bar();
1847  X x;
1848  aux();
1849  using namespace c;
1850  // FIXME: The last reference to cux() in body of foo should not be
1851  // qualified, since there is a using directive inside the function body.
1852  cux();
1853  })cpp";
1854  llvm::StringRef Expected = R"cpp(
1855  namespace a {
1856  void bar();
1857  namespace b { struct Foo{}; void aux(); }
1858  namespace c { void cux(); }
1859  }
1860  using namespace a;
1861  using X = b::Foo;
1862  void foo(){
1863  c::cux();
1864  bar();
1865  X x;
1866  b::aux();
1867  using namespace c;
1868  // FIXME: The last reference to cux() in body of foo should not be
1869  // qualified, since there is a using directive inside the function body.
1870  c::cux();
1871  }
1872 
1873  using namespace b;
1874  using namespace c;
1875  )cpp";
1876  EXPECT_EQ(apply(Test), Expected) << Test;
1877 }
1878 
1879 TEST_F(DefineInlineTest, AddInline) {
1880  ExtraArgs.push_back("-fno-delayed-template-parsing");
1881  llvm::StringMap<std::string> EditedFiles;
1882  ExtraFiles["a.h"] = "void foo();";
1883  apply(R"cpp(#include "a.h"
1884  void fo^o() {})cpp",
1885  &EditedFiles);
1886  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
1887  testPath("a.h"), "inline void foo(){}")));
1888 
1889  // Check we put inline before cv-qualifiers.
1890  ExtraFiles["a.h"] = "const int foo();";
1891  apply(R"cpp(#include "a.h"
1892  const int fo^o() {})cpp",
1893  &EditedFiles);
1894  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
1895  testPath("a.h"), "inline const int foo(){}")));
1896 
1897  // No double inline.
1898  ExtraFiles["a.h"] = "inline void foo();";
1899  apply(R"cpp(#include "a.h"
1900  inline void fo^o() {})cpp",
1901  &EditedFiles);
1902  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
1903  testPath("a.h"), "inline void foo(){}")));
1904 
1905  // Constexprs don't need "inline".
1906  ExtraFiles["a.h"] = "constexpr void foo();";
1907  apply(R"cpp(#include "a.h"
1908  constexpr void fo^o() {})cpp",
1909  &EditedFiles);
1910  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
1911  testPath("a.h"), "constexpr void foo(){}")));
1912 
1913  // Class members don't need "inline".
1914  ExtraFiles["a.h"] = "struct Foo { void foo(); };";
1915  apply(R"cpp(#include "a.h"
1916  void Foo::fo^o() {})cpp",
1917  &EditedFiles);
1918  EXPECT_THAT(EditedFiles,
1919  testing::ElementsAre(FileWithContents(
1920  testPath("a.h"), "struct Foo { void foo(){} };")));
1921 
1922  // Function template doesn't need to be "inline"d.
1923  ExtraFiles["a.h"] = "template <typename T> void foo();";
1924  apply(R"cpp(#include "a.h"
1925  template <typename T>
1926  void fo^o() {})cpp",
1927  &EditedFiles);
1928  EXPECT_THAT(EditedFiles,
1929  testing::ElementsAre(FileWithContents(
1930  testPath("a.h"), "template <typename T> void foo(){}")));
1931 
1932  // Specializations needs to be marked "inline".
1933  ExtraFiles["a.h"] = R"cpp(
1934  template <typename T> void foo();
1935  template <> void foo<int>();)cpp";
1936  apply(R"cpp(#include "a.h"
1937  template <>
1938  void fo^o<int>() {})cpp",
1939  &EditedFiles);
1940  EXPECT_THAT(EditedFiles,
1941  testing::ElementsAre(FileWithContents(testPath("a.h"),
1942  R"cpp(
1943  template <typename T> void foo();
1944  template <> inline void foo<int>(){})cpp")));
1945 }
1946 
1947 TWEAK_TEST(DefineOutline);
1948 TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
1949  FileName = "Test.cpp";
1950  // Not available unless in a header file.
1951  EXPECT_UNAVAILABLE(R"cpp(
1952  [[void [[f^o^o]]() [[{
1953  return;
1954  }]]]])cpp");
1955 
1956  FileName = "Test.hpp";
1957  // Not available unless function name or fully body is selected.
1958  EXPECT_UNAVAILABLE(R"cpp(
1959  // Not a definition
1960  vo^i[[d^ ^f]]^oo();
1961 
1962  [[vo^id ]]foo[[()]] {[[
1963  [[(void)(5+3);
1964  return;]]
1965  }]])cpp");
1966 
1967  // Available even if there are no implementation files.
1968  EXPECT_AVAILABLE(R"cpp(
1969  [[void [[f^o^o]]() [[{
1970  return;
1971  }]]]])cpp");
1972 
1973  // Not available for out-of-line methods.
1974  EXPECT_UNAVAILABLE(R"cpp(
1975  class Bar {
1976  void baz();
1977  };
1978 
1979  [[void [[Bar::[[b^a^z]]]]() [[{
1980  return;
1981  }]]]])cpp");
1982 
1983  // Basic check for function body and signature.
1984  EXPECT_AVAILABLE(R"cpp(
1985  class Bar {
1986  [[void [[f^o^o^]]() [[{ return; }]]]]
1987  };
1988 
1989  void foo();
1990  [[void [[f^o^o]]() [[{
1991  return;
1992  }]]]])cpp");
1993 
1994  // Not available on defaulted/deleted members.
1995  EXPECT_UNAVAILABLE(R"cpp(
1996  class Foo {
1997  Fo^o() = default;
1998  F^oo(const Foo&) = delete;
1999  };)cpp");
2000 
2001  // Not available within templated classes, as it is hard to spell class name
2002  // out-of-line in such cases.
2003  EXPECT_UNAVAILABLE(R"cpp(
2004  template <typename> struct Foo { void fo^o(){} };
2005  )cpp");
2006 }
2007 
2008 TEST_F(DefineOutlineTest, FailsWithoutSource) {
2009  FileName = "Test.hpp";
2010  llvm::StringRef Test = "void fo^o() { return; }";
2011  llvm::StringRef Expected =
2012  "fail: Couldn't find a suitable implementation file.";
2013  EXPECT_EQ(apply(Test), Expected);
2014 }
2015 
2016 TEST_F(DefineOutlineTest, ApplyTest) {
2017  llvm::StringMap<std::string> EditedFiles;
2018  ExtraFiles["Test.cpp"] = "";
2019  FileName = "Test.hpp";
2020  // Template body is not parsed until instantiation time on windows, which
2021  // results in arbitrary failures as function body becomes NULL.
2022  ExtraArgs.push_back("-fno-delayed-template-parsing");
2023 
2024  struct {
2025  llvm::StringRef Test;
2026  llvm::StringRef ExpectedHeader;
2027  llvm::StringRef ExpectedSource;
2028  } Cases[] = {
2029  // Simple check
2030  {
2031  "void fo^o() { return; }",
2032  "void foo() ;",
2033  "void foo() { return; }",
2034  },
2035  // Templated function.
2036  {
2037  "template <typename T> void fo^o(T, T x) { return; }",
2038  "template <typename T> void foo(T, T x) ;",
2039  "template <typename T> void foo(T, T x) { return; }",
2040  },
2041  {
2042  "template <typename> void fo^o() { return; }",
2043  "template <typename> void foo() ;",
2044  "template <typename> void foo() { return; }",
2045  },
2046  // Template specialization.
2047  {
2048  R"cpp(
2049  template <typename> void foo();
2050  template <> void fo^o<int>() { return; })cpp",
2051  R"cpp(
2052  template <typename> void foo();
2053  template <> void foo<int>() ;)cpp",
2054  "template <> void foo<int>() { return; }",
2055  },
2056  // Default args.
2057  {
2058  "void fo^o(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) {}",
2059  "void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;",
2060  "void foo(int x, int y , int , int (*foo)(int) ) {}",
2061  },
2062  // Constructors
2063  {
2064  R"cpp(
2065  class Foo {public: Foo(); Foo(int);};
2066  class Bar {
2067  Ba^r() {}
2068  Bar(int x) : f1(x) {}
2069  Foo f1;
2070  Foo f2 = 2;
2071  };)cpp",
2072  R"cpp(
2073  class Foo {public: Foo(); Foo(int);};
2074  class Bar {
2075  Bar() ;
2076  Bar(int x) : f1(x) {}
2077  Foo f1;
2078  Foo f2 = 2;
2079  };)cpp",
2080  "Bar::Bar() {}\n",
2081  },
2082  // Ctor with initializer.
2083  {
2084  R"cpp(
2085  class Foo {public: Foo(); Foo(int);};
2086  class Bar {
2087  Bar() {}
2088  B^ar(int x) : f1(x), f2(3) {}
2089  Foo f1;
2090  Foo f2 = 2;
2091  };)cpp",
2092  R"cpp(
2093  class Foo {public: Foo(); Foo(int);};
2094  class Bar {
2095  Bar() {}
2096  Bar(int x) ;
2097  Foo f1;
2098  Foo f2 = 2;
2099  };)cpp",
2100  "Bar::Bar(int x) : f1(x), f2(3) {}\n",
2101  },
2102  // Ctor initializer with attribute.
2103  {
2104  R"cpp(
2105  class Foo {
2106  F^oo(int z) __attribute__((weak)) : bar(2){}
2107  int bar;
2108  };)cpp",
2109  R"cpp(
2110  class Foo {
2111  Foo(int z) __attribute__((weak)) ;
2112  int bar;
2113  };)cpp",
2114  "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
2115  },
2116  // Virt specifiers.
2117  {
2118  R"cpp(
2119  struct A {
2120  virtual void f^oo() {}
2121  };)cpp",
2122  R"cpp(
2123  struct A {
2124  virtual void foo() ;
2125  };)cpp",
2126  " void A::foo() {}\n",
2127  },
2128  {
2129  R"cpp(
2130  struct A {
2131  virtual virtual void virtual f^oo() {}
2132  };)cpp",
2133  R"cpp(
2134  struct A {
2135  virtual virtual void virtual foo() ;
2136  };)cpp",
2137  " void A::foo() {}\n",
2138  },
2139  {
2140  R"cpp(
2141  struct A {
2142  virtual void foo() = 0;
2143  };
2144  struct B : A {
2145  void fo^o() override {}
2146  };)cpp",
2147  R"cpp(
2148  struct A {
2149  virtual void foo() = 0;
2150  };
2151  struct B : A {
2152  void foo() override ;
2153  };)cpp",
2154  "void B::foo() {}\n",
2155  },
2156  {
2157  R"cpp(
2158  struct A {
2159  virtual void foo() = 0;
2160  };
2161  struct B : A {
2162  void fo^o() final {}
2163  };)cpp",
2164  R"cpp(
2165  struct A {
2166  virtual void foo() = 0;
2167  };
2168  struct B : A {
2169  void foo() final ;
2170  };)cpp",
2171  "void B::foo() {}\n",
2172  },
2173  {
2174  R"cpp(
2175  struct A {
2176  virtual void foo() = 0;
2177  };
2178  struct B : A {
2179  void fo^o() final override {}
2180  };)cpp",
2181  R"cpp(
2182  struct A {
2183  virtual void foo() = 0;
2184  };
2185  struct B : A {
2186  void foo() final override ;
2187  };)cpp",
2188  "void B::foo() {}\n",
2189  },
2190  {
2191  R"cpp(
2192  struct A {
2193  static void fo^o() {}
2194  };)cpp",
2195  R"cpp(
2196  struct A {
2197  static void foo() ;
2198  };)cpp",
2199  " void A::foo() {}\n",
2200  },
2201  {
2202  R"cpp(
2203  struct A {
2204  static static void fo^o() {}
2205  };)cpp",
2206  R"cpp(
2207  struct A {
2208  static static void foo() ;
2209  };)cpp",
2210  " void A::foo() {}\n",
2211  },
2212  };
2213  for (const auto &Case : Cases) {
2214  SCOPED_TRACE(Case.Test);
2215  EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
2216  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2217  testPath("Test.cpp"), Case.ExpectedSource)));
2218  }
2219 }
2220 
2221 TEST_F(DefineOutlineTest, HandleMacros) {
2222  llvm::StringMap<std::string> EditedFiles;
2223  ExtraFiles["Test.cpp"] = "";
2224  FileName = "Test.hpp";
2225  ExtraArgs.push_back("-DVIRTUAL=virtual");
2226  ExtraArgs.push_back("-DOVER=override");
2227 
2228  struct {
2229  llvm::StringRef Test;
2230  llvm::StringRef ExpectedHeader;
2231  llvm::StringRef ExpectedSource;
2232  } Cases[] = {
2233  {R"cpp(
2234  #define BODY { return; }
2235  void f^oo()BODY)cpp",
2236  R"cpp(
2237  #define BODY { return; }
2238  void foo();)cpp",
2239  "void foo()BODY"},
2240 
2241  {R"cpp(
2242  #define BODY return;
2243  void f^oo(){BODY})cpp",
2244  R"cpp(
2245  #define BODY return;
2246  void foo();)cpp",
2247  "void foo(){BODY}"},
2248 
2249  {R"cpp(
2250  #define TARGET void foo()
2251  [[TARGET]]{ return; })cpp",
2252  R"cpp(
2253  #define TARGET void foo()
2254  TARGET;)cpp",
2255  "TARGET{ return; }"},
2256 
2257  {R"cpp(
2258  #define TARGET foo
2259  void [[TARGET]](){ return; })cpp",
2260  R"cpp(
2261  #define TARGET foo
2262  void TARGET();)cpp",
2263  "void TARGET(){ return; }"},
2264  {R"cpp(#define VIRT virtual
2265  struct A {
2266  VIRT void f^oo() {}
2267  };)cpp",
2268  R"cpp(#define VIRT virtual
2269  struct A {
2270  VIRT void foo() ;
2271  };)cpp",
2272  " void A::foo() {}\n"},
2273  {R"cpp(
2274  struct A {
2275  VIRTUAL void f^oo() {}
2276  };)cpp",
2277  R"cpp(
2278  struct A {
2279  VIRTUAL void foo() ;
2280  };)cpp",
2281  " void A::foo() {}\n"},
2282  {R"cpp(
2283  struct A {
2284  virtual void foo() = 0;
2285  };
2286  struct B : A {
2287  void fo^o() OVER {}
2288  };)cpp",
2289  R"cpp(
2290  struct A {
2291  virtual void foo() = 0;
2292  };
2293  struct B : A {
2294  void foo() OVER ;
2295  };)cpp",
2296  "void B::foo() {}\n"},
2297  {R"cpp(#define STUPID_MACRO(X) virtual
2298  struct A {
2299  STUPID_MACRO(sizeof sizeof int) void f^oo() {}
2300  };)cpp",
2301  R"cpp(#define STUPID_MACRO(X) virtual
2302  struct A {
2303  STUPID_MACRO(sizeof sizeof int) void foo() ;
2304  };)cpp",
2305  " void A::foo() {}\n"},
2306  {R"cpp(#define STAT static
2307  struct A {
2308  STAT void f^oo() {}
2309  };)cpp",
2310  R"cpp(#define STAT static
2311  struct A {
2312  STAT void foo() ;
2313  };)cpp",
2314  " void A::foo() {}\n"},
2315  {R"cpp(#define STUPID_MACRO(X) static
2316  struct A {
2317  STUPID_MACRO(sizeof sizeof int) void f^oo() {}
2318  };)cpp",
2319  R"cpp(#define STUPID_MACRO(X) static
2320  struct A {
2321  STUPID_MACRO(sizeof sizeof int) void foo() ;
2322  };)cpp",
2323  " void A::foo() {}\n"},
2324  };
2325  for (const auto &Case : Cases) {
2326  SCOPED_TRACE(Case.Test);
2327  EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
2328  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2329  testPath("Test.cpp"), Case.ExpectedSource)));
2330  }
2331 }
2332 
2333 TEST_F(DefineOutlineTest, QualifyReturnValue) {
2334  FileName = "Test.hpp";
2335  ExtraFiles["Test.cpp"] = "";
2336 
2337  struct {
2338  llvm::StringRef Test;
2339  llvm::StringRef ExpectedHeader;
2340  llvm::StringRef ExpectedSource;
2341  } Cases[] = {
2342  {R"cpp(
2343  namespace a { class Foo{}; }
2344  using namespace a;
2345  Foo fo^o() { return {}; })cpp",
2346  R"cpp(
2347  namespace a { class Foo{}; }
2348  using namespace a;
2349  Foo foo() ;)cpp",
2350  "a::Foo foo() { return {}; }"},
2351  {R"cpp(
2352  namespace a {
2353  class Foo {
2354  class Bar {};
2355  Bar fo^o() { return {}; }
2356  };
2357  })cpp",
2358  R"cpp(
2359  namespace a {
2360  class Foo {
2361  class Bar {};
2362  Bar foo() ;
2363  };
2364  })cpp",
2365  "a::Foo::Bar a::Foo::foo() { return {}; }\n"},
2366  {R"cpp(
2367  class Foo {};
2368  Foo fo^o() { return {}; })cpp",
2369  R"cpp(
2370  class Foo {};
2371  Foo foo() ;)cpp",
2372  "Foo foo() { return {}; }"},
2373  };
2374  llvm::StringMap<std::string> EditedFiles;
2375  for (auto &Case : Cases) {
2376  apply(Case.Test, &EditedFiles);
2377  EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
2378  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2379  testPath("Test.cpp"), Case.ExpectedSource)));
2380  }
2381 }
2382 
2383 TEST_F(DefineOutlineTest, QualifyFunctionName) {
2384  FileName = "Test.hpp";
2385  struct {
2386  llvm::StringRef TestHeader;
2387  llvm::StringRef TestSource;
2388  llvm::StringRef ExpectedHeader;
2389  llvm::StringRef ExpectedSource;
2390  } Cases[] = {
2391  {
2392  R"cpp(
2393  namespace a {
2394  namespace b {
2395  class Foo {
2396  void fo^o() {}
2397  };
2398  }
2399  })cpp",
2400  "",
2401  R"cpp(
2402  namespace a {
2403  namespace b {
2404  class Foo {
2405  void foo() ;
2406  };
2407  }
2408  })cpp",
2409  "void a::b::Foo::foo() {}\n",
2410  },
2411  {
2412  "namespace a { namespace b { void f^oo() {} } }",
2413  "namespace a{}",
2414  "namespace a { namespace b { void foo() ; } }",
2415  "namespace a{void b::foo() {} }",
2416  },
2417  {
2418  "namespace a { namespace b { void f^oo() {} } }",
2419  "using namespace a;",
2420  "namespace a { namespace b { void foo() ; } }",
2421  // FIXME: Take using namespace directives in the source file into
2422  // account. This can be spelled as b::foo instead.
2423  "using namespace a;void a::b::foo() {} ",
2424  },
2425  };
2426  llvm::StringMap<std::string> EditedFiles;
2427  for (auto &Case : Cases) {
2428  ExtraFiles["Test.cpp"] = std::string(Case.TestSource);
2429  EXPECT_EQ(apply(Case.TestHeader, &EditedFiles), Case.ExpectedHeader);
2430  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2431  testPath("Test.cpp"), Case.ExpectedSource)))
2432  << Case.TestHeader;
2433  }
2434 }
2435 
2436 TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
2437  FileName = "Test.hpp";
2438  ExtraFiles["Test.cpp"] = "";
2439  ExtraArgs.push_back("-DFINALOVER=final override");
2440 
2441  std::pair<StringRef, StringRef> Cases[] = {
2442  {
2443  R"cpp(
2444  #define VIRT virtual void
2445  struct A {
2446  VIRT fo^o() {}
2447  };)cpp",
2448  "fail: define outline: couldn't remove `virtual` keyword."},
2449  {
2450  R"cpp(
2451  #define OVERFINAL final override
2452  struct A {
2453  virtual void foo() {}
2454  };
2455  struct B : A {
2456  void fo^o() OVERFINAL {}
2457  };)cpp",
2458  "fail: define outline: Can't move out of line as function has a "
2459  "macro `override` specifier.\ndefine outline: Can't move out of line "
2460  "as function has a macro `final` specifier."},
2461  {
2462  R"cpp(
2463  struct A {
2464  virtual void foo() {}
2465  };
2466  struct B : A {
2467  void fo^o() FINALOVER {}
2468  };)cpp",
2469  "fail: define outline: Can't move out of line as function has a "
2470  "macro `override` specifier.\ndefine outline: Can't move out of line "
2471  "as function has a macro `final` specifier."},
2472  };
2473  for (const auto &Case : Cases) {
2474  EXPECT_EQ(apply(Case.first), Case.second);
2475  }
2476 }
2477 
2478 TWEAK_TEST(AddUsing);
2479 TEST_F(AddUsingTest, Prepare) {
2480  const std::string Header = R"cpp(
2481 #define NS(name) one::two::name
2482 namespace one {
2483 void oo() {}
2484 template<typename TT> class tt {};
2485 namespace two {
2486 enum ee {};
2487 void ff() {}
2488 class cc {
2489 public:
2490  struct st {};
2491  static void mm() {}
2492  cc operator|(const cc& x) const { return x; }
2493 };
2494 }
2495 })cpp";
2496 
2497  EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o^:^:^f^f(); }");
2498  EXPECT_AVAILABLE(Header + "void fun() { o^n^e^::^o^o(); }");
2499  EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o^:^:^e^e E; }");
2500  EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o:^:^c^c C; }");
2501  EXPECT_UNAVAILABLE(Header +
2502  "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^m^m(); }");
2503  EXPECT_UNAVAILABLE(Header +
2504  "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^s^t inst; }");
2505  EXPECT_UNAVAILABLE(Header +
2506  "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^s^t inst; }");
2507  EXPECT_UNAVAILABLE(Header + "void fun() { N^S(c^c) inst; }");
2508  // This used to crash. Ideally we would support this case, but for now we just
2509  // test that we don't crash.
2510  EXPECT_UNAVAILABLE(Header +
2511  "template<typename TT> using foo = one::tt<T^T>;");
2512  // Test that we don't crash or misbehave on unnamed DeclRefExpr.
2513  EXPECT_UNAVAILABLE(Header +
2514  "void fun() { one::two::cc() ^| one::two::cc(); }");
2515 
2516  // Check that we do not trigger in header files.
2517  FileName = "test.h";
2518  ExtraArgs.push_back("-xc++-header"); // .h file is treated a C by default.
2519  EXPECT_UNAVAILABLE(Header + "void fun() { one::two::f^f(); }");
2520  FileName = "test.hpp";
2521  EXPECT_UNAVAILABLE(Header + "void fun() { one::two::f^f(); }");
2522 }
2523 
2524 TEST_F(AddUsingTest, Apply) {
2525  FileName = "test.cpp";
2526  struct {
2527  llvm::StringRef TestSource;
2528  llvm::StringRef ExpectedSource;
2529  } Cases[]{{
2530  // Function, no other using, namespace.
2531  R"cpp(
2532 #include "test.hpp"
2533 namespace {
2534 void fun() {
2535  ^o^n^e^:^:^t^w^o^:^:^f^f();
2536 }
2537 })cpp",
2538  R"cpp(
2539 #include "test.hpp"
2540 namespace {using one::two::ff;
2541 
2542 void fun() {
2543  ff();
2544 }
2545 })cpp",
2546  },
2547  // Type, no other using, namespace.
2548  {
2549  R"cpp(
2550 #include "test.hpp"
2551 namespace {
2552 void fun() {
2553  ::on^e::t^wo::c^c inst;
2554 }
2555 })cpp",
2556  R"cpp(
2557 #include "test.hpp"
2558 namespace {using ::one::two::cc;
2559 
2560 void fun() {
2561  cc inst;
2562 }
2563 })cpp",
2564  },
2565  // Type, no other using, no namespace.
2566  {
2567  R"cpp(
2568 #include "test.hpp"
2569 
2570 void fun() {
2571  on^e::t^wo::e^e inst;
2572 })cpp",
2573  R"cpp(
2574 #include "test.hpp"
2575 
2576 using one::two::ee;
2577 
2578 void fun() {
2579  ee inst;
2580 })cpp"},
2581  // Function, other usings.
2582  {
2583  R"cpp(
2584 #include "test.hpp"
2585 
2586 using one::two::cc;
2587 using one::two::ee;
2588 
2589 namespace {
2590 void fun() {
2591  one::two::f^f();
2592 }
2593 })cpp",
2594  R"cpp(
2595 #include "test.hpp"
2596 
2597 using one::two::cc;
2598 using one::two::ff;using one::two::ee;
2599 
2600 namespace {
2601 void fun() {
2602  ff();
2603 }
2604 })cpp",
2605  },
2606  // Function, other usings inside namespace.
2607  {
2608  R"cpp(
2609 #include "test.hpp"
2610 
2611 using one::two::cc;
2612 
2613 namespace {
2614 
2615 using one::two::ff;
2616 
2617 void fun() {
2618  o^ne::o^o();
2619 }
2620 })cpp",
2621  R"cpp(
2622 #include "test.hpp"
2623 
2624 using one::two::cc;
2625 
2626 namespace {
2627 
2628 using one::oo;using one::two::ff;
2629 
2630 void fun() {
2631  oo();
2632 }
2633 })cpp"},
2634  // Using comes after cursor.
2635  {
2636  R"cpp(
2637 #include "test.hpp"
2638 
2639 namespace {
2640 
2641 void fun() {
2642  one::t^wo::ff();
2643 }
2644 
2645 using one::two::cc;
2646 
2647 })cpp",
2648  R"cpp(
2649 #include "test.hpp"
2650 
2651 namespace {using one::two::ff;
2652 
2653 
2654 void fun() {
2655  ff();
2656 }
2657 
2658 using one::two::cc;
2659 
2660 })cpp"},
2661  // Pointer type.
2662  {R"cpp(
2663 #include "test.hpp"
2664 
2665 void fun() {
2666  one::two::c^c *p;
2667 })cpp",
2668  R"cpp(
2669 #include "test.hpp"
2670 
2671 using one::two::cc;
2672 
2673 void fun() {
2674  cc *p;
2675 })cpp"},
2676  // Namespace declared via macro.
2677  {R"cpp(
2678 #include "test.hpp"
2679 #define NS_BEGIN(name) namespace name {
2680 
2681 NS_BEGIN(foo)
2682 
2683 void fun() {
2684  one::two::f^f();
2685 }
2686 })cpp",
2687  R"cpp(
2688 #include "test.hpp"
2689 #define NS_BEGIN(name) namespace name {
2690 
2691 using one::two::ff;
2692 
2693 NS_BEGIN(foo)
2694 
2695 void fun() {
2696  ff();
2697 }
2698 })cpp"},
2699  // Inside macro argument.
2700  {R"cpp(
2701 #include "test.hpp"
2702 #define CALL(name) name()
2703 
2704 void fun() {
2705  CALL(one::t^wo::ff);
2706 })cpp",
2707  R"cpp(
2708 #include "test.hpp"
2709 #define CALL(name) name()
2710 
2711 using one::two::ff;
2712 
2713 void fun() {
2714  CALL(ff);
2715 })cpp"},
2716  // Parent namespace != lexical parent namespace
2717  {R"cpp(
2718 #include "test.hpp"
2719 namespace foo { void fun(); }
2720 
2721 void foo::fun() {
2722  one::two::f^f();
2723 })cpp",
2724  R"cpp(
2725 #include "test.hpp"
2726 using one::two::ff;
2727 
2728 namespace foo { void fun(); }
2729 
2730 void foo::fun() {
2731  ff();
2732 })cpp"}};
2733  llvm::StringMap<std::string> EditedFiles;
2734  for (const auto &Case : Cases) {
2735  for (const auto &SubCase : expandCases(Case.TestSource)) {
2736  ExtraFiles["test.hpp"] = R"cpp(
2737 namespace one {
2738 void oo() {}
2739 namespace two {
2740 enum ee {};
2741 void ff() {}
2742 class cc {
2743 public:
2744  struct st { struct nested {}; };
2745  static void mm() {}
2746 };
2747 }
2748 })cpp";
2749  EXPECT_EQ(apply(SubCase, &EditedFiles), Case.ExpectedSource);
2750  }
2751  }
2752 }
2753 
2754 } // namespace
2755 } // namespace clangd
2756 } // namespace clang
clang::clangd::TEST
TEST(BackgroundQueueTest, Priority)
Definition: BackgroundIndexTests.cpp:704
clang::clangd::testPath
std::string testPath(PathRef File, llvm::sys::path::Style Style)
Definition: TestFS.cpp:82
clang::clangd::Path
std::string Path
A typedef to represent a file path.
Definition: Path.h:20
Expected
std::vector< const char * > Expected
Definition: PrintASTTests.cpp:27
TestTU.h
Contents
llvm::StringRef Contents
Definition: DraftStoreTests.cpp:22
clang::clangd::TEST_F
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
Definition: BackgroundIndexTests.cpp:92
clang::clangd::testRoot
const char * testRoot()
Definition: TestFS.cpp:74
Tweak.h
clang::clangd::CompletionItemKind::Function
TestFS.h
EXPECT_AVAILABLE
#define EXPECT_AVAILABLE(MarkedCode)
Definition: TweakTesting.h:109
Annotations.h
Output
std::string Output
Definition: TraceTests.cpp:161
SourceCode.h
clang::clangd::Tweak::Effect::fileEdit
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
InMemoryFileSystem
llvm::IntrusiveRefCntPtr< llvm::vfs::InMemoryFileSystem > InMemoryFileSystem
Definition: IndexActionTests.cpp:109
TWEAK_TEST
#define TWEAK_TEST(TweakID)
Definition: TweakTesting.h:103
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::FileEdits
llvm::StringMap< Edit > FileEdits
A mapping from absolute file path (the one used for accessing the underlying VFS) to edits.
Definition: SourceCode.h:198
EXPECT_UNAVAILABLE
#define EXPECT_UNAVAILABLE(MarkedCode)
Definition: TweakTesting.h:115
TweakTesting.h
Apply
std::vector< llvm::unique_function< void(Config &) const > > Apply
Definition: ConfigCompile.cpp:52
FileName
PathRef FileName
Definition: CodeComplete.cpp:1043