blob: 629ebf1b627eb77fc193eab7569c8563fdbce54f [file] [log] [blame]
Manuel Klimek78d084d2012-05-22 17:01:35 +00001//===--- 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"
Douglas Gregor275e8832012-10-23 22:55:10 +000018#include "clang/Basic/DiagnosticOptions.h"
Manuel Klimek78d084d2012-05-22 17:01:35 +000019#include "clang/Basic/FileManager.h"
20#include "clang/Basic/LangOptions.h"
21#include "clang/Basic/SourceManager.h"
Manuel Klimek78d084d2012-05-22 17:01:35 +000022#include "clang/Frontend/TextDiagnosticPrinter.h"
Ted Kremenekcdf81492012-09-01 05:09:24 +000023#include "clang/Rewrite/Core/Rewriter.h"
Manuel Klimek0a8b9cd2012-06-06 21:28:13 +000024#include "llvm/Support/FileSystem.h"
Manuel Klimek78d084d2012-05-22 17:01:35 +000025#include "llvm/Support/Path.h"
26#include "llvm/Support/raw_ostream.h"
27
28namespace 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.
35class RewriterTestContext {
36 public:
37 RewriterTestContext()
Douglas Gregor275e8832012-10-23 22:55:10 +000038 : DiagOpts(new DiagnosticOptions()),
Dmitri Gribenkof8579502013-01-12 19:30:44 +000039 Diagnostics(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
Douglas Gregor275e8832012-10-23 22:55:10 +000040 &*DiagOpts),
41 DiagnosticPrinter(llvm::outs(), &*DiagOpts),
Manuel Klimek78d084d2012-05-22 17:01:35 +000042 Files((FileSystemOptions())),
43 Sources(Diagnostics, Files),
44 Rewrite(Sources, Options) {
45 Diagnostics.setClient(&DiagnosticPrinter, false);
46 }
47
Rafael Espindola8b960942013-06-26 21:02:22 +000048 ~RewriterTestContext() {}
Manuel Klimek78d084d2012-05-22 17:01:35 +000049
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
Rafael Espindola8b960942013-06-26 21:02:22 +000060 // FIXME: this code is mostly a duplicate of
61 // unittests/Tooling/RefactoringTest.cpp. Figure out a way to share it.
Manuel Klimek78d084d2012-05-22 17:01:35 +000062 FileID createOnDiskFile(StringRef Name, StringRef Content) {
Rafael Espindola8b960942013-06-26 21:02:22 +000063 SmallString<1024> Path;
64 int FD;
65 llvm::error_code EC =
66 llvm::sys::fs::unique_file(Twine(Name) + "%%%%%%", FD, Path);
67 assert(!EC);
68 (void)EC;
69
70 llvm::raw_fd_ostream OutStream(FD, true);
Manuel Klimek78d084d2012-05-22 17:01:35 +000071 OutStream << Content;
72 OutStream.close();
73 const FileEntry *File = Files.getFile(Path);
74 assert(File != NULL);
Rafael Espindola8b960942013-06-26 21:02:22 +000075
76 StringRef Found = TemporaryFiles.GetOrCreateValue(Name, Path.str()).second;
77 assert(Found == Path);
78 (void)Found;
Manuel Klimek78d084d2012-05-22 17:01:35 +000079 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);
Manuel Klimekee56b542012-06-05 20:16:30 +000093 OS.flush();
Manuel Klimek78d084d2012-05-22 17:01:35 +000094 return Result;
95 }
96
97 std::string getFileContentFromDisk(StringRef Name) {
Rafael Espindola8b960942013-06-26 21:02:22 +000098 std::string Path = TemporaryFiles.lookup(Name);
99 assert(!Path.empty());
Manuel Klimek78d084d2012-05-22 17:01:35 +0000100 // 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
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000108 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
Manuel Klimek78d084d2012-05-22 17:01:35 +0000109 DiagnosticsEngine Diagnostics;
110 TextDiagnosticPrinter DiagnosticPrinter;
111 FileManager Files;
112 SourceManager Sources;
113 LangOptions Options;
114 Rewriter Rewrite;
115
Manuel Klimek0a8b9cd2012-06-06 21:28:13 +0000116 // Will be set once on disk files are generated.
Rafael Espindola8b960942013-06-26 21:02:22 +0000117 llvm::StringMap<std::string> TemporaryFiles;
Manuel Klimek78d084d2012-05-22 17:01:35 +0000118};
119
120} // end namespace clang
121
122#endif