[clang-tools-extra] 5934a79 - [clangd] Split tweak tests into one file per tweak.

Adam Czachorowski via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 9 08:18:51 PST 2020


Author: Adam Czachorowski
Date: 2020-12-09T17:17:06+01:00
New Revision: 5934a79196b937806d8260aab7ae16e74219fad9

URL: https://github.com/llvm/llvm-project/commit/5934a79196b937806d8260aab7ae16e74219fad9
DIFF: https://github.com/llvm/llvm-project/commit/5934a79196b937806d8260aab7ae16e74219fad9.diff

LOG: [clangd] Split tweak tests into one file per tweak.

No changes to the tests themselves, other than some auto -> const auto
diagnostic fixes and formatting.

Differential Revision: https://reviews.llvm.org/D92939

Added: 
    clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/AnnotateHighlightingsTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/DefineInlineTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/DumpASTTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/DumpRecordLayoutTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/DumpSymbolTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/ExpandAutoTypeTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/ExpandMacroTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/ExtractFunctionTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/ObjCLocalizeStringLiteralTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/PopulateSwitchTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/RawStringLiteralTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/ShowSelectionTreeTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/SwapIfBranchesTests.cpp
    clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp
    clang-tools-extra/clangd/unittests/tweaks/TweakTesting.h
    clang-tools-extra/clangd/unittests/tweaks/TweakTests.cpp

Modified: 
    clang-tools-extra/clangd/unittests/CMakeLists.txt

Removed: 
    clang-tools-extra/clangd/unittests/TweakTesting.cpp
    clang-tools-extra/clangd/unittests/TweakTesting.h
    clang-tools-extra/clangd/unittests/TweakTests.cpp


################################################################################
diff  --git a/clang-tools-extra/clangd/unittests/CMakeLists.txt b/clang-tools-extra/clangd/unittests/CMakeLists.txt
index 72ce97ed31b6..10f10f200471 100644
--- a/clang-tools-extra/clangd/unittests/CMakeLists.txt
+++ b/clang-tools-extra/clangd/unittests/CMakeLists.txt
@@ -93,8 +93,6 @@ add_unittest(ClangdUnitTests ClangdTests
   TestTU.cpp
   TestWorkspace.cpp
   TypeHierarchyTests.cpp
-  TweakTests.cpp
-  TweakTesting.cpp
   URITests.cpp
   XRefsTests.cpp
   ${CMAKE_CURRENT_BINARY_DIR}/DecisionForestRuntimeTest.cpp
@@ -108,6 +106,26 @@ add_unittest(ClangdUnitTests ClangdTests
   support/TestTracer.cpp
   support/TraceTests.cpp
 
+  tweaks/AddUsingTests.cpp
+  tweaks/AnnotateHighlightingsTests.cpp
+  tweaks/DefineInlineTests.cpp
+  tweaks/DefineOutlineTests.cpp
+  tweaks/DumpASTTests.cpp
+  tweaks/DumpRecordLayoutTests.cpp
+  tweaks/DumpSymbolTests.cpp
+  tweaks/ExpandAutoTypeTests.cpp
+  tweaks/ExpandMacroTests.cpp
+  tweaks/ExtractFunctionTests.cpp
+  tweaks/ExtractVariableTests.cpp
+  tweaks/ObjCLocalizeStringLiteralTests.cpp
+  tweaks/PopulateSwitchTests.cpp
+  tweaks/RawStringLiteralTests.cpp
+  tweaks/RemoveUsingNamespaceTests.cpp
+  tweaks/ShowSelectionTreeTests.cpp
+  tweaks/SwapIfBranchesTests.cpp
+  tweaks/TweakTesting.cpp
+  tweaks/TweakTests.cpp
+
   ${REMOTE_TEST_SOURCES}
 
   $<TARGET_OBJECTS:obj.clangDaemonTweaks>

diff  --git a/clang-tools-extra/clangd/unittests/TweakTests.cpp b/clang-tools-extra/clangd/unittests/TweakTests.cpp
deleted file mode 100644
index 0dcf8feb786f..000000000000
--- a/clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ /dev/null
@@ -1,3120 +0,0 @@
-//===-- TweakTests.cpp ------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "Annotations.h"
-#include "Config.h"
-#include "SourceCode.h"
-#include "TestFS.h"
-#include "TestTU.h"
-#include "TweakTesting.h"
-#include "refactor/Tweak.h"
-#include "clang/AST/Expr.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/DiagnosticIDs.h"
-#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/FileSystemOptions.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Rewrite/Core/Rewriter.h"
-#include "clang/Tooling/Core/Replacement.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/VirtualFileSystem.h"
-#include "llvm/Testing/Support/Error.h"
-#include "gmock/gmock-matchers.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include <cassert>
-#include <string>
-#include <utility>
-#include <vector>
-
-using ::testing::AllOf;
-using ::testing::ElementsAre;
-using ::testing::HasSubstr;
-using ::testing::StartsWith;
-
-namespace clang {
-namespace clangd {
-namespace {
-
-MATCHER_P2(FileWithContents, FileName, Contents, "") {
-  return arg.first() == FileName && arg.second == Contents;
-}
-
-TEST(FileEdits, AbsolutePath) {
-  auto RelPaths = {"a.h", "foo.cpp", "test/test.cpp"};
-
-  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> MemFS(
-      new llvm::vfs::InMemoryFileSystem);
-  MemFS->setCurrentWorkingDirectory(testRoot());
-  for (auto Path : RelPaths)
-    MemFS->addFile(Path, 0, llvm::MemoryBuffer::getMemBuffer("", Path));
-  FileManager FM(FileSystemOptions(), MemFS);
-  DiagnosticsEngine DE(new DiagnosticIDs, new DiagnosticOptions);
-  SourceManager SM(DE, FM);
-
-  for (auto Path : RelPaths) {
-    auto FID = SM.createFileID(*FM.getFile(Path), SourceLocation(),
-                               clang::SrcMgr::C_User);
-    auto Res = Tweak::Effect::fileEdit(SM, FID, tooling::Replacements());
-    ASSERT_THAT_EXPECTED(Res, llvm::Succeeded());
-    EXPECT_EQ(Res->first, testPath(Path));
-  }
-}
-
-TWEAK_TEST(SwapIfBranches);
-TEST_F(SwapIfBranchesTest, Test) {
-  Context = Function;
-  EXPECT_EQ(apply("^if (true) {return;} else {(void)0;}"),
-            "if (true) {(void)0;} else {return;}");
-  EXPECT_EQ(apply("^if (/*error-ok*/) {return;} else {(void)0;}"),
-            "if (/*error-ok*/) {(void)0;} else {return;}")
-      << "broken condition";
-  EXPECT_AVAILABLE("^i^f^^(^t^r^u^e^) { return; } ^e^l^s^e^ { return; }");
-  EXPECT_UNAVAILABLE("if (true) {^return ^;^ } else { ^return^;^ }");
-  // Available in subexpressions of the condition;
-  EXPECT_THAT("if(2 + [[2]] + 2) { return; } else {return;}", isAvailable());
-  // But not as part of the branches.
-  EXPECT_THAT("if(2 + 2 + 2) { [[return]]; } else { return; }",
-              Not(isAvailable()));
-  // Range covers the "else" token, so available.
-  EXPECT_THAT("if(2 + 2 + 2) { return[[; } else {return;]]}", isAvailable());
-  // Not available in compound statements in condition.
-  EXPECT_THAT("if([]{return [[true]];}()) { return; } else { return; }",
-              Not(isAvailable()));
-  // Not available if both sides aren't braced.
-  EXPECT_THAT("^if (1) return; else { return; }", Not(isAvailable()));
-  // Only one if statement is supported!
-  EXPECT_THAT("[[if(1){}else{}if(2){}else{}]]", Not(isAvailable()));
-}
-
-TWEAK_TEST(RawStringLiteral);
-TEST_F(RawStringLiteralTest, Test) {
-  Context = Expression;
-  EXPECT_AVAILABLE(R"cpp(^"^f^o^o^\^n^")cpp");
-  EXPECT_AVAILABLE(R"cpp(R"(multi )" ^"token " "str\ning")cpp");
-  EXPECT_UNAVAILABLE(R"cpp(^"f^o^o^o")cpp"); // no chars need escaping
-  EXPECT_UNAVAILABLE(R"cpp(R"(multi )" ^"token " u8"str\ning")cpp"); // nonascii
-  EXPECT_UNAVAILABLE(R"cpp(^R^"^(^multi )" "token " "str\ning")cpp"); // raw
-  EXPECT_UNAVAILABLE(R"cpp(^"token\n" __FILE__)cpp"); // chunk is macro
-  EXPECT_UNAVAILABLE(R"cpp(^"a\r\n";)cpp");           // forbidden escape char
-
-  const char *Input = R"cpp(R"(multi
-token)" "\nst^ring\n" "literal")cpp";
-  const char *Output = R"cpp(R"(multi
-token
-string
-literal)")cpp";
-  EXPECT_EQ(apply(Input), Output);
-}
-
-TWEAK_TEST(ObjCLocalizeStringLiteral);
-TEST_F(ObjCLocalizeStringLiteralTest, Test) {
-  ExtraArgs.push_back("-x");
-  ExtraArgs.push_back("objective-c");
-
-  // Ensure the action can be initiated in the string literal.
-  EXPECT_AVAILABLE(R"(id x = ^[[@[[^"^t^est^"]]]];)");
-
-  // Ensure that the action can't be initiated in other places.
-  EXPECT_UNAVAILABLE(R"([[i^d ^[[x]] ^= @"test";^]])");
-
-  // Ensure that the action is not available for regular C strings.
-  EXPECT_UNAVAILABLE(R"(const char * x= "^test";)");
-
-  const char *Input = R"(id x = [[@"test"]];)";
-  const char *Output = R"(id x = NSLocalizedString(@"test", @"");)";
-  EXPECT_EQ(apply(Input), Output);
-}
-
-TWEAK_TEST(DumpAST);
-TEST_F(DumpASTTest, Test) {
-  EXPECT_AVAILABLE("^int f^oo() { re^turn 2 ^+ 2; }");
-  EXPECT_UNAVAILABLE("/*c^omment*/ int foo() { return 2 ^ + 2; }");
-  EXPECT_THAT(apply("int x = 2 ^+ 2;"),
-              AllOf(StartsWith("message:"), HasSubstr("BinaryOperator"),
-                    HasSubstr("'+'"), HasSubstr("|-IntegerLiteral"),
-                    HasSubstr("<col:9> 'int' 2\n`-IntegerLiteral"),
-                    HasSubstr("<col:13> 'int' 2")));
-}
-
-TWEAK_TEST(DumpSymbol);
-TEST_F(DumpSymbolTest, Test) {
-  std::string ID = R"("id":"CA2EBE44A1D76D2A")";
-  std::string USR = R"("usr":"c:@F at foo#")";
-  EXPECT_THAT(apply("void f^oo();"),
-              AllOf(StartsWith("message:"), testing::HasSubstr(ID),
-                    testing::HasSubstr(USR)));
-}
-
-TWEAK_TEST(ShowSelectionTree);
-TEST_F(ShowSelectionTreeTest, Test) {
-  EXPECT_AVAILABLE("^int f^oo() { re^turn 2 ^+ 2; }");
-  EXPECT_AVAILABLE("/*c^omment*/ int foo() { return 2 ^ + 2; }");
-
-  const char *Output = R"(message:
- TranslationUnitDecl 
-   VarDecl int x = fcall(2 + 2)
-    .CallExpr fcall(2 + 2)
-       ImplicitCastExpr fcall
-        .DeclRefExpr fcall
-      .BinaryOperator 2 + 2
-        *IntegerLiteral 2
-)";
-  EXPECT_EQ(apply("int fcall(int); int x = fca[[ll(2 +]]2);"), Output);
-
-  Output = R"(message:
- TranslationUnitDecl 
-   FunctionDecl void x()
-     CompoundStmt { …
-       ForStmt for (;;) …
-        *BreakStmt break;
-)";
-  EXPECT_EQ(apply("void x() { for (;;) br^eak; }"), Output);
-}
-
-TWEAK_TEST(DumpRecordLayout);
-TEST_F(DumpRecordLayoutTest, Test) {
-  EXPECT_AVAILABLE("^s^truct ^X ^{ int x; ^};");
-  EXPECT_THAT("struct X { int ^a; };", Not(isAvailable()));
-  EXPECT_THAT("struct ^X;", Not(isAvailable()));
-  EXPECT_THAT("template <typename T> struct ^X { T t; };", Not(isAvailable()));
-  EXPECT_THAT("enum ^X {};", Not(isAvailable()));
-
-  EXPECT_THAT(apply("struct ^X { int x; int y; };"),
-              AllOf(StartsWith("message:"), HasSubstr("0 |   int x")));
-}
-
-TWEAK_TEST(ExtractVariable);
-TEST_F(ExtractVariableTest, Test) {
-  const char *AvailableCases = R"cpp(
-    int xyz(int a = 1) {
-      struct T {
-        int bar(int a = 1);
-        int z;
-      } t;
-      // return statement
-      return [[[[t.b[[a]]r]](t.z)]];
-    }
-    void f() {
-      int a = [[5 +]] [[4 * [[[[xyz]]()]]]];
-      // multivariable initialization
-      if(1)
-        int x = [[1]], y = [[a + 1]], a = [[1]], z = a + 1;
-      // if without else
-      if([[1]])
-        a = [[1]] + 1;
-      // if with else
-      if(a < [[3]])
-        if(a == [[4]])
-          a = [[5]] + 1;
-        else
-          a = [[5]] + 1;
-      else if (a < [[4]])
-        a = [[4]] + 1;
-      else
-        a = [[5]] + 1;
-      // for loop
-      for(a = [[1]] + 1; a > [[[[3]] + [[4]]]]; a++)
-        a = [[2]] + 1;
-      // while
-      while(a < [[1]])
-        a = [[1]] + 1;
-      // do while
-      do
-        a = [[1]] + 1;
-      while(a < [[3]]);
-    }
-  )cpp";
-  EXPECT_AVAILABLE(AvailableCases);
-
-  ExtraArgs = {"-xc"};
-  const char *AvailableButC = R"cpp(
-    void foo() {
-      int x = [[1]];
-    })cpp";
-  EXPECT_UNAVAILABLE(AvailableButC);
-  ExtraArgs = {};
-
-  const char *NoCrashCases = R"cpp(
-    // error-ok: broken code, but shouldn't crash
-    template<typename T, typename ...Args>
-    struct Test<T, Args...> {
-    Test(const T &v) :val[[(^]]) {}
-      T val;
-    };
-  )cpp";
-  EXPECT_UNAVAILABLE(NoCrashCases);
-
-  const char *UnavailableCases = R"cpp(
-    int xyz(int a = [[1]]) {
-      struct T {
-        int bar(int a = [[1]]);
-        int z = [[1]];
-      } t;
-      return [[t]].bar([[[[t]].z]]);
-    }
-    void v() { return; }
-    // function default argument
-    void f(int b = [[1]]) {
-      // empty selection
-      int a = ^1 ^+ ^2;
-      // void expressions
-      auto i = new int, j = new int;
-      [[[[delete i]], delete j]];
-      [[v]]();
-      // if
-      if(1)
-        int x = 1, y = a + 1, a = 1, z = [[a + 1]];
-      if(int a = 1)
-        if([[a + 1]] == 4)
-          a = [[[[a]] +]] 1;
-      // for loop
-      for(int a = 1, b = 2, c = 3; a > [[b + c]]; [[a++]])
-        a = [[a + 1]];
-      // lambda
-      auto lamb = [&[[a]], &[[b]]](int r = [[1]]) {return 1;};
-      // assignment
-      xyz([[a = 5]]);
-      xyz([[a *= 5]]);
-      // Variable DeclRefExpr
-      a = [[b]];
-      a = [[xyz()]];
-      // statement expression
-      [[xyz()]];
-      while (a)
-        [[++a]];
-      // label statement
-      goto label;
-      label:
-        a = [[1]];
-    }
-  )cpp";
-  EXPECT_UNAVAILABLE(UnavailableCases);
-
-  // vector of pairs of input and output strings
-  const std::vector<std::pair<std::string, std::string>> InputOutputs = {
-      // extraction from variable declaration/assignment
-      {R"cpp(void varDecl() {
-                   int a = 5 * (4 + (3 [[- 1)]]);
-                 })cpp",
-       R"cpp(void varDecl() {
-                   auto dummy = (3 - 1); int a = 5 * (4 + dummy);
-                 })cpp"},
-      // FIXME: extraction from switch case
-      /*{R"cpp(void f(int a) {
-               if(1)
-                 while(a < 1)
-                   switch (1) {
-                       case 1:
-                         a = [[1 + 2]];
-                         break;
-                       default:
-                         break;
-                   }
-             })cpp",
-       R"cpp(void f(int a) {
-               auto dummy = 1 + 2; if(1)
-                 while(a < 1)
-                   switch (1) {
-                       case 1:
-                         a = dummy;
-                         break;
-                       default:
-                         break;
-                   }
-             })cpp"},*/
-      // Macros
-      {R"cpp(#define PLUS(x) x++
-                 void f(int a) {
-                   int y = PLUS([[1+a]]);
-                 })cpp",
-       /*FIXME: It should be extracted like this.
-        R"cpp(#define PLUS(x) x++
-              void f(int a) {
-                auto dummy = 1+a; int y = PLUS(dummy);
-              })cpp"},*/
-       R"cpp(#define PLUS(x) x++
-                 void f(int a) {
-                   auto dummy = PLUS(1+a); int y = dummy;
-                 })cpp"},
-      // ensure InsertionPoint isn't inside a macro
-      {R"cpp(#define LOOP(x) while (1) {a = x;}
-                 void f(int a) {
-                   if(1)
-                    LOOP(5 + [[3]])
-                 })cpp",
-       R"cpp(#define LOOP(x) while (1) {a = x;}
-                 void f(int a) {
-                   auto dummy = 3; if(1)
-                    LOOP(5 + dummy)
-                 })cpp"},
-      {R"cpp(#define LOOP(x) do {x;} while(1);
-                 void f(int a) {
-                   if(1)
-                    LOOP(5 + [[3]])
-                 })cpp",
-       R"cpp(#define LOOP(x) do {x;} while(1);
-                 void f(int a) {
-                   auto dummy = 3; if(1)
-                    LOOP(5 + dummy)
-                 })cpp"},
-      // attribute testing
-      {R"cpp(void f(int a) {
-                    [ [gsl::suppress("type")] ] for (;;) a = [[1]] + 1;
-                 })cpp",
-       R"cpp(void f(int a) {
-                    auto dummy = 1; [ [gsl::suppress("type")] ] for (;;) a = dummy + 1;
-                 })cpp"},
-      // MemberExpr
-      {R"cpp(class T {
-                   T f() {
-                     return [[T().f()]].f();
-                   }
-                 };)cpp",
-       R"cpp(class T {
-                   T f() {
-                     auto dummy = T().f(); return dummy.f();
-                   }
-                 };)cpp"},
-      // Function DeclRefExpr
-      {R"cpp(int f() {
-                   return [[f]]();
-                 })cpp",
-       R"cpp(int f() {
-                   auto dummy = f(); return dummy;
-                 })cpp"},
-      // FIXME: Wrong result for \[\[clang::uninitialized\]\] int b = [[1]];
-      // since the attr is inside the DeclStmt and the bounds of
-      // DeclStmt don't cover the attribute.
-
-      // Binary subexpressions
-      {R"cpp(void f() {
-                   int x = 1 + [[2 + 3 + 4]] + 5;
-                 })cpp",
-       R"cpp(void f() {
-                   auto dummy = 2 + 3 + 4; int x = 1 + dummy + 5;
-                 })cpp"},
-      {R"cpp(void f() {
-                   int x = [[1 + 2 + 3]] + 4 + 5;
-                 })cpp",
-       R"cpp(void f() {
-                   auto dummy = 1 + 2 + 3; int x = dummy + 4 + 5;
-                 })cpp"},
-      {R"cpp(void f() {
-                   int x = 1 + 2 + [[3 + 4 + 5]];
-                 })cpp",
-       R"cpp(void f() {
-                   auto dummy = 3 + 4 + 5; int x = 1 + 2 + dummy;
-                 })cpp"},
-      // Non-associative operations have no special support
-      {R"cpp(void f() {
-                   int x = 1 - [[2 - 3 - 4]] - 5;
-                 })cpp",
-       R"cpp(void f() {
-                   auto dummy = 1 - 2 - 3 - 4; int x = dummy - 5;
-                 })cpp"},
-      // A mix of associative operators isn't associative.
-      {R"cpp(void f() {
-                   int x = 0 + 1 * [[2 + 3]] * 4 + 5;
-                 })cpp",
-       R"cpp(void f() {
-                   auto dummy = 1 * 2 + 3 * 4; int x = 0 + dummy + 5;
-                 })cpp"},
-      // Overloaded operators are supported, we assume associativity
-      // as if they were built-in.
-      {R"cpp(struct S {
-                   S(int);
-                 };
-                 S operator+(S, S);
-
-                 void f() {
-                   S x = S(1) + [[S(2) + S(3) + S(4)]] + S(5);
-                 })cpp",
-       R"cpp(struct S {
-                   S(int);
-                 };
-                 S operator+(S, S);
-
-                 void f() {
-                   auto dummy = S(2) + S(3) + S(4); S x = S(1) + dummy + S(5);
-                 })cpp"},
-      // Don't try to analyze across macro boundaries
-      // FIXME: it'd be nice to do this someday (in a safe way)
-      {R"cpp(#define ECHO(X) X
-                 void f() {
-                   int x = 1 + [[ECHO(2 + 3) + 4]] + 5;
-                 })cpp",
-       R"cpp(#define ECHO(X) X
-                 void f() {
-                   auto dummy = 1 + ECHO(2 + 3) + 4; int x = dummy + 5;
-                 })cpp"},
-      {R"cpp(#define ECHO(X) X
-                 void f() {
-                   int x = 1 + [[ECHO(2) + ECHO(3) + 4]] + 5;
-                 })cpp",
-       R"cpp(#define ECHO(X) X
-                 void f() {
-                   auto dummy = 1 + ECHO(2) + ECHO(3) + 4; int x = dummy + 5;
-                 })cpp"},
-  };
-  for (const auto &IO : InputOutputs) {
-    EXPECT_EQ(IO.second, apply(IO.first)) << IO.first;
-  }
-}
-
-TWEAK_TEST(AnnotateHighlightings);
-TEST_F(AnnotateHighlightingsTest, Test) {
-  EXPECT_AVAILABLE("^vo^id^ ^f(^) {^}^"); // available everywhere.
-  EXPECT_AVAILABLE("[[int a; int b;]]");
-  EXPECT_EQ("void /* entity.name.function.cpp */f() {}", apply("void ^f() {}"));
-
-  EXPECT_EQ(apply("[[void f1(); void f2();]]"),
-            "void /* entity.name.function.cpp */f1(); "
-            "void /* entity.name.function.cpp */f2();");
-
-  EXPECT_EQ(apply("void f1(); void f2() {^}"),
-            "void f1(); "
-            "void /* entity.name.function.cpp */f2() {}");
-}
-
-TWEAK_TEST(ExpandMacro);
-TEST_F(ExpandMacroTest, Test) {
-  Header = R"cpp(
-    // error-ok: not real c++, just token manipulation
-    #define FOO 1 2 3
-    #define FUNC(X) X+X+X
-    #define EMPTY
-    #define EMPTY_FN(X)
-  )cpp";
-
-  // Available on macro names, not available anywhere else.
-  EXPECT_AVAILABLE("^F^O^O^ BAR ^F^O^O^");
-  EXPECT_AVAILABLE("^F^U^N^C^(1)");
-  EXPECT_UNAVAILABLE("^#^d^efine^ ^XY^Z 1 ^2 ^3^");
-  EXPECT_UNAVAILABLE("FOO ^B^A^R^ FOO ^");
-  EXPECT_UNAVAILABLE("FUNC(^1^)^");
-
-  // Works as expected on object-like macros.
-  EXPECT_EQ(apply("^FOO BAR FOO"), "1 2 3 BAR FOO");
-  EXPECT_EQ(apply("FOO BAR ^FOO"), "FOO BAR 1 2 3");
-  // And function-like macros.
-  EXPECT_EQ(apply("F^UNC(2)"), "2 + 2 + 2");
-
-  // Works on empty macros.
-  EXPECT_EQ(apply("int a ^EMPTY;"), "int a ;");
-  EXPECT_EQ(apply("int a ^EMPTY_FN(1 2 3);"), "int a ;");
-  EXPECT_EQ(apply("int a = 123 ^EMPTY EMPTY_FN(1);"),
-            "int a = 123  EMPTY_FN(1);");
-  EXPECT_EQ(apply("int a = 123 ^EMPTY_FN(1) EMPTY;"), "int a = 123  EMPTY;");
-  EXPECT_EQ(apply("int a = 123 EMPTY_FN(1) ^EMPTY;"),
-            "int a = 123 EMPTY_FN(1) ;");
-}
-
-TWEAK_TEST(ExpandAutoType);
-TEST_F(ExpandAutoTypeTest, Test) {
-
-  Header = R"cpp(
-    namespace ns {
-      struct Class {
-        struct Nested {};
-      };
-      void Func();
-    }
-    inline namespace inl_ns {
-      namespace {
-        struct Visible {};
-      }
-    }
-  )cpp";
-
-  EXPECT_AVAILABLE("^a^u^t^o^ i = 0;");
-  EXPECT_UNAVAILABLE("auto ^i^ ^=^ ^0^;^");
-
-  // check primitive type
-  EXPECT_EQ(apply("[[auto]] i = 0;"), "int i = 0;");
-  EXPECT_EQ(apply("au^to i = 0;"), "int i = 0;");
-  // check classes and namespaces
-  EXPECT_EQ(apply("^auto C = ns::Class::Nested();"),
-            "ns::Class::Nested C = ns::Class::Nested();");
-  // check that namespaces are shortened
-  EXPECT_EQ(apply("namespace ns { void f() { ^auto C = Class(); } }"),
-            "namespace ns { void f() { Class C = Class(); } }");
-  // undefined functions should not be replaced
-  EXPECT_THAT(apply("au^to x = doesnt_exist(); // error-ok"),
-              StartsWith("fail: Could not deduce type for 'auto' type"));
-  // function pointers should not be replaced
-  EXPECT_THAT(apply("au^to x = &ns::Func;"),
-              StartsWith("fail: Could not expand type of function pointer"));
-  // lambda types are not replaced
-  EXPECT_UNAVAILABLE("au^to x = []{};");
-  // inline namespaces
-  EXPECT_EQ(apply("au^to x = inl_ns::Visible();"),
-            "Visible x = inl_ns::Visible();");
-  // local class
-  EXPECT_EQ(apply("namespace x { void y() { struct S{}; ^auto z = S(); } }"),
-            "namespace x { void y() { struct S{}; S z = S(); } }");
-  // replace array types
-  EXPECT_EQ(apply(R"cpp(au^to x = "test";)cpp"),
-            R"cpp(const char * x = "test";)cpp");
-
-  EXPECT_UNAVAILABLE("dec^ltype(au^to) x = 10;");
-  // expanding types in structured bindings is syntactically invalid.
-  EXPECT_UNAVAILABLE("const ^auto &[x,y] = (int[]){1,2};");
-
-  // FIXME: Auto-completion in a template requires disabling delayed template
-  // parsing.
-  ExtraArgs.push_back("-fno-delayed-template-parsing");
-  // unknown types in a template should not be replaced
-  EXPECT_THAT(apply("template <typename T> void x() { ^auto y = T::z(); }"),
-              StartsWith("fail: Could not deduce type for 'auto' type"));
-}
-
-TWEAK_TEST(ExtractFunction);
-TEST_F(ExtractFunctionTest, FunctionTest) {
-  Context = Function;
-
-  // Root statements should have common parent.
-  EXPECT_EQ(apply("for(;;) [[1+2; 1+2;]]"), "unavailable");
-  // Expressions aren't extracted.
-  EXPECT_EQ(apply("int x = 0; [[x++;]]"), "unavailable");
-  // We don't support extraction from lambdas.
-  EXPECT_EQ(apply("auto lam = [](){ [[int x;]] }; "), "unavailable");
-  // Partial statements aren't extracted.
-  EXPECT_THAT(apply("int [[x = 0]];"), "unavailable");
-  // FIXME: Support hoisting.
-  EXPECT_THAT(apply(" [[int a = 5;]] a++; "), "unavailable");
-
-  // Ensure that end of Zone and Beginning of PostZone being adjacent doesn't
-  // lead to break being included in the extraction zone.
-  EXPECT_THAT(apply("for(;;) { [[int x;]]break; }"), HasSubstr("extracted"));
-  // FIXME: ExtractFunction should be unavailable inside loop construct
-  // initializer/condition.
-  EXPECT_THAT(apply(" for([[int i = 0;]];);"), HasSubstr("extracted"));
-  // Extract certain return
-  EXPECT_THAT(apply(" if(true) [[{ return; }]] "), HasSubstr("extracted"));
-  // Don't extract uncertain return
-  EXPECT_THAT(apply(" if(true) [[if (false) return;]] "),
-              StartsWith("unavailable"));
-  EXPECT_THAT(
-      apply("#define RETURN_IF_ERROR(x) if (x) return\nRETU^RN_IF_ERROR(4);"),
-      StartsWith("unavailable"));
-
-  FileName = "a.c";
-  EXPECT_THAT(apply(" for([[int i = 0;]];);"), HasSubstr("unavailable"));
-}
-
-TEST_F(ExtractFunctionTest, FileTest) {
-  // Check all parameters are in order
-  std::string ParameterCheckInput = R"cpp(
-struct Foo {
-  int x;
-};
-void f(int a) {
-  int b;
-  int *ptr = &a;
-  Foo foo;
-  [[a += foo.x + b;
-  *ptr++;]]
-})cpp";
-  std::string ParameterCheckOutput = R"cpp(
-struct Foo {
-  int x;
-};
-void extracted(int &a, int &b, int * &ptr, Foo &foo) {
-a += foo.x + b;
-  *ptr++;
-}
-void f(int a) {
-  int b;
-  int *ptr = &a;
-  Foo foo;
-  extracted(a, b, ptr, foo);
-})cpp";
-  EXPECT_EQ(apply(ParameterCheckInput), ParameterCheckOutput);
-
-  // Check const qualifier
-  std::string ConstCheckInput = R"cpp(
-void f(const int c) {
-  [[while(c) {}]]
-})cpp";
-  std::string ConstCheckOutput = R"cpp(
-void extracted(const int &c) {
-while(c) {}
-}
-void f(const int c) {
-  extracted(c);
-})cpp";
-  EXPECT_EQ(apply(ConstCheckInput), ConstCheckOutput);
-
-  // Don't extract when we need to make a function as a parameter.
-  EXPECT_THAT(apply("void f() { [[int a; f();]] }"), StartsWith("fail"));
-
-  // We don't extract from methods for now since they may involve multi-file
-  // edits
-  std::string MethodFailInput = R"cpp(
-    class T {
-      void f() {
-        [[int x;]]
-      }
-    };
-  )cpp";
-  EXPECT_EQ(apply(MethodFailInput), "unavailable");
-
-  // We don't extract from templated functions for now as templates are hard
-  // to deal with.
-  std::string TemplateFailInput = R"cpp(
-    template<typename T>
-    void f() {
-      [[int x;]]
-    }
-  )cpp";
-  EXPECT_EQ(apply(TemplateFailInput), "unavailable");
-
-  std::string MacroInput = R"cpp(
-    #define F(BODY) void f() { BODY }
-    F ([[int x = 0;]])
-  )cpp";
-  std::string MacroOutput = R"cpp(
-    #define F(BODY) void f() { BODY }
-    void extracted() {
-int x = 0;
-}
-F (extracted();)
-  )cpp";
-  EXPECT_EQ(apply(MacroInput), MacroOutput);
-
-  // Shouldn't crash.
-  EXPECT_EQ(apply("void f([[int a]]);"), "unavailable");
-  // Don't extract if we select the entire function body (CompoundStmt).
-  std::string CompoundFailInput = R"cpp(
-    void f() [[{
-      int a;
-    }]]
-  )cpp";
-  EXPECT_EQ(apply(CompoundFailInput), "unavailable");
-}
-
-TEST_F(ExtractFunctionTest, ControlFlow) {
-  Context = Function;
-  // We should be able to extract break/continue with a parent loop/switch.
-  EXPECT_THAT(apply(" [[for(;;) if(1) break;]] "), HasSubstr("extracted"));
-  EXPECT_THAT(apply(" for(;;) [[while(1) break;]] "), HasSubstr("extracted"));
-  EXPECT_THAT(apply(" [[switch(1) { break; }]]"), HasSubstr("extracted"));
-  EXPECT_THAT(apply(" [[while(1) switch(1) { continue; }]]"),
-              HasSubstr("extracted"));
-  // Don't extract break and continue without a loop/switch parent.
-  EXPECT_THAT(apply(" for(;;) [[if(1) continue;]] "), StartsWith("fail"));
-  EXPECT_THAT(apply(" while(1) [[if(1) break;]] "), StartsWith("fail"));
-  EXPECT_THAT(apply(" switch(1) { [[break;]] }"), StartsWith("fail"));
-  EXPECT_THAT(apply(" for(;;) { [[while(1) break; break;]] }"),
-              StartsWith("fail"));
-}
-
-TEST_F(ExtractFunctionTest, ExistingReturnStatement) {
-  Context = File;
-  const char *Before = R"cpp(
-    bool lucky(int N);
-    int getNum(bool Superstitious, int Min, int Max) {
-      if (Superstitious) [[{
-        for (int I = Min; I <= Max; ++I)
-          if (lucky(I))
-            return I;
-        return -1;
-      }]] else {
-        return (Min + Max) / 2;
-      }
-    }
-  )cpp";
-  // FIXME: min/max should be by value.
-  // FIXME: avoid emitting redundant braces
-  const char *After = R"cpp(
-    bool lucky(int N);
-    int extracted(int &Min, int &Max) {
-{
-        for (int I = Min; I <= Max; ++I)
-          if (lucky(I))
-            return I;
-        return -1;
-      }
-}
-int getNum(bool Superstitious, int Min, int Max) {
-      if (Superstitious) return extracted(Min, Max); else {
-        return (Min + Max) / 2;
-      }
-    }
-  )cpp";
-  EXPECT_EQ(apply(Before), After);
-}
-
-TWEAK_TEST(RemoveUsingNamespace);
-TEST_F(RemoveUsingNamespaceTest, All) {
-  std::pair<llvm::StringRef /*Input*/, llvm::StringRef /*Expected*/> Cases[] = {
-      {// Remove all occurrences of ns. Qualify only unqualified.
-       R"cpp(
-      namespace ns1 { struct vector {}; }
-      namespace ns2 { struct map {}; }
-      using namespace n^s1;
-      using namespace ns2;
-      using namespace ns1;
-      int main() {
-        ns1::vector v1;
-        vector v2;
-        map m1;
-      }
-    )cpp",
-       R"cpp(
-      namespace ns1 { struct vector {}; }
-      namespace ns2 { struct map {}; }
-      
-      using namespace ns2;
-      
-      int main() {
-        ns1::vector v1;
-        ns1::vector v2;
-        map m1;
-      }
-    )cpp"},
-      {// Ident to be qualified is a macro arg.
-       R"cpp(
-      #define DECLARE(x, y) x y
-      namespace ns { struct vector {}; }
-      using namespace n^s;
-      int main() {
-        DECLARE(ns::vector, v1);
-        DECLARE(vector, v2);
-      }
-    )cpp",
-       R"cpp(
-      #define DECLARE(x, y) x y
-      namespace ns { struct vector {}; }
-      
-      int main() {
-        DECLARE(ns::vector, v1);
-        DECLARE(ns::vector, v2);
-      }
-    )cpp"},
-      {// Nested namespace: Fully qualify ident from inner ns.
-       R"cpp(
-      namespace aa { namespace bb { struct map {}; }}
-      using namespace aa::b^b;
-      int main() {
-        map m;
-      }
-    )cpp",
-       R"cpp(
-      namespace aa { namespace bb { struct map {}; }}
-      
-      int main() {
-        aa::bb::map m;
-      }
-    )cpp"},
-      {// Nested namespace: Fully qualify ident from inner ns.
-       R"cpp(
-      namespace aa { namespace bb { struct map {}; }}
-      using namespace a^a;
-      int main() {
-        bb::map m;
-      }
-    )cpp",
-       R"cpp(
-      namespace aa { namespace bb { struct map {}; }}
-      
-      int main() {
-        aa::bb::map m;
-      }
-    )cpp"},
-      {// Typedef.
-       R"cpp(
-      namespace aa { namespace bb { struct map {}; }}
-      using namespace a^a;
-      typedef bb::map map;
-      int main() { map M; }
-    )cpp",
-       R"cpp(
-      namespace aa { namespace bb { struct map {}; }}
-      
-      typedef aa::bb::map map;
-      int main() { map M; }
-    )cpp"},
-      {// FIXME: Nested namespaces: Not aware of using ns decl of outer ns.
-       R"cpp(
-      namespace aa { namespace bb { struct map {}; }}
-      using name[[space aa::b]]b;
-      using namespace aa;
-      int main() {
-        map m;
-      }
-    )cpp",
-       R"cpp(
-      namespace aa { namespace bb { struct map {}; }}
-      
-      using namespace aa;
-      int main() {
-        aa::bb::map m;
-      }
-    )cpp"},
-      {// Does not qualify ident from inner namespace.
-       R"cpp(
-      namespace aa { namespace bb { struct map {}; }}
-      using namespace aa::bb;
-      using namespace a^a;
-      int main() {
-        map m;
-      }
-    )cpp",
-       R"cpp(
-      namespace aa { namespace bb { struct map {}; }}
-      using namespace aa::bb;
-      
-      int main() {
-        map m;
-      }
-    )cpp"},
-      {// Available only for top level namespace decl.
-       R"cpp(
-        namespace aa {
-          namespace bb { struct map {}; }
-          using namespace b^b;
-        }
-        int main() { aa::map m; }
-    )cpp",
-       "unavailable"},
-      {// FIXME: Unavailable for namespaces containing using-namespace decl.
-       R"cpp(
-      namespace aa {
-        namespace bb { struct map {}; }
-        using namespace bb;
-      }
-      using namespace a^a;
-      int main() {
-        map m;
-      }
-    )cpp",
-       "unavailable"},
-      {R"cpp(
-      namespace a::b { struct Foo {}; }
-      using namespace a;
-      using namespace a::[[b]];
-      using namespace b;
-      int main() { Foo F;}
-    )cpp",
-       R"cpp(
-      namespace a::b { struct Foo {}; }
-      using namespace a;
-      
-      
-      int main() { a::b::Foo F;}
-    )cpp"},
-      {R"cpp(
-      namespace a::b { struct Foo {}; }
-      using namespace a;
-      using namespace a::b;
-      using namespace [[b]];
-      int main() { Foo F;}
-    )cpp",
-       R"cpp(
-      namespace a::b { struct Foo {}; }
-      using namespace a;
-      
-      
-      int main() { b::Foo F;}
-    )cpp"},
-      {// Enumerators.
-       R"cpp(
-      namespace tokens {
-      enum Token {
-        comma, identifier, numeric
-      };
-      }
-      using namespace tok^ens;
-      int main() {
-        auto x = comma;
-      }
-    )cpp",
-       R"cpp(
-      namespace tokens {
-      enum Token {
-        comma, identifier, numeric
-      };
-      }
-      
-      int main() {
-        auto x = tokens::comma;
-      }
-    )cpp"},
-      {// inline namespaces.
-       R"cpp(
-      namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
-      using namespace st^d;
-      int main() {
-        vector V;
-      }
-    )cpp",
-       R"cpp(
-      namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
-      
-      int main() {
-        std::vector V;
-      }
-    )cpp"}};
-  for (auto C : Cases)
-    EXPECT_EQ(C.second, apply(C.first)) << C.first;
-}
-
-TWEAK_TEST(DefineInline);
-TEST_F(DefineInlineTest, TriggersOnFunctionDecl) {
-  // Basic check for function body and signature.
-  EXPECT_AVAILABLE(R"cpp(
-  class Bar {
-    void baz();
-  };
-
-  [[void [[Bar::[[b^a^z]]]]() [[{
-    return;
-  }]]]]
-
-  void foo();
-  [[void [[f^o^o]]() [[{
-    return;
-  }]]]]
-  )cpp");
-
-  EXPECT_UNAVAILABLE(R"cpp(
-  // Not a definition
-  vo^i[[d^ ^f]]^oo();
-
-  [[vo^id ]]foo[[()]] {[[
-    [[(void)(5+3);
-    return;]]
-  }]]
-
-  // Definition with no body.
-  class Bar { Bar() = def^ault; };
-  )cpp");
-}
-
-TEST_F(DefineInlineTest, NoForwardDecl) {
-  Header = "void bar();";
-  EXPECT_UNAVAILABLE(R"cpp(
-  void bar() {
-    return;
-  }
-  // FIXME: Generate a decl in the header.
-  void fo^o() {
-    return;
-  })cpp");
-}
-
-TEST_F(DefineInlineTest, ReferencedDecls) {
-  EXPECT_AVAILABLE(R"cpp(
-    void bar();
-    void foo(int test);
-
-    void fo^o(int baz) {
-      int x = 10;
-      bar();
-    })cpp");
-
-  // Internal symbol usage.
-  Header = "void foo(int test);";
-  EXPECT_UNAVAILABLE(R"cpp(
-    void bar();
-    void fo^o(int baz) {
-      int x = 10;
-      bar();
-    })cpp");
-
-  // Becomes available after making symbol visible.
-  Header = "void bar();" + Header;
-  EXPECT_AVAILABLE(R"cpp(
-    void fo^o(int baz) {
-      int x = 10;
-      bar();
-    })cpp");
-
-  // FIXME: Move declaration below bar to make it visible.
-  Header.clear();
-  EXPECT_UNAVAILABLE(R"cpp(
-    void foo();
-    void bar();
-
-    void fo^o() {
-      bar();
-    })cpp");
-
-  // Order doesn't matter within a class.
-  EXPECT_AVAILABLE(R"cpp(
-    class Bar {
-      void foo();
-      void bar();
-    };
-
-    void Bar::fo^o() {
-      bar();
-    })cpp");
-
-  // FIXME: Perform include insertion to make symbol visible.
-  ExtraFiles["a.h"] = "void bar();";
-  Header = "void foo(int test);";
-  EXPECT_UNAVAILABLE(R"cpp(
-    #include "a.h"
-    void fo^o(int baz) {
-      int x = 10;
-      bar();
-    })cpp");
-}
-
-TEST_F(DefineInlineTest, TemplateSpec) {
-  EXPECT_UNAVAILABLE(R"cpp(
-    template <typename T> void foo();
-    template<> void foo<char>();
-
-    template<> void f^oo<int>() {
-    })cpp");
-  EXPECT_UNAVAILABLE(R"cpp(
-    template <typename T> void foo();
-
-    template<> void f^oo<int>() {
-    })cpp");
-  EXPECT_UNAVAILABLE(R"cpp(
-    template <typename T> struct Foo { void foo(); };
-
-    template <typename T> void Foo<T>::f^oo() {
-    })cpp");
-  EXPECT_AVAILABLE(R"cpp(
-    template <typename T> void foo();
-    void bar();
-    template <> void foo<int>();
-
-    template<> void f^oo<int>() {
-      bar();
-    })cpp");
-  EXPECT_UNAVAILABLE(R"cpp(
-    namespace bar {
-      template <typename T> void f^oo() {}
-      template void foo<int>();
-    })cpp");
-}
-
-TEST_F(DefineInlineTest, CheckForCanonDecl) {
-  EXPECT_UNAVAILABLE(R"cpp(
-    void foo();
-
-    void bar() {}
-    void f^oo() {
-      // This bar normally refers to the definition just above, but it is not
-      // visible from the forward declaration of foo.
-      bar();
-    })cpp");
-  // Make it available with a forward decl.
-  EXPECT_AVAILABLE(R"cpp(
-    void bar();
-    void foo();
-
-    void bar() {}
-    void f^oo() {
-      bar();
-    })cpp");
-}
-
-TEST_F(DefineInlineTest, UsingShadowDecls) {
-  // Template body is not parsed until instantiation time on windows, which
-  // results in arbitrary failures as function body becomes NULL.
-  ExtraArgs.push_back("-fno-delayed-template-parsing");
-  EXPECT_UNAVAILABLE(R"cpp(
-  namespace ns1 { void foo(int); }
-  namespace ns2 { void foo(int*); }
-  template <typename T>
-  void bar();
-
-  using ns1::foo;
-  using ns2::foo;
-
-  template <typename T>
-  void b^ar() {
-    foo(T());
-  })cpp");
-}
-
-TEST_F(DefineInlineTest, TransformNestedNamespaces) {
-  auto Test = R"cpp(
-    namespace a {
-      void bar();
-      namespace b {
-        void baz();
-        namespace c {
-          void aux();
-        }
-      }
-    }
-
-    void foo();
-    using namespace a;
-    using namespace b;
-    using namespace c;
-    void f^oo() {
-      bar();
-      a::bar();
-
-      baz();
-      b::baz();
-      a::b::baz();
-
-      aux();
-      c::aux();
-      b::c::aux();
-      a::b::c::aux();
-    })cpp";
-  auto Expected = R"cpp(
-    namespace a {
-      void bar();
-      namespace b {
-        void baz();
-        namespace c {
-          void aux();
-        }
-      }
-    }
-
-    void foo(){
-      a::bar();
-      a::bar();
-
-      a::b::baz();
-      a::b::baz();
-      a::b::baz();
-
-      a::b::c::aux();
-      a::b::c::aux();
-      a::b::c::aux();
-      a::b::c::aux();
-    }
-    using namespace a;
-    using namespace b;
-    using namespace c;
-    )cpp";
-  EXPECT_EQ(apply(Test), Expected);
-}
-
-TEST_F(DefineInlineTest, TransformUsings) {
-  auto Test = R"cpp(
-    namespace a { namespace b { namespace c { void aux(); } } }
-
-    void foo();
-    void f^oo() {
-      using namespace a;
-      using namespace b;
-      using namespace c;
-      using c::aux;
-      namespace d = c;
-    })cpp";
-  auto Expected = R"cpp(
-    namespace a { namespace b { namespace c { void aux(); } } }
-
-    void foo(){
-      using namespace a;
-      using namespace a::b;
-      using namespace a::b::c;
-      using a::b::c::aux;
-      namespace d = a::b::c;
-    }
-    )cpp";
-  EXPECT_EQ(apply(Test), Expected);
-}
-
-TEST_F(DefineInlineTest, TransformDecls) {
-  auto Test = R"cpp(
-    void foo();
-    void f^oo() {
-      class Foo {
-      public:
-        void foo();
-        int x;
-      };
-
-      enum En { Zero, One };
-      En x = Zero;
-
-      enum class EnClass { Zero, One };
-      EnClass y = EnClass::Zero;
-    })cpp";
-  auto Expected = R"cpp(
-    void foo(){
-      class Foo {
-      public:
-        void foo();
-        int x;
-      };
-
-      enum En { Zero, One };
-      En x = Zero;
-
-      enum class EnClass { Zero, One };
-      EnClass y = EnClass::Zero;
-    }
-    )cpp";
-  EXPECT_EQ(apply(Test), Expected);
-}
-
-TEST_F(DefineInlineTest, TransformTemplDecls) {
-  auto Test = R"cpp(
-    namespace a {
-      template <typename T> class Bar {
-      public:
-        void bar();
-      };
-      template <typename T> T bar;
-      template <typename T> void aux() {}
-    }
-
-    void foo();
-
-    using namespace a;
-    void f^oo() {
-      bar<Bar<int>>.bar();
-      aux<Bar<int>>();
-    })cpp";
-  auto Expected = R"cpp(
-    namespace a {
-      template <typename T> class Bar {
-      public:
-        void bar();
-      };
-      template <typename T> T bar;
-      template <typename T> void aux() {}
-    }
-
-    void foo(){
-      a::bar<a::Bar<int>>.bar();
-      a::aux<a::Bar<int>>();
-    }
-
-    using namespace a;
-    )cpp";
-  EXPECT_EQ(apply(Test), Expected);
-}
-
-TEST_F(DefineInlineTest, TransformMembers) {
-  auto Test = R"cpp(
-    class Foo {
-      void foo();
-    };
-
-    void Foo::f^oo() {
-      return;
-    })cpp";
-  auto Expected = R"cpp(
-    class Foo {
-      void foo(){
-      return;
-    }
-    };
-
-    )cpp";
-  EXPECT_EQ(apply(Test), Expected);
-
-  ExtraFiles["a.h"] = R"cpp(
-    class Foo {
-      void foo();
-    };)cpp";
-
-  llvm::StringMap<std::string> EditedFiles;
-  Test = R"cpp(
-    #include "a.h"
-    void Foo::f^oo() {
-      return;
-    })cpp";
-  Expected = R"cpp(
-    #include "a.h"
-    )cpp";
-  EXPECT_EQ(apply(Test, &EditedFiles), Expected);
-
-  Expected = R"cpp(
-    class Foo {
-      void foo(){
-      return;
-    }
-    };)cpp";
-  EXPECT_THAT(EditedFiles,
-              ElementsAre(FileWithContents(testPath("a.h"), Expected)));
-}
-
-TEST_F(DefineInlineTest, TransformDependentTypes) {
-  auto Test = R"cpp(
-    namespace a {
-      template <typename T> class Bar {};
-    }
-
-    template <typename T>
-    void foo();
-
-    using namespace a;
-    template <typename T>
-    void f^oo() {
-      Bar<T> B;
-      Bar<Bar<T>> q;
-    })cpp";
-  auto Expected = R"cpp(
-    namespace a {
-      template <typename T> class Bar {};
-    }
-
-    template <typename T>
-    void foo(){
-      a::Bar<T> B;
-      a::Bar<a::Bar<T>> q;
-    }
-
-    using namespace a;
-    )cpp";
-
-  // Template body is not parsed until instantiation time on windows, which
-  // results in arbitrary failures as function body becomes NULL.
-  ExtraArgs.push_back("-fno-delayed-template-parsing");
-  EXPECT_EQ(apply(Test), Expected);
-}
-
-TEST_F(DefineInlineTest, TransformFunctionTempls) {
-  // Check we select correct specialization decl.
-  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
-      {R"cpp(
-          template <typename T>
-          void foo(T p);
-
-          template <>
-          void foo<int>(int p);
-
-          template <>
-          void foo<char>(char p);
-
-          template <>
-          void fo^o<int>(int p) {
-            return;
-          })cpp",
-       R"cpp(
-          template <typename T>
-          void foo(T p);
-
-          template <>
-          void foo<int>(int p){
-            return;
-          }
-
-          template <>
-          void foo<char>(char p);
-
-          )cpp"},
-      {// Make sure we are not selecting the first specialization all the time.
-       R"cpp(
-          template <typename T>
-          void foo(T p);
-
-          template <>
-          void foo<int>(int p);
-
-          template <>
-          void foo<char>(char p);
-
-          template <>
-          void fo^o<char>(char p) {
-            return;
-          })cpp",
-       R"cpp(
-          template <typename T>
-          void foo(T p);
-
-          template <>
-          void foo<int>(int p);
-
-          template <>
-          void foo<char>(char p){
-            return;
-          }
-
-          )cpp"},
-      {R"cpp(
-          template <typename T>
-          void foo(T p);
-
-          template <>
-          void foo<int>(int p);
-
-          template <typename T>
-          void fo^o(T p) {
-            return;
-          })cpp",
-       R"cpp(
-          template <typename T>
-          void foo(T p){
-            return;
-          }
-
-          template <>
-          void foo<int>(int p);
-
-          )cpp"},
-  };
-  // Template body is not parsed until instantiation time on windows, which
-  // results in arbitrary failures as function body becomes NULL.
-  ExtraArgs.push_back("-fno-delayed-template-parsing");
-  for (const auto &Case : Cases)
-    EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
-}
-
-TEST_F(DefineInlineTest, TransformTypeLocs) {
-  auto Test = R"cpp(
-    namespace a {
-      template <typename T> class Bar {
-      public:
-        template <typename Q> class Baz {};
-      };
-      class Foo{};
-    }
-
-    void foo();
-
-    using namespace a;
-    void f^oo() {
-      Bar<int> B;
-      Foo foo;
-      a::Bar<Bar<int>>::Baz<Bar<int>> q;
-    })cpp";
-  auto Expected = R"cpp(
-    namespace a {
-      template <typename T> class Bar {
-      public:
-        template <typename Q> class Baz {};
-      };
-      class Foo{};
-    }
-
-    void foo(){
-      a::Bar<int> B;
-      a::Foo foo;
-      a::Bar<a::Bar<int>>::Baz<a::Bar<int>> q;
-    }
-
-    using namespace a;
-    )cpp";
-  EXPECT_EQ(apply(Test), Expected);
-}
-
-TEST_F(DefineInlineTest, TransformDeclRefs) {
-  auto Test = R"cpp(
-    namespace a {
-      template <typename T> class Bar {
-      public:
-        void foo();
-        static void bar();
-        int x;
-        static int y;
-      };
-      void bar();
-      void test();
-    }
-
-    void foo();
-    using namespace a;
-    void f^oo() {
-      a::Bar<int> B;
-      B.foo();
-      a::bar();
-      Bar<Bar<int>>::bar();
-      a::Bar<int>::bar();
-      B.x = Bar<int>::y;
-      Bar<int>::y = 3;
-      bar();
-      a::test();
-    })cpp";
-  auto Expected = R"cpp(
-    namespace a {
-      template <typename T> class Bar {
-      public:
-        void foo();
-        static void bar();
-        int x;
-        static int y;
-      };
-      void bar();
-      void test();
-    }
-
-    void foo(){
-      a::Bar<int> B;
-      B.foo();
-      a::bar();
-      a::Bar<a::Bar<int>>::bar();
-      a::Bar<int>::bar();
-      B.x = a::Bar<int>::y;
-      a::Bar<int>::y = 3;
-      a::bar();
-      a::test();
-    }
-    using namespace a;
-    )cpp";
-  EXPECT_EQ(apply(Test), Expected);
-}
-
-TEST_F(DefineInlineTest, StaticMembers) {
-  auto Test = R"cpp(
-    namespace ns { class X { static void foo(); void bar(); }; }
-    void ns::X::b^ar() {
-      foo();
-    })cpp";
-  auto Expected = R"cpp(
-    namespace ns { class X { static void foo(); void bar(){
-      foo();
-    } }; }
-    )cpp";
-  EXPECT_EQ(apply(Test), Expected);
-}
-
-TEST_F(DefineInlineTest, TransformParamNames) {
-  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
-      {R"cpp(
-        void foo(int, bool b, int T\
-est);
-        void ^foo(int f, bool x, int z) {})cpp",
-       R"cpp(
-        void foo(int f, bool x, int z){}
-        )cpp"},
-      {R"cpp(
-        #define PARAM int Z
-        void foo(PARAM);
-
-        void ^foo(int X) {})cpp",
-       "fail: Cant rename parameter inside macro body."},
-      {R"cpp(
-        #define TYPE int
-        #define PARAM TYPE Z
-        #define BODY(x) 5 * (x) + 2
-        template <int P>
-        void foo(PARAM, TYPE Q, TYPE, TYPE W = BODY(P));
-        template <int x>
-        void ^foo(int Z, int b, int c, int d) {})cpp",
-       R"cpp(
-        #define TYPE int
-        #define PARAM TYPE Z
-        #define BODY(x) 5 * (x) + 2
-        template <int x>
-        void foo(PARAM, TYPE b, TYPE c, TYPE d = BODY(x)){}
-        )cpp"},
-  };
-  ExtraArgs.push_back("-fno-delayed-template-parsing");
-  for (const auto &Case : Cases)
-    EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
-}
-
-TEST_F(DefineInlineTest, TransformTemplParamNames) {
-  auto Test = R"cpp(
-    struct Foo {
-      struct Bar {
-        template <class, class X,
-                  template<typename> class, template<typename> class Y,
-                  int, int Z>
-        void foo(X, Y<X>, int W = 5 * Z + 2);
-      };
-    };
-
-    template <class T, class U,
-              template<typename> class V, template<typename> class W,
-              int X, int Y>
-    void Foo::Bar::f^oo(U, W<U>, int Q) {})cpp";
-  auto Expected = R"cpp(
-    struct Foo {
-      struct Bar {
-        template <class T, class U,
-                  template<typename> class V, template<typename> class W,
-                  int X, int Y>
-        void foo(U, W<U>, int Q = 5 * Y + 2){}
-      };
-    };
-
-    )cpp";
-  ExtraArgs.push_back("-fno-delayed-template-parsing");
-  EXPECT_EQ(apply(Test), Expected);
-}
-
-TEST_F(DefineInlineTest, TransformInlineNamespaces) {
-  auto Test = R"cpp(
-    namespace a { inline namespace b { namespace { struct Foo{}; } } }
-    void foo();
-
-    using namespace a;
-    void ^foo() {Foo foo;})cpp";
-  auto Expected = R"cpp(
-    namespace a { inline namespace b { namespace { struct Foo{}; } } }
-    void foo(){a::Foo foo;}
-
-    using namespace a;
-    )cpp";
-  EXPECT_EQ(apply(Test), Expected);
-}
-
-TEST_F(DefineInlineTest, TokensBeforeSemicolon) {
-  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
-      {R"cpp(
-          void foo()    /*Comment -_-*/ /*Com 2*/ ;
-          void fo^o() { return ; })cpp",
-       R"cpp(
-          void foo()    /*Comment -_-*/ /*Com 2*/ { return ; }
-          )cpp"},
-
-      {R"cpp(
-          void foo();
-          void fo^o() { return ; })cpp",
-       R"cpp(
-          void foo(){ return ; }
-          )cpp"},
-
-      {R"cpp(
-          #define SEMI ;
-          void foo() SEMI
-          void fo^o() { return ; })cpp",
-       "fail: Couldn't find semicolon for target declaration."},
-  };
-  for (const auto &Case : Cases)
-    EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
-}
-
-TEST_F(DefineInlineTest, HandleMacros) {
-  EXPECT_UNAVAILABLE(R"cpp(
-    #define BODY { return; }
-    void foo();
-    void f^oo()BODY)cpp");
-
-  EXPECT_UNAVAILABLE(R"cpp(
-    #define BODY void foo(){ return; }
-    void foo();
-    [[BODY]])cpp");
-
-  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
-      // We don't qualify declarations coming from macros.
-      {R"cpp(
-          #define BODY Foo
-          namespace a { class Foo{}; }
-          void foo();
-          using namespace a;
-          void f^oo(){BODY();})cpp",
-       R"cpp(
-          #define BODY Foo
-          namespace a { class Foo{}; }
-          void foo(){BODY();}
-          using namespace a;
-          )cpp"},
-
-      // Macro is not visible at declaration location, but we proceed.
-      {R"cpp(
-          void foo();
-          #define BODY return;
-          void f^oo(){BODY})cpp",
-       R"cpp(
-          void foo(){BODY}
-          #define BODY return;
-          )cpp"},
-
-      {R"cpp(
-          #define TARGET void foo()
-          TARGET;
-          void f^oo(){ return; })cpp",
-       R"cpp(
-          #define TARGET void foo()
-          TARGET{ return; }
-          )cpp"},
-
-      {R"cpp(
-          #define TARGET foo
-          void TARGET();
-          void f^oo(){ return; })cpp",
-       R"cpp(
-          #define TARGET foo
-          void TARGET(){ return; }
-          )cpp"},
-  };
-  for (const auto &Case : Cases)
-    EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
-}
-
-TEST_F(DefineInlineTest, DropCommonNameSpecifiers) {
-  struct {
-    llvm::StringRef Test;
-    llvm::StringRef Expected;
-  } Cases[] = {
-      {R"cpp(
-        namespace a { namespace b { void aux(); } }
-        namespace ns1 {
-          void foo();
-          namespace qq { void test(); }
-          namespace ns2 {
-            void bar();
-            namespace ns3 { void baz(); }
-          }
-        }
-
-        using namespace a;
-        using namespace a::b;
-        using namespace ns1::qq;
-        void ns1::ns2::ns3::b^az() {
-          foo();
-          bar();
-          baz();
-          ns1::ns2::ns3::baz();
-          aux();
-          test();
-        })cpp",
-       R"cpp(
-        namespace a { namespace b { void aux(); } }
-        namespace ns1 {
-          void foo();
-          namespace qq { void test(); }
-          namespace ns2 {
-            void bar();
-            namespace ns3 { void baz(){
-          foo();
-          bar();
-          baz();
-          ns1::ns2::ns3::baz();
-          a::b::aux();
-          qq::test();
-        } }
-          }
-        }
-
-        using namespace a;
-        using namespace a::b;
-        using namespace ns1::qq;
-        )cpp"},
-      {R"cpp(
-        namespace ns1 {
-          namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
-          namespace ns2 { void baz(); }
-        }
-
-        using namespace ns1::qq;
-        void ns1::ns2::b^az() { Foo f; B b; })cpp",
-       R"cpp(
-        namespace ns1 {
-          namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
-          namespace ns2 { void baz(){ qq::Foo f; qq::B b; } }
-        }
-
-        using namespace ns1::qq;
-        )cpp"},
-      {R"cpp(
-        namespace ns1 {
-          namespace qq {
-            template<class T> struct Foo { template <class U> struct Bar {}; };
-            template<class T, class U>
-            using B = typename Foo<T>::template Bar<U>;
-          }
-          namespace ns2 { void baz(); }
-        }
-
-        using namespace ns1::qq;
-        void ns1::ns2::b^az() { B<int, bool> b; })cpp",
-       R"cpp(
-        namespace ns1 {
-          namespace qq {
-            template<class T> struct Foo { template <class U> struct Bar {}; };
-            template<class T, class U>
-            using B = typename Foo<T>::template Bar<U>;
-          }
-          namespace ns2 { void baz(){ qq::B<int, bool> b; } }
-        }
-
-        using namespace ns1::qq;
-        )cpp"},
-  };
-  for (const auto &Case : Cases)
-    EXPECT_EQ(apply(Case.Test), Case.Expected) << Case.Test;
-}
-
-TEST_F(DefineInlineTest, QualifyWithUsingDirectives) {
-  llvm::StringRef Test = R"cpp(
-    namespace a {
-      void bar();
-      namespace b { struct Foo{}; void aux(); }
-      namespace c { void cux(); }
-    }
-    using namespace a;
-    using X = b::Foo;
-    void foo();
-
-    using namespace b;
-    using namespace c;
-    void ^foo() {
-      cux();
-      bar();
-      X x;
-      aux();
-      using namespace c;
-      // FIXME: The last reference to cux() in body of foo should not be
-      // qualified, since there is a using directive inside the function body.
-      cux();
-    })cpp";
-  llvm::StringRef Expected = R"cpp(
-    namespace a {
-      void bar();
-      namespace b { struct Foo{}; void aux(); }
-      namespace c { void cux(); }
-    }
-    using namespace a;
-    using X = b::Foo;
-    void foo(){
-      c::cux();
-      bar();
-      X x;
-      b::aux();
-      using namespace c;
-      // FIXME: The last reference to cux() in body of foo should not be
-      // qualified, since there is a using directive inside the function body.
-      c::cux();
-    }
-
-    using namespace b;
-    using namespace c;
-    )cpp";
-  EXPECT_EQ(apply(Test), Expected) << Test;
-}
-
-TEST_F(DefineInlineTest, AddInline) {
-  ExtraArgs.push_back("-fno-delayed-template-parsing");
-  llvm::StringMap<std::string> EditedFiles;
-  ExtraFiles["a.h"] = "void foo();";
-  apply(R"cpp(#include "a.h"
-              void fo^o() {})cpp",
-        &EditedFiles);
-  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
-                               testPath("a.h"), "inline void foo(){}")));
-
-  // Check we put inline before cv-qualifiers.
-  ExtraFiles["a.h"] = "const int foo();";
-  apply(R"cpp(#include "a.h"
-              const int fo^o() {})cpp",
-        &EditedFiles);
-  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
-                               testPath("a.h"), "inline const int foo(){}")));
-
-  // No double inline.
-  ExtraFiles["a.h"] = "inline void foo();";
-  apply(R"cpp(#include "a.h"
-              inline void fo^o() {})cpp",
-        &EditedFiles);
-  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
-                               testPath("a.h"), "inline void foo(){}")));
-
-  // Constexprs don't need "inline".
-  ExtraFiles["a.h"] = "constexpr void foo();";
-  apply(R"cpp(#include "a.h"
-              constexpr void fo^o() {})cpp",
-        &EditedFiles);
-  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
-                               testPath("a.h"), "constexpr void foo(){}")));
-
-  // Class members don't need "inline".
-  ExtraFiles["a.h"] = "struct Foo { void foo(); };";
-  apply(R"cpp(#include "a.h"
-              void Foo::fo^o() {})cpp",
-        &EditedFiles);
-  EXPECT_THAT(EditedFiles,
-              testing::ElementsAre(FileWithContents(
-                  testPath("a.h"), "struct Foo { void foo(){} };")));
-
-  // Function template doesn't need to be "inline"d.
-  ExtraFiles["a.h"] = "template <typename T> void foo();";
-  apply(R"cpp(#include "a.h"
-              template <typename T>
-              void fo^o() {})cpp",
-        &EditedFiles);
-  EXPECT_THAT(EditedFiles,
-              testing::ElementsAre(FileWithContents(
-                  testPath("a.h"), "template <typename T> void foo(){}")));
-
-  // Specializations needs to be marked "inline".
-  ExtraFiles["a.h"] = R"cpp(
-                            template <typename T> void foo();
-                            template <> void foo<int>();)cpp";
-  apply(R"cpp(#include "a.h"
-              template <>
-              void fo^o<int>() {})cpp",
-        &EditedFiles);
-  EXPECT_THAT(EditedFiles,
-              testing::ElementsAre(FileWithContents(testPath("a.h"),
-                                                    R"cpp(
-                            template <typename T> void foo();
-                            template <> inline void foo<int>(){})cpp")));
-}
-
-TWEAK_TEST(DefineOutline);
-TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
-  FileName = "Test.cpp";
-  // Not available unless in a header file.
-  EXPECT_UNAVAILABLE(R"cpp(
-    [[void [[f^o^o]]() [[{
-      return;
-    }]]]])cpp");
-
-  FileName = "Test.hpp";
-  // Not available unless function name or fully body is selected.
-  EXPECT_UNAVAILABLE(R"cpp(
-    // Not a definition
-    vo^i[[d^ ^f]]^oo();
-
-    [[vo^id ]]foo[[()]] {[[
-      [[(void)(5+3);
-      return;]]
-    }]])cpp");
-
-  // Available even if there are no implementation files.
-  EXPECT_AVAILABLE(R"cpp(
-    [[void [[f^o^o]]() [[{
-      return;
-    }]]]])cpp");
-
-  // Not available for out-of-line methods.
-  EXPECT_UNAVAILABLE(R"cpp(
-    class Bar {
-      void baz();
-    };
-
-    [[void [[Bar::[[b^a^z]]]]() [[{
-      return;
-    }]]]])cpp");
-
-  // Basic check for function body and signature.
-  EXPECT_AVAILABLE(R"cpp(
-    class Bar {
-      [[void [[f^o^o^]]() [[{ return; }]]]]
-    };
-
-    void foo();
-    [[void [[f^o^o]]() [[{
-      return;
-    }]]]])cpp");
-
-  // Not available on defaulted/deleted members.
-  EXPECT_UNAVAILABLE(R"cpp(
-    class Foo {
-      Fo^o() = default;
-      F^oo(const Foo&) = delete;
-    };)cpp");
-
-  // Not available within templated classes, as it is hard to spell class name
-  // out-of-line in such cases.
-  EXPECT_UNAVAILABLE(R"cpp(
-    template <typename> struct Foo { void fo^o(){} };
-    )cpp");
-
-  // Not available on function templates and specializations, as definition must
-  // be visible to all translation units.
-  EXPECT_UNAVAILABLE(R"cpp(
-    template <typename> void fo^o() {};
-    template <> void fo^o<int>() {};
-  )cpp");
-}
-
-TEST_F(DefineOutlineTest, FailsWithoutSource) {
-  FileName = "Test.hpp";
-  llvm::StringRef Test = "void fo^o() { return; }";
-  llvm::StringRef Expected =
-      "fail: Couldn't find a suitable implementation file.";
-  EXPECT_EQ(apply(Test), Expected);
-}
-
-TEST_F(DefineOutlineTest, ApplyTest) {
-  llvm::StringMap<std::string> EditedFiles;
-  ExtraFiles["Test.cpp"] = "";
-  FileName = "Test.hpp";
-  // Template body is not parsed until instantiation time on windows, which
-  // results in arbitrary failures as function body becomes NULL.
-  ExtraArgs.push_back("-fno-delayed-template-parsing");
-
-  struct {
-    llvm::StringRef Test;
-    llvm::StringRef ExpectedHeader;
-    llvm::StringRef ExpectedSource;
-  } Cases[] = {
-      // Simple check
-      {
-          "void fo^o() { return; }",
-          "void foo() ;",
-          "void foo() { return; }",
-      },
-      // Default args.
-      {
-          "void fo^o(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) {}",
-          "void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;",
-          "void foo(int x, int y , int , int (*foo)(int) ) {}",
-      },
-      // Constructors
-      {
-          R"cpp(
-            class Foo {public: Foo(); Foo(int);};
-            class Bar {
-              Ba^r() {}
-              Bar(int x) : f1(x) {}
-              Foo f1;
-              Foo f2 = 2;
-            };)cpp",
-          R"cpp(
-            class Foo {public: Foo(); Foo(int);};
-            class Bar {
-              Bar() ;
-              Bar(int x) : f1(x) {}
-              Foo f1;
-              Foo f2 = 2;
-            };)cpp",
-          "Bar::Bar() {}\n",
-      },
-      // Ctor with initializer.
-      {
-          R"cpp(
-            class Foo {public: Foo(); Foo(int);};
-            class Bar {
-              Bar() {}
-              B^ar(int x) : f1(x), f2(3) {}
-              Foo f1;
-              Foo f2 = 2;
-            };)cpp",
-          R"cpp(
-            class Foo {public: Foo(); Foo(int);};
-            class Bar {
-              Bar() {}
-              Bar(int x) ;
-              Foo f1;
-              Foo f2 = 2;
-            };)cpp",
-          "Bar::Bar(int x) : f1(x), f2(3) {}\n",
-      },
-      // Ctor initializer with attribute.
-      {
-          R"cpp(
-              class Foo {
-                F^oo(int z) __attribute__((weak)) : bar(2){}
-                int bar;
-              };)cpp",
-          R"cpp(
-              class Foo {
-                Foo(int z) __attribute__((weak)) ;
-                int bar;
-              };)cpp",
-          "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
-      },
-      // Virt specifiers.
-      {
-          R"cpp(
-            struct A {
-              virtual void f^oo() {}
-            };)cpp",
-          R"cpp(
-            struct A {
-              virtual void foo() ;
-            };)cpp",
-          " void A::foo() {}\n",
-      },
-      {
-          R"cpp(
-            struct A {
-              virtual virtual void virtual f^oo() {}
-            };)cpp",
-          R"cpp(
-            struct A {
-              virtual virtual void virtual foo() ;
-            };)cpp",
-          "  void  A::foo() {}\n",
-      },
-      {
-          R"cpp(
-            struct A {
-              virtual void foo() = 0;
-            };
-            struct B : A {
-              void fo^o() override {}
-            };)cpp",
-          R"cpp(
-            struct A {
-              virtual void foo() = 0;
-            };
-            struct B : A {
-              void foo() override ;
-            };)cpp",
-          "void B::foo()  {}\n",
-      },
-      {
-          R"cpp(
-            struct A {
-              virtual void foo() = 0;
-            };
-            struct B : A {
-              void fo^o() final {}
-            };)cpp",
-          R"cpp(
-            struct A {
-              virtual void foo() = 0;
-            };
-            struct B : A {
-              void foo() final ;
-            };)cpp",
-          "void B::foo()  {}\n",
-      },
-      {
-          R"cpp(
-            struct A {
-              virtual void foo() = 0;
-            };
-            struct B : A {
-              void fo^o() final override {}
-            };)cpp",
-          R"cpp(
-            struct A {
-              virtual void foo() = 0;
-            };
-            struct B : A {
-              void foo() final override ;
-            };)cpp",
-          "void B::foo()   {}\n",
-      },
-      {
-          R"cpp(
-            struct A {
-              static void fo^o() {}
-            };)cpp",
-          R"cpp(
-            struct A {
-              static void foo() ;
-            };)cpp",
-          " void A::foo() {}\n",
-      },
-      {
-          R"cpp(
-            struct A {
-              static static void fo^o() {}
-            };)cpp",
-          R"cpp(
-            struct A {
-              static static void foo() ;
-            };)cpp",
-          "  void A::foo() {}\n",
-      },
-  };
-  for (const auto &Case : Cases) {
-    SCOPED_TRACE(Case.Test);
-    EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
-    EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
-                                 testPath("Test.cpp"), Case.ExpectedSource)));
-  }
-}
-
-TEST_F(DefineOutlineTest, HandleMacros) {
-  llvm::StringMap<std::string> EditedFiles;
-  ExtraFiles["Test.cpp"] = "";
-  FileName = "Test.hpp";
-  ExtraArgs.push_back("-DVIRTUAL=virtual");
-  ExtraArgs.push_back("-DOVER=override");
-
-  struct {
-    llvm::StringRef Test;
-    llvm::StringRef ExpectedHeader;
-    llvm::StringRef ExpectedSource;
-  } Cases[] = {
-      {R"cpp(
-          #define BODY { return; }
-          void f^oo()BODY)cpp",
-       R"cpp(
-          #define BODY { return; }
-          void foo();)cpp",
-       "void foo()BODY"},
-
-      {R"cpp(
-          #define BODY return;
-          void f^oo(){BODY})cpp",
-       R"cpp(
-          #define BODY return;
-          void foo();)cpp",
-       "void foo(){BODY}"},
-
-      {R"cpp(
-          #define TARGET void foo()
-          [[TARGET]]{ return; })cpp",
-       R"cpp(
-          #define TARGET void foo()
-          TARGET;)cpp",
-       "TARGET{ return; }"},
-
-      {R"cpp(
-          #define TARGET foo
-          void [[TARGET]](){ return; })cpp",
-       R"cpp(
-          #define TARGET foo
-          void TARGET();)cpp",
-       "void TARGET(){ return; }"},
-      {R"cpp(#define VIRT virtual
-          struct A {
-            VIRT void f^oo() {}
-          };)cpp",
-       R"cpp(#define VIRT virtual
-          struct A {
-            VIRT void foo() ;
-          };)cpp",
-       " void A::foo() {}\n"},
-      {R"cpp(
-          struct A {
-            VIRTUAL void f^oo() {}
-          };)cpp",
-       R"cpp(
-          struct A {
-            VIRTUAL void foo() ;
-          };)cpp",
-       " void A::foo() {}\n"},
-      {R"cpp(
-          struct A {
-            virtual void foo() = 0;
-          };
-          struct B : A {
-            void fo^o() OVER {}
-          };)cpp",
-       R"cpp(
-          struct A {
-            virtual void foo() = 0;
-          };
-          struct B : A {
-            void foo() OVER ;
-          };)cpp",
-       "void B::foo()  {}\n"},
-      {R"cpp(#define STUPID_MACRO(X) virtual
-          struct A {
-            STUPID_MACRO(sizeof sizeof int) void f^oo() {}
-          };)cpp",
-       R"cpp(#define STUPID_MACRO(X) virtual
-          struct A {
-            STUPID_MACRO(sizeof sizeof int) void foo() ;
-          };)cpp",
-       " void A::foo() {}\n"},
-      {R"cpp(#define STAT static
-          struct A {
-            STAT void f^oo() {}
-          };)cpp",
-       R"cpp(#define STAT static
-          struct A {
-            STAT void foo() ;
-          };)cpp",
-       " void A::foo() {}\n"},
-      {R"cpp(#define STUPID_MACRO(X) static
-          struct A {
-            STUPID_MACRO(sizeof sizeof int) void f^oo() {}
-          };)cpp",
-       R"cpp(#define STUPID_MACRO(X) static
-          struct A {
-            STUPID_MACRO(sizeof sizeof int) void foo() ;
-          };)cpp",
-       " void A::foo() {}\n"},
-  };
-  for (const auto &Case : Cases) {
-    SCOPED_TRACE(Case.Test);
-    EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
-    EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
-                                 testPath("Test.cpp"), Case.ExpectedSource)));
-  }
-}
-
-TEST_F(DefineOutlineTest, QualifyReturnValue) {
-  FileName = "Test.hpp";
-  ExtraFiles["Test.cpp"] = "";
-
-  struct {
-    llvm::StringRef Test;
-    llvm::StringRef ExpectedHeader;
-    llvm::StringRef ExpectedSource;
-  } Cases[] = {
-      {R"cpp(
-        namespace a { class Foo{}; }
-        using namespace a;
-        Foo fo^o() { return {}; })cpp",
-       R"cpp(
-        namespace a { class Foo{}; }
-        using namespace a;
-        Foo foo() ;)cpp",
-       "a::Foo foo() { return {}; }"},
-      {R"cpp(
-        namespace a {
-          class Foo {
-            class Bar {};
-            Bar fo^o() { return {}; }
-          };
-        })cpp",
-       R"cpp(
-        namespace a {
-          class Foo {
-            class Bar {};
-            Bar foo() ;
-          };
-        })cpp",
-       "a::Foo::Bar a::Foo::foo() { return {}; }\n"},
-      {R"cpp(
-        class Foo {};
-        Foo fo^o() { return {}; })cpp",
-       R"cpp(
-        class Foo {};
-        Foo foo() ;)cpp",
-       "Foo foo() { return {}; }"},
-  };
-  llvm::StringMap<std::string> EditedFiles;
-  for (auto &Case : Cases) {
-    apply(Case.Test, &EditedFiles);
-    EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
-    EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
-                                 testPath("Test.cpp"), Case.ExpectedSource)));
-  }
-}
-
-TEST_F(DefineOutlineTest, QualifyFunctionName) {
-  FileName = "Test.hpp";
-  struct {
-    llvm::StringRef TestHeader;
-    llvm::StringRef TestSource;
-    llvm::StringRef ExpectedHeader;
-    llvm::StringRef ExpectedSource;
-  } Cases[] = {
-      {
-          R"cpp(
-            namespace a {
-              namespace b {
-                class Foo {
-                  void fo^o() {}
-                };
-              }
-            })cpp",
-          "",
-          R"cpp(
-            namespace a {
-              namespace b {
-                class Foo {
-                  void foo() ;
-                };
-              }
-            })cpp",
-          "void a::b::Foo::foo() {}\n",
-      },
-      {
-          "namespace a { namespace b { void f^oo() {} } }",
-          "namespace a{}",
-          "namespace a { namespace b { void foo() ; } }",
-          "namespace a{void b::foo() {} }",
-      },
-      {
-          "namespace a { namespace b { void f^oo() {} } }",
-          "using namespace a;",
-          "namespace a { namespace b { void foo() ; } }",
-          // FIXME: Take using namespace directives in the source file into
-          // account. This can be spelled as b::foo instead.
-          "using namespace a;void a::b::foo() {} ",
-      },
-  };
-  llvm::StringMap<std::string> EditedFiles;
-  for (auto &Case : Cases) {
-    ExtraFiles["Test.cpp"] = std::string(Case.TestSource);
-    EXPECT_EQ(apply(Case.TestHeader, &EditedFiles), Case.ExpectedHeader);
-    EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
-                                 testPath("Test.cpp"), Case.ExpectedSource)))
-        << Case.TestHeader;
-  }
-}
-
-TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
-  FileName = "Test.hpp";
-  ExtraFiles["Test.cpp"] = "";
-  ExtraArgs.push_back("-DFINALOVER=final override");
-
-  std::pair<StringRef, StringRef> Cases[] = {
-      {
-          R"cpp(
-          #define VIRT virtual void
-          struct A {
-            VIRT fo^o() {}
-          };)cpp",
-          "fail: define outline: couldn't remove `virtual` keyword."},
-      {
-          R"cpp(
-          #define OVERFINAL final override
-          struct A {
-            virtual void foo() {}
-          };
-          struct B : A {
-            void fo^o() OVERFINAL {}
-          };)cpp",
-          "fail: define outline: Can't move out of line as function has a "
-          "macro `override` specifier.\ndefine outline: Can't move out of line "
-          "as function has a macro `final` specifier."},
-      {
-          R"cpp(
-          struct A {
-            virtual void foo() {}
-          };
-          struct B : A {
-            void fo^o() FINALOVER {}
-          };)cpp",
-          "fail: define outline: Can't move out of line as function has a "
-          "macro `override` specifier.\ndefine outline: Can't move out of line "
-          "as function has a macro `final` specifier."},
-  };
-  for (const auto &Case : Cases) {
-    EXPECT_EQ(apply(Case.first), Case.second);
-  }
-}
-
-TWEAK_TEST(AddUsing);
-TEST_F(AddUsingTest, Prepare) {
-  Config Cfg;
-  Cfg.Style.FullyQualifiedNamespaces.push_back("ban");
-  WithContextValue WithConfig(Config::Key, std::move(Cfg));
-
-  const std::string Header = R"cpp(
-#define NS(name) one::two::name
-namespace ban { void foo() {} }
-namespace banana { void foo() {} }
-namespace one {
-void oo() {}
-template<typename TT> class tt {};
-namespace two {
-enum ee {};
-void ff() {}
-class cc {
-public:
-  struct st {};
-  static void mm() {}
-  cc operator|(const cc& x) const { return x; }
-};
-}
-})cpp";
-
-  EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o^:^:^f^f(); }");
-  EXPECT_AVAILABLE(Header + "void fun() { o^n^e^::^o^o(); }");
-  EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o^:^:^e^e E; }");
-  EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o:^:^c^c C; }");
-  EXPECT_UNAVAILABLE(Header +
-                     "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^m^m(); }");
-  EXPECT_UNAVAILABLE(Header +
-                     "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^s^t inst; }");
-  EXPECT_UNAVAILABLE(Header +
-                     "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^s^t inst; }");
-  EXPECT_UNAVAILABLE(Header + "void fun() { N^S(c^c) inst; }");
-  // This used to crash. Ideally we would support this case, but for now we just
-  // test that we don't crash.
-  EXPECT_UNAVAILABLE(Header +
-                     "template<typename TT> using foo = one::tt<T^T>;");
-  // Test that we don't crash or misbehave on unnamed DeclRefExpr.
-  EXPECT_UNAVAILABLE(Header +
-                     "void fun() { one::two::cc() ^| one::two::cc(); }");
-  // Do not offer code action when operating on a banned namespace.
-  EXPECT_UNAVAILABLE(Header + "void fun() { ban::fo^o(); }");
-  EXPECT_UNAVAILABLE(Header + "void fun() { ::ban::fo^o(); }");
-  EXPECT_AVAILABLE(Header + "void fun() { banana::fo^o(); }");
-
-  // Do not offer code action on typo-corrections.
-  EXPECT_UNAVAILABLE(Header + "/*error-ok*/c^c C;");
-
-  // NestedNameSpecifier, but no namespace.
-  EXPECT_UNAVAILABLE(Header + "class Foo {}; class F^oo foo;");
-
-  // Check that we do not trigger in header files.
-  FileName = "test.h";
-  ExtraArgs.push_back("-xc++-header"); // .h file is treated a C by default.
-  EXPECT_UNAVAILABLE(Header + "void fun() { one::two::f^f(); }");
-  FileName = "test.hpp";
-  EXPECT_UNAVAILABLE(Header + "void fun() { one::two::f^f(); }");
-}
-
-TEST_F(AddUsingTest, Apply) {
-  FileName = "test.cpp";
-  struct {
-    llvm::StringRef TestSource;
-    llvm::StringRef ExpectedSource;
-  } Cases[]{{
-                // Function, no other using, namespace.
-                R"cpp(
-#include "test.hpp"
-namespace {
-void fun() {
-  ^o^n^e^:^:^t^w^o^:^:^f^f();
-}
-})cpp",
-                R"cpp(
-#include "test.hpp"
-namespace {using one::two::ff;
-
-void fun() {
-  ff();
-}
-})cpp",
-            },
-            // Type, no other using, namespace.
-            {
-                R"cpp(
-#include "test.hpp"
-namespace {
-void fun() {
-  ::on^e::t^wo::c^c inst;
-}
-})cpp",
-                R"cpp(
-#include "test.hpp"
-namespace {using ::one::two::cc;
-
-void fun() {
-  cc inst;
-}
-})cpp",
-            },
-            // Type, no other using, no namespace.
-            {
-                R"cpp(
-#include "test.hpp"
-
-void fun() {
-  on^e::t^wo::e^e inst;
-})cpp",
-                R"cpp(
-#include "test.hpp"
-
-using one::two::ee;
-
-void fun() {
-  ee inst;
-})cpp"},
-            // Function, other usings.
-            {
-                R"cpp(
-#include "test.hpp"
-
-using one::two::cc;
-using one::two::ee;
-
-namespace {
-void fun() {
-  one::two::f^f();
-}
-})cpp",
-                R"cpp(
-#include "test.hpp"
-
-using one::two::cc;
-using one::two::ff;using one::two::ee;
-
-namespace {
-void fun() {
-  ff();
-}
-})cpp",
-            },
-            // Function, other usings inside namespace.
-            {
-                R"cpp(
-#include "test.hpp"
-
-using one::two::cc;
-
-namespace {
-
-using one::two::ff;
-
-void fun() {
-  o^ne::o^o();
-}
-})cpp",
-                R"cpp(
-#include "test.hpp"
-
-using one::two::cc;
-
-namespace {
-
-using one::oo;using one::two::ff;
-
-void fun() {
-  oo();
-}
-})cpp"},
-            // Using comes after cursor.
-            {
-                R"cpp(
-#include "test.hpp"
-
-namespace {
-
-void fun() {
-  one::t^wo::ff();
-}
-
-using one::two::cc;
-
-})cpp",
-                R"cpp(
-#include "test.hpp"
-
-namespace {using one::two::ff;
-
-
-void fun() {
-  ff();
-}
-
-using one::two::cc;
-
-})cpp"},
-            // Pointer type.
-            {R"cpp(
-#include "test.hpp"
-
-void fun() {
-  one::two::c^c *p;
-})cpp",
-             R"cpp(
-#include "test.hpp"
-
-using one::two::cc;
-
-void fun() {
-  cc *p;
-})cpp"},
-            // Namespace declared via macro.
-            {R"cpp(
-#include "test.hpp"
-#define NS_BEGIN(name) namespace name {
-
-NS_BEGIN(foo)
-
-void fun() {
-  one::two::f^f();
-}
-})cpp",
-             R"cpp(
-#include "test.hpp"
-#define NS_BEGIN(name) namespace name {
-
-using one::two::ff;
-
-NS_BEGIN(foo)
-
-void fun() {
-  ff();
-}
-})cpp"},
-            // Inside macro argument.
-            {R"cpp(
-#include "test.hpp"
-#define CALL(name) name()
-
-void fun() {
-  CALL(one::t^wo::ff);
-})cpp",
-             R"cpp(
-#include "test.hpp"
-#define CALL(name) name()
-
-using one::two::ff;
-
-void fun() {
-  CALL(ff);
-})cpp"},
-            // Parent namespace != lexical parent namespace
-            {R"cpp(
-#include "test.hpp"
-namespace foo { void fun(); }
-
-void foo::fun() {
-  one::two::f^f();
-})cpp",
-             R"cpp(
-#include "test.hpp"
-using one::two::ff;
-
-namespace foo { void fun(); }
-
-void foo::fun() {
-  ff();
-})cpp"},
-            // If all other using are fully qualified, add ::
-            {R"cpp(
-#include "test.hpp"
-
-using ::one::two::cc;
-using ::one::two::ee;
-
-void fun() {
-  one::two::f^f();
-})cpp",
-             R"cpp(
-#include "test.hpp"
-
-using ::one::two::cc;
-using ::one::two::ff;using ::one::two::ee;
-
-void fun() {
-  ff();
-})cpp"},
-            // Make sure we don't add :: if it's already there
-            {R"cpp(
-#include "test.hpp"
-
-using ::one::two::cc;
-using ::one::two::ee;
-
-void fun() {
-  ::one::two::f^f();
-})cpp",
-             R"cpp(
-#include "test.hpp"
-
-using ::one::two::cc;
-using ::one::two::ff;using ::one::two::ee;
-
-void fun() {
-  ff();
-})cpp"},
-            // If even one using doesn't start with ::, do not add it
-            {R"cpp(
-#include "test.hpp"
-
-using ::one::two::cc;
-using one::two::ee;
-
-void fun() {
-  one::two::f^f();
-})cpp",
-             R"cpp(
-#include "test.hpp"
-
-using ::one::two::cc;
-using one::two::ff;using one::two::ee;
-
-void fun() {
-  ff();
-})cpp"},
-            // using alias; insert using for the spelled name.
-            {R"cpp(
-#include "test.hpp"
-
-void fun() {
-  one::u^u u;
-})cpp",
-             R"cpp(
-#include "test.hpp"
-
-using one::uu;
-
-void fun() {
-  uu u;
-})cpp"},
-            // using namespace.
-            {R"cpp(
-#include "test.hpp"
-using namespace one;
-namespace {
-two::c^c C;
-})cpp",
-             R"cpp(
-#include "test.hpp"
-using namespace one;
-namespace {using two::cc;
-
-cc C;
-})cpp"},
-            // Type defined in main file, make sure using is after that.
-            {R"cpp(
-namespace xx {
-  struct yy {};
-}
-
-x^x::yy X;
-)cpp",
-             R"cpp(
-namespace xx {
-  struct yy {};
-}
-
-using xx::yy;
-
-yy X;
-)cpp"},
-            // Type defined in main file via "using", insert after that.
-            {R"cpp(
-#include "test.hpp"
-
-namespace xx {
-  using yy = one::two::cc;
-}
-
-x^x::yy X;
-)cpp",
-             R"cpp(
-#include "test.hpp"
-
-namespace xx {
-  using yy = one::two::cc;
-}
-
-using xx::yy;
-
-yy X;
-)cpp"},
-            // Using must come after function definition.
-            {R"cpp(
-namespace xx {
-  void yy();
-}
-
-void fun() {
-  x^x::yy();
-}
-)cpp",
-             R"cpp(
-namespace xx {
-  void yy();
-}
-
-using xx::yy;
-
-void fun() {
-  yy();
-}
-)cpp"},
-            // Existing using with non-namespace part.
-            {R"cpp(
-#include "test.hpp"
-using one::two::ee::ee_one;
-one::t^wo::cc c;
-)cpp",
-             R"cpp(
-#include "test.hpp"
-using one::two::cc;using one::two::ee::ee_one;
-cc c;
-)cpp"}};
-  llvm::StringMap<std::string> EditedFiles;
-  for (const auto &Case : Cases) {
-    for (const auto &SubCase : expandCases(Case.TestSource)) {
-      ExtraFiles["test.hpp"] = R"cpp(
-namespace one {
-void oo() {}
-namespace two {
-enum ee {ee_one};
-void ff() {}
-class cc {
-public:
-  struct st { struct nested {}; };
-  static void mm() {}
-};
-}
-using uu = two::cc;
-})cpp";
-      EXPECT_EQ(apply(SubCase, &EditedFiles), Case.ExpectedSource);
-    }
-  }
-}
-
-TWEAK_TEST(PopulateSwitch);
-TEST_F(PopulateSwitchTest, Test) {
-  struct Case {
-    CodeContext Context;
-    llvm::StringRef TestSource;
-    llvm::StringRef ExpectedSource;
-  };
-
-  Case Cases[]{
-      {
-          // No enumerators
-          Function,
-          R""(enum Enum {}; ^switch ((Enum)0) {})"",
-          "unavailable",
-      },
-      {
-          // All enumerators already in switch (unscoped)
-          Function,
-          R""(enum Enum {A,B}; ^switch (A) {case A:break;case B:break;})"",
-          "unavailable",
-      },
-      {
-          // All enumerators already in switch (scoped)
-          Function,
-          R""(
-            enum class Enum {A,B};
-            ^switch (Enum::A) {case Enum::A:break;case Enum::B:break;}
-          )"",
-          "unavailable",
-      },
-      {
-          // Default case in switch
-          Function,
-          R""(
-            enum class Enum {A,B};
-            ^switch (Enum::A) {default:break;}
-          )"",
-          "unavailable",
-      },
-      {
-          // GNU range in switch
-          Function,
-          R""(
-            enum class Enum {A,B};
-            ^switch (Enum::A) {case Enum::A ... Enum::B:break;}
-          )"",
-          "unavailable",
-      },
-      {
-          // Value dependent case expression
-          File,
-          R""(
-            enum class Enum {A,B};
-            template<Enum Value>
-            void function() {
-                ^switch (Enum::A) {case Value:break;}
-            }
-          )"",
-          "unavailable",
-      },
-      {
-          // Body not CompoundStmt
-          Function,
-          R""(enum Enum {A}; ^switch (A);)"",
-          "unavailable",
-      },
-      {
-          // Selection on switch token
-          Function,
-          R""(enum Enum {A}; ^switch (A) {})"",
-          R""(enum Enum {A}; switch (A) {case A:break;})"",
-      },
-      {
-          // Selection on switch condition
-          Function,
-          R""(enum Enum {A}; switch (^A) {})"",
-          R""(enum Enum {A}; switch (A) {case A:break;})"",
-      },
-      {
-          // Selection in switch body
-          Function,
-          R""(enum Enum {A}; switch (A) {^})"",
-          R""(enum Enum {A}; switch (A) {case A:break;})"",
-      },
-      {
-          // Scoped enumeration
-          Function,
-          R""(enum class Enum {A}; ^switch (Enum::A) {})"",
-          R""(enum class Enum {A}; switch (Enum::A) {case Enum::A:break;})"",
-      },
-      {
-          // Scoped enumeration with multiple enumerators
-          Function,
-          R""(
-            enum class Enum {A,B};
-            ^switch (Enum::A) {}
-          )"",
-          R""(
-            enum class Enum {A,B};
-            switch (Enum::A) {case Enum::A:case Enum::B:break;}
-          )"",
-      },
-      {
-          // Only filling in missing enumerators (unscoped)
-          Function,
-          R""(
-            enum Enum {A,B,C};
-            ^switch (A) {case B:break;}
-          )"",
-          R""(
-            enum Enum {A,B,C};
-            switch (A) {case B:break;case A:case C:break;}
-          )"",
-      },
-      {
-          // Only filling in missing enumerators,
-          // even when using integer literals
-          Function,
-          R""(
-            enum Enum {A,B=1,C};
-            ^switch (A) {case 1:break;}
-          )"",
-          R""(
-            enum Enum {A,B=1,C};
-            switch (A) {case 1:break;case A:case C:break;}
-          )"",
-      },
-      {
-          // Only filling in missing enumerators (scoped)
-          Function,
-          R""(
-            enum class Enum {A,B,C};
-            ^switch (Enum::A)
-            {case Enum::B:break;}
-          )"",
-          R""(
-            enum class Enum {A,B,C};
-            switch (Enum::A)
-            {case Enum::B:break;case Enum::A:case Enum::C:break;}
-          )"",
-      },
-      {
-          // Scoped enumerations in namespace
-          File,
-          R""(
-            namespace ns { enum class Enum {A}; }
-            void function() { ^switch (ns::Enum::A) {} }
-          )"",
-          R""(
-            namespace ns { enum class Enum {A}; }
-            void function() { switch (ns::Enum::A) {case ns::Enum::A:break;} }
-          )"",
-      },
-      {
-          // Unscoped enumerations in namespace
-          File,
-          R""(
-            namespace ns { enum Enum {A}; }
-            void function() { ^switch (ns::A) {} }
-          )"",
-          R""(
-            namespace ns { enum Enum {A}; }
-            void function() { switch (ns::A) {case ns::A:break;} }
-          )"",
-      },
-      {
-          // Duplicated constant names
-          Function,
-          R""(enum Enum {A,B,b=B}; ^switch (A) {})"",
-          R""(enum Enum {A,B,b=B}; switch (A) {case A:case B:break;})"",
-      },
-      {
-          // Duplicated constant names all in switch
-          Function,
-          R""(enum Enum {A,B,b=B}; ^switch (A) {case A:case B:break;})"",
-          "unavailable",
-      },
-      {
-          // Enum is dependent type
-          File,
-          R""(template<typename T> void f() {enum Enum {A}; ^switch (A) {}})"",
-          "unavailable",
-      },
-  };
-
-  for (const auto &Case : Cases) {
-    Context = Case.Context;
-    EXPECT_EQ(apply(Case.TestSource), Case.ExpectedSource);
-  }
-}
-
-} // namespace
-} // namespace clangd
-} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp
new file mode 100644
index 000000000000..c0c66dbc14d7
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp
@@ -0,0 +1,472 @@
+//===-- AddUsingTests.cpp ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Config.h"
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(AddUsing);
+
+TEST_F(AddUsingTest, Prepare) {
+  Config Cfg;
+  Cfg.Style.FullyQualifiedNamespaces.push_back("ban");
+  WithContextValue WithConfig(Config::Key, std::move(Cfg));
+
+  const std::string Header = R"cpp(
+#define NS(name) one::two::name
+namespace ban { void foo() {} }
+namespace banana { void foo() {} }
+namespace one {
+void oo() {}
+template<typename TT> class tt {};
+namespace two {
+enum ee {};
+void ff() {}
+class cc {
+public:
+  struct st {};
+  static void mm() {}
+  cc operator|(const cc& x) const { return x; }
+};
+}
+})cpp";
+
+  EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o^:^:^f^f(); }");
+  EXPECT_AVAILABLE(Header + "void fun() { o^n^e^::^o^o(); }");
+  EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o^:^:^e^e E; }");
+  EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o:^:^c^c C; }");
+  EXPECT_UNAVAILABLE(Header +
+                     "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^m^m(); }");
+  EXPECT_UNAVAILABLE(Header +
+                     "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^s^t inst; }");
+  EXPECT_UNAVAILABLE(Header +
+                     "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^s^t inst; }");
+  EXPECT_UNAVAILABLE(Header + "void fun() { N^S(c^c) inst; }");
+  // This used to crash. Ideally we would support this case, but for now we just
+  // test that we don't crash.
+  EXPECT_UNAVAILABLE(Header +
+                     "template<typename TT> using foo = one::tt<T^T>;");
+  // Test that we don't crash or misbehave on unnamed DeclRefExpr.
+  EXPECT_UNAVAILABLE(Header +
+                     "void fun() { one::two::cc() ^| one::two::cc(); }");
+  // Do not offer code action when operating on a banned namespace.
+  EXPECT_UNAVAILABLE(Header + "void fun() { ban::fo^o(); }");
+  EXPECT_UNAVAILABLE(Header + "void fun() { ::ban::fo^o(); }");
+  EXPECT_AVAILABLE(Header + "void fun() { banana::fo^o(); }");
+
+  // Do not offer code action on typo-corrections.
+  EXPECT_UNAVAILABLE(Header + "/*error-ok*/c^c C;");
+
+  // NestedNameSpecifier, but no namespace.
+  EXPECT_UNAVAILABLE(Header + "class Foo {}; class F^oo foo;");
+
+  // Check that we do not trigger in header files.
+  FileName = "test.h";
+  ExtraArgs.push_back("-xc++-header"); // .h file is treated a C by default.
+  EXPECT_UNAVAILABLE(Header + "void fun() { one::two::f^f(); }");
+  FileName = "test.hpp";
+  EXPECT_UNAVAILABLE(Header + "void fun() { one::two::f^f(); }");
+}
+
+TEST_F(AddUsingTest, Apply) {
+  FileName = "test.cpp";
+  struct {
+    llvm::StringRef TestSource;
+    llvm::StringRef ExpectedSource;
+  } Cases[]{{
+                // Function, no other using, namespace.
+                R"cpp(
+#include "test.hpp"
+namespace {
+void fun() {
+  ^o^n^e^:^:^t^w^o^:^:^f^f();
+}
+})cpp",
+                R"cpp(
+#include "test.hpp"
+namespace {using one::two::ff;
+
+void fun() {
+  ff();
+}
+})cpp",
+            },
+            // Type, no other using, namespace.
+            {
+                R"cpp(
+#include "test.hpp"
+namespace {
+void fun() {
+  ::on^e::t^wo::c^c inst;
+}
+})cpp",
+                R"cpp(
+#include "test.hpp"
+namespace {using ::one::two::cc;
+
+void fun() {
+  cc inst;
+}
+})cpp",
+            },
+            // Type, no other using, no namespace.
+            {
+                R"cpp(
+#include "test.hpp"
+
+void fun() {
+  on^e::t^wo::e^e inst;
+})cpp",
+                R"cpp(
+#include "test.hpp"
+
+using one::two::ee;
+
+void fun() {
+  ee inst;
+})cpp"},
+            // Function, other usings.
+            {
+                R"cpp(
+#include "test.hpp"
+
+using one::two::cc;
+using one::two::ee;
+
+namespace {
+void fun() {
+  one::two::f^f();
+}
+})cpp",
+                R"cpp(
+#include "test.hpp"
+
+using one::two::cc;
+using one::two::ff;using one::two::ee;
+
+namespace {
+void fun() {
+  ff();
+}
+})cpp",
+            },
+            // Function, other usings inside namespace.
+            {
+                R"cpp(
+#include "test.hpp"
+
+using one::two::cc;
+
+namespace {
+
+using one::two::ff;
+
+void fun() {
+  o^ne::o^o();
+}
+})cpp",
+                R"cpp(
+#include "test.hpp"
+
+using one::two::cc;
+
+namespace {
+
+using one::oo;using one::two::ff;
+
+void fun() {
+  oo();
+}
+})cpp"},
+            // Using comes after cursor.
+            {
+                R"cpp(
+#include "test.hpp"
+
+namespace {
+
+void fun() {
+  one::t^wo::ff();
+}
+
+using one::two::cc;
+
+})cpp",
+                R"cpp(
+#include "test.hpp"
+
+namespace {using one::two::ff;
+
+
+void fun() {
+  ff();
+}
+
+using one::two::cc;
+
+})cpp"},
+            // Pointer type.
+            {R"cpp(
+#include "test.hpp"
+
+void fun() {
+  one::two::c^c *p;
+})cpp",
+             R"cpp(
+#include "test.hpp"
+
+using one::two::cc;
+
+void fun() {
+  cc *p;
+})cpp"},
+            // Namespace declared via macro.
+            {R"cpp(
+#include "test.hpp"
+#define NS_BEGIN(name) namespace name {
+
+NS_BEGIN(foo)
+
+void fun() {
+  one::two::f^f();
+}
+})cpp",
+             R"cpp(
+#include "test.hpp"
+#define NS_BEGIN(name) namespace name {
+
+using one::two::ff;
+
+NS_BEGIN(foo)
+
+void fun() {
+  ff();
+}
+})cpp"},
+            // Inside macro argument.
+            {R"cpp(
+#include "test.hpp"
+#define CALL(name) name()
+
+void fun() {
+  CALL(one::t^wo::ff);
+})cpp",
+             R"cpp(
+#include "test.hpp"
+#define CALL(name) name()
+
+using one::two::ff;
+
+void fun() {
+  CALL(ff);
+})cpp"},
+            // Parent namespace != lexical parent namespace
+            {R"cpp(
+#include "test.hpp"
+namespace foo { void fun(); }
+
+void foo::fun() {
+  one::two::f^f();
+})cpp",
+             R"cpp(
+#include "test.hpp"
+using one::two::ff;
+
+namespace foo { void fun(); }
+
+void foo::fun() {
+  ff();
+})cpp"},
+            // If all other using are fully qualified, add ::
+            {R"cpp(
+#include "test.hpp"
+
+using ::one::two::cc;
+using ::one::two::ee;
+
+void fun() {
+  one::two::f^f();
+})cpp",
+             R"cpp(
+#include "test.hpp"
+
+using ::one::two::cc;
+using ::one::two::ff;using ::one::two::ee;
+
+void fun() {
+  ff();
+})cpp"},
+            // Make sure we don't add :: if it's already there
+            {R"cpp(
+#include "test.hpp"
+
+using ::one::two::cc;
+using ::one::two::ee;
+
+void fun() {
+  ::one::two::f^f();
+})cpp",
+             R"cpp(
+#include "test.hpp"
+
+using ::one::two::cc;
+using ::one::two::ff;using ::one::two::ee;
+
+void fun() {
+  ff();
+})cpp"},
+            // If even one using doesn't start with ::, do not add it
+            {R"cpp(
+#include "test.hpp"
+
+using ::one::two::cc;
+using one::two::ee;
+
+void fun() {
+  one::two::f^f();
+})cpp",
+             R"cpp(
+#include "test.hpp"
+
+using ::one::two::cc;
+using one::two::ff;using one::two::ee;
+
+void fun() {
+  ff();
+})cpp"},
+            // using alias; insert using for the spelled name.
+            {R"cpp(
+#include "test.hpp"
+
+void fun() {
+  one::u^u u;
+})cpp",
+             R"cpp(
+#include "test.hpp"
+
+using one::uu;
+
+void fun() {
+  uu u;
+})cpp"},
+            // using namespace.
+            {R"cpp(
+#include "test.hpp"
+using namespace one;
+namespace {
+two::c^c C;
+})cpp",
+             R"cpp(
+#include "test.hpp"
+using namespace one;
+namespace {using two::cc;
+
+cc C;
+})cpp"},
+            // Type defined in main file, make sure using is after that.
+            {R"cpp(
+namespace xx {
+  struct yy {};
+}
+
+x^x::yy X;
+)cpp",
+             R"cpp(
+namespace xx {
+  struct yy {};
+}
+
+using xx::yy;
+
+yy X;
+)cpp"},
+            // Type defined in main file via "using", insert after that.
+            {R"cpp(
+#include "test.hpp"
+
+namespace xx {
+  using yy = one::two::cc;
+}
+
+x^x::yy X;
+)cpp",
+             R"cpp(
+#include "test.hpp"
+
+namespace xx {
+  using yy = one::two::cc;
+}
+
+using xx::yy;
+
+yy X;
+)cpp"},
+            // Using must come after function definition.
+            {R"cpp(
+namespace xx {
+  void yy();
+}
+
+void fun() {
+  x^x::yy();
+}
+)cpp",
+             R"cpp(
+namespace xx {
+  void yy();
+}
+
+using xx::yy;
+
+void fun() {
+  yy();
+}
+)cpp"},
+            // Existing using with non-namespace part.
+            {R"cpp(
+#include "test.hpp"
+using one::two::ee::ee_one;
+one::t^wo::cc c;
+)cpp",
+             R"cpp(
+#include "test.hpp"
+using one::two::cc;using one::two::ee::ee_one;
+cc c;
+)cpp"}};
+  llvm::StringMap<std::string> EditedFiles;
+  for (const auto &Case : Cases) {
+    for (const auto &SubCase : expandCases(Case.TestSource)) {
+      ExtraFiles["test.hpp"] = R"cpp(
+namespace one {
+void oo() {}
+namespace two {
+enum ee {ee_one};
+void ff() {}
+class cc {
+public:
+  struct st { struct nested {}; };
+  static void mm() {}
+};
+}
+using uu = two::cc;
+})cpp";
+      EXPECT_EQ(apply(SubCase, &EditedFiles), Case.ExpectedSource);
+    }
+  }
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/AnnotateHighlightingsTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/AnnotateHighlightingsTests.cpp
new file mode 100644
index 000000000000..4c218f5f7b04
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/AnnotateHighlightingsTests.cpp
@@ -0,0 +1,34 @@
+//===-- AnnotateHighlightingsTests.cpp --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TweakTesting.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(AnnotateHighlightings);
+
+TEST_F(AnnotateHighlightingsTest, Test) {
+  EXPECT_AVAILABLE("^vo^id^ ^f(^) {^}^"); // available everywhere.
+  EXPECT_AVAILABLE("[[int a; int b;]]");
+  EXPECT_EQ("void /* entity.name.function.cpp */f() {}", apply("void ^f() {}"));
+
+  EXPECT_EQ(apply("[[void f1(); void f2();]]"),
+            "void /* entity.name.function.cpp */f1(); "
+            "void /* entity.name.function.cpp */f2();");
+
+  EXPECT_EQ(apply("void f1(); void f2() {^}"),
+            "void f1(); "
+            "void /* entity.name.function.cpp */f2() {}");
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/DefineInlineTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/DefineInlineTests.cpp
new file mode 100644
index 000000000000..f190a314bc4a
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/DefineInlineTests.cpp
@@ -0,0 +1,1008 @@
+//===-- DefineInlineTests.cpp -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using ::testing::ElementsAre;
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(DefineInline);
+
+TEST_F(DefineInlineTest, TriggersOnFunctionDecl) {
+  // Basic check for function body and signature.
+  EXPECT_AVAILABLE(R"cpp(
+  class Bar {
+    void baz();
+  };
+
+  [[void [[Bar::[[b^a^z]]]]() [[{
+    return;
+  }]]]]
+
+  void foo();
+  [[void [[f^o^o]]() [[{
+    return;
+  }]]]]
+  )cpp");
+
+  EXPECT_UNAVAILABLE(R"cpp(
+  // Not a definition
+  vo^i[[d^ ^f]]^oo();
+
+  [[vo^id ]]foo[[()]] {[[
+    [[(void)(5+3);
+    return;]]
+  }]]
+
+  // Definition with no body.
+  class Bar { Bar() = def^ault; };
+  )cpp");
+}
+
+TEST_F(DefineInlineTest, NoForwardDecl) {
+  Header = "void bar();";
+  EXPECT_UNAVAILABLE(R"cpp(
+  void bar() {
+    return;
+  }
+  // FIXME: Generate a decl in the header.
+  void fo^o() {
+    return;
+  })cpp");
+}
+
+TEST_F(DefineInlineTest, ReferencedDecls) {
+  EXPECT_AVAILABLE(R"cpp(
+    void bar();
+    void foo(int test);
+
+    void fo^o(int baz) {
+      int x = 10;
+      bar();
+    })cpp");
+
+  // Internal symbol usage.
+  Header = "void foo(int test);";
+  EXPECT_UNAVAILABLE(R"cpp(
+    void bar();
+    void fo^o(int baz) {
+      int x = 10;
+      bar();
+    })cpp");
+
+  // Becomes available after making symbol visible.
+  Header = "void bar();" + Header;
+  EXPECT_AVAILABLE(R"cpp(
+    void fo^o(int baz) {
+      int x = 10;
+      bar();
+    })cpp");
+
+  // FIXME: Move declaration below bar to make it visible.
+  Header.clear();
+  EXPECT_UNAVAILABLE(R"cpp(
+    void foo();
+    void bar();
+
+    void fo^o() {
+      bar();
+    })cpp");
+
+  // Order doesn't matter within a class.
+  EXPECT_AVAILABLE(R"cpp(
+    class Bar {
+      void foo();
+      void bar();
+    };
+
+    void Bar::fo^o() {
+      bar();
+    })cpp");
+
+  // FIXME: Perform include insertion to make symbol visible.
+  ExtraFiles["a.h"] = "void bar();";
+  Header = "void foo(int test);";
+  EXPECT_UNAVAILABLE(R"cpp(
+    #include "a.h"
+    void fo^o(int baz) {
+      int x = 10;
+      bar();
+    })cpp");
+}
+
+TEST_F(DefineInlineTest, TemplateSpec) {
+  EXPECT_UNAVAILABLE(R"cpp(
+    template <typename T> void foo();
+    template<> void foo<char>();
+
+    template<> void f^oo<int>() {
+    })cpp");
+  EXPECT_UNAVAILABLE(R"cpp(
+    template <typename T> void foo();
+
+    template<> void f^oo<int>() {
+    })cpp");
+  EXPECT_UNAVAILABLE(R"cpp(
+    template <typename T> struct Foo { void foo(); };
+
+    template <typename T> void Foo<T>::f^oo() {
+    })cpp");
+  EXPECT_AVAILABLE(R"cpp(
+    template <typename T> void foo();
+    void bar();
+    template <> void foo<int>();
+
+    template<> void f^oo<int>() {
+      bar();
+    })cpp");
+  EXPECT_UNAVAILABLE(R"cpp(
+    namespace bar {
+      template <typename T> void f^oo() {}
+      template void foo<int>();
+    })cpp");
+}
+
+TEST_F(DefineInlineTest, CheckForCanonDecl) {
+  EXPECT_UNAVAILABLE(R"cpp(
+    void foo();
+
+    void bar() {}
+    void f^oo() {
+      // This bar normally refers to the definition just above, but it is not
+      // visible from the forward declaration of foo.
+      bar();
+    })cpp");
+  // Make it available with a forward decl.
+  EXPECT_AVAILABLE(R"cpp(
+    void bar();
+    void foo();
+
+    void bar() {}
+    void f^oo() {
+      bar();
+    })cpp");
+}
+
+TEST_F(DefineInlineTest, UsingShadowDecls) {
+  // Template body is not parsed until instantiation time on windows, which
+  // results in arbitrary failures as function body becomes NULL.
+  ExtraArgs.push_back("-fno-delayed-template-parsing");
+  EXPECT_UNAVAILABLE(R"cpp(
+  namespace ns1 { void foo(int); }
+  namespace ns2 { void foo(int*); }
+  template <typename T>
+  void bar();
+
+  using ns1::foo;
+  using ns2::foo;
+
+  template <typename T>
+  void b^ar() {
+    foo(T());
+  })cpp");
+}
+
+TEST_F(DefineInlineTest, TransformNestedNamespaces) {
+  auto Test = R"cpp(
+    namespace a {
+      void bar();
+      namespace b {
+        void baz();
+        namespace c {
+          void aux();
+        }
+      }
+    }
+
+    void foo();
+    using namespace a;
+    using namespace b;
+    using namespace c;
+    void f^oo() {
+      bar();
+      a::bar();
+
+      baz();
+      b::baz();
+      a::b::baz();
+
+      aux();
+      c::aux();
+      b::c::aux();
+      a::b::c::aux();
+    })cpp";
+  auto Expected = R"cpp(
+    namespace a {
+      void bar();
+      namespace b {
+        void baz();
+        namespace c {
+          void aux();
+        }
+      }
+    }
+
+    void foo(){
+      a::bar();
+      a::bar();
+
+      a::b::baz();
+      a::b::baz();
+      a::b::baz();
+
+      a::b::c::aux();
+      a::b::c::aux();
+      a::b::c::aux();
+      a::b::c::aux();
+    }
+    using namespace a;
+    using namespace b;
+    using namespace c;
+    )cpp";
+  EXPECT_EQ(apply(Test), Expected);
+}
+
+TEST_F(DefineInlineTest, TransformUsings) {
+  auto Test = R"cpp(
+    namespace a { namespace b { namespace c { void aux(); } } }
+
+    void foo();
+    void f^oo() {
+      using namespace a;
+      using namespace b;
+      using namespace c;
+      using c::aux;
+      namespace d = c;
+    })cpp";
+  auto Expected = R"cpp(
+    namespace a { namespace b { namespace c { void aux(); } } }
+
+    void foo(){
+      using namespace a;
+      using namespace a::b;
+      using namespace a::b::c;
+      using a::b::c::aux;
+      namespace d = a::b::c;
+    }
+    )cpp";
+  EXPECT_EQ(apply(Test), Expected);
+}
+
+TEST_F(DefineInlineTest, TransformDecls) {
+  auto Test = R"cpp(
+    void foo();
+    void f^oo() {
+      class Foo {
+      public:
+        void foo();
+        int x;
+      };
+
+      enum En { Zero, One };
+      En x = Zero;
+
+      enum class EnClass { Zero, One };
+      EnClass y = EnClass::Zero;
+    })cpp";
+  auto Expected = R"cpp(
+    void foo(){
+      class Foo {
+      public:
+        void foo();
+        int x;
+      };
+
+      enum En { Zero, One };
+      En x = Zero;
+
+      enum class EnClass { Zero, One };
+      EnClass y = EnClass::Zero;
+    }
+    )cpp";
+  EXPECT_EQ(apply(Test), Expected);
+}
+
+TEST_F(DefineInlineTest, TransformTemplDecls) {
+  auto Test = R"cpp(
+    namespace a {
+      template <typename T> class Bar {
+      public:
+        void bar();
+      };
+      template <typename T> T bar;
+      template <typename T> void aux() {}
+    }
+
+    void foo();
+
+    using namespace a;
+    void f^oo() {
+      bar<Bar<int>>.bar();
+      aux<Bar<int>>();
+    })cpp";
+  auto Expected = R"cpp(
+    namespace a {
+      template <typename T> class Bar {
+      public:
+        void bar();
+      };
+      template <typename T> T bar;
+      template <typename T> void aux() {}
+    }
+
+    void foo(){
+      a::bar<a::Bar<int>>.bar();
+      a::aux<a::Bar<int>>();
+    }
+
+    using namespace a;
+    )cpp";
+  EXPECT_EQ(apply(Test), Expected);
+}
+
+TEST_F(DefineInlineTest, TransformMembers) {
+  auto Test = R"cpp(
+    class Foo {
+      void foo();
+    };
+
+    void Foo::f^oo() {
+      return;
+    })cpp";
+  auto Expected = R"cpp(
+    class Foo {
+      void foo(){
+      return;
+    }
+    };
+
+    )cpp";
+  EXPECT_EQ(apply(Test), Expected);
+
+  ExtraFiles["a.h"] = R"cpp(
+    class Foo {
+      void foo();
+    };)cpp";
+
+  llvm::StringMap<std::string> EditedFiles;
+  Test = R"cpp(
+    #include "a.h"
+    void Foo::f^oo() {
+      return;
+    })cpp";
+  Expected = R"cpp(
+    #include "a.h"
+    )cpp";
+  EXPECT_EQ(apply(Test, &EditedFiles), Expected);
+
+  Expected = R"cpp(
+    class Foo {
+      void foo(){
+      return;
+    }
+    };)cpp";
+  EXPECT_THAT(EditedFiles,
+              ElementsAre(FileWithContents(testPath("a.h"), Expected)));
+}
+
+TEST_F(DefineInlineTest, TransformDependentTypes) {
+  auto Test = R"cpp(
+    namespace a {
+      template <typename T> class Bar {};
+    }
+
+    template <typename T>
+    void foo();
+
+    using namespace a;
+    template <typename T>
+    void f^oo() {
+      Bar<T> B;
+      Bar<Bar<T>> q;
+    })cpp";
+  auto Expected = R"cpp(
+    namespace a {
+      template <typename T> class Bar {};
+    }
+
+    template <typename T>
+    void foo(){
+      a::Bar<T> B;
+      a::Bar<a::Bar<T>> q;
+    }
+
+    using namespace a;
+    )cpp";
+
+  // Template body is not parsed until instantiation time on windows, which
+  // results in arbitrary failures as function body becomes NULL.
+  ExtraArgs.push_back("-fno-delayed-template-parsing");
+  EXPECT_EQ(apply(Test), Expected);
+}
+
+TEST_F(DefineInlineTest, TransformFunctionTempls) {
+  // Check we select correct specialization decl.
+  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
+      {R"cpp(
+          template <typename T>
+          void foo(T p);
+
+          template <>
+          void foo<int>(int p);
+
+          template <>
+          void foo<char>(char p);
+
+          template <>
+          void fo^o<int>(int p) {
+            return;
+          })cpp",
+       R"cpp(
+          template <typename T>
+          void foo(T p);
+
+          template <>
+          void foo<int>(int p){
+            return;
+          }
+
+          template <>
+          void foo<char>(char p);
+
+          )cpp"},
+      {// Make sure we are not selecting the first specialization all the time.
+       R"cpp(
+          template <typename T>
+          void foo(T p);
+
+          template <>
+          void foo<int>(int p);
+
+          template <>
+          void foo<char>(char p);
+
+          template <>
+          void fo^o<char>(char p) {
+            return;
+          })cpp",
+       R"cpp(
+          template <typename T>
+          void foo(T p);
+
+          template <>
+          void foo<int>(int p);
+
+          template <>
+          void foo<char>(char p){
+            return;
+          }
+
+          )cpp"},
+      {R"cpp(
+          template <typename T>
+          void foo(T p);
+
+          template <>
+          void foo<int>(int p);
+
+          template <typename T>
+          void fo^o(T p) {
+            return;
+          })cpp",
+       R"cpp(
+          template <typename T>
+          void foo(T p){
+            return;
+          }
+
+          template <>
+          void foo<int>(int p);
+
+          )cpp"},
+  };
+  // Template body is not parsed until instantiation time on windows, which
+  // results in arbitrary failures as function body becomes NULL.
+  ExtraArgs.push_back("-fno-delayed-template-parsing");
+  for (const auto &Case : Cases)
+    EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
+}
+
+TEST_F(DefineInlineTest, TransformTypeLocs) {
+  auto Test = R"cpp(
+    namespace a {
+      template <typename T> class Bar {
+      public:
+        template <typename Q> class Baz {};
+      };
+      class Foo{};
+    }
+
+    void foo();
+
+    using namespace a;
+    void f^oo() {
+      Bar<int> B;
+      Foo foo;
+      a::Bar<Bar<int>>::Baz<Bar<int>> q;
+    })cpp";
+  auto Expected = R"cpp(
+    namespace a {
+      template <typename T> class Bar {
+      public:
+        template <typename Q> class Baz {};
+      };
+      class Foo{};
+    }
+
+    void foo(){
+      a::Bar<int> B;
+      a::Foo foo;
+      a::Bar<a::Bar<int>>::Baz<a::Bar<int>> q;
+    }
+
+    using namespace a;
+    )cpp";
+  EXPECT_EQ(apply(Test), Expected);
+}
+
+TEST_F(DefineInlineTest, TransformDeclRefs) {
+  auto Test = R"cpp(
+    namespace a {
+      template <typename T> class Bar {
+      public:
+        void foo();
+        static void bar();
+        int x;
+        static int y;
+      };
+      void bar();
+      void test();
+    }
+
+    void foo();
+    using namespace a;
+    void f^oo() {
+      a::Bar<int> B;
+      B.foo();
+      a::bar();
+      Bar<Bar<int>>::bar();
+      a::Bar<int>::bar();
+      B.x = Bar<int>::y;
+      Bar<int>::y = 3;
+      bar();
+      a::test();
+    })cpp";
+  auto Expected = R"cpp(
+    namespace a {
+      template <typename T> class Bar {
+      public:
+        void foo();
+        static void bar();
+        int x;
+        static int y;
+      };
+      void bar();
+      void test();
+    }
+
+    void foo(){
+      a::Bar<int> B;
+      B.foo();
+      a::bar();
+      a::Bar<a::Bar<int>>::bar();
+      a::Bar<int>::bar();
+      B.x = a::Bar<int>::y;
+      a::Bar<int>::y = 3;
+      a::bar();
+      a::test();
+    }
+    using namespace a;
+    )cpp";
+  EXPECT_EQ(apply(Test), Expected);
+}
+
+TEST_F(DefineInlineTest, StaticMembers) {
+  auto Test = R"cpp(
+    namespace ns { class X { static void foo(); void bar(); }; }
+    void ns::X::b^ar() {
+      foo();
+    })cpp";
+  auto Expected = R"cpp(
+    namespace ns { class X { static void foo(); void bar(){
+      foo();
+    } }; }
+    )cpp";
+  EXPECT_EQ(apply(Test), Expected);
+}
+
+TEST_F(DefineInlineTest, TransformParamNames) {
+  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
+      {R"cpp(
+        void foo(int, bool b, int T\
+est);
+        void ^foo(int f, bool x, int z) {})cpp",
+       R"cpp(
+        void foo(int f, bool x, int z){}
+        )cpp"},
+      {R"cpp(
+        #define PARAM int Z
+        void foo(PARAM);
+
+        void ^foo(int X) {})cpp",
+       "fail: Cant rename parameter inside macro body."},
+      {R"cpp(
+        #define TYPE int
+        #define PARAM TYPE Z
+        #define BODY(x) 5 * (x) + 2
+        template <int P>
+        void foo(PARAM, TYPE Q, TYPE, TYPE W = BODY(P));
+        template <int x>
+        void ^foo(int Z, int b, int c, int d) {})cpp",
+       R"cpp(
+        #define TYPE int
+        #define PARAM TYPE Z
+        #define BODY(x) 5 * (x) + 2
+        template <int x>
+        void foo(PARAM, TYPE b, TYPE c, TYPE d = BODY(x)){}
+        )cpp"},
+  };
+  ExtraArgs.push_back("-fno-delayed-template-parsing");
+  for (const auto &Case : Cases)
+    EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
+}
+
+TEST_F(DefineInlineTest, TransformTemplParamNames) {
+  auto Test = R"cpp(
+    struct Foo {
+      struct Bar {
+        template <class, class X,
+                  template<typename> class, template<typename> class Y,
+                  int, int Z>
+        void foo(X, Y<X>, int W = 5 * Z + 2);
+      };
+    };
+
+    template <class T, class U,
+              template<typename> class V, template<typename> class W,
+              int X, int Y>
+    void Foo::Bar::f^oo(U, W<U>, int Q) {})cpp";
+  auto Expected = R"cpp(
+    struct Foo {
+      struct Bar {
+        template <class T, class U,
+                  template<typename> class V, template<typename> class W,
+                  int X, int Y>
+        void foo(U, W<U>, int Q = 5 * Y + 2){}
+      };
+    };
+
+    )cpp";
+  ExtraArgs.push_back("-fno-delayed-template-parsing");
+  EXPECT_EQ(apply(Test), Expected);
+}
+
+TEST_F(DefineInlineTest, TransformInlineNamespaces) {
+  auto Test = R"cpp(
+    namespace a { inline namespace b { namespace { struct Foo{}; } } }
+    void foo();
+
+    using namespace a;
+    void ^foo() {Foo foo;})cpp";
+  auto Expected = R"cpp(
+    namespace a { inline namespace b { namespace { struct Foo{}; } } }
+    void foo(){a::Foo foo;}
+
+    using namespace a;
+    )cpp";
+  EXPECT_EQ(apply(Test), Expected);
+}
+
+TEST_F(DefineInlineTest, TokensBeforeSemicolon) {
+  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
+      {R"cpp(
+          void foo()    /*Comment -_-*/ /*Com 2*/ ;
+          void fo^o() { return ; })cpp",
+       R"cpp(
+          void foo()    /*Comment -_-*/ /*Com 2*/ { return ; }
+          )cpp"},
+
+      {R"cpp(
+          void foo();
+          void fo^o() { return ; })cpp",
+       R"cpp(
+          void foo(){ return ; }
+          )cpp"},
+
+      {R"cpp(
+          #define SEMI ;
+          void foo() SEMI
+          void fo^o() { return ; })cpp",
+       "fail: Couldn't find semicolon for target declaration."},
+  };
+  for (const auto &Case : Cases)
+    EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
+}
+
+TEST_F(DefineInlineTest, HandleMacros) {
+  EXPECT_UNAVAILABLE(R"cpp(
+    #define BODY { return; }
+    void foo();
+    void f^oo()BODY)cpp");
+
+  EXPECT_UNAVAILABLE(R"cpp(
+    #define BODY void foo(){ return; }
+    void foo();
+    [[BODY]])cpp");
+
+  std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
+      // We don't qualify declarations coming from macros.
+      {R"cpp(
+          #define BODY Foo
+          namespace a { class Foo{}; }
+          void foo();
+          using namespace a;
+          void f^oo(){BODY();})cpp",
+       R"cpp(
+          #define BODY Foo
+          namespace a { class Foo{}; }
+          void foo(){BODY();}
+          using namespace a;
+          )cpp"},
+
+      // Macro is not visible at declaration location, but we proceed.
+      {R"cpp(
+          void foo();
+          #define BODY return;
+          void f^oo(){BODY})cpp",
+       R"cpp(
+          void foo(){BODY}
+          #define BODY return;
+          )cpp"},
+
+      {R"cpp(
+          #define TARGET void foo()
+          TARGET;
+          void f^oo(){ return; })cpp",
+       R"cpp(
+          #define TARGET void foo()
+          TARGET{ return; }
+          )cpp"},
+
+      {R"cpp(
+          #define TARGET foo
+          void TARGET();
+          void f^oo(){ return; })cpp",
+       R"cpp(
+          #define TARGET foo
+          void TARGET(){ return; }
+          )cpp"},
+  };
+  for (const auto &Case : Cases)
+    EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
+}
+
+TEST_F(DefineInlineTest, DropCommonNameSpecifiers) {
+  struct {
+    llvm::StringRef Test;
+    llvm::StringRef Expected;
+  } Cases[] = {
+      {R"cpp(
+        namespace a { namespace b { void aux(); } }
+        namespace ns1 {
+          void foo();
+          namespace qq { void test(); }
+          namespace ns2 {
+            void bar();
+            namespace ns3 { void baz(); }
+          }
+        }
+
+        using namespace a;
+        using namespace a::b;
+        using namespace ns1::qq;
+        void ns1::ns2::ns3::b^az() {
+          foo();
+          bar();
+          baz();
+          ns1::ns2::ns3::baz();
+          aux();
+          test();
+        })cpp",
+       R"cpp(
+        namespace a { namespace b { void aux(); } }
+        namespace ns1 {
+          void foo();
+          namespace qq { void test(); }
+          namespace ns2 {
+            void bar();
+            namespace ns3 { void baz(){
+          foo();
+          bar();
+          baz();
+          ns1::ns2::ns3::baz();
+          a::b::aux();
+          qq::test();
+        } }
+          }
+        }
+
+        using namespace a;
+        using namespace a::b;
+        using namespace ns1::qq;
+        )cpp"},
+      {R"cpp(
+        namespace ns1 {
+          namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
+          namespace ns2 { void baz(); }
+        }
+
+        using namespace ns1::qq;
+        void ns1::ns2::b^az() { Foo f; B b; })cpp",
+       R"cpp(
+        namespace ns1 {
+          namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; }
+          namespace ns2 { void baz(){ qq::Foo f; qq::B b; } }
+        }
+
+        using namespace ns1::qq;
+        )cpp"},
+      {R"cpp(
+        namespace ns1 {
+          namespace qq {
+            template<class T> struct Foo { template <class U> struct Bar {}; };
+            template<class T, class U>
+            using B = typename Foo<T>::template Bar<U>;
+          }
+          namespace ns2 { void baz(); }
+        }
+
+        using namespace ns1::qq;
+        void ns1::ns2::b^az() { B<int, bool> b; })cpp",
+       R"cpp(
+        namespace ns1 {
+          namespace qq {
+            template<class T> struct Foo { template <class U> struct Bar {}; };
+            template<class T, class U>
+            using B = typename Foo<T>::template Bar<U>;
+          }
+          namespace ns2 { void baz(){ qq::B<int, bool> b; } }
+        }
+
+        using namespace ns1::qq;
+        )cpp"},
+  };
+  for (const auto &Case : Cases)
+    EXPECT_EQ(apply(Case.Test), Case.Expected) << Case.Test;
+}
+
+TEST_F(DefineInlineTest, QualifyWithUsingDirectives) {
+  llvm::StringRef Test = R"cpp(
+    namespace a {
+      void bar();
+      namespace b { struct Foo{}; void aux(); }
+      namespace c { void cux(); }
+    }
+    using namespace a;
+    using X = b::Foo;
+    void foo();
+
+    using namespace b;
+    using namespace c;
+    void ^foo() {
+      cux();
+      bar();
+      X x;
+      aux();
+      using namespace c;
+      // FIXME: The last reference to cux() in body of foo should not be
+      // qualified, since there is a using directive inside the function body.
+      cux();
+    })cpp";
+  llvm::StringRef Expected = R"cpp(
+    namespace a {
+      void bar();
+      namespace b { struct Foo{}; void aux(); }
+      namespace c { void cux(); }
+    }
+    using namespace a;
+    using X = b::Foo;
+    void foo(){
+      c::cux();
+      bar();
+      X x;
+      b::aux();
+      using namespace c;
+      // FIXME: The last reference to cux() in body of foo should not be
+      // qualified, since there is a using directive inside the function body.
+      c::cux();
+    }
+
+    using namespace b;
+    using namespace c;
+    )cpp";
+  EXPECT_EQ(apply(Test), Expected) << Test;
+}
+
+TEST_F(DefineInlineTest, AddInline) {
+  ExtraArgs.push_back("-fno-delayed-template-parsing");
+  llvm::StringMap<std::string> EditedFiles;
+  ExtraFiles["a.h"] = "void foo();";
+  apply(R"cpp(#include "a.h"
+              void fo^o() {})cpp",
+        &EditedFiles);
+  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
+                               testPath("a.h"), "inline void foo(){}")));
+
+  // Check we put inline before cv-qualifiers.
+  ExtraFiles["a.h"] = "const int foo();";
+  apply(R"cpp(#include "a.h"
+              const int fo^o() {})cpp",
+        &EditedFiles);
+  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
+                               testPath("a.h"), "inline const int foo(){}")));
+
+  // No double inline.
+  ExtraFiles["a.h"] = "inline void foo();";
+  apply(R"cpp(#include "a.h"
+              inline void fo^o() {})cpp",
+        &EditedFiles);
+  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
+                               testPath("a.h"), "inline void foo(){}")));
+
+  // Constexprs don't need "inline".
+  ExtraFiles["a.h"] = "constexpr void foo();";
+  apply(R"cpp(#include "a.h"
+              constexpr void fo^o() {})cpp",
+        &EditedFiles);
+  EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
+                               testPath("a.h"), "constexpr void foo(){}")));
+
+  // Class members don't need "inline".
+  ExtraFiles["a.h"] = "struct Foo { void foo(); };";
+  apply(R"cpp(#include "a.h"
+              void Foo::fo^o() {})cpp",
+        &EditedFiles);
+  EXPECT_THAT(EditedFiles,
+              testing::ElementsAre(FileWithContents(
+                  testPath("a.h"), "struct Foo { void foo(){} };")));
+
+  // Function template doesn't need to be "inline"d.
+  ExtraFiles["a.h"] = "template <typename T> void foo();";
+  apply(R"cpp(#include "a.h"
+              template <typename T>
+              void fo^o() {})cpp",
+        &EditedFiles);
+  EXPECT_THAT(EditedFiles,
+              testing::ElementsAre(FileWithContents(
+                  testPath("a.h"), "template <typename T> void foo(){}")));
+
+  // Specializations needs to be marked "inline".
+  ExtraFiles["a.h"] = R"cpp(
+                            template <typename T> void foo();
+                            template <> void foo<int>();)cpp";
+  apply(R"cpp(#include "a.h"
+              template <>
+              void fo^o<int>() {})cpp",
+        &EditedFiles);
+  EXPECT_THAT(EditedFiles,
+              testing::ElementsAre(FileWithContents(testPath("a.h"),
+                                                    R"cpp(
+                            template <typename T> void foo();
+                            template <> inline void foo<int>(){})cpp")));
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
new file mode 100644
index 000000000000..1a49a3750335
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
@@ -0,0 +1,541 @@
+//===-- DefineOutline.cpp ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using ::testing::ElementsAre;
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(DefineOutline);
+
+TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
+  FileName = "Test.cpp";
+  // Not available unless in a header file.
+  EXPECT_UNAVAILABLE(R"cpp(
+    [[void [[f^o^o]]() [[{
+      return;
+    }]]]])cpp");
+
+  FileName = "Test.hpp";
+  // Not available unless function name or fully body is selected.
+  EXPECT_UNAVAILABLE(R"cpp(
+    // Not a definition
+    vo^i[[d^ ^f]]^oo();
+
+    [[vo^id ]]foo[[()]] {[[
+      [[(void)(5+3);
+      return;]]
+    }]])cpp");
+
+  // Available even if there are no implementation files.
+  EXPECT_AVAILABLE(R"cpp(
+    [[void [[f^o^o]]() [[{
+      return;
+    }]]]])cpp");
+
+  // Not available for out-of-line methods.
+  EXPECT_UNAVAILABLE(R"cpp(
+    class Bar {
+      void baz();
+    };
+
+    [[void [[Bar::[[b^a^z]]]]() [[{
+      return;
+    }]]]])cpp");
+
+  // Basic check for function body and signature.
+  EXPECT_AVAILABLE(R"cpp(
+    class Bar {
+      [[void [[f^o^o^]]() [[{ return; }]]]]
+    };
+
+    void foo();
+    [[void [[f^o^o]]() [[{
+      return;
+    }]]]])cpp");
+
+  // Not available on defaulted/deleted members.
+  EXPECT_UNAVAILABLE(R"cpp(
+    class Foo {
+      Fo^o() = default;
+      F^oo(const Foo&) = delete;
+    };)cpp");
+
+  // Not available within templated classes, as it is hard to spell class name
+  // out-of-line in such cases.
+  EXPECT_UNAVAILABLE(R"cpp(
+    template <typename> struct Foo { void fo^o(){} };
+    )cpp");
+
+  // Not available on function templates and specializations, as definition must
+  // be visible to all translation units.
+  EXPECT_UNAVAILABLE(R"cpp(
+    template <typename> void fo^o() {};
+    template <> void fo^o<int>() {};
+  )cpp");
+}
+
+TEST_F(DefineOutlineTest, FailsWithoutSource) {
+  FileName = "Test.hpp";
+  llvm::StringRef Test = "void fo^o() { return; }";
+  llvm::StringRef Expected =
+      "fail: Couldn't find a suitable implementation file.";
+  EXPECT_EQ(apply(Test), Expected);
+}
+
+TEST_F(DefineOutlineTest, ApplyTest) {
+  llvm::StringMap<std::string> EditedFiles;
+  ExtraFiles["Test.cpp"] = "";
+  FileName = "Test.hpp";
+  // Template body is not parsed until instantiation time on windows, which
+  // results in arbitrary failures as function body becomes NULL.
+  ExtraArgs.push_back("-fno-delayed-template-parsing");
+
+  struct {
+    llvm::StringRef Test;
+    llvm::StringRef ExpectedHeader;
+    llvm::StringRef ExpectedSource;
+  } Cases[] = {
+      // Simple check
+      {
+          "void fo^o() { return; }",
+          "void foo() ;",
+          "void foo() { return; }",
+      },
+      // Default args.
+      {
+          "void fo^o(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) {}",
+          "void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;",
+          "void foo(int x, int y , int , int (*foo)(int) ) {}",
+      },
+      // Constructors
+      {
+          R"cpp(
+            class Foo {public: Foo(); Foo(int);};
+            class Bar {
+              Ba^r() {}
+              Bar(int x) : f1(x) {}
+              Foo f1;
+              Foo f2 = 2;
+            };)cpp",
+          R"cpp(
+            class Foo {public: Foo(); Foo(int);};
+            class Bar {
+              Bar() ;
+              Bar(int x) : f1(x) {}
+              Foo f1;
+              Foo f2 = 2;
+            };)cpp",
+          "Bar::Bar() {}\n",
+      },
+      // Ctor with initializer.
+      {
+          R"cpp(
+            class Foo {public: Foo(); Foo(int);};
+            class Bar {
+              Bar() {}
+              B^ar(int x) : f1(x), f2(3) {}
+              Foo f1;
+              Foo f2 = 2;
+            };)cpp",
+          R"cpp(
+            class Foo {public: Foo(); Foo(int);};
+            class Bar {
+              Bar() {}
+              Bar(int x) ;
+              Foo f1;
+              Foo f2 = 2;
+            };)cpp",
+          "Bar::Bar(int x) : f1(x), f2(3) {}\n",
+      },
+      // Ctor initializer with attribute.
+      {
+          R"cpp(
+              class Foo {
+                F^oo(int z) __attribute__((weak)) : bar(2){}
+                int bar;
+              };)cpp",
+          R"cpp(
+              class Foo {
+                Foo(int z) __attribute__((weak)) ;
+                int bar;
+              };)cpp",
+          "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
+      },
+      // Virt specifiers.
+      {
+          R"cpp(
+            struct A {
+              virtual void f^oo() {}
+            };)cpp",
+          R"cpp(
+            struct A {
+              virtual void foo() ;
+            };)cpp",
+          " void A::foo() {}\n",
+      },
+      {
+          R"cpp(
+            struct A {
+              virtual virtual void virtual f^oo() {}
+            };)cpp",
+          R"cpp(
+            struct A {
+              virtual virtual void virtual foo() ;
+            };)cpp",
+          "  void  A::foo() {}\n",
+      },
+      {
+          R"cpp(
+            struct A {
+              virtual void foo() = 0;
+            };
+            struct B : A {
+              void fo^o() override {}
+            };)cpp",
+          R"cpp(
+            struct A {
+              virtual void foo() = 0;
+            };
+            struct B : A {
+              void foo() override ;
+            };)cpp",
+          "void B::foo()  {}\n",
+      },
+      {
+          R"cpp(
+            struct A {
+              virtual void foo() = 0;
+            };
+            struct B : A {
+              void fo^o() final {}
+            };)cpp",
+          R"cpp(
+            struct A {
+              virtual void foo() = 0;
+            };
+            struct B : A {
+              void foo() final ;
+            };)cpp",
+          "void B::foo()  {}\n",
+      },
+      {
+          R"cpp(
+            struct A {
+              virtual void foo() = 0;
+            };
+            struct B : A {
+              void fo^o() final override {}
+            };)cpp",
+          R"cpp(
+            struct A {
+              virtual void foo() = 0;
+            };
+            struct B : A {
+              void foo() final override ;
+            };)cpp",
+          "void B::foo()   {}\n",
+      },
+      {
+          R"cpp(
+            struct A {
+              static void fo^o() {}
+            };)cpp",
+          R"cpp(
+            struct A {
+              static void foo() ;
+            };)cpp",
+          " void A::foo() {}\n",
+      },
+      {
+          R"cpp(
+            struct A {
+              static static void fo^o() {}
+            };)cpp",
+          R"cpp(
+            struct A {
+              static static void foo() ;
+            };)cpp",
+          "  void A::foo() {}\n",
+      },
+  };
+  for (const auto &Case : Cases) {
+    SCOPED_TRACE(Case.Test);
+    EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
+    EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
+                                 testPath("Test.cpp"), Case.ExpectedSource)));
+  }
+}
+
+TEST_F(DefineOutlineTest, HandleMacros) {
+  llvm::StringMap<std::string> EditedFiles;
+  ExtraFiles["Test.cpp"] = "";
+  FileName = "Test.hpp";
+  ExtraArgs.push_back("-DVIRTUAL=virtual");
+  ExtraArgs.push_back("-DOVER=override");
+
+  struct {
+    llvm::StringRef Test;
+    llvm::StringRef ExpectedHeader;
+    llvm::StringRef ExpectedSource;
+  } Cases[] = {
+      {R"cpp(
+          #define BODY { return; }
+          void f^oo()BODY)cpp",
+       R"cpp(
+          #define BODY { return; }
+          void foo();)cpp",
+       "void foo()BODY"},
+
+      {R"cpp(
+          #define BODY return;
+          void f^oo(){BODY})cpp",
+       R"cpp(
+          #define BODY return;
+          void foo();)cpp",
+       "void foo(){BODY}"},
+
+      {R"cpp(
+          #define TARGET void foo()
+          [[TARGET]]{ return; })cpp",
+       R"cpp(
+          #define TARGET void foo()
+          TARGET;)cpp",
+       "TARGET{ return; }"},
+
+      {R"cpp(
+          #define TARGET foo
+          void [[TARGET]](){ return; })cpp",
+       R"cpp(
+          #define TARGET foo
+          void TARGET();)cpp",
+       "void TARGET(){ return; }"},
+      {R"cpp(#define VIRT virtual
+          struct A {
+            VIRT void f^oo() {}
+          };)cpp",
+       R"cpp(#define VIRT virtual
+          struct A {
+            VIRT void foo() ;
+          };)cpp",
+       " void A::foo() {}\n"},
+      {R"cpp(
+          struct A {
+            VIRTUAL void f^oo() {}
+          };)cpp",
+       R"cpp(
+          struct A {
+            VIRTUAL void foo() ;
+          };)cpp",
+       " void A::foo() {}\n"},
+      {R"cpp(
+          struct A {
+            virtual void foo() = 0;
+          };
+          struct B : A {
+            void fo^o() OVER {}
+          };)cpp",
+       R"cpp(
+          struct A {
+            virtual void foo() = 0;
+          };
+          struct B : A {
+            void foo() OVER ;
+          };)cpp",
+       "void B::foo()  {}\n"},
+      {R"cpp(#define STUPID_MACRO(X) virtual
+          struct A {
+            STUPID_MACRO(sizeof sizeof int) void f^oo() {}
+          };)cpp",
+       R"cpp(#define STUPID_MACRO(X) virtual
+          struct A {
+            STUPID_MACRO(sizeof sizeof int) void foo() ;
+          };)cpp",
+       " void A::foo() {}\n"},
+      {R"cpp(#define STAT static
+          struct A {
+            STAT void f^oo() {}
+          };)cpp",
+       R"cpp(#define STAT static
+          struct A {
+            STAT void foo() ;
+          };)cpp",
+       " void A::foo() {}\n"},
+      {R"cpp(#define STUPID_MACRO(X) static
+          struct A {
+            STUPID_MACRO(sizeof sizeof int) void f^oo() {}
+          };)cpp",
+       R"cpp(#define STUPID_MACRO(X) static
+          struct A {
+            STUPID_MACRO(sizeof sizeof int) void foo() ;
+          };)cpp",
+       " void A::foo() {}\n"},
+  };
+  for (const auto &Case : Cases) {
+    SCOPED_TRACE(Case.Test);
+    EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
+    EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
+                                 testPath("Test.cpp"), Case.ExpectedSource)));
+  }
+}
+
+TEST_F(DefineOutlineTest, QualifyReturnValue) {
+  FileName = "Test.hpp";
+  ExtraFiles["Test.cpp"] = "";
+
+  struct {
+    llvm::StringRef Test;
+    llvm::StringRef ExpectedHeader;
+    llvm::StringRef ExpectedSource;
+  } Cases[] = {
+      {R"cpp(
+        namespace a { class Foo{}; }
+        using namespace a;
+        Foo fo^o() { return {}; })cpp",
+       R"cpp(
+        namespace a { class Foo{}; }
+        using namespace a;
+        Foo foo() ;)cpp",
+       "a::Foo foo() { return {}; }"},
+      {R"cpp(
+        namespace a {
+          class Foo {
+            class Bar {};
+            Bar fo^o() { return {}; }
+          };
+        })cpp",
+       R"cpp(
+        namespace a {
+          class Foo {
+            class Bar {};
+            Bar foo() ;
+          };
+        })cpp",
+       "a::Foo::Bar a::Foo::foo() { return {}; }\n"},
+      {R"cpp(
+        class Foo {};
+        Foo fo^o() { return {}; })cpp",
+       R"cpp(
+        class Foo {};
+        Foo foo() ;)cpp",
+       "Foo foo() { return {}; }"},
+  };
+  llvm::StringMap<std::string> EditedFiles;
+  for (auto &Case : Cases) {
+    apply(Case.Test, &EditedFiles);
+    EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
+    EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
+                                 testPath("Test.cpp"), Case.ExpectedSource)));
+  }
+}
+
+TEST_F(DefineOutlineTest, QualifyFunctionName) {
+  FileName = "Test.hpp";
+  struct {
+    llvm::StringRef TestHeader;
+    llvm::StringRef TestSource;
+    llvm::StringRef ExpectedHeader;
+    llvm::StringRef ExpectedSource;
+  } Cases[] = {
+      {
+          R"cpp(
+            namespace a {
+              namespace b {
+                class Foo {
+                  void fo^o() {}
+                };
+              }
+            })cpp",
+          "",
+          R"cpp(
+            namespace a {
+              namespace b {
+                class Foo {
+                  void foo() ;
+                };
+              }
+            })cpp",
+          "void a::b::Foo::foo() {}\n",
+      },
+      {
+          "namespace a { namespace b { void f^oo() {} } }",
+          "namespace a{}",
+          "namespace a { namespace b { void foo() ; } }",
+          "namespace a{void b::foo() {} }",
+      },
+      {
+          "namespace a { namespace b { void f^oo() {} } }",
+          "using namespace a;",
+          "namespace a { namespace b { void foo() ; } }",
+          // FIXME: Take using namespace directives in the source file into
+          // account. This can be spelled as b::foo instead.
+          "using namespace a;void a::b::foo() {} ",
+      },
+  };
+  llvm::StringMap<std::string> EditedFiles;
+  for (auto &Case : Cases) {
+    ExtraFiles["Test.cpp"] = std::string(Case.TestSource);
+    EXPECT_EQ(apply(Case.TestHeader, &EditedFiles), Case.ExpectedHeader);
+    EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
+                                 testPath("Test.cpp"), Case.ExpectedSource)))
+        << Case.TestHeader;
+  }
+}
+
+TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
+  FileName = "Test.hpp";
+  ExtraFiles["Test.cpp"] = "";
+  ExtraArgs.push_back("-DFINALOVER=final override");
+
+  std::pair<StringRef, StringRef> Cases[] = {
+      {
+          R"cpp(
+          #define VIRT virtual void
+          struct A {
+            VIRT fo^o() {}
+          };)cpp",
+          "fail: define outline: couldn't remove `virtual` keyword."},
+      {
+          R"cpp(
+          #define OVERFINAL final override
+          struct A {
+            virtual void foo() {}
+          };
+          struct B : A {
+            void fo^o() OVERFINAL {}
+          };)cpp",
+          "fail: define outline: Can't move out of line as function has a "
+          "macro `override` specifier.\ndefine outline: Can't move out of line "
+          "as function has a macro `final` specifier."},
+      {
+          R"cpp(
+          struct A {
+            virtual void foo() {}
+          };
+          struct B : A {
+            void fo^o() FINALOVER {}
+          };)cpp",
+          "fail: define outline: Can't move out of line as function has a "
+          "macro `override` specifier.\ndefine outline: Can't move out of line "
+          "as function has a macro `final` specifier."},
+  };
+  for (const auto &Case : Cases) {
+    EXPECT_EQ(apply(Case.first), Case.second);
+  }
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/DumpASTTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/DumpASTTests.cpp
new file mode 100644
index 000000000000..fe9ab9a70999
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/DumpASTTests.cpp
@@ -0,0 +1,36 @@
+//===-- DumpASTTests.cpp ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using ::testing::AllOf;
+using ::testing::HasSubstr;
+using ::testing::StartsWith;
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(DumpAST);
+
+TEST_F(DumpASTTest, Test) {
+  EXPECT_AVAILABLE("^int f^oo() { re^turn 2 ^+ 2; }");
+  EXPECT_UNAVAILABLE("/*c^omment*/ int foo() { return 2 ^ + 2; }");
+  EXPECT_THAT(apply("int x = 2 ^+ 2;"),
+              AllOf(StartsWith("message:"), HasSubstr("BinaryOperator"),
+                    HasSubstr("'+'"), HasSubstr("|-IntegerLiteral"),
+                    HasSubstr("<col:9> 'int' 2\n`-IntegerLiteral"),
+                    HasSubstr("<col:13> 'int' 2")));
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/DumpRecordLayoutTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/DumpRecordLayoutTests.cpp
new file mode 100644
index 000000000000..75478dbb3b94
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/DumpRecordLayoutTests.cpp
@@ -0,0 +1,37 @@
+//===-- DumpRecordLayoutTests.cpp -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using ::testing::AllOf;
+using ::testing::HasSubstr;
+using ::testing::StartsWith;
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(DumpRecordLayout);
+
+TEST_F(DumpRecordLayoutTest, Test) {
+  EXPECT_AVAILABLE("^s^truct ^X ^{ int x; ^};");
+  EXPECT_THAT("struct X { int ^a; };", Not(isAvailable()));
+  EXPECT_THAT("struct ^X;", Not(isAvailable()));
+  EXPECT_THAT("template <typename T> struct ^X { T t; };", Not(isAvailable()));
+  EXPECT_THAT("enum ^X {};", Not(isAvailable()));
+
+  EXPECT_THAT(apply("struct ^X { int x; int y; };"),
+              AllOf(StartsWith("message:"), HasSubstr("0 |   int x")));
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/DumpSymbolTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/DumpSymbolTests.cpp
new file mode 100644
index 000000000000..2a239275d4b1
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/DumpSymbolTests.cpp
@@ -0,0 +1,35 @@
+//===-- DumpSymbolTests.cpp -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include <string>
+
+using ::testing::AllOf;
+using ::testing::HasSubstr;
+using ::testing::StartsWith;
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(DumpSymbol);
+
+TEST_F(DumpSymbolTest, Test) {
+  std::string ID = R"("id":"CA2EBE44A1D76D2A")";
+  std::string USR = R"("usr":"c:@F at foo#")";
+  EXPECT_THAT(apply("void f^oo();"),
+              AllOf(StartsWith("message:"), testing::HasSubstr(ID),
+                    testing::HasSubstr(USR)));
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/ExpandAutoTypeTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/ExpandAutoTypeTests.cpp
new file mode 100644
index 000000000000..ba783e551e84
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/ExpandAutoTypeTests.cpp
@@ -0,0 +1,82 @@
+//===-- ExpandAutoTypeTests.cpp ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using ::testing::StartsWith;
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(ExpandAutoType);
+
+TEST_F(ExpandAutoTypeTest, Test) {
+  Header = R"cpp(
+    namespace ns {
+      struct Class {
+        struct Nested {};
+      };
+      void Func();
+    }
+    inline namespace inl_ns {
+      namespace {
+        struct Visible {};
+      }
+    }
+  )cpp";
+
+  EXPECT_AVAILABLE("^a^u^t^o^ i = 0;");
+  EXPECT_UNAVAILABLE("auto ^i^ ^=^ ^0^;^");
+
+  // check primitive type
+  EXPECT_EQ(apply("[[auto]] i = 0;"), "int i = 0;");
+  EXPECT_EQ(apply("au^to i = 0;"), "int i = 0;");
+  // check classes and namespaces
+  EXPECT_EQ(apply("^auto C = ns::Class::Nested();"),
+            "ns::Class::Nested C = ns::Class::Nested();");
+  // check that namespaces are shortened
+  EXPECT_EQ(apply("namespace ns { void f() { ^auto C = Class(); } }"),
+            "namespace ns { void f() { Class C = Class(); } }");
+  // undefined functions should not be replaced
+  EXPECT_THAT(apply("au^to x = doesnt_exist(); // error-ok"),
+              StartsWith("fail: Could not deduce type for 'auto' type"));
+  // function pointers should not be replaced
+  EXPECT_THAT(apply("au^to x = &ns::Func;"),
+              StartsWith("fail: Could not expand type of function pointer"));
+  // lambda types are not replaced
+  EXPECT_UNAVAILABLE("au^to x = []{};");
+  // inline namespaces
+  EXPECT_EQ(apply("au^to x = inl_ns::Visible();"),
+            "Visible x = inl_ns::Visible();");
+  // local class
+  EXPECT_EQ(apply("namespace x { void y() { struct S{}; ^auto z = S(); } }"),
+            "namespace x { void y() { struct S{}; S z = S(); } }");
+  // replace array types
+  EXPECT_EQ(apply(R"cpp(au^to x = "test";)cpp"),
+            R"cpp(const char * x = "test";)cpp");
+
+  EXPECT_UNAVAILABLE("dec^ltype(au^to) x = 10;");
+  // expanding types in structured bindings is syntactically invalid.
+  EXPECT_UNAVAILABLE("const ^auto &[x,y] = (int[]){1,2};");
+
+  // FIXME: Auto-completion in a template requires disabling delayed template
+  // parsing.
+  ExtraArgs.push_back("-fno-delayed-template-parsing");
+  // unknown types in a template should not be replaced
+  EXPECT_THAT(apply("template <typename T> void x() { ^auto y = T::z(); }"),
+              StartsWith("fail: Could not deduce type for 'auto' type"));
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/ExpandMacroTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/ExpandMacroTests.cpp
new file mode 100644
index 000000000000..6602fc7e6e6e
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/ExpandMacroTests.cpp
@@ -0,0 +1,55 @@
+//===-- ExpandMacroTests.cpp ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(ExpandMacro);
+
+TEST_F(ExpandMacroTest, Test) {
+  Header = R"cpp(
+    // error-ok: not real c++, just token manipulation
+    #define FOO 1 2 3
+    #define FUNC(X) X+X+X
+    #define EMPTY
+    #define EMPTY_FN(X)
+  )cpp";
+
+  // Available on macro names, not available anywhere else.
+  EXPECT_AVAILABLE("^F^O^O^ BAR ^F^O^O^");
+  EXPECT_AVAILABLE("^F^U^N^C^(1)");
+  EXPECT_UNAVAILABLE("^#^d^efine^ ^XY^Z 1 ^2 ^3^");
+  EXPECT_UNAVAILABLE("FOO ^B^A^R^ FOO ^");
+  EXPECT_UNAVAILABLE("FUNC(^1^)^");
+
+  // Works as expected on object-like macros.
+  EXPECT_EQ(apply("^FOO BAR FOO"), "1 2 3 BAR FOO");
+  EXPECT_EQ(apply("FOO BAR ^FOO"), "FOO BAR 1 2 3");
+  // And function-like macros.
+  EXPECT_EQ(apply("F^UNC(2)"), "2 + 2 + 2");
+
+  // Works on empty macros.
+  EXPECT_EQ(apply("int a ^EMPTY;"), "int a ;");
+  EXPECT_EQ(apply("int a ^EMPTY_FN(1 2 3);"), "int a ;");
+  EXPECT_EQ(apply("int a = 123 ^EMPTY EMPTY_FN(1);"),
+            "int a = 123  EMPTY_FN(1);");
+  EXPECT_EQ(apply("int a = 123 ^EMPTY_FN(1) EMPTY;"), "int a = 123  EMPTY;");
+  EXPECT_EQ(apply("int a = 123 EMPTY_FN(1) ^EMPTY;"),
+            "int a = 123 EMPTY_FN(1) ;");
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/ExtractFunctionTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/ExtractFunctionTests.cpp
new file mode 100644
index 000000000000..2033b479896b
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/ExtractFunctionTests.cpp
@@ -0,0 +1,202 @@
+//===-- ExtractFunctionTests.cpp --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using ::testing::HasSubstr;
+using ::testing::StartsWith;
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(ExtractFunction);
+
+TEST_F(ExtractFunctionTest, FunctionTest) {
+  Context = Function;
+
+  // Root statements should have common parent.
+  EXPECT_EQ(apply("for(;;) [[1+2; 1+2;]]"), "unavailable");
+  // Expressions aren't extracted.
+  EXPECT_EQ(apply("int x = 0; [[x++;]]"), "unavailable");
+  // We don't support extraction from lambdas.
+  EXPECT_EQ(apply("auto lam = [](){ [[int x;]] }; "), "unavailable");
+  // Partial statements aren't extracted.
+  EXPECT_THAT(apply("int [[x = 0]];"), "unavailable");
+  // FIXME: Support hoisting.
+  EXPECT_THAT(apply(" [[int a = 5;]] a++; "), "unavailable");
+
+  // Ensure that end of Zone and Beginning of PostZone being adjacent doesn't
+  // lead to break being included in the extraction zone.
+  EXPECT_THAT(apply("for(;;) { [[int x;]]break; }"), HasSubstr("extracted"));
+  // FIXME: ExtractFunction should be unavailable inside loop construct
+  // initializer/condition.
+  EXPECT_THAT(apply(" for([[int i = 0;]];);"), HasSubstr("extracted"));
+  // Extract certain return
+  EXPECT_THAT(apply(" if(true) [[{ return; }]] "), HasSubstr("extracted"));
+  // Don't extract uncertain return
+  EXPECT_THAT(apply(" if(true) [[if (false) return;]] "),
+              StartsWith("unavailable"));
+  EXPECT_THAT(
+      apply("#define RETURN_IF_ERROR(x) if (x) return\nRETU^RN_IF_ERROR(4);"),
+      StartsWith("unavailable"));
+
+  FileName = "a.c";
+  EXPECT_THAT(apply(" for([[int i = 0;]];);"), HasSubstr("unavailable"));
+}
+
+TEST_F(ExtractFunctionTest, FileTest) {
+  // Check all parameters are in order
+  std::string ParameterCheckInput = R"cpp(
+struct Foo {
+  int x;
+};
+void f(int a) {
+  int b;
+  int *ptr = &a;
+  Foo foo;
+  [[a += foo.x + b;
+  *ptr++;]]
+})cpp";
+  std::string ParameterCheckOutput = R"cpp(
+struct Foo {
+  int x;
+};
+void extracted(int &a, int &b, int * &ptr, Foo &foo) {
+a += foo.x + b;
+  *ptr++;
+}
+void f(int a) {
+  int b;
+  int *ptr = &a;
+  Foo foo;
+  extracted(a, b, ptr, foo);
+})cpp";
+  EXPECT_EQ(apply(ParameterCheckInput), ParameterCheckOutput);
+
+  // Check const qualifier
+  std::string ConstCheckInput = R"cpp(
+void f(const int c) {
+  [[while(c) {}]]
+})cpp";
+  std::string ConstCheckOutput = R"cpp(
+void extracted(const int &c) {
+while(c) {}
+}
+void f(const int c) {
+  extracted(c);
+})cpp";
+  EXPECT_EQ(apply(ConstCheckInput), ConstCheckOutput);
+
+  // Don't extract when we need to make a function as a parameter.
+  EXPECT_THAT(apply("void f() { [[int a; f();]] }"), StartsWith("fail"));
+
+  // We don't extract from methods for now since they may involve multi-file
+  // edits
+  std::string MethodFailInput = R"cpp(
+    class T {
+      void f() {
+        [[int x;]]
+      }
+    };
+  )cpp";
+  EXPECT_EQ(apply(MethodFailInput), "unavailable");
+
+  // We don't extract from templated functions for now as templates are hard
+  // to deal with.
+  std::string TemplateFailInput = R"cpp(
+    template<typename T>
+    void f() {
+      [[int x;]]
+    }
+  )cpp";
+  EXPECT_EQ(apply(TemplateFailInput), "unavailable");
+
+  std::string MacroInput = R"cpp(
+    #define F(BODY) void f() { BODY }
+    F ([[int x = 0;]])
+  )cpp";
+  std::string MacroOutput = R"cpp(
+    #define F(BODY) void f() { BODY }
+    void extracted() {
+int x = 0;
+}
+F (extracted();)
+  )cpp";
+  EXPECT_EQ(apply(MacroInput), MacroOutput);
+
+  // Shouldn't crash.
+  EXPECT_EQ(apply("void f([[int a]]);"), "unavailable");
+  // Don't extract if we select the entire function body (CompoundStmt).
+  std::string CompoundFailInput = R"cpp(
+    void f() [[{
+      int a;
+    }]]
+  )cpp";
+  EXPECT_EQ(apply(CompoundFailInput), "unavailable");
+}
+
+TEST_F(ExtractFunctionTest, ControlFlow) {
+  Context = Function;
+  // We should be able to extract break/continue with a parent loop/switch.
+  EXPECT_THAT(apply(" [[for(;;) if(1) break;]] "), HasSubstr("extracted"));
+  EXPECT_THAT(apply(" for(;;) [[while(1) break;]] "), HasSubstr("extracted"));
+  EXPECT_THAT(apply(" [[switch(1) { break; }]]"), HasSubstr("extracted"));
+  EXPECT_THAT(apply(" [[while(1) switch(1) { continue; }]]"),
+              HasSubstr("extracted"));
+  // Don't extract break and continue without a loop/switch parent.
+  EXPECT_THAT(apply(" for(;;) [[if(1) continue;]] "), StartsWith("fail"));
+  EXPECT_THAT(apply(" while(1) [[if(1) break;]] "), StartsWith("fail"));
+  EXPECT_THAT(apply(" switch(1) { [[break;]] }"), StartsWith("fail"));
+  EXPECT_THAT(apply(" for(;;) { [[while(1) break; break;]] }"),
+              StartsWith("fail"));
+}
+
+TEST_F(ExtractFunctionTest, ExistingReturnStatement) {
+  Context = File;
+  const char *Before = R"cpp(
+    bool lucky(int N);
+    int getNum(bool Superstitious, int Min, int Max) {
+      if (Superstitious) [[{
+        for (int I = Min; I <= Max; ++I)
+          if (lucky(I))
+            return I;
+        return -1;
+      }]] else {
+        return (Min + Max) / 2;
+      }
+    }
+  )cpp";
+  // FIXME: min/max should be by value.
+  // FIXME: avoid emitting redundant braces
+  const char *After = R"cpp(
+    bool lucky(int N);
+    int extracted(int &Min, int &Max) {
+{
+        for (int I = Min; I <= Max; ++I)
+          if (lucky(I))
+            return I;
+        return -1;
+      }
+}
+int getNum(bool Superstitious, int Min, int Max) {
+      if (Superstitious) return extracted(Min, Max); else {
+        return (Min + Max) / 2;
+      }
+    }
+  )cpp";
+  EXPECT_EQ(apply(Before), After);
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp
new file mode 100644
index 000000000000..4e9223cfe553
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp
@@ -0,0 +1,300 @@
+//===-- ExtractVariableTests.cpp --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(ExtractVariable);
+
+TEST_F(ExtractVariableTest, Test) {
+  const char *AvailableCases = R"cpp(
+    int xyz(int a = 1) {
+      struct T {
+        int bar(int a = 1);
+        int z;
+      } t;
+      // return statement
+      return [[[[t.b[[a]]r]](t.z)]];
+    }
+    void f() {
+      int a = [[5 +]] [[4 * [[[[xyz]]()]]]];
+      // multivariable initialization
+      if(1)
+        int x = [[1]], y = [[a + 1]], a = [[1]], z = a + 1;
+      // if without else
+      if([[1]])
+        a = [[1]] + 1;
+      // if with else
+      if(a < [[3]])
+        if(a == [[4]])
+          a = [[5]] + 1;
+        else
+          a = [[5]] + 1;
+      else if (a < [[4]])
+        a = [[4]] + 1;
+      else
+        a = [[5]] + 1;
+      // for loop
+      for(a = [[1]] + 1; a > [[[[3]] + [[4]]]]; a++)
+        a = [[2]] + 1;
+      // while
+      while(a < [[1]])
+        a = [[1]] + 1;
+      // do while
+      do
+        a = [[1]] + 1;
+      while(a < [[3]]);
+    }
+  )cpp";
+  EXPECT_AVAILABLE(AvailableCases);
+
+  ExtraArgs = {"-xc"};
+  const char *AvailableButC = R"cpp(
+    void foo() {
+      int x = [[1]];
+    })cpp";
+  EXPECT_UNAVAILABLE(AvailableButC);
+  ExtraArgs = {};
+
+  const char *NoCrashCases = R"cpp(
+    // error-ok: broken code, but shouldn't crash
+    template<typename T, typename ...Args>
+    struct Test<T, Args...> {
+    Test(const T &v) :val[[(^]]) {}
+      T val;
+    };
+  )cpp";
+  EXPECT_UNAVAILABLE(NoCrashCases);
+
+  const char *UnavailableCases = R"cpp(
+    int xyz(int a = [[1]]) {
+      struct T {
+        int bar(int a = [[1]]);
+        int z = [[1]];
+      } t;
+      return [[t]].bar([[[[t]].z]]);
+    }
+    void v() { return; }
+    // function default argument
+    void f(int b = [[1]]) {
+      // empty selection
+      int a = ^1 ^+ ^2;
+      // void expressions
+      auto i = new int, j = new int;
+      [[[[delete i]], delete j]];
+      [[v]]();
+      // if
+      if(1)
+        int x = 1, y = a + 1, a = 1, z = [[a + 1]];
+      if(int a = 1)
+        if([[a + 1]] == 4)
+          a = [[[[a]] +]] 1;
+      // for loop
+      for(int a = 1, b = 2, c = 3; a > [[b + c]]; [[a++]])
+        a = [[a + 1]];
+      // lambda
+      auto lamb = [&[[a]], &[[b]]](int r = [[1]]) {return 1;};
+      // assignment
+      xyz([[a = 5]]);
+      xyz([[a *= 5]]);
+      // Variable DeclRefExpr
+      a = [[b]];
+      a = [[xyz()]];
+      // statement expression
+      [[xyz()]];
+      while (a)
+        [[++a]];
+      // label statement
+      goto label;
+      label:
+        a = [[1]];
+    }
+  )cpp";
+  EXPECT_UNAVAILABLE(UnavailableCases);
+
+  // vector of pairs of input and output strings
+  const std::vector<std::pair<std::string, std::string>> InputOutputs = {
+      // extraction from variable declaration/assignment
+      {R"cpp(void varDecl() {
+                   int a = 5 * (4 + (3 [[- 1)]]);
+                 })cpp",
+       R"cpp(void varDecl() {
+                   auto dummy = (3 - 1); int a = 5 * (4 + dummy);
+                 })cpp"},
+      // FIXME: extraction from switch case
+      /*{R"cpp(void f(int a) {
+               if(1)
+                 while(a < 1)
+                   switch (1) {
+                       case 1:
+                         a = [[1 + 2]];
+                         break;
+                       default:
+                         break;
+                   }
+             })cpp",
+       R"cpp(void f(int a) {
+               auto dummy = 1 + 2; if(1)
+                 while(a < 1)
+                   switch (1) {
+                       case 1:
+                         a = dummy;
+                         break;
+                       default:
+                         break;
+                   }
+             })cpp"},*/
+      // Macros
+      {R"cpp(#define PLUS(x) x++
+                 void f(int a) {
+                   int y = PLUS([[1+a]]);
+                 })cpp",
+       /*FIXME: It should be extracted like this.
+        R"cpp(#define PLUS(x) x++
+              void f(int a) {
+                auto dummy = 1+a; int y = PLUS(dummy);
+              })cpp"},*/
+       R"cpp(#define PLUS(x) x++
+                 void f(int a) {
+                   auto dummy = PLUS(1+a); int y = dummy;
+                 })cpp"},
+      // ensure InsertionPoint isn't inside a macro
+      {R"cpp(#define LOOP(x) while (1) {a = x;}
+                 void f(int a) {
+                   if(1)
+                    LOOP(5 + [[3]])
+                 })cpp",
+       R"cpp(#define LOOP(x) while (1) {a = x;}
+                 void f(int a) {
+                   auto dummy = 3; if(1)
+                    LOOP(5 + dummy)
+                 })cpp"},
+      {R"cpp(#define LOOP(x) do {x;} while(1);
+                 void f(int a) {
+                   if(1)
+                    LOOP(5 + [[3]])
+                 })cpp",
+       R"cpp(#define LOOP(x) do {x;} while(1);
+                 void f(int a) {
+                   auto dummy = 3; if(1)
+                    LOOP(5 + dummy)
+                 })cpp"},
+      // attribute testing
+      {R"cpp(void f(int a) {
+                    [ [gsl::suppress("type")] ] for (;;) a = [[1]] + 1;
+                 })cpp",
+       R"cpp(void f(int a) {
+                    auto dummy = 1; [ [gsl::suppress("type")] ] for (;;) a = dummy + 1;
+                 })cpp"},
+      // MemberExpr
+      {R"cpp(class T {
+                   T f() {
+                     return [[T().f()]].f();
+                   }
+                 };)cpp",
+       R"cpp(class T {
+                   T f() {
+                     auto dummy = T().f(); return dummy.f();
+                   }
+                 };)cpp"},
+      // Function DeclRefExpr
+      {R"cpp(int f() {
+                   return [[f]]();
+                 })cpp",
+       R"cpp(int f() {
+                   auto dummy = f(); return dummy;
+                 })cpp"},
+      // FIXME: Wrong result for \[\[clang::uninitialized\]\] int b = [[1]];
+      // since the attr is inside the DeclStmt and the bounds of
+      // DeclStmt don't cover the attribute.
+
+      // Binary subexpressions
+      {R"cpp(void f() {
+                   int x = 1 + [[2 + 3 + 4]] + 5;
+                 })cpp",
+       R"cpp(void f() {
+                   auto dummy = 2 + 3 + 4; int x = 1 + dummy + 5;
+                 })cpp"},
+      {R"cpp(void f() {
+                   int x = [[1 + 2 + 3]] + 4 + 5;
+                 })cpp",
+       R"cpp(void f() {
+                   auto dummy = 1 + 2 + 3; int x = dummy + 4 + 5;
+                 })cpp"},
+      {R"cpp(void f() {
+                   int x = 1 + 2 + [[3 + 4 + 5]];
+                 })cpp",
+       R"cpp(void f() {
+                   auto dummy = 3 + 4 + 5; int x = 1 + 2 + dummy;
+                 })cpp"},
+      // Non-associative operations have no special support
+      {R"cpp(void f() {
+                   int x = 1 - [[2 - 3 - 4]] - 5;
+                 })cpp",
+       R"cpp(void f() {
+                   auto dummy = 1 - 2 - 3 - 4; int x = dummy - 5;
+                 })cpp"},
+      // A mix of associative operators isn't associative.
+      {R"cpp(void f() {
+                   int x = 0 + 1 * [[2 + 3]] * 4 + 5;
+                 })cpp",
+       R"cpp(void f() {
+                   auto dummy = 1 * 2 + 3 * 4; int x = 0 + dummy + 5;
+                 })cpp"},
+      // Overloaded operators are supported, we assume associativity
+      // as if they were built-in.
+      {R"cpp(struct S {
+                   S(int);
+                 };
+                 S operator+(S, S);
+
+                 void f() {
+                   S x = S(1) + [[S(2) + S(3) + S(4)]] + S(5);
+                 })cpp",
+       R"cpp(struct S {
+                   S(int);
+                 };
+                 S operator+(S, S);
+
+                 void f() {
+                   auto dummy = S(2) + S(3) + S(4); S x = S(1) + dummy + S(5);
+                 })cpp"},
+      // Don't try to analyze across macro boundaries
+      // FIXME: it'd be nice to do this someday (in a safe way)
+      {R"cpp(#define ECHO(X) X
+                 void f() {
+                   int x = 1 + [[ECHO(2 + 3) + 4]] + 5;
+                 })cpp",
+       R"cpp(#define ECHO(X) X
+                 void f() {
+                   auto dummy = 1 + ECHO(2 + 3) + 4; int x = dummy + 5;
+                 })cpp"},
+      {R"cpp(#define ECHO(X) X
+                 void f() {
+                   int x = 1 + [[ECHO(2) + ECHO(3) + 4]] + 5;
+                 })cpp",
+       R"cpp(#define ECHO(X) X
+                 void f() {
+                   auto dummy = 1 + ECHO(2) + ECHO(3) + 4; int x = dummy + 5;
+                 })cpp"},
+  };
+  for (const auto &IO : InputOutputs) {
+    EXPECT_EQ(IO.second, apply(IO.first)) << IO.first;
+  }
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/ObjCLocalizeStringLiteralTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/ObjCLocalizeStringLiteralTests.cpp
new file mode 100644
index 000000000000..d52a1b3a78c1
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/ObjCLocalizeStringLiteralTests.cpp
@@ -0,0 +1,41 @@
+//===-- ObjCLocalizeStringLiteralTests.cpp ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(ObjCLocalizeStringLiteral);
+
+TEST_F(ObjCLocalizeStringLiteralTest, Test) {
+  ExtraArgs.push_back("-x");
+  ExtraArgs.push_back("objective-c");
+
+  // Ensure the action can be initiated in the string literal.
+  EXPECT_AVAILABLE(R"(id x = ^[[@[[^"^t^est^"]]]];)");
+
+  // Ensure that the action can't be initiated in other places.
+  EXPECT_UNAVAILABLE(R"([[i^d ^[[x]] ^= @"test";^]])");
+
+  // Ensure that the action is not available for regular C strings.
+  EXPECT_UNAVAILABLE(R"(const char * x= "^test";)");
+
+  const char *Input = R"(id x = [[@"test"]];)";
+  const char *Output = R"(id x = NSLocalizedString(@"test", @"");)";
+  EXPECT_EQ(apply(Input), Output);
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/PopulateSwitchTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/PopulateSwitchTests.cpp
new file mode 100644
index 000000000000..41518108a4f8
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/PopulateSwitchTests.cpp
@@ -0,0 +1,213 @@
+//===-- PopulateSwitchTest.cpp ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(PopulateSwitch);
+
+TEST_F(PopulateSwitchTest, Test) {
+  struct Case {
+    CodeContext Context;
+    llvm::StringRef TestSource;
+    llvm::StringRef ExpectedSource;
+  };
+
+  Case Cases[]{
+      {
+          // No enumerators
+          Function,
+          R""(enum Enum {}; ^switch ((Enum)0) {})"",
+          "unavailable",
+      },
+      {
+          // All enumerators already in switch (unscoped)
+          Function,
+          R""(enum Enum {A,B}; ^switch (A) {case A:break;case B:break;})"",
+          "unavailable",
+      },
+      {
+          // All enumerators already in switch (scoped)
+          Function,
+          R""(
+            enum class Enum {A,B};
+            ^switch (Enum::A) {case Enum::A:break;case Enum::B:break;}
+          )"",
+          "unavailable",
+      },
+      {
+          // Default case in switch
+          Function,
+          R""(
+            enum class Enum {A,B};
+            ^switch (Enum::A) {default:break;}
+          )"",
+          "unavailable",
+      },
+      {
+          // GNU range in switch
+          Function,
+          R""(
+            enum class Enum {A,B};
+            ^switch (Enum::A) {case Enum::A ... Enum::B:break;}
+          )"",
+          "unavailable",
+      },
+      {
+          // Value dependent case expression
+          File,
+          R""(
+            enum class Enum {A,B};
+            template<Enum Value>
+            void function() {
+                ^switch (Enum::A) {case Value:break;}
+            }
+          )"",
+          "unavailable",
+      },
+      {
+          // Body not CompoundStmt
+          Function,
+          R""(enum Enum {A}; ^switch (A);)"",
+          "unavailable",
+      },
+      {
+          // Selection on switch token
+          Function,
+          R""(enum Enum {A}; ^switch (A) {})"",
+          R""(enum Enum {A}; switch (A) {case A:break;})"",
+      },
+      {
+          // Selection on switch condition
+          Function,
+          R""(enum Enum {A}; switch (^A) {})"",
+          R""(enum Enum {A}; switch (A) {case A:break;})"",
+      },
+      {
+          // Selection in switch body
+          Function,
+          R""(enum Enum {A}; switch (A) {^})"",
+          R""(enum Enum {A}; switch (A) {case A:break;})"",
+      },
+      {
+          // Scoped enumeration
+          Function,
+          R""(enum class Enum {A}; ^switch (Enum::A) {})"",
+          R""(enum class Enum {A}; switch (Enum::A) {case Enum::A:break;})"",
+      },
+      {
+          // Scoped enumeration with multiple enumerators
+          Function,
+          R""(
+            enum class Enum {A,B};
+            ^switch (Enum::A) {}
+          )"",
+          R""(
+            enum class Enum {A,B};
+            switch (Enum::A) {case Enum::A:case Enum::B:break;}
+          )"",
+      },
+      {
+          // Only filling in missing enumerators (unscoped)
+          Function,
+          R""(
+            enum Enum {A,B,C};
+            ^switch (A) {case B:break;}
+          )"",
+          R""(
+            enum Enum {A,B,C};
+            switch (A) {case B:break;case A:case C:break;}
+          )"",
+      },
+      {
+          // Only filling in missing enumerators,
+          // even when using integer literals
+          Function,
+          R""(
+            enum Enum {A,B=1,C};
+            ^switch (A) {case 1:break;}
+          )"",
+          R""(
+            enum Enum {A,B=1,C};
+            switch (A) {case 1:break;case A:case C:break;}
+          )"",
+      },
+      {
+          // Only filling in missing enumerators (scoped)
+          Function,
+          R""(
+            enum class Enum {A,B,C};
+            ^switch (Enum::A)
+            {case Enum::B:break;}
+          )"",
+          R""(
+            enum class Enum {A,B,C};
+            switch (Enum::A)
+            {case Enum::B:break;case Enum::A:case Enum::C:break;}
+          )"",
+      },
+      {
+          // Scoped enumerations in namespace
+          File,
+          R""(
+            namespace ns { enum class Enum {A}; }
+            void function() { ^switch (ns::Enum::A) {} }
+          )"",
+          R""(
+            namespace ns { enum class Enum {A}; }
+            void function() { switch (ns::Enum::A) {case ns::Enum::A:break;} }
+          )"",
+      },
+      {
+          // Unscoped enumerations in namespace
+          File,
+          R""(
+            namespace ns { enum Enum {A}; }
+            void function() { ^switch (ns::A) {} }
+          )"",
+          R""(
+            namespace ns { enum Enum {A}; }
+            void function() { switch (ns::A) {case ns::A:break;} }
+          )"",
+      },
+      {
+          // Duplicated constant names
+          Function,
+          R""(enum Enum {A,B,b=B}; ^switch (A) {})"",
+          R""(enum Enum {A,B,b=B}; switch (A) {case A:case B:break;})"",
+      },
+      {
+          // Duplicated constant names all in switch
+          Function,
+          R""(enum Enum {A,B,b=B}; ^switch (A) {case A:case B:break;})"",
+          "unavailable",
+      },
+      {
+          // Enum is dependent type
+          File,
+          R""(template<typename T> void f() {enum Enum {A}; ^switch (A) {}})"",
+          "unavailable",
+      },
+  };
+
+  for (const auto &Case : Cases) {
+    Context = Case.Context;
+    EXPECT_EQ(apply(Case.TestSource), Case.ExpectedSource);
+  }
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/RawStringLiteralTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/RawStringLiteralTests.cpp
new file mode 100644
index 000000000000..db92928ba3d0
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/RawStringLiteralTests.cpp
@@ -0,0 +1,42 @@
+//===-- RawStringLiteralTests.cpp -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(RawStringLiteral);
+
+TEST_F(RawStringLiteralTest, Test) {
+  Context = Expression;
+  EXPECT_AVAILABLE(R"cpp(^"^f^o^o^\^n^")cpp");
+  EXPECT_AVAILABLE(R"cpp(R"(multi )" ^"token " "str\ning")cpp");
+  EXPECT_UNAVAILABLE(R"cpp(^"f^o^o^o")cpp"); // no chars need escaping
+  EXPECT_UNAVAILABLE(R"cpp(R"(multi )" ^"token " u8"str\ning")cpp"); // nonascii
+  EXPECT_UNAVAILABLE(R"cpp(^R^"^(^multi )" "token " "str\ning")cpp"); // raw
+  EXPECT_UNAVAILABLE(R"cpp(^"token\n" __FILE__)cpp"); // chunk is macro
+  EXPECT_UNAVAILABLE(R"cpp(^"a\r\n";)cpp");           // forbidden escape char
+
+  const char *Input = R"cpp(R"(multi
+token)" "\nst^ring\n" "literal")cpp";
+  const char *Output = R"cpp(R"(multi
+token
+string
+literal)")cpp";
+  EXPECT_EQ(apply(Input), Output);
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp
new file mode 100644
index 000000000000..3a15f05041ad
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp
@@ -0,0 +1,237 @@
+//===-- RemoveUsingNamespaceTest.cpp ----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(RemoveUsingNamespace);
+
+TEST_F(RemoveUsingNamespaceTest, All) {
+  std::pair<llvm::StringRef /*Input*/, llvm::StringRef /*Expected*/> Cases[] = {
+      {// Remove all occurrences of ns. Qualify only unqualified.
+       R"cpp(
+      namespace ns1 { struct vector {}; }
+      namespace ns2 { struct map {}; }
+      using namespace n^s1;
+      using namespace ns2;
+      using namespace ns1;
+      int main() {
+        ns1::vector v1;
+        vector v2;
+        map m1;
+      }
+    )cpp",
+       R"cpp(
+      namespace ns1 { struct vector {}; }
+      namespace ns2 { struct map {}; }
+      
+      using namespace ns2;
+      
+      int main() {
+        ns1::vector v1;
+        ns1::vector v2;
+        map m1;
+      }
+    )cpp"},
+      {// Ident to be qualified is a macro arg.
+       R"cpp(
+      #define DECLARE(x, y) x y
+      namespace ns { struct vector {}; }
+      using namespace n^s;
+      int main() {
+        DECLARE(ns::vector, v1);
+        DECLARE(vector, v2);
+      }
+    )cpp",
+       R"cpp(
+      #define DECLARE(x, y) x y
+      namespace ns { struct vector {}; }
+      
+      int main() {
+        DECLARE(ns::vector, v1);
+        DECLARE(ns::vector, v2);
+      }
+    )cpp"},
+      {// Nested namespace: Fully qualify ident from inner ns.
+       R"cpp(
+      namespace aa { namespace bb { struct map {}; }}
+      using namespace aa::b^b;
+      int main() {
+        map m;
+      }
+    )cpp",
+       R"cpp(
+      namespace aa { namespace bb { struct map {}; }}
+      
+      int main() {
+        aa::bb::map m;
+      }
+    )cpp"},
+      {// Nested namespace: Fully qualify ident from inner ns.
+       R"cpp(
+      namespace aa { namespace bb { struct map {}; }}
+      using namespace a^a;
+      int main() {
+        bb::map m;
+      }
+    )cpp",
+       R"cpp(
+      namespace aa { namespace bb { struct map {}; }}
+      
+      int main() {
+        aa::bb::map m;
+      }
+    )cpp"},
+      {// Typedef.
+       R"cpp(
+      namespace aa { namespace bb { struct map {}; }}
+      using namespace a^a;
+      typedef bb::map map;
+      int main() { map M; }
+    )cpp",
+       R"cpp(
+      namespace aa { namespace bb { struct map {}; }}
+      
+      typedef aa::bb::map map;
+      int main() { map M; }
+    )cpp"},
+      {// FIXME: Nested namespaces: Not aware of using ns decl of outer ns.
+       R"cpp(
+      namespace aa { namespace bb { struct map {}; }}
+      using name[[space aa::b]]b;
+      using namespace aa;
+      int main() {
+        map m;
+      }
+    )cpp",
+       R"cpp(
+      namespace aa { namespace bb { struct map {}; }}
+      
+      using namespace aa;
+      int main() {
+        aa::bb::map m;
+      }
+    )cpp"},
+      {// Does not qualify ident from inner namespace.
+       R"cpp(
+      namespace aa { namespace bb { struct map {}; }}
+      using namespace aa::bb;
+      using namespace a^a;
+      int main() {
+        map m;
+      }
+    )cpp",
+       R"cpp(
+      namespace aa { namespace bb { struct map {}; }}
+      using namespace aa::bb;
+      
+      int main() {
+        map m;
+      }
+    )cpp"},
+      {// Available only for top level namespace decl.
+       R"cpp(
+        namespace aa {
+          namespace bb { struct map {}; }
+          using namespace b^b;
+        }
+        int main() { aa::map m; }
+    )cpp",
+       "unavailable"},
+      {// FIXME: Unavailable for namespaces containing using-namespace decl.
+       R"cpp(
+      namespace aa {
+        namespace bb { struct map {}; }
+        using namespace bb;
+      }
+      using namespace a^a;
+      int main() {
+        map m;
+      }
+    )cpp",
+       "unavailable"},
+      {R"cpp(
+      namespace a::b { struct Foo {}; }
+      using namespace a;
+      using namespace a::[[b]];
+      using namespace b;
+      int main() { Foo F;}
+    )cpp",
+       R"cpp(
+      namespace a::b { struct Foo {}; }
+      using namespace a;
+      
+      
+      int main() { a::b::Foo F;}
+    )cpp"},
+      {R"cpp(
+      namespace a::b { struct Foo {}; }
+      using namespace a;
+      using namespace a::b;
+      using namespace [[b]];
+      int main() { Foo F;}
+    )cpp",
+       R"cpp(
+      namespace a::b { struct Foo {}; }
+      using namespace a;
+      
+      
+      int main() { b::Foo F;}
+    )cpp"},
+      {// Enumerators.
+       R"cpp(
+      namespace tokens {
+      enum Token {
+        comma, identifier, numeric
+      };
+      }
+      using namespace tok^ens;
+      int main() {
+        auto x = comma;
+      }
+    )cpp",
+       R"cpp(
+      namespace tokens {
+      enum Token {
+        comma, identifier, numeric
+      };
+      }
+      
+      int main() {
+        auto x = tokens::comma;
+      }
+    )cpp"},
+      {// inline namespaces.
+       R"cpp(
+      namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
+      using namespace st^d;
+      int main() {
+        vector V;
+      }
+    )cpp",
+       R"cpp(
+      namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
+      
+      int main() {
+        std::vector V;
+      }
+    )cpp"}};
+  for (auto C : Cases)
+    EXPECT_EQ(C.second, apply(C.first)) << C.first;
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/ShowSelectionTreeTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/ShowSelectionTreeTests.cpp
new file mode 100644
index 000000000000..8ec3d3801c42
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/ShowSelectionTreeTests.cpp
@@ -0,0 +1,48 @@
+//===-- ShowSelectionTreeTests.cpp ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(ShowSelectionTree);
+
+TEST_F(ShowSelectionTreeTest, Test) {
+  EXPECT_AVAILABLE("^int f^oo() { re^turn 2 ^+ 2; }");
+  EXPECT_AVAILABLE("/*c^omment*/ int foo() { return 2 ^ + 2; }");
+
+  const char *Output = R"(message:
+ TranslationUnitDecl 
+   VarDecl int x = fcall(2 + 2)
+    .CallExpr fcall(2 + 2)
+       ImplicitCastExpr fcall
+        .DeclRefExpr fcall
+      .BinaryOperator 2 + 2
+        *IntegerLiteral 2
+)";
+  EXPECT_EQ(apply("int fcall(int); int x = fca[[ll(2 +]]2);"), Output);
+
+  Output = R"(message:
+ TranslationUnitDecl 
+   FunctionDecl void x()
+     CompoundStmt { …
+       ForStmt for (;;) …
+        *BreakStmt break;
+)";
+  EXPECT_EQ(apply("void x() { for (;;) br^eak; }"), Output);
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/SwapIfBranchesTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/SwapIfBranchesTests.cpp
new file mode 100644
index 000000000000..989cfbfcc237
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/SwapIfBranchesTests.cpp
@@ -0,0 +1,48 @@
+//===-- SwapIfBranchesTests.cpp ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(SwapIfBranches);
+
+TEST_F(SwapIfBranchesTest, Test) {
+  Context = Function;
+  EXPECT_EQ(apply("^if (true) {return;} else {(void)0;}"),
+            "if (true) {(void)0;} else {return;}");
+  EXPECT_EQ(apply("^if (/*error-ok*/) {return;} else {(void)0;}"),
+            "if (/*error-ok*/) {(void)0;} else {return;}")
+      << "broken condition";
+  EXPECT_AVAILABLE("^i^f^^(^t^r^u^e^) { return; } ^e^l^s^e^ { return; }");
+  EXPECT_UNAVAILABLE("if (true) {^return ^;^ } else { ^return^;^ }");
+  // Available in subexpressions of the condition;
+  EXPECT_THAT("if(2 + [[2]] + 2) { return; } else {return;}", isAvailable());
+  // But not as part of the branches.
+  EXPECT_THAT("if(2 + 2 + 2) { [[return]]; } else { return; }",
+              Not(isAvailable()));
+  // Range covers the "else" token, so available.
+  EXPECT_THAT("if(2 + 2 + 2) { return[[; } else {return;]]}", isAvailable());
+  // Not available in compound statements in condition.
+  EXPECT_THAT("if([]{return [[true]];}()) { return; } else { return; }",
+              Not(isAvailable()));
+  // Not available if both sides aren't braced.
+  EXPECT_THAT("^if (1) return; else { return; }", Not(isAvailable()));
+  // Only one if statement is supported!
+  EXPECT_THAT("[[if(1){}else{}if(2){}else{}]]", Not(isAvailable()));
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/unittests/TweakTesting.cpp b/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp
similarity index 93%
rename from clang-tools-extra/clangd/unittests/TweakTesting.cpp
rename to clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp
index bbb1af46f93c..680280f83149 100644
--- a/clang-tools-extra/clangd/unittests/TweakTesting.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp
@@ -25,12 +25,12 @@ using Context = TweakTest::CodeContext;
 
 std::pair<llvm::StringRef, llvm::StringRef> wrapping(Context Ctx) {
   switch (Ctx) {
-    case TweakTest::File:
-      return {"",""};
-    case TweakTest::Function:
-      return {"void wrapperFunction(){\n", "\n}"};
-    case TweakTest::Expression:
-      return {"auto expressionWrapper(){return\n", "\n;}"};
+  case TweakTest::File:
+    return {"", ""};
+  case TweakTest::Function:
+    return {"void wrapperFunction(){\n", "\n}"};
+  case TweakTest::Expression:
+    return {"auto expressionWrapper(){return\n", "\n;}"};
   }
   llvm_unreachable("Unknown TweakTest::CodeContext enum");
 }
@@ -46,7 +46,8 @@ llvm::StringRef unwrap(Context Ctx, llvm::StringRef Outer) {
   // Don't allow the begin/end wrapping to overlap!
   if (Outer.startswith(Wrapping.first) && Outer.endswith(Wrapping.second) &&
       Outer.size() >= Wrapping.first.size() + Wrapping.second.size())
-    return Outer.drop_front(Wrapping.first.size()).drop_back(Wrapping.second.size());
+    return Outer.drop_front(Wrapping.first.size())
+        .drop_back(Wrapping.second.size());
   return Outer;
 }
 
@@ -157,11 +158,11 @@ std::vector<std::string> TweakTest::expandCases(llvm::StringRef MarkedCode) {
   Annotations Test(MarkedCode);
   llvm::StringRef Code = Test.code();
   std::vector<std::string> Cases;
-  for (const auto& Point : Test.points()) {
+  for (const auto &Point : Test.points()) {
     size_t Offset = llvm::cantFail(positionToOffset(Code, Point));
     Cases.push_back((Code.substr(0, Offset) + "^" + Code.substr(Offset)).str());
   }
-  for (const auto& Range : Test.ranges()) {
+  for (const auto &Range : Test.ranges()) {
     size_t Begin = llvm::cantFail(positionToOffset(Code, Range.start));
     size_t End = llvm::cantFail(positionToOffset(Code, Range.end));
     Cases.push_back((Code.substr(0, Begin) + "[[" +

diff  --git a/clang-tools-extra/clangd/unittests/TweakTesting.h b/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.h
similarity index 97%
rename from clang-tools-extra/clangd/unittests/TweakTesting.h
rename to clang-tools-extra/clangd/unittests/tweaks/TweakTesting.h
index c771149a72fc..7b1a117130ba 100644
--- a/clang-tools-extra/clangd/unittests/TweakTesting.h
+++ b/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.h
@@ -100,6 +100,10 @@ class TweakTest : public ::testing::Test {
   ::testing::Matcher<llvm::StringRef> isAvailable() const;
 };
 
+MATCHER_P2(FileWithContents, FileName, Contents, "") {
+  return arg.first() == FileName && arg.second == Contents;
+}
+
 #define TWEAK_TEST(TweakID)                                                    \
   class TweakID##Test : public ::clang::clangd::TweakTest {                    \
   protected:                                                                   \

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/TweakTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/TweakTests.cpp
new file mode 100644
index 000000000000..cb0b38dc99ec
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/tweaks/TweakTests.cpp
@@ -0,0 +1,66 @@
+//===-- TweakTests.cpp ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestFS.h"
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "refactor/Tweak.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include <cassert>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TEST(FileEdits, AbsolutePath) {
+  auto RelPaths = {"a.h", "foo.cpp", "test/test.cpp"};
+
+  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> MemFS(
+      new llvm::vfs::InMemoryFileSystem);
+  MemFS->setCurrentWorkingDirectory(testRoot());
+  for (const auto *Path : RelPaths)
+    MemFS->addFile(Path, 0, llvm::MemoryBuffer::getMemBuffer("", Path));
+  FileManager FM(FileSystemOptions(), MemFS);
+  DiagnosticsEngine DE(new DiagnosticIDs, new DiagnosticOptions);
+  SourceManager SM(DE, FM);
+
+  for (const auto *Path : RelPaths) {
+    auto FID = SM.createFileID(*FM.getFile(Path), SourceLocation(),
+                               clang::SrcMgr::C_User);
+    auto Res = Tweak::Effect::fileEdit(SM, FID, tooling::Replacements());
+    ASSERT_THAT_EXPECTED(Res, llvm::Succeeded());
+    EXPECT_EQ(Res->first, testPath(Path));
+  }
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang


        


More information about the cfe-commits mailing list