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