Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(clang-apply-replacements) add_subdirectory(clang-rename) +add_subdirectory(clang-refactor) add_subdirectory(clang-reorder-fields) add_subdirectory(modularize) if(CLANG_ENABLE_STATIC_ANALYZER) @@ -24,4 +25,3 @@ if( CLANG_TOOLS_EXTRA_INCLUDE_DOCS ) add_subdirectory(docs) endif() - Index: clang-refactor/CMakeLists.txt =================================================================== --- /dev/null +++ clang-refactor/CMakeLists.txt @@ -0,0 +1,4 @@ +include_directories(core) + +add_subdirectory(core) +add_subdirectory(driver) Index: clang-refactor/core/BasicExecutor.h =================================================================== --- /dev/null +++ clang-refactor/core/BasicExecutor.h @@ -0,0 +1,36 @@ +//===--- BasicExecutor.h - clang-refactor -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_BASIC_EXECUTOR_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_BASIC_EXECUTOR_H + +#include "Executor.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include +#include + +namespace clang { +namespace refactor { + +class BasicExecutor : public Executor { +public: + void addTask(StringRef TU, const RefactoringOptions &Opts); + + llvm::Error runTasks(); +private: + std::vector> Tasks; +}; + +} // end namespace refactor +} // end namespace refactor + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_BASIC_EXECUTOR Index: clang-refactor/core/BasicExecutor.cpp =================================================================== --- /dev/null +++ clang-refactor/core/BasicExecutor.cpp @@ -0,0 +1,30 @@ +//===--- BasicExecutor.cpp - clang-refactor ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "BasicExecutor.h" + +namespace clang { +namespace refactor { + +void BasicExecutor::addTask(StringRef TU, + const RefactoringOptions &Opts) { + Tasks.push_back({TU, Opts}); +} + +llvm::Error BasicExecutor::runTasks() { + llvm::Error Err; + for (const auto &Task : Tasks) { + // FIXME: Actually do stuff. + (void)Task; + } + return Err; +} + +} // end namespace refactor +} // end namespace refactor Index: clang-refactor/core/CMakeLists.txt =================================================================== --- /dev/null +++ clang-refactor/core/CMakeLists.txt @@ -0,0 +1,16 @@ +add_clang_library(clangRefactorCore + RefactoringContext.cpp + RefactoringModule.cpp + BasicExecutor.cpp + ModuleManager.cpp + ModuleEntryPoint.cpp + + LINK_LIBS + clangAST + clangASTMatchers + clangBasic + clangFrontend + clangLex + clangTooling + clangToolingCore + ) Index: clang-refactor/core/Executor.h =================================================================== --- /dev/null +++ clang-refactor/core/Executor.h @@ -0,0 +1,34 @@ +//===--- Executor.h - clang-refactor ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_EXECUTOR_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_EXECUTOR_H + +#include "RefactoringOptions.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include +#include + +namespace clang { +namespace refactor { + +class Executor { +public: + virtual void addTask(StringRef TU, const RefactoringOptions &Opts) = 0; + virtual llvm::Error runTasks() = 0; + virtual ~Executor() = default; +}; + +} // end namespace refactor +} // end namespace refactor + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_EXECUTOR_H Index: clang-refactor/core/ModuleEntryPoint.h =================================================================== --- /dev/null +++ clang-refactor/core/ModuleEntryPoint.h @@ -0,0 +1,29 @@ +//===--- ModuleEntryPoint.h - clang-refactor --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_MODULE_ENTRY_POINT_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_MODULE_ENTRY_POINT_H + +#include "BasicExecutor.h" +#include "RefactoringModule.h" +#include "RefactoringContext.h" +#include "SymbolIndexClient.h" +#include "llvm/Support/Error.h" + +namespace clang { +namespace refactor { + +class RefactoringModule; +llvm::Error EntryPoint(std::unique_ptr &Module, int argc, + const char **argv); + +} // end namespace refactor +} // end namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_MODULE_ENTRY_POINT Index: clang-refactor/core/ModuleEntryPoint.cpp =================================================================== --- /dev/null +++ clang-refactor/core/ModuleEntryPoint.cpp @@ -0,0 +1,38 @@ +//===--- ModuleEntryPoint.cpp - clang-refactor ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ModuleEntryPoint.h" + +namespace clang { +namespace refactor { + +llvm::Error EntryPoint(std::unique_ptr &Module, + int argc, const char **argv) { + llvm::Error Err; + + Module->registerOptions(); + + // FIXME: Create RefactoringOptions from CLI arguments. + RefactoringOptions CommandLineOptions; + + SymbolIndexClient IndexClient; + BasicExecutor Exec; + + RefactoringContext Ctx(&IndexClient, &Exec); + + RefactoringOptions PlanExecutionOptions = + Module->planExecution(Ctx, CommandLineOptions); + + Exec.runTasks(); + + return Err; +} + +} // end namespace refactor +} // end namespace clang Index: clang-refactor/core/ModuleManager.h =================================================================== --- /dev/null +++ clang-refactor/core/ModuleManager.h @@ -0,0 +1,46 @@ +//===--- ModuleManager.h - clang-refactor -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_MODULE_MANAGER_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_MODULE_MANAGER_H + +#include "ModuleEntryPoint.h" +#include "BasicExecutor.h" +#include "RefactoringModule.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/StringRef.h" +#include +#include +#include + +namespace clang { +namespace refactor { + +class ModuleManager { +public: + void addModule(StringRef Command, std::unique_ptr Module); + + int dispatch(StringRef Command, int argc, const char **argv); + + std::string getTopLevelHelp(); + +private: + const std::string HelpHead = "USAGE: clang-refactor [subcommand] [options] " + " [... ]\n" + "\n" + "Subcommands:\n"; + + std::map> + CommandToModule; +}; + +} // end namespace refactor +} // end namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_MODULE_MANAGER_H Index: clang-refactor/core/ModuleManager.cpp =================================================================== --- /dev/null +++ clang-refactor/core/ModuleManager.cpp @@ -0,0 +1,38 @@ +//===--- ModuleManager.cpp - clang-refactor ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ModuleManager.h" + +namespace clang { +namespace refactor { + +void ModuleManager::addModule(StringRef Command, + std::unique_ptr Module) { + CommandToModule[Command] = std::move(Module); +} + +int ModuleManager::dispatch(StringRef Command, int argc, + const char **argv) { + auto it = CommandToModule.find(Command); + if (it != CommandToModule.end()) { + EntryPoint(it->second, argc, argv); + } + return 1; +} + +std::string ModuleManager::getTopLevelHelp() { + std::string Result = HelpHead; + for (const auto &CommandToModulePair : CommandToModule) { + Result += std::string(CommandToModulePair.second->getModuleName()); + } + return Result; +} + +} // end namespace refactor +} // end namespace clang Index: clang-refactor/core/RefactoringContext.h =================================================================== --- /dev/null +++ clang-refactor/core/RefactoringContext.h @@ -0,0 +1,43 @@ +//===--- RefactoringContext.h - clang-refactor ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_REFACTORING_CONTEXT_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_REFACTORING_CONTEXT_H + +#include "BasicExecutor.h" +#include "ModuleEntryPoint.h" +#include "SymbolIndexClient.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/StringRef.h" +#include +#include +#include +#include + +namespace clang { +namespace refactor { + +class RefactoringContext { +public: + RefactoringContext(SymbolIndexClient *IndexClient, Executor *Exec); + + void parseAST(/* ... */); + +private: + SymbolIndexClient *IndexClient; + Executor *Exec; + // FIXME: What else? + // File? + // ...? +}; + +} // end namespace refactor +} // end namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_REFACTORING_CONTEXT_H Index: clang-refactor/core/RefactoringContext.cpp =================================================================== --- /dev/null +++ clang-refactor/core/RefactoringContext.cpp @@ -0,0 +1,22 @@ +//===--- RefactoringContext.cpp - clang-refactor ----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RefactoringContext.h" + +namespace clang { +namespace refactor { + +RefactoringContext::RefactoringContext(SymbolIndexClient *IndexClient, + Executor *Exec) + : IndexClient(IndexClient), Exec(Exec) {} + +void RefactoringContext::parseAST(/* ... */) {} + +} // end namespace refactor +} // end namespace clang Index: clang-refactor/core/RefactoringModule.h =================================================================== --- /dev/null +++ clang-refactor/core/RefactoringModule.h @@ -0,0 +1,98 @@ +//===--- RefactoringModule.h - clang-refactor -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_REFACTORING_MODULE_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_REFACTORING_MODULE_H + +#include "Executor.h" +#include "RefactoringContext.h" +#include "RefactoringOptions.h" +#include "SymbolIndexClient.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/LLVM.h" +#include "clang/Tooling/CommonOptionsParser.h" +#include "clang/Tooling/CompilationDatabase.h" +#include "clang/Tooling/Refactoring.h" +#include "clang/Tooling/Tooling.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Signals.h" +#include + +namespace clang { +namespace refactor { + +class RefactoringContext; + +class RefactoringModule { +public: + RefactoringModule(StringRef ModuleName, StringRef ModuleDescription); + + //===--------------------------------------------------------------------===// + // Pre-stage I: register CLI options. + //===--------------------------------------------------------------------===// + virtual llvm::cl::OptionCategory registerOptions() = 0; + //===--------------------------------------------------------------------===// + + //===--------------------------------------------------------------------===// + // Stage I: Plan execution. + // + // FIXME: Describe current stage. + // + // Input: Options retrieved from command line arguments, ASTContext for + // translation unit, to which belongs to, cross-reference symbol + // index, executor. + // + // Ouput: Submodule-specific information for independent translation unit + // processing. + // + //===--------------------------------------------------------------------===// + virtual RefactoringOptions planExecution(const RefactoringContext &Ctx, + const RefactoringOptions &Opts) = 0; + //===--------------------------------------------------------------------===// + + //===--------------------------------------------------------------------===// + // Stage II: Running on a single translation unit. + // + // FIXME: Describe current stage. + // + // Input: Compiler instance, translation unit main file. + // + // Output: list of replacements and diagnostics. + // + // Has access to: AST of given translation unit. + // + //===--------------------------------------------------------------------===// + virtual std::unique_ptr + createASTConsumer(CompilerInstance &CI, StringRef InputFile, + const RefactoringOptions &Opts) = 0; + //===--------------------------------------------------------------------===// + + StringRef getModuleName(); + StringRef getModuleDescription(); + + virtual ~RefactoringModule(); + +private: + // ModuleName is the lowercase submodule name, which will be passed to + // clang-refactor to invoke the submodule tool. + const std::string ModuleName; + + // ModuleDescription will appear as the module description upon calling + // $ clang-refactor --help + const std::string ModuleDescription; +}; + +} // end namespace refactor +} // end namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_REFACTORING_MODULE_H Index: clang-refactor/core/RefactoringModule.cpp =================================================================== --- /dev/null +++ clang-refactor/core/RefactoringModule.cpp @@ -0,0 +1,28 @@ +//===--- RefactoringModule.cpp - clang-refactor -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RefactoringModule.h" + +namespace clang { +namespace refactor { + +RefactoringModule::RefactoringModule(StringRef ModuleName, + StringRef ModuleDescription) + : ModuleName(ModuleName), ModuleDescription(ModuleDescription) {} + +StringRef RefactoringModule::getModuleName() { return ModuleName; } + +StringRef RefactoringModule::getModuleDescription() { + return ModuleDescription; +} + +RefactoringModule::~RefactoringModule() = default; + +} // end namespace refactor +} // end namespace clang Index: clang-refactor/core/RefactoringOptions.h =================================================================== --- /dev/null +++ clang-refactor/core/RefactoringOptions.h @@ -0,0 +1,25 @@ +//===--- RefactoringOptions.h - clang-refactor ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_REFACTORING_OPTIONS_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_REFACTORING_OPTIONS_H + +#include "llvm/ADT/StringMap.h" +#include + +namespace clang { +namespace refactor { + +// FIXME: Once it's not enough, implement . +typedef llvm::StringMap RefactoringOptions; + +} // end namespace refactor +} // end namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_REFACTORING_OPTIONS_H Index: clang-refactor/core/SymbolIndexClient.h =================================================================== --- /dev/null +++ clang-refactor/core/SymbolIndexClient.h @@ -0,0 +1,33 @@ +//===--- SymbolIndexClient.h - clang-refactor -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_SYMBOL_INDEX_CLIENT_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_SYMBOL_INDEX_CLIENT_H + +#include +#include + +namespace clang { +namespace refactor { + +// FIXME: Implement two following classes. +// SymbolDeclaration and SymbolUsage might reuse clang::tooling::Range. +struct SymbolDeclaration {}; +struct SymbolUsage {}; + +class SymbolIndexClient { +public: + std::vector getDeclarationsForUSR(StringRef USR); + std::vector getReferencesForUSR(StringRef USR); +}; + +} // end namespace refactor +} // end namespace refactor + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_SYMBOL_INDEX_CLIENT_H Index: clang-refactor/driver/CMakeLists.txt =================================================================== --- /dev/null +++ clang-refactor/driver/CMakeLists.txt @@ -0,0 +1,17 @@ +set(LLVM_LINK_COMPONENTS + Support + ) + +add_clang_executable(clang-refactor + Driver.cpp + ) + +target_link_libraries(clang-refactor + clangAST + clangASTMatchers + clangBasic + clangFrontend + clangTooling + + clangRefactorCore + ) Index: clang-refactor/driver/Driver.cpp =================================================================== --- /dev/null +++ clang-refactor/driver/Driver.cpp @@ -0,0 +1,48 @@ +//===--- Driver.cpp - clang-refactor ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file This file implements a clang-refactor tool. +/// +////===----------------------------------------------------------------------===// + +#include "clang/Tooling/CommonOptionsParser.h" +#include "llvm/Support/raw_ostream.h" + +#include "ModuleManager.h" + +namespace clang { +namespace refactor { + +static int printHelpMessage(ModuleManager &Manager) { + llvm::outs() << Manager.getTopLevelHelp(); + return 1; +} + +int clangRefactorMain(int argc, const char **argv) { + ModuleManager Manager; + if (argc > 1) { + llvm::StringRef FirstArgument(argv[1]); + if (FirstArgument == "-h" || FirstArgument == "-help" || + FirstArgument == "--help") + return printHelpMessage(Manager); + const std::string Command = argv[1]; + argv[1] = (llvm::Twine(argv[0]) + " " + llvm::Twine(argv[1])).str().c_str(); + Manager.dispatch(Command, argc - 1, argv + 1); + } else { + return printHelpMessage(Manager); + } + return 0; +} + +} // end namespace refactor +} // end namespace clang + +int main(int argc, const char **argv) { + return clang::refactor::clangRefactorMain(argc, argv); +}