[refactor] Use CommonOptionsParser in clang-refactor

This commit ensures that CommonOptionsParser works with subcommands. This allows
clang-refactor to use the CommonOptionsParser.

Differential Revision: https://reviews.llvm.org/D37618

llvm-svn: 313260
This commit is contained in:
Alex Lorenz 2017-09-14 13:16:14 +00:00
parent 0b220c7524
commit 3d712c46e6
5 changed files with 27 additions and 60 deletions

View File

@ -84,24 +84,26 @@ std::vector<CompileCommand> ArgumentsAdjustingCompilations::adjustCommands(
CommonOptionsParser::CommonOptionsParser(
int &argc, const char **argv, cl::OptionCategory &Category,
llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) {
static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);
static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden,
cl::sub(*cl::AllSubCommands));
static cl::opt<std::string> BuildPath("p", cl::desc("Build path"),
cl::Optional, cl::cat(Category));
cl::Optional, cl::cat(Category),
cl::sub(*cl::AllSubCommands));
static cl::list<std::string> SourcePaths(
cl::Positional, cl::desc("<source0> [... <sourceN>]"), OccurrencesFlag,
cl::cat(Category));
cl::cat(Category), cl::sub(*cl::AllSubCommands));
static cl::list<std::string> ArgsAfter(
"extra-arg",
cl::desc("Additional argument to append to the compiler command line"),
cl::cat(Category));
cl::cat(Category), cl::sub(*cl::AllSubCommands));
static cl::list<std::string> ArgsBefore(
"extra-arg-before",
cl::desc("Additional argument to prepend to the compiler command line"),
cl::cat(Category));
cl::cat(Category), cl::sub(*cl::AllSubCommands));
cl::HideUnrelatedOptions(Category);

View File

@ -1,4 +1,4 @@
// RUN: clang-refactor local-rename -selection=test:%s -no-dbs %s | FileCheck %s
// RUN: clang-refactor local-rename -selection=test:%s %s -- | FileCheck %s
class Baz {
int /*range=*/Foo; // CHECK: int /*range=*/Bar;

View File

@ -1,6 +1,3 @@
// RUN: not clang-refactor 2>&1 | FileCheck --check-prefix=MISSING_ACTION %s
// MISSING_ACTION: error: no refactoring action given
// MISSING_ACTION-NEXT: note: the following actions are supported:
// RUN: not clang-refactor local-rename -no-dbs 2>&1 | FileCheck --check-prefix=MISSING_SOURCES %s
// MISSING_SOURCES: error: must provide paths to the source files when '-no-dbs' is used

View File

@ -1,4 +1,4 @@
// RUN: clang-refactor local-rename -selection=test:%s -no-dbs -v %s 2>&1 | FileCheck %s
// RUN: clang-refactor local-rename -selection=test:%s -v %s -- 2>&1 | FileCheck %s
/*range=*/int test;
@ -11,12 +11,12 @@
/*range named =+0*/int test5;
// CHECK: Test selection group '':
// CHECK-NEXT: 100-100
// CHECK-NEXT: 153-153
// CHECK-NEXT: 192-192
// CHECK-NEXT: 95-95
// CHECK-NEXT: 148-148
// CHECK-NEXT: 187-187
// CHECK-NEXT: Test selection group 'named':
// CHECK-NEXT: 127-127
// CHECK-NEXT: 213-213
// CHECK-NEXT: 122-122
// CHECK-NEXT: 208-208
// The following invocations are in the default group:

View File

@ -15,6 +15,7 @@
#include "TestSupport.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Refactoring/RefactoringAction.h"
#include "clang/Tooling/Refactoring/Rename/RenamingAction.h"
@ -33,12 +34,6 @@ namespace opts {
static cl::OptionCategory CommonRefactorOptions("Common refactoring options");
static cl::opt<bool>
NoDatabases("no-dbs",
cl::desc("Ignore external databases including Clang's "
"compilation database and indexer stores"),
cl::cat(CommonRefactorOptions), cl::sub(*cl::AllSubCommands));
static cl::opt<bool> Verbose("v", cl::desc("Use verbose output"),
cl::cat(CommonRefactorOptions),
cl::sub(*cl::AllSubCommands));
@ -129,10 +124,6 @@ public:
cl::OptionCategory &Category)
: SubCommand(Action->getCommand(), Action->getDescription()),
Action(std::move(Action)), ActionRules(std::move(ActionRules)) {
Sources = llvm::make_unique<cl::list<std::string>>(
cl::Positional, cl::ZeroOrMore, cl::desc("<source0> [... <sourceN>]"),
cl::cat(Category), cl::sub(*this));
// Check if the selection option is supported.
bool HasSelection = false;
for (const auto &Rule : this->ActionRules) {
@ -169,13 +160,9 @@ public:
assert(Selection && "selection not supported!");
return ParsedSelection.get();
}
ArrayRef<std::string> getSources() const { return *Sources; }
private:
std::unique_ptr<RefactoringAction> Action;
RefactoringActionRules ActionRules;
std::unique_ptr<cl::list<std::string>> Sources;
std::unique_ptr<cl::opt<std::string>> Selection;
std::unique_ptr<SourceSelectionArgument> ParsedSelection;
};
@ -221,20 +208,9 @@ public:
/// Parses the translation units that were given to the subcommand using
/// the 'sources' option and invokes the callback for each parsed
/// translation unit.
bool foreachTranslationUnit(RefactoringActionSubcommand &Subcommand,
bool foreachTranslationUnit(const CompilationDatabase &DB,
ArrayRef<std::string> Sources,
TUCallbackType Callback) {
std::unique_ptr<CompilationDatabase> Compilations;
if (opts::NoDatabases) {
// FIXME (Alex L): Support compilation options.
Compilations =
llvm::make_unique<clang::tooling::FixedCompilationDatabase>(
".", std::vector<std::string>());
} else {
// FIXME (Alex L): Support compilation database.
llvm::errs() << "compilation databases are not supported yet!\n";
return true;
}
class ToolASTConsumer : public ASTConsumer {
public:
TUCallbackType Callback;
@ -254,7 +230,7 @@ public:
}
};
ClangTool Tool(*Compilations, Subcommand.getSources());
ClangTool Tool(DB, Sources);
ActionWrapper ToolAction(std::move(Callback));
std::unique_ptr<tooling::FrontendActionFactory> Factory =
tooling::newFrontendActionFactory(&ToolAction);
@ -277,7 +253,9 @@ public:
}
}
bool invokeAction(RefactoringActionSubcommand &Subcommand) {
bool invokeAction(RefactoringActionSubcommand &Subcommand,
const CompilationDatabase &DB,
ArrayRef<std::string> Sources) {
// Find a set of matching rules.
SmallVector<RefactoringActionRule *, 4> MatchingRules;
llvm::StringSet<> MissingOptions;
@ -303,7 +281,7 @@ public:
bool HasFailed = false;
ClangRefactorConsumer Consumer;
if (foreachTranslationUnit(Subcommand, [&](ASTContext &AST) {
if (foreachTranslationUnit(DB, Sources, [&](ASTContext &AST) {
RefactoringRuleContext Context(AST.getSourceManager());
Context.setASTContext(AST);
@ -347,12 +325,9 @@ public:
int main(int argc, const char **argv) {
ClangRefactorTool Tool;
// FIXME: Use LibTooling's CommonOptions parser when subcommands are supported
// by it.
cl::HideUnrelatedOptions(opts::CommonRefactorOptions);
cl::ParseCommandLineOptions(
argc, argv, "Clang-based refactoring tool for C, C++ and Objective-C");
cl::PrintOptionValues();
CommonOptionsParser Options(
argc, argv, opts::CommonRefactorOptions, cl::ZeroOrMore,
"Clang-based refactoring tool for C, C++ and Objective-C");
// Figure out which action is specified by the user. The user must specify
// the action using a command-line subcommand, e.g. the invocation
@ -374,17 +349,10 @@ int main(int argc, const char **argv) {
}
RefactoringActionSubcommand &ActionCommand = **It;
ArrayRef<std::string> Sources = ActionCommand.getSources();
// When -no-dbs is used, at least one file (TU) must be given to any
// subcommand.
if (opts::NoDatabases && Sources.empty()) {
llvm::errs() << "error: must provide paths to the source files when "
"'-no-dbs' is used\n";
return 1;
}
if (ActionCommand.parseArguments())
return 1;
if (Tool.invokeAction(ActionCommand))
if (Tool.invokeAction(ActionCommand, Options.getCompilations(),
Options.getSourcePathList()))
return 1;
return 0;