/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Tooling/Transformer/Transformer.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- Transformer.cpp - Transformer library implementation ---*- C++ -*-===// |
2 | | // |
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 |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
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" |
15 | | #include <map> |
16 | | #include <utility> |
17 | | #include <vector> |
18 | | |
19 | | namespace clang { |
20 | | namespace tooling { |
21 | | |
22 | | using ::clang::ast_matchers::MatchFinder; |
23 | | |
24 | | namespace detail { |
25 | | |
26 | | void TransformerImpl::onMatch( |
27 | 99 | const ast_matchers::MatchFinder::MatchResult &Result) { |
28 | 99 | if (Result.Context->getDiagnostics().hasErrorOccurred()) |
29 | 0 | return; |
30 | | |
31 | 99 | onMatchImpl(Result); |
32 | 99 | } |
33 | | |
34 | | llvm::Expected<llvm::SmallVector<AtomicChange, 1>> |
35 | | TransformerImpl::convertToAtomicChanges( |
36 | | const llvm::SmallVectorImpl<transformer::Edit> &Edits, |
37 | 88 | 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 | 88 | std::map<FileID, AtomicChange> ChangesByFileID; |
41 | 126 | for (const auto &T : Edits) { |
42 | 126 | auto ID = Result.SourceManager->getFileID(T.Range.getBegin()); |
43 | 126 | auto Iter = ChangesByFileID |
44 | 126 | .emplace(ID, AtomicChange(*Result.SourceManager, |
45 | 126 | T.Range.getBegin(), T.Metadata)) |
46 | 126 | .first; |
47 | 126 | auto &AC = Iter->second; |
48 | 126 | switch (T.Kind) { |
49 | 121 | case transformer::EditKind::Range: |
50 | 121 | if (auto Err = |
51 | 121 | AC.replace(*Result.SourceManager, T.Range, T.Replacement)) { |
52 | 1 | return std::move(Err); |
53 | 1 | } |
54 | 120 | break; |
55 | 120 | case transformer::EditKind::AddInclude: |
56 | 5 | AC.addHeader(T.Replacement); |
57 | 5 | break; |
58 | 126 | } |
59 | 126 | } |
60 | | |
61 | 87 | llvm::SmallVector<AtomicChange, 1> Changes; |
62 | 87 | Changes.reserve(ChangesByFileID.size()); |
63 | 87 | for (auto &IDChangePair : ChangesByFileID) |
64 | 88 | Changes.push_back(std::move(IDChangePair.second)); |
65 | | |
66 | 87 | return Changes; |
67 | 88 | } |
68 | | |
69 | | } // namespace detail |
70 | | |
71 | 73 | void Transformer::registerMatchers(MatchFinder *MatchFinder) { |
72 | 73 | for (auto &Matcher : Impl->buildMatchers()) |
73 | 74 | MatchFinder->addDynamicMatcher(Matcher, this); |
74 | 73 | } |
75 | | |
76 | 100 | void Transformer::run(const MatchFinder::MatchResult &Result) { |
77 | 100 | if (Result.Context->getDiagnostics().hasErrorOccurred()) |
78 | 1 | return; |
79 | | |
80 | 99 | Impl->onMatch(Result); |
81 | 99 | } |
82 | | |
83 | | } // namespace tooling |
84 | | } // namespace clang |