1 //===--- Transformer.cpp - Transformer library implementation ---*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "clang/Tooling/Transformer/Transformer.h"
10 #include "clang/ASTMatchers/ASTMatchFinder.h"
11 #include "clang/ASTMatchers/ASTMatchersInternal.h"
12 #include "clang/Basic/SourceLocation.h"
13 #include "clang/Tooling/Refactoring/AtomicChange.h"
14 #include "llvm/Support/Error.h"
22 using ::clang::ast_matchers::MatchFinder
;
26 void TransformerImpl::onMatch(
27 const ast_matchers::MatchFinder::MatchResult
&Result
) {
28 if (Result
.Context
->getDiagnostics().hasErrorOccurred())
34 llvm::Expected
<llvm::SmallVector
<AtomicChange
, 1>>
35 TransformerImpl::convertToAtomicChanges(
36 const llvm::SmallVectorImpl
<transformer::Edit
> &Edits
,
37 const MatchFinder::MatchResult
&Result
) {
38 // Group the transformations, by file, into AtomicChanges, each anchored by
39 // the location of the first change in that file.
40 std::map
<FileID
, AtomicChange
> ChangesByFileID
;
41 for (const auto &T
: Edits
) {
42 auto ID
= Result
.SourceManager
->getFileID(T
.Range
.getBegin());
43 auto Iter
= ChangesByFileID
44 .emplace(ID
, AtomicChange(*Result
.SourceManager
,
45 T
.Range
.getBegin(), T
.Metadata
))
47 auto &AC
= Iter
->second
;
49 case transformer::EditKind::Range
:
51 AC
.replace(*Result
.SourceManager
, T
.Range
, T
.Replacement
)) {
52 return std::move(Err
);
55 case transformer::EditKind::AddInclude
:
56 AC
.addHeader(T
.Replacement
);
61 llvm::SmallVector
<AtomicChange
, 1> Changes
;
62 Changes
.reserve(ChangesByFileID
.size());
63 for (auto &IDChangePair
: ChangesByFileID
)
64 Changes
.push_back(std::move(IDChangePair
.second
));
71 void Transformer::registerMatchers(MatchFinder
*MatchFinder
) {
72 for (auto &Matcher
: Impl
->buildMatchers())
73 MatchFinder
->addDynamicMatcher(Matcher
, this);
76 void Transformer::run(const MatchFinder::MatchResult
&Result
) {
77 if (Result
.Context
->getDiagnostics().hasErrorOccurred())
80 Impl
->onMatch(Result
);
83 } // namespace tooling