1f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//===- unittest/Tooling/RefactoringTest.cpp - Refactoring unit tests ------===// 2f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// 3f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// The LLVM Compiler Infrastructure 4f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// 5f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// This file is distributed under the University of Illinois Open Source 6f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// License. See LICENSE.TXT for details. 7f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// 8f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//===----------------------------------------------------------------------===// 9f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 10f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "RewriterTestContext.h" 11f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/AST/ASTConsumer.h" 121050e8b2252d89a0004a6fd25a58dab88b5ee625Chandler Carruth#include "clang/AST/ASTContext.h" 13f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/AST/DeclCXX.h" 14f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/AST/DeclGroup.h" 15f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/AST/RecursiveASTVisitor.h" 16f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Basic/Diagnostic.h" 1799eb4a7920667d23a89df8fcc6429d12b36e4d57Douglas Gregor#include "clang/Basic/DiagnosticOptions.h" 18f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Basic/FileManager.h" 19f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Basic/LangOptions.h" 20f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Basic/SourceManager.h" 21f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Frontend/CompilerInstance.h" 22f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Frontend/FrontendAction.h" 23f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Frontend/TextDiagnosticPrinter.h" 24305c613af6cfc40e519c75d9d2c84c6fa9a841c0Ted Kremenek#include "clang/Rewrite/Core/Rewriter.h" 251050e8b2252d89a0004a6fd25a58dab88b5ee625Chandler Carruth#include "clang/Tooling/Refactoring.h" 26f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Tooling/Tooling.h" 27f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "llvm/ADT/SmallString.h" 28f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "llvm/Support/Path.h" 29f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "gtest/gtest.h" 30f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 31f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimeknamespace clang { 32f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimeknamespace tooling { 33f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 34f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekclass ReplacementTest : public ::testing::Test { 35f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek protected: 36f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacement createReplacement(SourceLocation Start, unsigned Length, 37f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek llvm::StringRef ReplacementText) { 38f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek return Replacement(Context.Sources, Start, Length, ReplacementText); 39f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek } 40f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 41f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek RewriterTestContext Context; 42f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}; 43f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 44f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST_F(ReplacementTest, CanDeleteAllText) { 45f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek FileID ID = Context.createInMemoryFile("input.cpp", "text"); 46f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek SourceLocation Location = Context.getLocation(ID, 1, 1); 47f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacement Replace(createReplacement(Location, 4, "")); 48f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(Replace.apply(Context.Rewrite)); 49f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ("", Context.getRewrittenText(ID)); 50f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 51f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 52f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST_F(ReplacementTest, CanDeleteAllTextInTextWithNewlines) { 53f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek FileID ID = Context.createInMemoryFile("input.cpp", "line1\nline2\nline3"); 54f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek SourceLocation Location = Context.getLocation(ID, 1, 1); 55f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacement Replace(createReplacement(Location, 17, "")); 56f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(Replace.apply(Context.Rewrite)); 57f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ("", Context.getRewrittenText(ID)); 58f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 59f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 60f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST_F(ReplacementTest, CanAddText) { 61f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek FileID ID = Context.createInMemoryFile("input.cpp", ""); 62f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek SourceLocation Location = Context.getLocation(ID, 1, 1); 63f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacement Replace(createReplacement(Location, 0, "result")); 64f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(Replace.apply(Context.Rewrite)); 65f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ("result", Context.getRewrittenText(ID)); 66f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 67f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 68f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST_F(ReplacementTest, CanReplaceTextAtPosition) { 69f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek FileID ID = Context.createInMemoryFile("input.cpp", 70f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek "line1\nline2\nline3\nline4"); 71f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek SourceLocation Location = Context.getLocation(ID, 2, 3); 72f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacement Replace(createReplacement(Location, 12, "x")); 73f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(Replace.apply(Context.Rewrite)); 74f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ("line1\nlixne4", Context.getRewrittenText(ID)); 75f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 76f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 77f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST_F(ReplacementTest, CanReplaceTextAtPositionMultipleTimes) { 78f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek FileID ID = Context.createInMemoryFile("input.cpp", 79f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek "line1\nline2\nline3\nline4"); 80f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek SourceLocation Location1 = Context.getLocation(ID, 2, 3); 81f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacement Replace1(createReplacement(Location1, 12, "x\ny\n")); 82f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(Replace1.apply(Context.Rewrite)); 83f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ("line1\nlix\ny\nne4", Context.getRewrittenText(ID)); 84f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 85f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek // Since the original source has not been modified, the (4, 4) points to the 86f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek // 'e' in the original content. 87f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek SourceLocation Location2 = Context.getLocation(ID, 4, 4); 88f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacement Replace2(createReplacement(Location2, 1, "f")); 89f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(Replace2.apply(Context.Rewrite)); 90f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ("line1\nlix\ny\nnf4", Context.getRewrittenText(ID)); 91f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 92f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 93f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST_F(ReplacementTest, ApplyFailsForNonExistentLocation) { 94f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacement Replace("nonexistent-file.cpp", 0, 1, ""); 95f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_FALSE(Replace.apply(Context.Rewrite)); 96f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 97f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 98f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST_F(ReplacementTest, CanRetrivePath) { 99f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacement Replace("/path/to/file.cpp", 0, 1, ""); 100f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ("/path/to/file.cpp", Replace.getFilePath()); 101f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 102f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 103f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST_F(ReplacementTest, ReturnsInvalidPath) { 104f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacement Replace1(Context.Sources, SourceLocation(), 0, ""); 105f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(Replace1.getFilePath().empty()); 106f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 107f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacement Replace2; 108f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(Replace2.getFilePath().empty()); 109f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 110f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 111f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST_F(ReplacementTest, CanApplyReplacements) { 112f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek FileID ID = Context.createInMemoryFile("input.cpp", 113f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek "line1\nline2\nline3\nline4"); 114f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacements Replaces; 115f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replaces.insert(Replacement(Context.Sources, Context.getLocation(ID, 2, 1), 116f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 5, "replaced")); 117f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replaces.insert(Replacement(Context.Sources, Context.getLocation(ID, 3, 1), 118f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 5, "other")); 119f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(applyAllReplacements(Replaces, Context.Rewrite)); 120f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ("line1\nreplaced\nother\nline4", Context.getRewrittenText(ID)); 121f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 122f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 123b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane// FIXME: Remove this test case when Replacements is implemented as std::vector 124b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane// instead of std::set. The other ReplacementTest tests will need to be updated 125b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane// at that point as well. 126b58cfd93c49727c1d471ce71901502df824556c7Edwin VaneTEST_F(ReplacementTest, VectorCanApplyReplacements) { 127b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane FileID ID = Context.createInMemoryFile("input.cpp", 128b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane "line1\nline2\nline3\nline4"); 129b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane std::vector<Replacement> Replaces; 130b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane Replaces.push_back(Replacement(Context.Sources, Context.getLocation(ID, 2, 1), 131b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane 5, "replaced")); 132b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane Replaces.push_back( 133b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane Replacement(Context.Sources, Context.getLocation(ID, 3, 1), 5, "other")); 134b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane EXPECT_TRUE(applyAllReplacements(Replaces, Context.Rewrite)); 135b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane EXPECT_EQ("line1\nreplaced\nother\nline4", Context.getRewrittenText(ID)); 136b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane} 137b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane 138f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST_F(ReplacementTest, SkipsDuplicateReplacements) { 139f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek FileID ID = Context.createInMemoryFile("input.cpp", 140f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek "line1\nline2\nline3\nline4"); 141f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacements Replaces; 142f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replaces.insert(Replacement(Context.Sources, Context.getLocation(ID, 2, 1), 143f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 5, "replaced")); 144f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replaces.insert(Replacement(Context.Sources, Context.getLocation(ID, 2, 1), 145f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 5, "replaced")); 146f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replaces.insert(Replacement(Context.Sources, Context.getLocation(ID, 2, 1), 147f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 5, "replaced")); 148f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(applyAllReplacements(Replaces, Context.Rewrite)); 149f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ("line1\nreplaced\nline3\nline4", Context.getRewrittenText(ID)); 150f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 151f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 152f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST_F(ReplacementTest, ApplyAllFailsIfOneApplyFails) { 153f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek // This test depends on the value of the file name of an invalid source 154f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek // location being in the range ]a, z[. 155f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek FileID IDa = Context.createInMemoryFile("a.cpp", "text"); 156f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek FileID IDz = Context.createInMemoryFile("z.cpp", "text"); 157f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacements Replaces; 158f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replaces.insert(Replacement(Context.Sources, Context.getLocation(IDa, 1, 1), 159f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 4, "a")); 160f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replaces.insert(Replacement(Context.Sources, SourceLocation(), 161f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 5, "2")); 162f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replaces.insert(Replacement(Context.Sources, Context.getLocation(IDz, 1, 1), 163f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 4, "z")); 164f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_FALSE(applyAllReplacements(Replaces, Context.Rewrite)); 165f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ("a", Context.getRewrittenText(IDa)); 166f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ("z", Context.getRewrittenText(IDz)); 167f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 168f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 1696bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel JasperTEST(ShiftedCodePositionTest, FindsNewCodePosition) { 1706bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper Replacements Replaces; 1716bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper Replaces.insert(Replacement("", 0, 1, "")); 1726bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper Replaces.insert(Replacement("", 4, 3, " ")); 1736bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper // Assume ' int i;' is turned into 'int i;' and cursor is located at '|'. 1746bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper EXPECT_EQ(0u, shiftedCodePosition(Replaces, 0)); // |int i; 1756bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper EXPECT_EQ(0u, shiftedCodePosition(Replaces, 1)); // |nt i; 1766bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper EXPECT_EQ(1u, shiftedCodePosition(Replaces, 2)); // i|t i; 1776bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper EXPECT_EQ(2u, shiftedCodePosition(Replaces, 3)); // in| i; 1786bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper EXPECT_EQ(3u, shiftedCodePosition(Replaces, 4)); // int| i; 1796bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper EXPECT_EQ(4u, shiftedCodePosition(Replaces, 5)); // int | i; 180a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane EXPECT_EQ(4u, shiftedCodePosition(Replaces, 6)); // int |i; 181a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane EXPECT_EQ(4u, shiftedCodePosition(Replaces, 7)); // int |; 182a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane EXPECT_EQ(5u, shiftedCodePosition(Replaces, 8)); // int i| 183a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane} 184a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane 185a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane// FIXME: Remove this test case when Replacements is implemented as std::vector 186a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane// instead of std::set. The other ReplacementTest tests will need to be updated 187a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane// at that point as well. 188a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin VaneTEST(ShiftedCodePositionTest, VectorFindsNewCodePositionWithInserts) { 189a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane std::vector<Replacement> Replaces; 190a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane Replaces.push_back(Replacement("", 0, 1, "")); 191a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane Replaces.push_back(Replacement("", 4, 3, " ")); 192a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane // Assume ' int i;' is turned into 'int i;' and cursor is located at '|'. 193a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane EXPECT_EQ(0u, shiftedCodePosition(Replaces, 0)); // |int i; 194a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane EXPECT_EQ(0u, shiftedCodePosition(Replaces, 1)); // |nt i; 195a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane EXPECT_EQ(1u, shiftedCodePosition(Replaces, 2)); // i|t i; 196a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane EXPECT_EQ(2u, shiftedCodePosition(Replaces, 3)); // in| i; 197a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane EXPECT_EQ(3u, shiftedCodePosition(Replaces, 4)); // int| i; 198a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane EXPECT_EQ(4u, shiftedCodePosition(Replaces, 5)); // int | i; 1996bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper EXPECT_EQ(4u, shiftedCodePosition(Replaces, 6)); // int |i; 2006bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper EXPECT_EQ(4u, shiftedCodePosition(Replaces, 7)); // int |; 2016bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper EXPECT_EQ(5u, shiftedCodePosition(Replaces, 8)); // int i| 2026bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper} 2036bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper 2046bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel JasperTEST(ShiftedCodePositionTest, FindsNewCodePositionWithInserts) { 2056bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper Replacements Replaces; 2066bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper Replaces.insert(Replacement("", 4, 0, "\"\n\"")); 2076bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper // Assume '"12345678"' is turned into '"1234"\n"5678"'. 2086bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper EXPECT_EQ(4u, shiftedCodePosition(Replaces, 4)); // "123|5678" 2096bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper EXPECT_EQ(8u, shiftedCodePosition(Replaces, 5)); // "1234|678" 2106bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper} 2116bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper 212f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekclass FlushRewrittenFilesTest : public ::testing::Test { 213902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindolapublic: 214902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola FlushRewrittenFilesTest() {} 215f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 216f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek ~FlushRewrittenFilesTest() { 217902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola for (llvm::StringMap<std::string>::iterator I = TemporaryFiles.begin(), 218902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola E = TemporaryFiles.end(); 219902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola I != E; ++I) { 220902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola llvm::StringRef Name = I->second; 221ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC = llvm::sys::fs::remove(Name); 222902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola (void)EC; 223902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola assert(!EC); 224902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola } 225f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek } 226f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 227f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek FileID createFile(llvm::StringRef Name, llvm::StringRef Content) { 228902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola SmallString<1024> Path; 229902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola int FD; 230ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC = llvm::sys::fs::createTemporaryFile(Name, "", FD, Path); 231902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola assert(!EC); 232902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola (void)EC; 233902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola 234902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola llvm::raw_fd_ostream OutStream(FD, true); 235f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek OutStream << Content; 236f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek OutStream.close(); 237f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek const FileEntry *File = Context.Files.getFile(Path); 238ef8225444452a1486bd721f3285301fe84643b00Stephen Hines assert(File != nullptr); 239902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola 240902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola StringRef Found = TemporaryFiles.GetOrCreateValue(Name, Path.str()).second; 241902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola assert(Found == Path); 242902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola (void)Found; 243f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek return Context.Sources.createFileID(File, SourceLocation(), SrcMgr::C_User); 244f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek } 245f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 246f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek std::string getFileContentFromDisk(llvm::StringRef Name) { 247902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola std::string Path = TemporaryFiles.lookup(Name); 248902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola assert(!Path.empty()); 249f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek // We need to read directly from the FileManager without relaying through 250f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek // a FileEntry, as otherwise we'd read through an already opened file 251f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek // descriptor, which might not see the changes made. 252f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek // FIXME: Figure out whether there is a way to get the SourceManger to 253f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek // reopen the file. 2546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines std::unique_ptr<const llvm::MemoryBuffer> FileBuffer( 255ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Context.Files.getBufferForFile(Path, nullptr)); 2566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return FileBuffer->getBuffer(); 257f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek } 258f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 259902a86385361d5d0a3ae731c89a5b62e470dd875Rafael Espindola llvm::StringMap<std::string> TemporaryFiles; 260f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek RewriterTestContext Context; 261f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}; 262f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 263f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST_F(FlushRewrittenFilesTest, StoresChangesOnDisk) { 264f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek FileID ID = createFile("input.cpp", "line1\nline2\nline3\nline4"); 265f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacements Replaces; 266f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replaces.insert(Replacement(Context.Sources, Context.getLocation(ID, 2, 1), 267f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 5, "replaced")); 268f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(applyAllReplacements(Replaces, Context.Rewrite)); 269f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_FALSE(Context.Rewrite.overwriteChangedFiles()); 270f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ("line1\nreplaced\nline3\nline4", 271f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek getFileContentFromDisk("input.cpp")); 272f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 273f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 274f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimeknamespace { 275f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimektemplate <typename T> 276f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekclass TestVisitor : public clang::RecursiveASTVisitor<T> { 277f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekpublic: 278f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek bool runOver(StringRef Code) { 279f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek return runToolOnCode(new TestAction(this), Code); 280f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek } 281f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 282f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekprotected: 283f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek clang::SourceManager *SM; 284f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 285f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekprivate: 286f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek class FindConsumer : public clang::ASTConsumer { 287f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek public: 288f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek FindConsumer(TestVisitor *Visitor) : Visitor(Visitor) {} 289f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 290f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek virtual void HandleTranslationUnit(clang::ASTContext &Context) { 291f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Visitor->TraverseDecl(Context.getTranslationUnitDecl()); 292f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek } 293f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 294f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek private: 295f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek TestVisitor *Visitor; 296f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek }; 297f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 298f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek class TestAction : public clang::ASTFrontendAction { 299f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek public: 300f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek TestAction(TestVisitor *Visitor) : Visitor(Visitor) {} 301f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 302f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek virtual clang::ASTConsumer* CreateASTConsumer( 303f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek clang::CompilerInstance& compiler, llvm::StringRef dummy) { 304f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Visitor->SM = &compiler.getSourceManager(); 305f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek /// TestConsumer will be deleted by the framework calling us. 306f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek return new FindConsumer(Visitor); 307f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek } 308f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 309f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek private: 310f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek TestVisitor *Visitor; 311f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek }; 312f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}; 313f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} // end namespace 314f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 315f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekvoid expectReplacementAt(const Replacement &Replace, 316f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek StringRef File, unsigned Offset, unsigned Length) { 317f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek ASSERT_TRUE(Replace.isApplicable()); 318f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ(File, Replace.getFilePath()); 319f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ(Offset, Replace.getOffset()); 320f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_EQ(Length, Replace.getLength()); 321f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 322f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 323f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekclass ClassDeclXVisitor : public TestVisitor<ClassDeclXVisitor> { 324f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekpublic: 325f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek bool VisitCXXRecordDecl(CXXRecordDecl *Record) { 326f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek if (Record->getName() == "X") { 327f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replace = Replacement(*SM, Record, ""); 328f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek } 329f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek return true; 330f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek } 331f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacement Replace; 332f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}; 333f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 334f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST(Replacement, CanBeConstructedFromNode) { 335f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek ClassDeclXVisitor ClassDeclX; 336f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(ClassDeclX.runOver(" class X;")); 337f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek expectReplacementAt(ClassDeclX.Replace, "input.cc", 5, 7); 338f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 339f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 340f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST(Replacement, ReplacesAtSpellingLocation) { 341f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek ClassDeclXVisitor ClassDeclX; 342f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(ClassDeclX.runOver("#define A(Y) Y\nA(class X);")); 343f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek expectReplacementAt(ClassDeclX.Replace, "input.cc", 17, 7); 344f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 345f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 346f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekclass CallToFVisitor : public TestVisitor<CallToFVisitor> { 347f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekpublic: 348f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek bool VisitCallExpr(CallExpr *Call) { 349f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek if (Call->getDirectCallee()->getName() == "F") { 350f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replace = Replacement(*SM, Call, ""); 351f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek } 352f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek return true; 353f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek } 354f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Replacement Replace; 355f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}; 356f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 357f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST(Replacement, FunctionCall) { 358f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek CallToFVisitor CallToF; 359f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(CallToF.runOver("void F(); void G() { F(); }")); 360f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek expectReplacementAt(CallToF.Replace, "input.cc", 21, 3); 361f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 362f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 363f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekTEST(Replacement, TemplatedFunctionCall) { 364f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek CallToFVisitor CallToF; 365f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek EXPECT_TRUE(CallToF.runOver( 366f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek "template <typename T> void F(); void G() { F<int>(); }")); 367f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek expectReplacementAt(CallToF.Replace, "input.cc", 43, 8); 368f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 369f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 37046fa4c355bd45197dff580b63240494a53b16c1dManuel KlimekTEST(Range, overlaps) { 37146fa4c355bd45197dff580b63240494a53b16c1dManuel Klimek EXPECT_TRUE(Range(10, 10).overlapsWith(Range(0, 11))); 37246fa4c355bd45197dff580b63240494a53b16c1dManuel Klimek EXPECT_TRUE(Range(0, 11).overlapsWith(Range(10, 10))); 37346fa4c355bd45197dff580b63240494a53b16c1dManuel Klimek EXPECT_FALSE(Range(10, 10).overlapsWith(Range(0, 10))); 37446fa4c355bd45197dff580b63240494a53b16c1dManuel Klimek EXPECT_FALSE(Range(0, 10).overlapsWith(Range(10, 10))); 37546fa4c355bd45197dff580b63240494a53b16c1dManuel Klimek EXPECT_TRUE(Range(0, 10).overlapsWith(Range(2, 6))); 376f758bc7125d59bca12bb6c5f1d3c9025f395710eEdwin Vane EXPECT_TRUE(Range(2, 6).overlapsWith(Range(0, 10))); 37746fa4c355bd45197dff580b63240494a53b16c1dManuel Klimek} 37846fa4c355bd45197dff580b63240494a53b16c1dManuel Klimek 37946fa4c355bd45197dff580b63240494a53b16c1dManuel KlimekTEST(Range, contains) { 38046fa4c355bd45197dff580b63240494a53b16c1dManuel Klimek EXPECT_TRUE(Range(0, 10).contains(Range(0, 10))); 38146fa4c355bd45197dff580b63240494a53b16c1dManuel Klimek EXPECT_TRUE(Range(0, 10).contains(Range(2, 6))); 38246fa4c355bd45197dff580b63240494a53b16c1dManuel Klimek EXPECT_FALSE(Range(2, 6).contains(Range(0, 10))); 38346fa4c355bd45197dff580b63240494a53b16c1dManuel Klimek EXPECT_FALSE(Range(0, 10).contains(Range(0, 11))); 38446fa4c355bd45197dff580b63240494a53b16c1dManuel Klimek} 38546fa4c355bd45197dff580b63240494a53b16c1dManuel Klimek 386d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin VaneTEST(DeduplicateTest, removesDuplicates) { 387d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane std::vector<Replacement> Input; 388d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 50, 0, " foo ")); 389d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 10, 3, " bar ")); 390d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 10, 2, " bar ")); // Length differs 391d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 9, 3, " bar ")); // Offset differs 392d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 50, 0, " foo ")); // Duplicate 393d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 51, 3, " bar ")); 394d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileB", 51, 3, " bar ")); // Filename differs! 395d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 51, 3, " moo ")); // Replacement text 396d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane // differs! 397d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane 398d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane std::vector<Replacement> Expected; 399d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Expected.push_back(Replacement("fileA", 9, 3, " bar ")); 400d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Expected.push_back(Replacement("fileA", 10, 2, " bar ")); 401d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Expected.push_back(Replacement("fileA", 10, 3, " bar ")); 402d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Expected.push_back(Replacement("fileA", 50, 0, " foo ")); 403d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Expected.push_back(Replacement("fileA", 51, 3, " bar ")); 404d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Expected.push_back(Replacement("fileA", 51, 3, " moo ")); 405d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Expected.push_back(Replacement("fileB", 51, 3, " bar ")); 406d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane 407d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane std::vector<Range> Conflicts; // Ignored for this test 408d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane deduplicate(Input, Conflicts); 409d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane 410d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane ASSERT_TRUE(Expected == Input); 411d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane} 412d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane 413d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin VaneTEST(DeduplicateTest, detectsConflicts) { 414d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane { 415d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane std::vector<Replacement> Input; 416d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 0, 5, " foo ")); 417d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 0, 5, " foo ")); // Duplicate not a 418d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane // conflict. 419d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 2, 6, " bar ")); 420d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 7, 3, " moo ")); 421d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane 422d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane std::vector<Range> Conflicts; 423d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane deduplicate(Input, Conflicts); 424d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane 425d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane // One duplicate is removed and the remaining three items form one 426d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane // conflicted range. 427d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane ASSERT_EQ(3u, Input.size()); 428d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane ASSERT_EQ(1u, Conflicts.size()); 429d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane ASSERT_EQ(0u, Conflicts.front().getOffset()); 430d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane ASSERT_EQ(3u, Conflicts.front().getLength()); 431d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane } 432d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane { 433d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane std::vector<Replacement> Input; 434d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane 435d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane // Expected sorted order is shown. It is the sorted order to which the 436d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane // returned conflict info refers to. 437d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 0, 5, " foo ")); // 0 438d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 5, 5, " bar ")); // 1 43995f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane Input.push_back(Replacement("fileA", 6, 0, " bar ")); // 3 440d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane Input.push_back(Replacement("fileA", 5, 5, " moo ")); // 2 44195f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane Input.push_back(Replacement("fileA", 7, 2, " bar ")); // 4 44295f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane Input.push_back(Replacement("fileA", 15, 5, " golf ")); // 5 44395f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane Input.push_back(Replacement("fileA", 16, 5, " bag ")); // 6 44495f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane Input.push_back(Replacement("fileA", 10, 3, " club ")); // 7 44595f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane 44695f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane // #3 is special in that it is completely contained by another conflicting 44795f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane // Replacement. #4 ensures #3 hasn't messed up the conflicting range size. 448d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane 449d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane std::vector<Range> Conflicts; 450d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane deduplicate(Input, Conflicts); 451d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane 452d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane // No duplicates 45395f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane ASSERT_EQ(8u, Input.size()); 454d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane ASSERT_EQ(2u, Conflicts.size()); 455d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane ASSERT_EQ(1u, Conflicts[0].getOffset()); 45695f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane ASSERT_EQ(4u, Conflicts[0].getLength()); 45795f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane ASSERT_EQ(6u, Conflicts[1].getOffset()); 458d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane ASSERT_EQ(2u, Conflicts[1].getLength()); 459d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane } 460d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane} 461d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane 462f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} // end namespace tooling 463f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} // end namespace clang 464