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: RewriterTestContext()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 ~RewriterTestContext()48 ~RewriterTestContext() {} 49 createInMemoryFile(StringRef Name,StringRef Content)50 FileID createInMemoryFile(StringRef Name, StringRef Content) { 51 llvm::MemoryBuffer *Source = llvm::MemoryBuffer::getMemBuffer(Content); 52 const FileEntry *Entry = 53 Files.getVirtualFile(Name, Source->getBufferSize(), 0); 54 Sources.overrideFileContents(Entry, Source); 55 assert(Entry != nullptr); 56 return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User); 57 } 58 59 // FIXME: this code is mostly a duplicate of 60 // unittests/Tooling/RefactoringTest.cpp. Figure out a way to share it. createOnDiskFile(StringRef Name,StringRef Content)61 FileID createOnDiskFile(StringRef Name, StringRef Content) { 62 SmallString<1024> Path; 63 int FD; 64 std::error_code EC = llvm::sys::fs::createTemporaryFile(Name, "", FD, Path); 65 assert(!EC); 66 (void)EC; 67 68 llvm::raw_fd_ostream OutStream(FD, true); 69 OutStream << Content; 70 OutStream.close(); 71 const FileEntry *File = Files.getFile(Path); 72 assert(File != nullptr); 73 74 StringRef Found = TemporaryFiles.GetOrCreateValue(Name, Path.str()).second; 75 assert(Found == Path); 76 (void)Found; 77 return Sources.createFileID(File, SourceLocation(), SrcMgr::C_User); 78 } 79 getLocation(FileID ID,unsigned Line,unsigned Column)80 SourceLocation getLocation(FileID ID, unsigned Line, unsigned Column) { 81 SourceLocation Result = Sources.translateFileLineCol( 82 Sources.getFileEntryForID(ID), Line, Column); 83 assert(Result.isValid()); 84 return Result; 85 } 86 getRewrittenText(FileID ID)87 std::string getRewrittenText(FileID ID) { 88 std::string Result; 89 llvm::raw_string_ostream OS(Result); 90 Rewrite.getEditBuffer(ID).write(OS); 91 OS.flush(); 92 return Result; 93 } 94 getFileContentFromDisk(StringRef Name)95 std::string getFileContentFromDisk(StringRef Name) { 96 std::string Path = TemporaryFiles.lookup(Name); 97 assert(!Path.empty()); 98 // We need to read directly from the FileManager without relaying through 99 // a FileEntry, as otherwise we'd read through an already opened file 100 // descriptor, which might not see the changes made. 101 // FIXME: Figure out whether there is a way to get the SourceManger to 102 // reopen the file. 103 std::unique_ptr<const llvm::MemoryBuffer> FileBuffer( 104 Files.getBufferForFile(Path, nullptr)); 105 return FileBuffer->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