omtcyfz updated this revision to Diff 70397.
omtcyfz marked 11 inline comments as done.
omtcyfz added a comment.

Addressing a round of comments.


https://reviews.llvm.org/D24192

Files:
  CMakeLists.txt
  clang-refactor/CMakeLists.txt
  clang-refactor/driver/CMakeLists.txt
  clang-refactor/driver/Driver.cpp
  clang-refactor/driver/ModuleManager.cpp
  clang-refactor/driver/ModuleManager.h
  clang-refactor/modules/CMakeLists.txt
  clang-refactor/modules/core/RefactoringModule.h

Index: clang-refactor/modules/core/RefactoringModule.h
===================================================================
--- /dev/null
+++ clang-refactor/modules/core/RefactoringModule.h
@@ -0,0 +1,169 @@
+//===--- 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 "clang/Tooling/CommonOptionsParser.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Signals.h"
+
+#include <string>
+
+namespace clang {
+namespace refactor {
+
+class RefactoringModule {
+public:
+  RefactoringModule(const std::string &ModuleName,
+                    const std::string &ModuleMetaDescription)
+      : ModuleName(ModuleName), ModuleMetaDescription(ModuleMetaDescription) {}
+
+  // Refactoring consists of 3.5 stages:
+  //
+  // 0. Check arguments for validity.
+  //
+  // 1. Extract infromation needed for the refactoring upon tool invocation.
+  //
+  // 2. Handle translation unit and identify whether the refactoring can be
+  // applied. If it can, store the replacements. Panic otherwise.
+  //
+  // 3. Merge duplicate replacements, panic if there are conflicting ones.
+  // Process translation unit and apply refactoring.
+  //
+  // Few examples of how each of these stages would look like for future
+  // modules "rename" and "inline".
+  //
+  // Rename
+  // ======
+  //
+  // 0. Check arguments for validity.
+  //
+  // 1. Rename operates with USRs, so the first stage would be finding the
+  // symbol, which will be renamed and storing its USR.
+  //
+  // 2. Check whether renaming will introduce any name conflicts. If it won't
+  // find each occurance of the symbol in translation unit using USR and store
+  // replacements.
+  //
+  // 3. Apply replacements or output diagnostics. Handle duplicates and panic if
+  // there are conflicts.
+  //
+  // Inline
+  // ======
+  //
+  // 0. Check arguments for validity.
+  //
+  // 1. Find function, identify what the possible issues might be.
+  //
+  // 2. Check whether inlining will introduce any issues, e.g. there is a
+  // pointer passed somewhere to the inlined function and after inlining it the
+  // code will no longer compile. If it won't find function calls, add needed
+  // temprorary variables and replace the call with function body.
+  //
+  // 3. Apply replacements. Handle duplicates and panic if there are conflicts.
+  //
+  // Summary
+  // =======
+  //
+  // As one can easily see, step 1 should be performed upon module invocation
+  // and it needs to process translation unit, from which the passed <source0>
+  // comes from.
+  //
+  // With appropriate facilities step 2 can be parallelized to process multiple
+  // translation units of the project independently. If none of them have any
+  // issues with applying this refactoring replacements are stored and queued
+  // for later.
+  //
+  // Step 3 can be parallelized even more easily. It basically consists of text
+  // replacements.
+  //
+  int run(int argc, const char **argv) {
+    // Register options.
+    llvm::cl::OptionCategory RefactoringModuleOptions(ModuleName.c_str(),
+                                                      ModuleMetaDescription.c_str());
+    registerCustomOptions(RefactoringModuleOptions);
+    registerCustomOptions(RefactoringModuleOptions);
+    // Parse options and get compilations.
+    llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
+    tooling::CommonOptionsParser OptionsParser(argc, argv,
+                                               RefactoringModuleOptions);
+    tooling::RefactoringTool Tool(OptionsParser.getCompilations(),
+                                  OptionsParser.getSourcePathList());
+
+    // Actual routine.
+    checkArguments();
+    extractRefactoringInformation();
+    handleTranslationUnit();
+    applyReplacementsOrOutputDiagnostics();
+    return 0;
+  }
+
+  // Routine for regiestering common modules options.
+  void registerCommonOptions(llvm::cl::OptionCategory &Category) {
+  }
+
+  // A way for each tool to provide additional options. Overriding this one is
+  // optional.
+  virtual void registerCustomOptions(llvm::cl::OptionCategory &Category) {}
+
+  // Step 0.
+  // Just checking arguments.
+  //
+  // Panic: if they are not valid.
+  virtual int checkArguments() = 0;
+
+  // Step 1.
+  //
+  // Process translation <source0> and figure out what should be done.
+  //
+  // Panic: if refactoring can not be applied. E.g. unsupported cases like
+  // renaming macros etc.
+  virtual int extractRefactoringInformation() = 0;
+
+  // Step 2.
+  //
+  // Find places where refactoring should be applied and store replacements for
+  // the future.
+  //
+  // Panic: if there are any issues with applying refactorings to the
+  // translation unit.
+  virtual int handleTranslationUnit() = 0;
+
+  // Step 3.
+  //
+  // Handle duplicates.
+  //
+  // Panic: if there are conflicting replacements.
+  virtual int applyReplacementsOrOutputDiagnostics() = 0;
+
+  virtual ~RefactoringModule() = default;
+
+  StringRef getModuleName() { return ModuleName; }
+
+  StringRef getModuleMetaDescription() { return ModuleMetaDescription; }
+
+private:
+  // ModuleName is the lowercase submodule name, which will be passed to
+  // clang-refactor to invoke the submodule tool.
+  const std::string ModuleName;
+
+  // ModuleMetaDescription will appear as the module description upon calling
+  // $ clang-refactor --help
+  const std::string ModuleMetaDescription;
+};
+
+} // end namespace refactor
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_REFACTORING_MODULE_H
Index: clang-refactor/modules/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang-refactor/modules/CMakeLists.txt
@@ -0,0 +1 @@
+include_directories(core)
Index: clang-refactor/driver/ModuleManager.h
===================================================================
--- /dev/null
+++ clang-refactor/driver/ModuleManager.h
@@ -0,0 +1,40 @@
+//===--- 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 "llvm/ADT/StringRef.h"
+
+#include <string>
+#include <vector>
+#include <unordered_map>
+
+#include "core/RefactoringModule.h"
+
+using namespace llvm;
+
+namespace clang {
+namespace refactor {
+
+class ModuleManager {
+public:
+  void AddModule(StringRef Command, std::unique_ptr<RefactoringModule> Module);
+
+  int Dispatch(StringRef Command, int argc, const char **argv);
+
+private:
+  std::vector<std::unique_ptr<RefactoringModule>> RegisteredModules;
+  std::unordered_map<std::string, unsigned> CommandToModuleID;
+};
+
+} // end namespace refactor
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_MODULE_MANAGER_H
Index: clang-refactor/driver/ModuleManager.cpp
===================================================================
--- /dev/null
+++ clang-refactor/driver/ModuleManager.cpp
@@ -0,0 +1,29 @@
+//===--- 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<RefactoringModule> Module) {
+  RegisteredModules.push_back(std::move(Module));
+  CommandToModuleID[Command] = RegisteredModules.size() - 1;
+}
+
+int ModuleManager::Dispatch(StringRef Command, int argc, const char **argv) {
+  if (CommandToModuleID.find(Command) != CommandToModuleID.end()) {
+    return RegisteredModules[CommandToModuleID[Command]]->run(argc, argv);
+  }
+  return 1;
+}
+
+} // end namespace refactor
+} // end namespace clang
Index: clang-refactor/driver/Driver.cpp
===================================================================
--- /dev/null
+++ clang-refactor/driver/Driver.cpp
@@ -0,0 +1,55 @@
+//===--- 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 {
+
+const char HelpHead[] = "USAGE: clang-refactor [subcommand] [options] "
+                        "<source0> [... <sourceN>]\n"
+                        "\n"
+                        "Subcommands:\n";
+
+static int printHelpMessage() {
+  llvm::outs() << HelpHead;
+  return 1;
+}
+
+int clangRefactorMain(int argc, const char **argv) {
+  ModuleManager Manager;
+  std::string Command = "";
+  if (argc > 1) {
+    llvm::StringRef FirstArgument(argv[1]);
+    if (FirstArgument == "-h" || FirstArgument == "-help" ||
+        FirstArgument == "--help")
+      return printHelpMessage();
+    Command = argv[1];
+    std::string Invocation = std::string(argv[0]) + " " + argv[1];
+    argv[1] = Invocation.c_str();
+    Manager.Dispatch(Command, argc - 1, argv + 1);
+  } else {
+    return printHelpMessage();
+  }
+  return 0;
+}
+
+} // end namespace refactor
+} // end namespace clang
+
+int main(int argc, const char **argv) {
+  return clang::refactor::clangRefactorMain(argc, argv);
+}
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
+
+  ModuleManager.cpp
+  )
+
+target_link_libraries(clang-refactor
+  clangAST
+  clangASTMatchers
+  clangBasic
+  clangFrontend
+  clangTooling
+  )
Index: clang-refactor/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang-refactor/CMakeLists.txt
@@ -0,0 +1,4 @@
+include_directories(modules)
+
+add_subdirectory(driver)
+add_subdirectory(modules)
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)
@@ -23,4 +24,3 @@
 if( CLANG_TOOLS_EXTRA_INCLUDE_DOCS )
   add_subdirectory(docs)
 endif()
-
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to