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 50 FileID createInMemoryFile(StringRef Name, StringRef Content) { 51 const llvm::MemoryBuffer *Source = 52 llvm::MemoryBuffer::getMemBuffer(Content); 53 const FileEntry *Entry = 54 Files.getVirtualFile(Name, Source->getBufferSize(), 0); 55 Sources.overrideFileContents(Entry, Source, true); 56 assert(Entry != NULL); 57 return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User); 58 } 59 60 // FIXME: this code is mostly a duplicate of 61 // unittests/Tooling/RefactoringTest.cpp. Figure out a way to share it. 62 FileID createOnDiskFile(StringRef Name, StringRef Content) { 63 SmallString<1024> Path; 64 int FD; 65 llvm::error_code EC = 66 llvm::sys::fs::createTemporaryFile(Name, "", FD, Path); 67 assert(!EC); 68 (void)EC; 69 70 llvm::raw_fd_ostream OutStream(FD, true); 71 OutStream << Content; 72 OutStream.close(); 73 const FileEntry *File = Files.getFile(Path); 74 assert(File != NULL); 75 76 StringRef Found = TemporaryFiles.GetOrCreateValue(Name, Path.str()).second; 77 assert(Found == Path); 78 (void)Found; 79 return Sources.createFileID(File, SourceLocation(), SrcMgr::C_User); 80 } 81 82 SourceLocation getLocation(FileID ID, unsigned Line, unsigned Column) { 83 SourceLocation Result = Sources.translateFileLineCol( 84 Sources.getFileEntryForID(ID), Line, Column); 85 assert(Result.isValid()); 86 return Result; 87 } 88 89 std::string getRewrittenText(FileID ID) { 90 std::string Result; 91 llvm::raw_string_ostream OS(Result); 92 Rewrite.getEditBuffer(ID).write(OS); 93 OS.flush(); 94 return Result; 95 } 96 97 std::string getFileContentFromDisk(StringRef Name) { 98 std::string Path = TemporaryFiles.lookup(Name); 99 assert(!Path.empty()); 100 // We need to read directly from the FileManager without relaying through 101 // a FileEntry, as otherwise we'd read through an already opened file 102 // descriptor, which might not see the changes made. 103 // FIXME: Figure out whether there is a way to get the SourceManger to 104 // reopen the file. 105 return Files.getBufferForFile(Path, NULL)->getBuffer(); 106 } 107 108 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; 109 DiagnosticsEngine Diagnostics; 110 TextDiagnosticPrinter DiagnosticPrinter; 111 FileManager Files; 112 SourceManager Sources; 113 LangOptions Options; 114 Rewriter Rewrite; 115 116 // Will be set once on disk files are generated. 117 llvm::StringMap<std::string> TemporaryFiles; 118 }; 119 120 } // end namespace clang 121 122 #endif 123