1 //===--- RewriterTestContext.h ----------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines a utility class for Rewriter related tests. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_REWRITER_TEST_CONTEXT_H 15 #define LLVM_CLANG_REWRITER_TEST_CONTEXT_H 16 17 #include "clang/Basic/Diagnostic.h" 18 #include "clang/Basic/DiagnosticOptions.h" 19 #include "clang/Basic/FileManager.h" 20 #include "clang/Basic/LangOptions.h" 21 #include "clang/Basic/SourceManager.h" 22 #include "clang/Frontend/TextDiagnosticPrinter.h" 23 #include "clang/Rewrite/Core/Rewriter.h" 24 #include "llvm/Support/FileSystem.h" 25 #include "llvm/Support/Path.h" 26 #include "llvm/Support/raw_ostream.h" 27 28 namespace clang { 29 30 /// \brief A class that sets up a ready to use Rewriter. 31 /// 32 /// Useful in unit tests that need a Rewriter. Creates all dependencies 33 /// of a Rewriter with default values for testing and provides convenience 34 /// methods, which help with writing tests that change files. 35 class RewriterTestContext { 36 public: 37 RewriterTestContext() 38 : DiagOpts(new DiagnosticOptions()), 39 Diagnostics(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), 40 &*DiagOpts), 41 DiagnosticPrinter(llvm::outs(), &*DiagOpts), 42 Files((FileSystemOptions())), 43 Sources(Diagnostics, Files), 44 Rewrite(Sources, Options) { 45 Diagnostics.setClient(&DiagnosticPrinter, false); 46 } 47 48 ~RewriterTestContext() { 49 if (!TemporaryDirectory.empty()) { 50 uint32_t RemovedCount = 0; 51 llvm::sys::fs::remove_all(TemporaryDirectory.str(), RemovedCount); 52 } 53 } 54 55 FileID createInMemoryFile(StringRef Name, StringRef Content) { 56 const llvm::MemoryBuffer *Source = 57 llvm::MemoryBuffer::getMemBuffer(Content); 58 const FileEntry *Entry = 59 Files.getVirtualFile(Name, Source->getBufferSize(), 0); 60 Sources.overrideFileContents(Entry, Source, true); 61 assert(Entry != NULL); 62 return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User); 63 } 64 65 FileID createOnDiskFile(StringRef Name, StringRef Content) { 66 if (TemporaryDirectory.empty()) { 67 int FD; 68 bool error = 69 llvm::sys::fs::unique_file("rewriter-test-%%-%%-%%-%%/anchor", FD, 70 TemporaryDirectory); 71 assert(!error); (void)error; 72 llvm::raw_fd_ostream Closer(FD, /*shouldClose=*/true); 73 TemporaryDirectory = llvm::sys::path::parent_path(TemporaryDirectory); 74 } 75 SmallString<1024> Path(TemporaryDirectory); 76 llvm::sys::path::append(Path, Name); 77 std::string ErrorInfo; 78 llvm::raw_fd_ostream OutStream(Path.c_str(), 79 ErrorInfo, llvm::raw_fd_ostream::F_Binary); 80 assert(ErrorInfo.empty()); 81 OutStream << Content; 82 OutStream.close(); 83 const FileEntry *File = Files.getFile(Path); 84 assert(File != NULL); 85 return Sources.createFileID(File, SourceLocation(), SrcMgr::C_User); 86 } 87 88 SourceLocation getLocation(FileID ID, unsigned Line, unsigned Column) { 89 SourceLocation Result = Sources.translateFileLineCol( 90 Sources.getFileEntryForID(ID), Line, Column); 91 assert(Result.isValid()); 92 return Result; 93 } 94 95 std::string getRewrittenText(FileID ID) { 96 std::string Result; 97 llvm::raw_string_ostream OS(Result); 98 Rewrite.getEditBuffer(ID).write(OS); 99 OS.flush(); 100 return Result; 101 } 102 103 std::string getFileContentFromDisk(StringRef Name) { 104 SmallString<1024> Path(TemporaryDirectory.str()); 105 llvm::sys::path::append(Path, Name); 106 // We need to read directly from the FileManager without relaying through 107 // a FileEntry, as otherwise we'd read through an already opened file 108 // descriptor, which might not see the changes made. 109 // FIXME: Figure out whether there is a way to get the SourceManger to 110 // reopen the file. 111 return Files.getBufferForFile(Path, NULL)->getBuffer(); 112 } 113 114 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; 115 DiagnosticsEngine Diagnostics; 116 TextDiagnosticPrinter DiagnosticPrinter; 117 FileManager Files; 118 SourceManager Sources; 119 LangOptions Options; 120 Rewriter Rewrite; 121 122 // Will be set once on disk files are generated. 123 SmallString<128> TemporaryDirectory; 124 }; 125 126 } // end namespace clang 127 128 #endif 129