• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     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.
createOnDiskFile(StringRef Name,StringRef Content)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 
getLocation(FileID ID,unsigned Line,unsigned Column)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 
getRewrittenText(FileID ID)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 
getFileContentFromDisk(StringRef Name)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