84 lines · cpp
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-exception6//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 18namespace clang {19namespace tooling {20 21using ::clang::ast_matchers::MatchFinder;22 23namespace detail {24 25void TransformerImpl::onMatch(26 const ast_matchers::MatchFinder::MatchResult &Result) {27 if (Result.Context->getDiagnostics().hasErrorOccurred())28 return;29 30 onMatchImpl(Result);31}32 33llvm::Expected<llvm::SmallVector<AtomicChange, 1>>34TransformerImpl::convertToAtomicChanges(35 const llvm::SmallVectorImpl<transformer::Edit> &Edits,36 const MatchFinder::MatchResult &Result) {37 // Group the transformations, by file, into AtomicChanges, each anchored by38 // the location of the first change in that file.39 std::map<FileID, AtomicChange> ChangesByFileID;40 for (const auto &T : Edits) {41 auto ID = Result.SourceManager->getFileID(T.Range.getBegin());42 auto Iter = ChangesByFileID43 .emplace(ID, AtomicChange(*Result.SourceManager,44 T.Range.getBegin(), T.Metadata))45 .first;46 auto &AC = Iter->second;47 switch (T.Kind) {48 case transformer::EditKind::Range:49 if (auto Err =50 AC.replace(*Result.SourceManager, T.Range, T.Replacement)) {51 return std::move(Err);52 }53 break;54 case transformer::EditKind::AddInclude:55 AC.addHeader(T.Replacement);56 break;57 }58 }59 60 llvm::SmallVector<AtomicChange, 1> Changes;61 Changes.reserve(ChangesByFileID.size());62 for (auto &IDChangePair : ChangesByFileID)63 Changes.push_back(std::move(IDChangePair.second));64 65 return Changes;66}67 68} // namespace detail69 70void Transformer::registerMatchers(MatchFinder *MatchFinder) {71 for (auto &Matcher : Impl->buildMatchers())72 MatchFinder->addDynamicMatcher(Matcher, this);73}74 75void Transformer::run(const MatchFinder::MatchResult &Result) {76 if (Result.Context->getDiagnostics().hasErrorOccurred())77 return;78 79 Impl->onMatch(Result);80}81 82} // namespace tooling83} // namespace clang84