Clang Project

clang_source_code/tools/clang-refactor/ClangRefactor.cpp
1//===--- ClangRefactor.cpp - Clang-based refactoring tool -----------------===//
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/// \file
10/// This file implements a clang-refactor tool that performs various
11/// source transformations.
12///
13//===----------------------------------------------------------------------===//
14
15#include "TestSupport.h"
16#include "clang/Frontend/CommandLineSourceLoc.h"
17#include "clang/Frontend/TextDiagnosticPrinter.h"
18#include "clang/Rewrite/Core/Rewriter.h"
19#include "clang/Tooling/CommonOptionsParser.h"
20#include "clang/Tooling/Refactoring.h"
21#include "clang/Tooling/Refactoring/RefactoringAction.h"
22#include "clang/Tooling/Refactoring/RefactoringOptions.h"
23#include "clang/Tooling/Refactoring/Rename/RenamingAction.h"
24#include "clang/Tooling/Tooling.h"
25#include "llvm/Support/CommandLine.h"
26#include "llvm/Support/FileSystem.h"
27#include "llvm/Support/Signals.h"
28#include "llvm/Support/raw_ostream.h"
29#include <string>
30
31using namespace clang;
32using namespace tooling;
33using namespace refactor;
34namespace cl = llvm::cl;
35
36namespace opts {
37
38static cl::OptionCategory CommonRefactorOptions("Refactoring options");
39
40static cl::opt<boolVerbose("v", cl::desc("Use verbose output"),
41                             cl::cat(cl::GeneralCategory),
42                             cl::sub(*cl::AllSubCommands));
43
44static cl::opt<boolInplace("i", cl::desc("Inplace edit <file>s"),
45                             cl::cat(cl::GeneralCategory),
46                             cl::sub(*cl::AllSubCommands));
47
48// end namespace opts
49
50namespace {
51
52/// Stores the parsed `-selection` argument.
53class SourceSelectionArgument {
54public:
55  virtual ~SourceSelectionArgument() {}
56
57  /// Parse the `-selection` argument.
58  ///
59  /// \returns A valid argument when the parse succedeed, null otherwise.
60  static std::unique_ptr<SourceSelectionArgumentfromString(StringRef Value);
61
62  /// Prints any additional state associated with the selection argument to
63  /// the given output stream.
64  virtual void print(raw_ostream &OS) {}
65
66  /// Returns a replacement refactoring result consumer (if any) that should
67  /// consume the results of a refactoring operation.
68  ///
69  /// The replacement refactoring result consumer is used by \c
70  /// TestSourceSelectionArgument to inject a test-specific result handling
71  /// logic into the refactoring operation. The test-specific consumer
72  /// ensures that the individual results in a particular test group are
73  /// identical.
74  virtual std::unique_ptr<ClangRefactorToolConsumerInterface>
75  createCustomConsumer() {
76    return nullptr;
77  }
78
79  /// Runs the give refactoring function for each specified selection.
80  ///
81  /// \returns true if an error occurred, false otherwise.
82  virtual bool
83  forAllRanges(const SourceManager &SM,
84               llvm::function_ref<void(SourceRange R)> Callback) = 0;
85};
86
87/// Stores the parsed -selection=test:<filename> option.
88class TestSourceSelectionArgument final : public SourceSelectionArgument {
89public:
90  TestSourceSelectionArgument(TestSelectionRangesInFile TestSelections)
91      : TestSelections(std::move(TestSelections)) {}
92
93  void print(raw_ostream &OS) override { TestSelections.dump(OS); }
94
95  std::unique_ptr<ClangRefactorToolConsumerInterface>
96  createCustomConsumer() override {
97    return TestSelections.createConsumer();
98  }
99
100  /// Testing support: invokes the selection action for each selection range in
101  /// the test file.
102  bool forAllRanges(const SourceManager &SM,
103                    llvm::function_ref<void(SourceRange R)> Callback) override {
104    return TestSelections.foreachRange(SM, Callback);
105  }
106
107private:
108  TestSelectionRangesInFile TestSelections;
109};
110
111/// Stores the parsed -selection=filename:line:column[-line:column] option.
112class SourceRangeSelectionArgument final : public SourceSelectionArgument {
113public:
114  SourceRangeSelectionArgument(ParsedSourceRange Range)
115      : Range(std::move(Range)) {}
116
117  bool forAllRanges(const SourceManager &SM,
118                    llvm::function_ref<void(SourceRange R)> Callback) override {
119    const FileEntry *FE = SM.getFileManager().getFile(Range.FileName);
120    FileID FID = FE ? SM.translateFile(FE) : FileID();
121    if (!FE || FID.isInvalid()) {
122      llvm::errs() << "error: -selection=" << Range.FileName
123                   << ":... : given file is not in the target TU\n";
124      return true;
125    }
126
127    SourceLocation Start = SM.getMacroArgExpandedLocation(
128        SM.translateLineCol(FID, Range.Begin.first, Range.Begin.second));
129    SourceLocation End = SM.getMacroArgExpandedLocation(
130        SM.translateLineCol(FID, Range.End.first, Range.End.second));
131    if (Start.isInvalid() || End.isInvalid()) {
132      llvm::errs() << "error: -selection=" << Range.FileName << ':'
133                   << Range.Begin.first << ':' << Range.Begin.second << '-'
134                   << Range.End.first << ':' << Range.End.second
135                   << " : invalid source location\n";
136      return true;
137    }
138    Callback(SourceRange(Start, End));
139    return false;
140  }
141
142private:
143  ParsedSourceRange Range;
144};
145
146std::unique_ptr<SourceSelectionArgument>
147SourceSelectionArgument::fromString(StringRef Value) {
148  if (Value.startswith("test:")) {
149    StringRef Filename = Value.drop_front(strlen("test:"));
150    Optional<TestSelectionRangesInFile> ParsedTestSelection =
151        findTestSelectionRanges(Filename);
152    if (!ParsedTestSelection)
153      return nullptr// A parsing error was already reported.
154    return llvm::make_unique<TestSourceSelectionArgument>(
155        std::move(*ParsedTestSelection));
156  }
157  Optional<ParsedSourceRange> Range = ParsedSourceRange::fromString(Value);
158  if (Range)
159    return llvm::make_unique<SourceRangeSelectionArgument>(std::move(*Range));
160  llvm::errs() << "error: '-selection' option must be specified using "
161                  "<file>:<line>:<column> or "
162                  "<file>:<line>:<column>-<line>:<column> format\n";
163  return nullptr;
164}
165
166/// A container that stores the command-line options used by a single
167/// refactoring option.
168class RefactoringActionCommandLineOptions {
169public:
170  void addStringOption(const RefactoringOption &Option,
171                       std::unique_ptr<cl::opt<std::string>> CLOption) {
172    StringOptions[&Option] = std::move(CLOption);
173  }
174
175  const cl::opt<std::string> &
176  getStringOption(const RefactoringOption &Opt) const {
177    auto It = StringOptions.find(&Opt);
178    return *It->second;
179  }
180
181private:
182  llvm::DenseMap<const RefactoringOption *,
183                 std::unique_ptr<cl::opt<std::string>>>
184      StringOptions;
185};
186
187/// Passes the command-line option values to the options used by a single
188/// refactoring action rule.
189class CommandLineRefactoringOptionVisitor final
190    : public RefactoringOptionVisitor {
191public:
192  CommandLineRefactoringOptionVisitor(
193      const RefactoringActionCommandLineOptions &Options)
194      : Options(Options) {}
195
196  void visit(const RefactoringOption &Opt,
197             Optional<std::string> &Value) override {
198    const cl::opt<std::string> &CLOpt = Options.getStringOption(Opt);
199    if (!CLOpt.getValue().empty()) {
200      Value = CLOpt.getValue();
201      return;
202    }
203    Value = None;
204    if (Opt.isRequired())
205      MissingRequiredOptions.push_back(&Opt);
206  }
207
208  ArrayRef<const RefactoringOption *> getMissingRequiredOptions() const {
209    return MissingRequiredOptions;
210  }
211
212private:
213  llvm::SmallVector<const RefactoringOption *, 4MissingRequiredOptions;
214  const RefactoringActionCommandLineOptions &Options;
215};
216
217/// Creates the refactoring options used by all the rules in a single
218/// refactoring action.
219class CommandLineRefactoringOptionCreator final
220    : public RefactoringOptionVisitor {
221public:
222  CommandLineRefactoringOptionCreator(
223      cl::OptionCategory &Category, cl::SubCommand &Subcommand,
224      RefactoringActionCommandLineOptions &Options)
225      : Category(Category), Subcommand(Subcommand), Options(Options) {}
226
227  void visit(const RefactoringOption &OptOptional<std::string> &) override {
228    if (Visited.insert(&Opt).second)
229      Options.addStringOption(Opt, create<std::string>(Opt));
230  }
231
232private:
233  template <typename T>
234  std::unique_ptr<cl::opt<T>> create(const RefactoringOption &Opt) {
235    if (!OptionNames.insert(Opt.getName()).second)
236      llvm::report_fatal_error("Multiple identical refactoring options "
237                               "specified for one refactoring action");
238    // FIXME: cl::Required can be specified when this option is present
239    // in all rules in an action.
240    return llvm::make_unique<cl::opt<T>>(
241        Opt.getName(), cl::desc(Opt.getDescription()), cl::Optional,
242        cl::cat(Category), cl::sub(Subcommand));
243  }
244
245  llvm::SmallPtrSet<const RefactoringOption *, 8> Visited;
246  llvm::StringSet<> OptionNames;
247  cl::OptionCategory &Category;
248  cl::SubCommand &Subcommand;
249  RefactoringActionCommandLineOptions &Options;
250};
251
252/// A subcommand that corresponds to individual refactoring action.
253class RefactoringActionSubcommand : public cl::SubCommand {
254public:
255  RefactoringActionSubcommand(std::unique_ptr<RefactoringActionAction,
256                              RefactoringActionRules ActionRules,
257                              cl::OptionCategory &Category)
258      : SubCommand(Action->getCommand(), Action->getDescription()),
259        Action(std::move(Action)), ActionRules(std::move(ActionRules)) {
260    // Check if the selection option is supported.
261    for (const auto &Rule : this->ActionRules) {
262      if (Rule->hasSelectionRequirement()) {
263        Selection = llvm::make_unique<cl::opt<std::string>>(
264            "selection",
265            cl::desc(
266                "The selected source range in which the refactoring should "
267                "be initiated (<file>:<line>:<column>-<line>:<column> or "
268                "<file>:<line>:<column>)"),
269            cl::cat(Category), cl::sub(*this));
270        break;
271      }
272    }
273    // Create the refactoring options.
274    for (const auto &Rule : this->ActionRules) {
275      CommandLineRefactoringOptionCreator OptionCreator(Category, *this,
276                                                        Options);
277      Rule->visitRefactoringOptions(OptionCreator);
278    }
279  }
280
281  ~RefactoringActionSubcommand() { unregisterSubCommand(); }
282
283  const RefactoringActionRules &getActionRules() const { return ActionRules; }
284
285  /// Parses the "-selection" command-line argument.
286  ///
287  /// \returns true on error, false otherwise.
288  bool parseSelectionArgument() {
289    if (Selection) {
290      ParsedSelection = SourceSelectionArgument::fromString(*Selection);
291      if (!ParsedSelection)
292        return true;
293    }
294    return false;
295  }
296
297  SourceSelectionArgument *getSelection() const {
298     (0) . __assert_fail ("Selection && \"selection not supported!\"", "/home/seafit/code_projects/clang_source/clang/tools/clang-refactor/ClangRefactor.cpp", 298, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Selection && "selection not supported!");
299    return ParsedSelection.get();
300  }
301
302  const RefactoringActionCommandLineOptions &getOptions() const {
303    return Options;
304  }
305
306private:
307  std::unique_ptr<RefactoringActionAction;
308  RefactoringActionRules ActionRules;
309  std::unique_ptr<cl::opt<std::string>> Selection;
310  std::unique_ptr<SourceSelectionArgumentParsedSelection;
311  RefactoringActionCommandLineOptions Options;
312};
313
314class ClangRefactorConsumer final : public ClangRefactorToolConsumerInterface {
315public:
316  ClangRefactorConsumer(AtomicChanges &Changes) : SourceChanges(&Changes) {}
317
318  void handleError(llvm::Error Err) override {
319    Optional<PartialDiagnosticAtDiag = DiagnosticError::take(Err);
320    if (!Diag) {
321      llvm::errs() << llvm::toString(std::move(Err)) << "\n";
322      return;
323    }
324    llvm::cantFail(std::move(Err)); // This is a success.
325    DiagnosticBuilder DB(
326        getDiags().Report(Diag->first, Diag->second.getDiagID()));
327    Diag->second.Emit(DB);
328  }
329
330  void handle(AtomicChanges Changes) override {
331    SourceChanges->insert(SourceChanges->begin(), Changes.begin(),
332                          Changes.end());
333  }
334
335  void handle(SymbolOccurrences Occurrences) override {
336    llvm_unreachable("symbol occurrence results are not handled yet");
337  }
338
339private:
340  AtomicChanges *SourceChanges;
341};
342
343class ClangRefactorTool {
344public:
345  ClangRefactorTool()
346      : SelectedSubcommand(nullptr), MatchingRule(nullptr),
347        Consumer(new ClangRefactorConsumer(Changes)), HasFailed(false) {
348    std::vector<std::unique_ptr<RefactoringAction>> Actions =
349        createRefactoringActions();
350
351    // Actions must have unique command names so that we can map them to one
352    // subcommand.
353    llvm::StringSet<> CommandNames;
354    for (const auto &Action : Actions) {
355      if (!CommandNames.insert(Action->getCommand()).second) {
356        llvm::errs() << "duplicate refactoring action command '"
357                     << Action->getCommand() << "'!";
358        exit(1);
359      }
360    }
361
362    // Create subcommands and command-line options.
363    for (auto &Action : Actions) {
364      SubCommands.push_back(llvm::make_unique<RefactoringActionSubcommand>(
365          std::move(Action), Action->createActiveActionRules(),
366          opts::CommonRefactorOptions));
367    }
368  }
369
370  // Initializes the selected subcommand and refactoring rule based on the
371  // command line options.
372  llvm::Error Init() {
373    auto Subcommand = getSelectedSubcommand();
374    if (!Subcommand)
375      return Subcommand.takeError();
376    auto Rule = getMatchingRule(**Subcommand);
377    if (!Rule)
378      return Rule.takeError();
379
380    SelectedSubcommand = *Subcommand;
381    MatchingRule = *Rule;
382
383    return llvm::Error::success();
384  }
385
386  bool hasFailed() const { return HasFailed; }
387
388  using TUCallbackType = std::function<void(ASTContext &)>;
389
390  // Callback of an AST action. This invokes the matching rule on the given AST.
391  void callback(ASTContext &AST) {
392    assert(SelectedSubcommand && MatchingRule && Consumer);
393    RefactoringRuleContext Context(AST.getSourceManager());
394    Context.setASTContext(AST);
395
396    // If the selection option is test specific, we use a test-specific
397    // consumer.
398    std::unique_ptr<ClangRefactorToolConsumerInterface> TestConsumer;
399    bool HasSelection = MatchingRule->hasSelectionRequirement();
400    if (HasSelection)
401      TestConsumer = SelectedSubcommand->getSelection()->createCustomConsumer();
402    ClangRefactorToolConsumerInterface *ActiveConsumer =
403        TestConsumer ? TestConsumer.get() : Consumer.get();
404    ActiveConsumer->beginTU(AST);
405
406    auto InvokeRule = [&](RefactoringResultConsumer &Consumer) {
407      if (opts::Verbose)
408        logInvocation(*SelectedSubcommandContext);
409      MatchingRule->invoke(*ActiveConsumer, Context);
410    };
411    if (HasSelection) {
412       (0) . __assert_fail ("SelectedSubcommand->getSelection() && \"Missing selection argument?\"", "/home/seafit/code_projects/clang_source/clang/tools/clang-refactor/ClangRefactor.cpp", 413, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(SelectedSubcommand->getSelection() &&
413 (0) . __assert_fail ("SelectedSubcommand->getSelection() && \"Missing selection argument?\"", "/home/seafit/code_projects/clang_source/clang/tools/clang-refactor/ClangRefactor.cpp", 413, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">             "Missing selection argument?");
414      if (opts::Verbose)
415        SelectedSubcommand->getSelection()->print(llvm::outs());
416      if (SelectedSubcommand->getSelection()->forAllRanges(
417              Context.getSources(), [&](SourceRange R) {
418                Context.setSelectionRange(R);
419                InvokeRule(*ActiveConsumer);
420              }))
421        HasFailed = true;
422      ActiveConsumer->endTU();
423      return;
424    }
425    InvokeRule(*ActiveConsumer);
426    ActiveConsumer->endTU();
427  }
428
429  llvm::Expected<std::unique_ptr<FrontendActionFactory>>
430  getFrontendActionFactory() {
431    class ToolASTConsumer : public ASTConsumer {
432    public:
433      TUCallbackType Callback;
434      ToolASTConsumer(TUCallbackType Callback)
435          : Callback(std::move(Callback)) {}
436
437      void HandleTranslationUnit(ASTContext &Context) override {
438        Callback(Context);
439      }
440    };
441    class ToolASTAction : public ASTFrontendAction {
442    public:
443      explicit ToolASTAction(TUCallbackType Callback)
444          : Callback(std::move(Callback)) {}
445
446    protected:
447      std::unique_ptr<clang::ASTConsumer>
448      CreateASTConsumer(clang::CompilerInstance &compiler,
449                        StringRef /* dummy */) override {
450        std::unique_ptr<clang::ASTConsumerConsumer{
451            new ToolASTConsumer(Callback)};
452        return Consumer;
453      }
454
455    private:
456      TUCallbackType Callback;
457    };
458
459    class ToolActionFactory : public FrontendActionFactory {
460    public:
461      ToolActionFactory(TUCallbackType Callback)
462          : Callback(std::move(Callback)) {}
463
464      FrontendAction *create() override { return new ToolASTAction(Callback); }
465
466    private:
467      TUCallbackType Callback;
468    };
469
470    return llvm::make_unique<ToolActionFactory>(
471        [this](ASTContext &AST) { return callback(AST); });
472  }
473
474  // FIXME(ioeric): this seems to only works for changes in a single file at
475  // this point.
476  bool applySourceChanges() {
477    std::set<std::stringFiles;
478    for (const auto &Change : Changes)
479      Files.insert(Change.getFilePath());
480    // FIXME: Add automatic formatting support as well.
481    tooling::ApplyChangesSpec Spec;
482    // FIXME: We should probably cleanup the result by default as well.
483    Spec.Cleanup = false;
484    for (const auto &File : Files) {
485      llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> BufferErr =
486          llvm::MemoryBuffer::getFile(File);
487      if (!BufferErr) {
488        llvm::errs() << "error: failed to open " << File << " for rewriting\n";
489        return true;
490      }
491      auto Result = tooling::applyAtomicChanges(File, (*BufferErr)->getBuffer(),
492                                                Changes, Spec);
493      if (!Result) {
494        llvm::errs() << toString(Result.takeError());
495        return true;
496      }
497
498      if (opts::Inplace) {
499        std::error_code EC;
500        llvm::raw_fd_ostream OS(File, EC, llvm::sys::fs::F_Text);
501        if (EC) {
502          llvm::errs() << EC.message() << "\n";
503          return true;
504        }
505        OS << *Result;
506        continue;
507      }
508
509      llvm::outs() << *Result;
510    }
511    return false;
512  }
513
514private:
515  /// Logs an individual refactoring action invocation to STDOUT.
516  void logInvocation(RefactoringActionSubcommand &Subcommand,
517                     const RefactoringRuleContext &Context) {
518    llvm::outs() << "invoking action '" << Subcommand.getName() << "':\n";
519    if (Context.getSelectionRange().isValid()) {
520      SourceRange R = Context.getSelectionRange();
521      llvm::outs() << "  -selection=";
522      R.getBegin().print(llvm::outs(), Context.getSources());
523      llvm::outs() << " -> ";
524      R.getEnd().print(llvm::outs(), Context.getSources());
525      llvm::outs() << "\n";
526    }
527  }
528
529  llvm::Expected<RefactoringActionRule *>
530  getMatchingRule(RefactoringActionSubcommand &Subcommand) {
531    SmallVector<RefactoringActionRule *, 4MatchingRules;
532    llvm::StringSet<> MissingOptions;
533
534    for (const auto &Rule : Subcommand.getActionRules()) {
535      CommandLineRefactoringOptionVisitor Visitor(Subcommand.getOptions());
536      Rule->visitRefactoringOptions(Visitor);
537      if (Visitor.getMissingRequiredOptions().empty()) {
538        if (!Rule->hasSelectionRequirement()) {
539          MatchingRules.push_back(Rule.get());
540        } else {
541          Subcommand.parseSelectionArgument();
542          if (Subcommand.getSelection()) {
543            MatchingRules.push_back(Rule.get());
544          } else {
545            MissingOptions.insert("selection");
546          }
547        }
548      }
549      for (const RefactoringOption *Opt : Visitor.getMissingRequiredOptions())
550        MissingOptions.insert(Opt->getName());
551    }
552    if (MatchingRules.empty()) {
553      std::string Error;
554      llvm::raw_string_ostream OS(Error);
555      OS << "ERROR: '" << Subcommand.getName()
556         << "' can't be invoked with the given arguments:\n";
557      for (const auto &Opt : MissingOptions)
558        OS << "  missing '-" << Opt.getKey() << "' option\n";
559      OS.flush();
560      return llvm::make_error<llvm::StringError>(
561          Error, llvm::inconvertibleErrorCode());
562    }
563    if (MatchingRules.size() != 1) {
564      return llvm::make_error<llvm::StringError>(
565          llvm::Twine("ERROR: more than one matching rule of action") +
566              Subcommand.getName() + "was found with given options.",
567          llvm::inconvertibleErrorCode());
568    }
569    return MatchingRules.front();
570  }
571  // Figure out which action is specified by the user. The user must specify the
572  // action using a command-line subcommand, e.g. the invocation `clang-refactor
573  // local-rename` corresponds to the `LocalRename` refactoring action. All
574  // subcommands must have a unique names. This allows us to figure out which
575  // refactoring action should be invoked by looking at the first subcommand
576  // that's enabled by LLVM's command-line parser.
577  llvm::Expected<RefactoringActionSubcommand *> getSelectedSubcommand() {
578    auto It = llvm::find_if(
579        SubCommands,
580        [](const std::unique_ptr<RefactoringActionSubcommand> &SubCommand) {
581          return !!(*SubCommand);
582        });
583    if (It == SubCommands.end()) {
584      std::string Error;
585      llvm::raw_string_ostream OS(Error);
586      OS << "error: no refactoring action given\n";
587      OS << "note: the following actions are supported:\n";
588      for (const auto &Subcommand : SubCommands)
589        OS.indent(2) << Subcommand->getName() << "\n";
590      OS.flush();
591      return llvm::make_error<llvm::StringError>(
592          Error, llvm::inconvertibleErrorCode());
593    }
594    RefactoringActionSubcommand *Subcommand = &(**It);
595    return Subcommand;
596  }
597
598  std::vector<std::unique_ptr<RefactoringActionSubcommand>> SubCommands;
599  RefactoringActionSubcommand *SelectedSubcommand;
600  RefactoringActionRule *MatchingRule;
601  std::unique_ptr<ClangRefactorToolConsumerInterface> Consumer;
602  AtomicChanges Changes;
603  bool HasFailed;
604};
605
606// end anonymous namespace
607
608int main(int argcconst char **argv) {
609  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
610
611  ClangRefactorTool RefactorTool;
612
613  CommonOptionsParser Options(
614      argc, argv, cl::GeneralCategory, cl::ZeroOrMore,
615      "Clang-based refactoring tool for C, C++ and Objective-C");
616
617  if (auto Err = RefactorTool.Init()) {
618    llvm::errs() << llvm::toString(std::move(Err)) << "\n";
619    return 1;
620  }
621
622  auto ActionFactory = RefactorTool.getFrontendActionFactory();
623  if (!ActionFactory) {
624    llvm::errs() << llvm::toString(ActionFactory.takeError()) << "\n";
625    return 1;
626  }
627  ClangTool Tool(Options.getCompilations(), Options.getSourcePathList());
628  bool Failed = false;
629  if (Tool.run(ActionFactory->get()) != 0) {
630    llvm::errs() << "Failed to run refactoring action on files\n";
631    // It is possible that TUs are broken while changes are generated correctly,
632    // so we still try applying changes.
633    Failed = true;
634  }
635  return RefactorTool.applySourceChanges() || Failed ||
636         RefactorTool.hasFailed();
637}
638