14#include "llvm/Support/Error.h"
15#include "gmock/gmock.h"
16#include "gtest/gtest.h"
25std::pair<llvm::StringRef, llvm::StringRef> wrapping(
Context Ctx) {
30 return {
"void wrapperFunction(){\n",
"\n}"};
32 return {
"auto expressionWrapper(){return\n",
"\n;}"};
34 llvm_unreachable(
"Unknown TweakTest::CodeContext enum");
37std::string
wrap(
Context Ctx, llvm::StringRef Inner) {
38 auto Wrapping = wrapping(Ctx);
39 return (Wrapping.first + Inner + Wrapping.second).str();
42llvm::StringRef unwrap(
Context Ctx, llvm::StringRef Outer) {
43 auto Wrapping = wrapping(Ctx);
46 if (Outer.starts_with(Wrapping.first) && Outer.ends_with(Wrapping.second) &&
47 Outer.size() >= Wrapping.first.size() + Wrapping.second.size())
48 return Outer.drop_front(Wrapping.first.size())
49 .drop_back(Wrapping.second.size());
53llvm::Annotations::Range rangeOrPoint(
const llvm::Annotations &A) {
54 if (
A.points().size() != 0) {
55 assert(
A.ranges().size() == 0 &&
56 "both a cursor point and a selection range were specified");
57 return {
A.point(),
A.point()};
64std::optional<llvm::Expected<Tweak::Effect>>
66 const SymbolIndex *Index, llvm::vfs::FileSystem *FS) {
67 std::optional<llvm::Expected<Tweak::Effect>> Result;
70 Tweak::Selection S(Index, AST, Range.Begin,
71 Range.End, std::move(ST), FS);
72 if (auto T = prepareTweak(TweakID, S, nullptr)) {
73 Result = (*T)->apply(S);
76 llvm::consumeError(T.takeError());
86 llvm::StringMap<std::string> *EditedFiles)
const {
87 std::string WrappedCode = wrap(
Context, MarkedCode);
88 llvm::Annotations Input(WrappedCode);
93 TU.
Code = std::string(Input.code());
97 auto Result = applyTweak(
98 AST, rangeOrPoint(Input), TweakID,
Index.get(),
99 &
AST.getSourceManager().getFileManager().getVirtualFileSystem());
101 return "unavailable";
103 return "fail: " + llvm::toString(Result->takeError());
104 const auto &Effect = **Result;
105 if ((*Result)->ShowMessage)
106 return "message:\n" + *Effect.ShowMessage;
107 if (Effect.ApplyEdits.empty())
110 std::string EditedMainFile;
111 for (
auto &It : Effect.ApplyEdits) {
112 auto NewText = It.second.apply();
114 return "bad edits: " + llvm::toString(NewText.takeError());
115 llvm::StringRef Unwrapped = unwrap(
Context, *NewText);
117 EditedMainFile = std::string(Unwrapped);
120 ADD_FAILURE() <<
"There were changes to additional files, but client "
121 "provided a nullptr for EditedFiles.";
123 EditedFiles->insert_or_assign(It.first(), Unwrapped.str());
126 return EditedMainFile;
130 llvm::Annotations::Range
Range)
const {
134 auto Result = applyTweak(
136 &
AST.first.getSourceManager().getFileManager().getVirtualFileSystem());
138 if (Result && !*Result)
139 consumeError(Result->takeError());
140 return Result.has_value();
154 return (Code.substr(0, Point) +
"^" + Code.substr(Point)).str();
158 llvm::Annotations::Range
Range) {
159 return (Code.substr(0,
Range.Begin) +
"[[" +
161 Code.substr(
Range.End))
A context is an immutable container for per-request data that must be propagated through layers that ...
Stores and provides access to parsed AST.
static bool createEach(ASTContext &AST, const syntax::TokenBuffer &Tokens, unsigned Begin, unsigned End, llvm::function_ref< bool(SelectionTree)> Func)
Interface for symbol indexes that can be used for searching or matching symbols among a set of symbol...
std::vector< std::string > ExtraArgs
llvm::StringMap< std::string > ExtraFiles
static std::string decorate(llvm::StringRef, unsigned)
WrappedAST build(llvm::StringRef) const
std::pair< ParsedAST, unsigned > WrappedAST
std::string apply(llvm::StringRef MarkedCode, llvm::StringMap< std::string > *EditedFiles=nullptr) const
bool isAvailable(WrappedAST &, llvm::Annotations::Range) const
std::unique_ptr< const SymbolIndex > Index
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
std::string testPath(PathRef File, llvm::sys::path::Style Style)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::vector< std::string > ExtraArgs
llvm::StringMap< std::string > AdditionalFiles