]> granicus.if.org Git - clang/commitdiff
This patch fixes replacements that are not applied when relative paths are
authorAriel J. Bernal <ariel.j.bernal@intel.com>
Fri, 18 Oct 2013 18:38:24 +0000 (18:38 +0000)
committerAriel J. Bernal <ariel.j.bernal@intel.com>
Fri, 18 Oct 2013 18:38:24 +0000 (18:38 +0000)
specified.

In particular it makes sure that  relative paths for non-virtual files aren't
made absolute.
Added unittest.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192992 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Tooling/Refactoring.cpp
unittests/Tooling/RefactoringTest.cpp

index 9e58db0f482443c6a01ad42a8506e87110bf7c8f..175dbd42acec8738f2c0263a80768a0df0e38bb6 100644 (file)
@@ -107,10 +107,16 @@ void Replacement::setFromSourceLocation(SourceManager &Sources,
   const FileEntry *Entry = Sources.getFileEntryForID(DecomposedLocation.first);
   if (Entry != NULL) {
     // Make FilePath absolute so replacements can be applied correctly when
-    // relative paths for files are used.
-    llvm::SmallString<256> FilePath(Entry->getName());
-    llvm::error_code EC = llvm::sys::fs::make_absolute(FilePath);
-    this->FilePath = EC ? FilePath.c_str() : Entry->getName();
+    // relative paths for files are used. But we don't want to change virtual
+    // files.
+    if (llvm::sys::fs::exists(Entry->getName())) {
+      llvm::SmallString<256> FilePath(Entry->getName());
+      llvm::sys::fs::make_absolute(FilePath);
+      this->FilePath = FilePath.c_str();
+    }
+    else {
+      this->FilePath = Entry->getName();
+    }
   } else {
     this->FilePath = InvalidLocation;
   }
index 8c7bfa1c767a344924b1a3d6f60dc3975bf824aa..004ab2aa784e434a6b053ba73bfca5a1afbb1ee6 100644 (file)
@@ -244,6 +244,10 @@ public:
     return Context.Sources.createFileID(File, SourceLocation(), SrcMgr::C_User);
   }
 
+  StringRef getFilePath(llvm::StringRef Name) {
+    return TemporaryFiles.lookup(Name);
+  }
+
   std::string getFileContentFromDisk(llvm::StringRef Name) {
     std::string Path = TemporaryFiles.lookup(Name);
     assert(!Path.empty());
@@ -270,6 +274,48 @@ TEST_F(FlushRewrittenFilesTest, StoresChangesOnDisk) {
             getFileContentFromDisk("input.cpp"));
 }
 
+TEST_F(FlushRewrittenFilesTest, GetFilePath) {
+  // Create a temporary file.
+  createFile("input.cpp", "line1\nline2\nline3\nline4");
+  StringRef FilePath = getFilePath("input.cpp");
+  StringRef TempPath = llvm::sys::path::parent_path(FilePath);
+  StringRef TempFile = llvm::sys::path::filename(FilePath);
+
+  // Save current path.
+  SmallString<512> CurrentPath;
+  llvm::sys::fs::current_path(CurrentPath);
+
+  // Change directory to the temporary directory.
+  EXPECT_EQ(0, chdir(TempPath.str().c_str()));
+
+  // Get a FileEntry from the current directory.
+  FileManager Files((FileSystemOptions()));
+  const FileEntry *Entry = Files.getFile(TempFile);
+  ASSERT_TRUE(Entry != NULL);
+
+  FileID ID = Context.Sources.createFileID(Entry, SourceLocation(),
+               SrcMgr::C_User);
+
+  Replacement R = Replacement(Context.Sources, Context.getLocation(ID, 2, 1),
+                              5, "replaced");
+
+  // Change back to the original path so we can verify that replacements
+  // are being applied independently of the location.
+  EXPECT_EQ(0, chdir(CurrentPath.c_str()));
+
+  // We expect that the file path of the replacement is using an absolute path
+  EXPECT_TRUE(llvm::sys::fs::equivalent(R.getFilePath(),
+      getFilePath("input.cpp")));
+
+  // Apply replacements.
+  Replacements Replaces;
+  Replaces.insert(R);
+  EXPECT_TRUE(applyAllReplacements(Replaces, Context.Rewrite));
+  EXPECT_FALSE(Context.Rewrite.overwriteChangedFiles());
+  EXPECT_EQ("line1\nreplaced\nline3\nline4",
+                 getFileContentFromDisk("input.cpp"));
+}
+
 namespace {
 template <typename T>
 class TestVisitor : public clang::RecursiveASTVisitor<T> {