16 #include "llvm/ADT/Optional.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/Errc.h"
19 #include "llvm/Support/Error.h"
25 using namespace clang;
26 using namespace transformer;
29 using ast_matchers::internal::DynTypedMatcher;
38 for (
const auto &E : ASTEdits) {
41 return Range.takeError();
53 auto Replacement = E.Replacement->eval(Result);
55 return Replacement.takeError();
56 auto Metadata = E.Metadata(Result);
58 return Metadata.takeError();
64 Edits.push_back(std::move(T));
70 return [Edits = std::move(Edits)](
const MatchResult &Result) {
82 return [Anchor = std::move(Anchor)](
const MatchResult &Result)
86 return Range.takeError();
90 Result.SourceManager->getSpellingLoc(
Range->getBegin());
101 if (Generators.size() == 1)
102 return std::move(Generators[0]);
104 [Gs = std::move(Generators)](
107 for (
const auto &G : Gs) {
110 return Edits.takeError();
111 AllEdits.append(Edits->begin(), Edits->end());
134 return llvm::Error::success();
137 return (llvm::Twine(
"text(\"") + S +
"\")").str();
143 return std::make_shared<SimpleTextGenerator>(std::move(S));
155 return (
"<" + Header +
">").str();
157 llvm_unreachable(
"Unknown transformer::IncludeFormat enum");
181 R.
Cases = {{std::move(M), std::move(Edits)}};
186 std::initializer_list<ASTEdit> Edits) {
195 template <
typename T>
196 class BindingsMatcher :
public ast_matchers::internal::MatcherInterface<T> {
198 const ast_matchers::internal::Matcher<T> InnerMatcher;
202 ast_matchers::internal::Matcher<T> InnerMatcher)
206 const T &
Node, ast_matchers::internal::ASTMatchFinder *Finder,
207 ast_matchers::internal::BoundNodesTreeBuilder *Builder)
const override {
208 ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
209 for (
const auto &N :
Nodes.getMap())
210 Result.setBinding(N.first, N.second);
211 if (InnerMatcher.matches(
Node, Finder, &Result)) {
212 *Builder = std::move(Result);
224 template <
typename T>
225 class DynamicForEachDescendantMatcher
226 :
public ast_matchers::internal::MatcherInterface<T> {
227 const DynTypedMatcher DescendantMatcher;
230 explicit DynamicForEachDescendantMatcher(DynTypedMatcher DescendantMatcher)
231 : DescendantMatcher(
std::move(DescendantMatcher)) {}
234 const T &
Node, ast_matchers::internal::ASTMatchFinder *Finder,
235 ast_matchers::internal::BoundNodesTreeBuilder *Builder)
const override {
236 return Finder->matchesDescendantOf(
237 Node, this->DescendantMatcher, Builder,
238 ast_matchers::internal::ASTMatchFinder::BK_All);
242 template <
typename T>
243 ast_matchers::internal::Matcher<T>
246 return ast_matchers::internal::makeMatcher(
new BindingsMatcher<T>(
248 ast_matchers::internal::makeMatcher(
249 new DynamicForEachDescendantMatcher<T>(std::move(M)))));
256 template <
typename T>
267 auto Transformations = Rule.Cases[I].Edits(Result);
268 if (!Transformations) {
269 Edits = Transformations.takeError();
272 Edits->append(Transformations->begin(), Transformations->end());
282 template <
typename T>
286 ApplyRuleCallback Callback(std::move(Rule));
288 Callback.registerMatchers<T>(Result.Nodes, &Finder);
289 Finder.match(
Node, *Result.Context);
290 return std::move(Callback.Edits);
322 return llvm::make_error<llvm::StringError>(
323 llvm::errc::invalid_argument,
324 "type unsupported for recursive rewriting, Kind=" +
330 return [NodeId = std::move(NodeId),
334 Result.Nodes.getMap();
335 auto It = NodesMap.find(NodeId);
336 if (It == NodesMap.end())
337 return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument,
338 "ID not bound: " + NodeId);
345 for (
auto &Case : Rule.
Cases)
366 std::vector<DynTypedMatcher> Matchers;
367 Matchers.reserve(Cases.size());
368 for (
const auto &Case : Cases) {
369 std::string Tag = (TagBase + Twine(Case.first)).str();
371 DynTypedMatcher BoundMatcher(Case.second.Matcher);
372 BoundMatcher.setAllowBind(
true);
373 auto M = *BoundMatcher.tryBind(Tag);
374 Matchers.push_back(!M.getTraversalKind()
375 ? M.withTraversalKind(DefaultTraversalKind)
388 for (
auto &Rule : Rules)
393 std::vector<DynTypedMatcher>
403 for (
int I = 0, N = Cases.size(); I < N; ++I) {
405 "Matcher must be non-(Qual)Type node matcher");
406 Buckets[Cases[I].Matcher.getSupportedKind()].emplace_back(I, Cases[I]);
414 std::vector<DynTypedMatcher> Matchers;
415 for (
const auto &Bucket : Buckets) {
416 DynTypedMatcher M = DynTypedMatcher::constructVariadic(
417 DynTypedMatcher::VO_AnyOf, Bucket.first,
419 M.setAllowBind(
true);
421 Matchers.push_back(M.tryBind(
RootID)->withTraversalKind(
TK_AsIs));
428 assert(Ms.size() == 1 &&
"Cases must have compatible matchers.");
433 auto &NodesMap = Result.Nodes.getMap();
434 auto Root = NodesMap.find(
RootID);
435 assert(Root != NodesMap.end() &&
"Transformation failed: missing root node.");
440 return RootRange->getBegin();
443 return Result.SourceManager->getExpansionLoc(
444 Root->second.getSourceRange().getBegin());
451 if (Rule.
Cases.size() == 1)
454 auto &NodesMap = Result.Nodes.getMap();
455 for (
size_t i = 0, N = Rule.
Cases.size(); i < N; ++i) {
457 if (NodesMap.find(Tag) != NodesMap.end())
460 llvm_unreachable(
"No tag found for this rule.");