RewriterTestContext.h
4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//===--- RewriterTestContext.h ----------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines a utility class for Rewriter related tests.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_UNITTESTS_TOOLING_REWRITERTESTCONTEXT_H
#define LLVM_CLANG_UNITTESTS_TOOLING_REWRITERTESTCONTEXT_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Rewrite/Core/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()
: DiagOpts(new DiagnosticOptions()),
Diagnostics(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
&*DiagOpts),
DiagnosticPrinter(llvm::outs(), &*DiagOpts),
InMemoryFileSystem(new llvm::vfs::InMemoryFileSystem),
OverlayFileSystem(
new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem())),
Files(FileSystemOptions(), OverlayFileSystem),
Sources(Diagnostics, Files), Rewrite(Sources, Options) {
Diagnostics.setClient(&DiagnosticPrinter, false);
// FIXME: To make these tests truly in-memory, we need to overlay the
// builtin headers.
OverlayFileSystem->pushOverlay(InMemoryFileSystem);
}
~RewriterTestContext() {}
FileID createInMemoryFile(StringRef Name, StringRef Content) {
std::unique_ptr<llvm::MemoryBuffer> Source =
llvm::MemoryBuffer::getMemBuffer(Content);
InMemoryFileSystem->addFile(Name, 0, std::move(Source));
auto Entry = Files.getFile(Name);
assert(Entry);
return Sources.createFileID(*Entry, SourceLocation(), SrcMgr::C_User);
}
// FIXME: this code is mostly a duplicate of
// unittests/Tooling/RefactoringTest.cpp. Figure out a way to share it.
FileID createOnDiskFile(StringRef Name, StringRef Content) {
SmallString<1024> Path;
int FD;
std::error_code EC = llvm::sys::fs::createTemporaryFile(Name, "", FD, Path);
assert(!EC);
(void)EC;
llvm::raw_fd_ostream OutStream(FD, true);
OutStream << Content;
OutStream.close();
auto File = Files.getFile(Path);
assert(File);
StringRef Found =
TemporaryFiles.insert(std::make_pair(Name, std::string(Path.str())))
.first->second;
assert(Found == Path);
(void)Found;
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) {
std::string Path = TemporaryFiles.lookup(Name);
assert(!Path.empty());
// 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.
auto FileBuffer = Files.getBufferForFile(Path);
return std::string((*FileBuffer)->getBuffer());
}
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
DiagnosticsEngine Diagnostics;
TextDiagnosticPrinter DiagnosticPrinter;
IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem;
FileManager Files;
SourceManager Sources;
LangOptions Options;
Rewriter Rewrite;
// Will be set once on disk files are generated.
llvm::StringMap<std::string> TemporaryFiles;
};
} // end namespace clang
#endif