changeset 809:7e84472f4e91

Refactored the importgraph command.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Sun, 09 Mar 2008 16:39:46 +0100
parents 28e1ff1dcfcf
children 525ee3f848d9
files src/cmd/ImportGraph.d src/main.d
diffstat 2 files changed, 104 insertions(+), 87 deletions(-) [+]
line wrap: on
line diff
--- a/src/cmd/ImportGraph.d	Sun Mar 09 16:10:25 2008 +0100
+++ b/src/cmd/ImportGraph.d	Sun Mar 09 16:39:46 2008 +0100
@@ -20,19 +20,79 @@
 
 alias FileConst.PathSeparatorChar dirSep;
 
-/// Options for the importgraph command.
-enum IGraphOption
+/// The importgraph command.
+struct IGraphCommand
 {
-  None,
-  IncludeUnlocatableModules = 1,
-  PrintDot                  = 1<<1,
-  HighlightCyclicEdges      = 1<<2,
-  HighlightCyclicVertices   = 1<<3,
-  GroupByPackageNames       = 1<<4,
-  GroupByFullPackageName    = 1<<5,
-  PrintPaths                = 1<<6,
-  PrintList                 = 1<<7,
-  MarkCyclicModules         = 1<<8,
+  /// Options for the command.
+  enum Option
+  {
+    None,
+    IncludeUnlocatableModules = 1,
+    PrintDot                  = 1<<1,
+    HighlightCyclicEdges      = 1<<2,
+    HighlightCyclicVertices   = 1<<3,
+    GroupByPackageNames       = 1<<4,
+    GroupByFullPackageName    = 1<<5,
+    PrintPaths                = 1<<6,
+    PrintList                 = 1<<7,
+    MarkCyclicModules         = 1<<8,
+  }
+  alias Option Options;
+
+  Options options; /// Command options.
+  string filePath; /// File path to the root module.
+  string[] regexps; /// Regular expressions.
+  string siStyle = "dashed"; /// Static import style.
+  string piStyle = "bold";   /// Public import style.
+  uint levels; /// How many levels to print.
+
+  CompilationContext context;
+
+  /// Adds o to the options.
+  void add(Option o)
+  {
+    options |= o;
+  }
+
+  void run()
+  {
+    // Init regular expressions.
+    RegExp[] regexps;
+    foreach (strRegexp; this.regexps)
+      regexps ~= new RegExp(strRegexp);
+
+    // Add the directory of the file to the import paths.
+    auto filePath = new FilePath(this.filePath);
+    auto fileDir = filePath.folder();
+    context.importPaths ~= fileDir;
+
+    auto gbuilder = new GraphBuilder;
+
+    gbuilder.importPaths = context.importPaths;
+    gbuilder.options = options;
+    gbuilder.filterPredicate = (string moduleFQNPath) {
+      foreach (rx; regexps)
+        // Replace slashes: dil/ast/Node -> dil.ast.Node
+        if (rx.test(replace(moduleFQNPath.dup, dirSep, '.')))
+          return true;
+      return false;
+    };
+
+    auto graph = gbuilder.start(filePath.name());
+
+    if (options & (Option.PrintList | Option.PrintPaths))
+    {
+      if (options & Option.MarkCyclicModules)
+        graph.detectCycles();
+
+      if (options & Option.PrintPaths)
+        printModulePaths(graph.vertices, levels+1, "");
+      else
+        printModuleList(graph.vertices, levels+1, "");
+    }
+    else
+      printDotDocument(graph, siStyle, piStyle, options);
+  }
 }
 
 /// Represents a module dependency graph.
@@ -148,7 +208,7 @@
 class GraphBuilder
 {
   Graph graph;
-  IGraphOption options;
+  IGraphCommand.Options options;
   string[] importPaths; /// Where to look for modules.
   Vertex[string] loadedModulesTable; /// Maps FQN paths to modules.
   bool delegate(string) filterPredicate;
@@ -192,7 +252,7 @@
 
     if (moduleFilePath is null)
     { // Module not found.
-      if (options & IGraphOption.IncludeUnlocatableModules)
+      if (options & IGraphCommand.Option.IncludeUnlocatableModules)
       { // Include module nevertheless.
         vertex = new Vertex;
         vertex.modul = new Module("");
@@ -234,48 +294,6 @@
   }
 }
 
-/// Executes the importgraph command.
-void execute(string filePathString, CompilationContext context, string[] strRegexps,
-             uint levels, string siStyle, string piStyle, IGraphOption options)
-{
-  // Init regular expressions.
-  RegExp[] regexps;
-  foreach (strRegexp; strRegexps)
-    regexps ~= new RegExp(strRegexp);
-
-  // Add the directory of the file to the import paths.
-  auto filePath = new FilePath(filePathString);
-  auto fileDir = filePath.folder();
-  context.importPaths ~= fileDir;
-
-  auto gbuilder = new GraphBuilder;
-
-  gbuilder.importPaths = context.importPaths;
-  gbuilder.options = options;
-  gbuilder.filterPredicate = (string moduleFQNPath) {
-    foreach (rx; regexps)
-      // Replace slashes: dil/ast/Node -> dil.ast.Node
-      if (rx.test(replace(moduleFQNPath.dup, dirSep, '.')))
-        return true;
-    return false;
-  };
-
-  auto graph = gbuilder.start(filePath.name());
-
-  if (options & (IGraphOption.PrintList | IGraphOption.PrintPaths))
-  {
-    if (options & IGraphOption.MarkCyclicModules)
-      graph.detectCycles();
-
-    if (options & IGraphOption.PrintPaths)
-      printModulePaths(graph.vertices, levels+1, "");
-    else
-      printModuleList(graph.vertices, levels+1, "");
-  }
-  else
-    printDotDocument(graph, siStyle, piStyle, options);
-}
-
 /// Prints the file paths to the modules.
 void printModulePaths(Vertex[] vertices, uint level, char[] indent)
 {
@@ -304,15 +322,15 @@
 
 /// Prints the graph as a graphviz dot document.
 void printDotDocument(Graph graph, string siStyle, string piStyle,
-                      IGraphOption options)
+                      IGraphCommand.Options options)
 {
   Vertex[][string] verticesByPckgName;
-  if (options & IGraphOption.GroupByFullPackageName)
+  if (options & IGraphCommand.Option.GroupByFullPackageName)
     foreach (vertex; graph.vertices)
       verticesByPckgName[vertex.modul.packageName] ~= vertex;
 
-  if (options & (IGraphOption.HighlightCyclicVertices |
-                 IGraphOption.HighlightCyclicEdges))
+  if (options & (IGraphCommand.Option.HighlightCyclicVertices |
+                 IGraphCommand.Option.HighlightCyclicEdges))
     graph.detectCycles();
 
   // Output header of the dot document.
@@ -338,7 +356,7 @@
     Stdout.formatln(`  n{} -> n{} {};`, edge.from.id, edge.to.id, edgeStyles);
   }
 
-  if (options & IGraphOption.GroupByFullPackageName)
+  if (options & IGraphCommand.Option.GroupByFullPackageName)
     foreach (packageName, vertices; verticesByPckgName)
     { // Output nodes in a cluster.
       Stdout.format(`  subgraph "cluster_{}" {`\n`    label="{}";color=blue;`"\n    ", packageName, packageName);
--- a/src/main.d	Sun Mar 09 16:10:25 2008 +0100
+++ b/src/main.d	Sun Mar 09 16:39:46 2008 +0100
@@ -156,53 +156,52 @@
     infoMan.hasInfo && printErrors(infoMan);
     break;
   case "importgraph", "igraph":
-    string filePath;
-    string[] regexps;
-    string siStyle = "dashed"; // static import style
-    string piStyle = "bold";   // public import style
-    uint levels;
-    IGraphOption options;
-    auto context = newCompilationContext();
+    if (args.length < 3)
+      return printHelp("hl");
+
+    IGraphCommand cmd;
+    cmd.context = newCompilationContext();
+
     foreach (arg; args[2..$])
     {
-      if (parseDebugOrVersion(arg, context))
+      if (parseDebugOrVersion(arg, cmd.context))
       {}
       else if (strbeg(arg, "-I"))
-        context.importPaths ~= arg[2..$];
-      else if(strbeg(arg, "-r"))
-        regexps ~= arg[2..$];
+        cmd.context.importPaths ~= arg[2..$];
+      else if(strbeg(arg, "-x"))
+        cmd.regexps ~= arg[2..$];
       else if(strbeg(arg, "-l"))
-        levels = Integer.toInt(arg[2..$]);
+        cmd.levels = Integer.toInt(arg[2..$]);
       else if(strbeg(arg, "-si"))
-        siStyle = arg[3..$];
+        cmd.siStyle = arg[3..$];
       else if(strbeg(arg, "-pi"))
-        piStyle = arg[3..$];
+        cmd.piStyle = arg[3..$];
       else
         switch (arg)
         {
         case "--dot":
-          options |= IGraphOption.PrintDot; break;
+          cmd.add(IGraphCommand.Option.PrintDot); break;
         case "--paths":
-          options |= IGraphOption.PrintPaths; break;
+          cmd.add(IGraphCommand.Option.PrintPaths); break;
         case "--list":
-          options |= IGraphOption.PrintList; break;
+          cmd.add(IGraphCommand.Option.PrintList); break;
         case "-i":
-          options |= IGraphOption.IncludeUnlocatableModules; break;
+          cmd.add(IGraphCommand.Option.IncludeUnlocatableModules); break;
         case "-hle":
-          options |= IGraphOption.HighlightCyclicEdges; break;
+          cmd.add(IGraphCommand.Option.HighlightCyclicEdges); break;
         case "-hlv":
-          options |= IGraphOption.HighlightCyclicVertices; break;
+          cmd.add(IGraphCommand.Option.HighlightCyclicVertices); break;
         case "-gbp":
-          options |= IGraphOption.GroupByPackageNames; break;
+          cmd.add(IGraphCommand.Option.GroupByPackageNames); break;
         case "-gbf":
-          options |= IGraphOption.GroupByFullPackageName; break;
+          cmd.add(IGraphCommand.Option.GroupByFullPackageName); break;
         case "-m":
-          options |= IGraphOption.MarkCyclicModules; break;
+          cmd.add(IGraphCommand.Option.MarkCyclicModules); break;
         default:
-          filePath = arg;
+          cmd.filePath = arg;
         }
     }
-    cmd.ImportGraph.execute(filePath, context, regexps, levels, siStyle, piStyle, options);
+    cmd.run();
     break;
   case "stats", "statistics":
     char[][] filePaths;
@@ -503,7 +502,7 @@
 Options:
   -Ipath           : add 'path' to the list of import paths where modules are
                      looked for
-  -rREGEXP         : exclude modules whose names match the regular expression
+  -xREGEXP         : exclude modules whose names match the regular expression
                      REGEXP
   -i               : include unlocatable modules