summaryrefslogtreecommitdiffstats
path: root/unittests/Tooling/RewriterTestContext.h
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Tooling/RewriterTestContext.h')
-rw-r--r--unittests/Tooling/RewriterTestContext.h125
1 files changed, 125 insertions, 0 deletions
diff --git a/unittests/Tooling/RewriterTestContext.h b/unittests/Tooling/RewriterTestContext.h
new file mode 100644
index 0000000..f68be6b
--- /dev/null
+++ b/unittests/Tooling/RewriterTestContext.h
@@ -0,0 +1,125 @@
+//===--- RewriterTestContext.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a utility class for Rewriter related tests.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_REWRITER_TEST_CONTEXT_H
+#define LLVM_CLANG_REWRITER_TEST_CONTEXT_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/DiagnosticOptions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Rewrite/Rewriter.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+
+/// \brief A class that sets up a ready to use Rewriter.
+///
+/// Useful in unit tests that need a Rewriter. Creates all dependencies
+/// of a Rewriter with default values for testing and provides convenience
+/// methods, which help with writing tests that change files.
+class RewriterTestContext {
+ public:
+ RewriterTestContext()
+ : Diagnostics(llvm::IntrusiveRefCntPtr<DiagnosticIDs>()),
+ DiagnosticPrinter(llvm::outs(), DiagnosticOptions()),
+ Files((FileSystemOptions())),
+ Sources(Diagnostics, Files),
+ Rewrite(Sources, Options) {
+ Diagnostics.setClient(&DiagnosticPrinter, false);
+ }
+
+ ~RewriterTestContext() {
+ if (!TemporaryDirectory.empty()) {
+ uint32_t RemovedCount = 0;
+ llvm::sys::fs::remove_all(TemporaryDirectory.str(), RemovedCount);
+ }
+ }
+
+ FileID createInMemoryFile(StringRef Name, StringRef Content) {
+ const llvm::MemoryBuffer *Source =
+ llvm::MemoryBuffer::getMemBuffer(Content);
+ const FileEntry *Entry =
+ Files.getVirtualFile(Name, Source->getBufferSize(), 0);
+ Sources.overrideFileContents(Entry, Source, true);
+ assert(Entry != NULL);
+ return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
+ }
+
+ FileID createOnDiskFile(StringRef Name, StringRef Content) {
+ if (TemporaryDirectory.empty()) {
+ int FD;
+ bool error =
+ llvm::sys::fs::unique_file("rewriter-test-%%-%%-%%-%%/anchor", FD,
+ TemporaryDirectory);
+ assert(!error); (void)error;
+ llvm::raw_fd_ostream Closer(FD, /*shouldClose=*/true);
+ TemporaryDirectory = llvm::sys::path::parent_path(TemporaryDirectory);
+ }
+ llvm::SmallString<1024> Path(TemporaryDirectory);
+ llvm::sys::path::append(Path, Name);
+ std::string ErrorInfo;
+ llvm::raw_fd_ostream OutStream(Path.c_str(),
+ ErrorInfo, llvm::raw_fd_ostream::F_Binary);
+ assert(ErrorInfo.empty());
+ OutStream << Content;
+ OutStream.close();
+ const FileEntry *File = Files.getFile(Path);
+ assert(File != NULL);
+ return Sources.createFileID(File, SourceLocation(), SrcMgr::C_User);
+ }
+
+ SourceLocation getLocation(FileID ID, unsigned Line, unsigned Column) {
+ SourceLocation Result = Sources.translateFileLineCol(
+ Sources.getFileEntryForID(ID), Line, Column);
+ assert(Result.isValid());
+ return Result;
+ }
+
+ std::string getRewrittenText(FileID ID) {
+ std::string Result;
+ llvm::raw_string_ostream OS(Result);
+ Rewrite.getEditBuffer(ID).write(OS);
+ OS.flush();
+ return Result;
+ }
+
+ std::string getFileContentFromDisk(StringRef Name) {
+ llvm::SmallString<1024> Path(TemporaryDirectory.str());
+ llvm::sys::path::append(Path, Name);
+ // We need to read directly from the FileManager without relaying through
+ // a FileEntry, as otherwise we'd read through an already opened file
+ // descriptor, which might not see the changes made.
+ // FIXME: Figure out whether there is a way to get the SourceManger to
+ // reopen the file.
+ return Files.getBufferForFile(Path, NULL)->getBuffer();
+ }
+
+ DiagnosticsEngine Diagnostics;
+ TextDiagnosticPrinter DiagnosticPrinter;
+ FileManager Files;
+ SourceManager Sources;
+ LangOptions Options;
+ Rewriter Rewrite;
+
+ // Will be set once on disk files are generated.
+ SmallString<128> TemporaryDirectory;
+};
+
+} // end namespace clang
+
+#endif
OpenPOWER on IntegriCloud