changeset 462:b7503e02fbe7

Docgen code for handling public imports.
author Jari-Matti M?kel? <jmjm@iki.fi>
date Tue, 30 Oct 2007 20:52:29 +0200
parents c78a54b2617c
children 12b4ba9248a7
files trunk/src/docgen/config/configurator.d trunk/src/docgen/config/default.cfg trunk/src/docgen/docgen.d trunk/src/docgen/document/generator.d trunk/src/docgen/graphutils/dotwriter.d trunk/src/docgen/graphutils/primitives.d trunk/src/docgen/graphutils/writer.d trunk/src/docgen/misc/misc.d trunk/src/docgen/misc/parser.d trunk/src/docgen/tests/graphs.d trunk/src/docgen/tests/listing.d trunk/src/docgen/tests/parse.d
diffstat 12 files changed, 94 insertions(+), 200 deletions(-) [+]
line wrap: on
line diff
--- a/trunk/src/docgen/config/configurator.d	Tue Oct 30 18:17:14 2007 +0100
+++ b/trunk/src/docgen/config/configurator.d	Tue Oct 30 20:52:29 2007 +0200
@@ -127,6 +127,9 @@
         _parseS("options.graph.nodeColor") ~
         _parseS("options.graph.cyclicNodeColor") ~
         _parseS("options.graph.unlocatableNodeColor") ~
+        _parseS("options.graph.depColor") ~
+        _parseS("options.graph.cyclicDepColor") ~
+        _parseS("options.graph.publicDepColor") ~
         _parseS("options.graph.clusterColor") ~
         _parseB("options.graph.includeUnlocatableModules") ~
         _parseB("options.graph.highlightCyclicEdges") ~
@@ -148,6 +151,7 @@
             "Doxygen", "CommentFormat.Doxygen",
             "Ddoc", "CommentFormat.Ddoc"
         ) ~
+        _parseI("options.parser.depth") ~
         _parseEnumList!("options.outputFormats",
             "LaTeX", "DocFormat.LaTeX",
             "HTML", "DocFormat.HTML",
--- a/trunk/src/docgen/config/default.cfg	Tue Oct 30 18:17:14 2007 +0100
+++ b/trunk/src/docgen/config/default.cfg	Tue Oct 30 20:52:29 2007 +0200
@@ -2,9 +2,12 @@
   (graph
     (imageFormat PDF)
     (depth -1)
-    (nodeColor tomato)
-    (cyclicNodeColor red)
+    (nodeColor white)
+    (cyclicNodeColor tomato)
     (unlocatableNodeColor gray)
+    (depColor black)
+    (cyclicDepColor red)
+    (publicDepColor blue)
     (clusterColor blue)
     (includeUnlocatableModules false)
     (highlightCyclicEdges true)
@@ -29,7 +32,8 @@
     (rootPaths)
     (strRegexps)
     (commentFormat Doxygen)
+    (depth -1)
   )
-  (outputFormats LaTeX LaTeX)
+  (outputFormats LaTeX)
   (outputDir tmp/)
 )
--- a/trunk/src/docgen/docgen.d	Tue Oct 30 18:17:14 2007 +0100
+++ b/trunk/src/docgen/docgen.d	Tue Oct 30 20:52:29 2007 +0200
@@ -4,159 +4,16 @@
  */
 module docgen.docgen;
 
-import docgen.document.generator;
-
-import docgen.sourcelisting.writers;
-import docgen.page.writers;
 import docgen.graphutils.writers;
-import docgen.misc.misc;
-import docgen.misc.parser;
 import docgen.config.configurator;
-import tango.core.Array;
-import tango.io.stream.FileStream;
-import tango.text.Ascii;
-import tango.text.Util : replace;
-import tango.io.FilePath;
-
-import tango.io.Stdout;
-
-
-class HTMLDocGenerator : DefaultDocGenerator!("html") {
-  this(DocGeneratorOptions options, ParserDg parser) {
-    super(options, parser);
-  }
-  public void generate() { /* TODO */ }
-}
-class XMLDocGenerator : DefaultDocGenerator!("xml") {
-  this(DocGeneratorOptions options, ParserDg parser) {
-    super(options, parser);
-  }
-  public void generate() { /* TODO */ }
-}
-class PlainTextDocGenerator : DefaultDocGenerator!("txt") {
-  this(DocGeneratorOptions options, ParserDg parser) {
-    super(options, parser);
-  }
-  public void generate() { /* TODO */ }
-}
-
-/**
- * Main routine for LaTeX doc generation.
- */
-class LaTeXDocGenerator : DefaultCachingDocGenerator!("latex") {
-  this(DocGeneratorOptions options, ParserDg parser, GraphCache graphcache) {
-    super(options, parser, graphcache);
-  }
-
-  /**
-   * Generates document skeleton.
-   */
-  void generateDoc(char[] docFileName) {
-    auto docFile = new FileOutput(outPath(docFileName));
-    docWriter = pageFactory.createPageWriter( [ docFile ], DocFormat.LaTeX );
-
-    docWriter.generateFirstPage();
-    docWriter.generateTOC(modules);
-    docWriter.generateModuleSection();
-    docWriter.generateListingSection();
-    docWriter.generateDepGraphSection();
-    docWriter.generateIndexSection();
-    docWriter.generateLastPage();
-
-    docFile.close();
-  }
-
-  /**
-   * Generates D language definition file.
-   */
-  void generateLangDef() {
-    auto docFile = new FileOutput(outPath("lstlang0.sty"));
-    docWriter.setOutput([docFile]);
-
-    docWriter.generateLangDef();
-
-    docFile.close();
-  }
+import docgen.document.latexgenerator;
+import docgen.document.htmlgenerator;
+import docgen.document.xmlgenerator;
+import docgen.document.plaintextgenerator;
 
-  /**
-   * Generates "makefile" for processing the .dot and .tex files.
-   */
-  void generateMakeFile() {
-    auto docFile = new FileOutput(outPath("make.sh"));
-    docWriter.setOutput([docFile]);
-
-    docWriter.generateMakeFile();
-
-    docFile.close();
-  }
-
-  /**
-   * Generates documentation for modules.
-   */
-  void generateModules(char[] modulesFile) {
-    auto docFile = new FileOutput(outPath(modulesFile));
-    docFile.close();
-  }
-
-  /**
-   * Generates source file listings.
-   */
-  void generateListings(char[] listingsFile) {
-    auto dlwf = new DefaultListingWriterFactory(this);
-    auto docFile = new FileOutput(outPath(listingsFile));
-    docWriter.setOutput([docFile]);
-    auto writer = dlwf.createListingWriter(docWriter, DocFormat.LaTeX);
-
-
-    foreach(mod; modules) {
-      auto dstFname = replace(mod.moduleFQN.dup, '.', '_') ~ ".d";
-      
-      auto srcFile = new FileInput(mod.filePath);
-      auto dstFile = new FileOutput(outPath(dstFname));
-      
-      writer.generateListing(srcFile, dstFile, mod.moduleFQN);
-
-      srcFile.close();
-      dstFile.close();
-    }
-    
-    docFile.close();
-  }
-
-  /**
-   * Generates dependency graphs.
-   */
-  void generateDependencies(char[] depGraphTexFile, char[] depGraphFile) {
-    auto docFile = new FileOutput(outPath(depGraphTexFile));
-    docWriter.setOutput([docFile]);
-
-    createDepGraph(depGraphFile);
-
-    docFile.close();
-  }
-
-  public void generate() {
-    auto docFileName = "document.tex";
-    auto depGraphTexFile = "dependencies.tex";
-    auto depGraphFile = "depgraph.dot";
-    auto listingFile = "files.tex";
-    auto modulesFile = "modules.tex";
-
-    parseSources();
-
-    generateDoc(docFileName);
-
-    if (options.listing.enableListings)
-      generateListings(listingFile);
-
-    generateModules(modulesFile);
-
-    generateDependencies(depGraphTexFile, depGraphFile);
-
-    generateLangDef();
-    generateMakeFile();
-  }
-}
+import tango.core.Array;
+import tango.text.Ascii;
+import tango.io.Stdout;
 
 void usage() {
   Stdout(
@@ -198,7 +55,7 @@
       options.parser.importPaths,
       options.parser.strRegexps,
       options.graph.includeUnlocatableModules,
-      options.graph.depth,
+      options.parser.depth,
       (char[] fqn, char[] path, Module m) {
         if (m is null) {
           if (fqn in vertices) {
@@ -216,9 +73,12 @@
           debug Stdout.format("Setting {} = {}.\n", m.moduleFQN, m.filePath);
         }
       },
-      (Module imported, Module importer) {
+      (Module imported, Module importer, bool isPublic) {
         debug Stdout.format("Connecting {} - {}.\n", imported.moduleFQN, importer.moduleFQN);
-        edges ~= vertices[imported.moduleFQN].addChild(vertices[importer.moduleFQN]);
+        auto edge = vertices[imported.moduleFQN].addChild(vertices[importer.moduleFQN]);
+        edge.type = isPublic ? EdgeType.PublicDependency : EdgeType.Dependency;
+        edge.type = id % 2 ? EdgeType.PublicDependency : EdgeType.Dependency; // FIXME: temporary feature for demonstrating public imports
+        edges ~= edge;
       },
       modules
     );
--- a/trunk/src/docgen/document/generator.d	Tue Oct 30 18:17:14 2007 +0100
+++ b/trunk/src/docgen/document/generator.d	Tue Oct 30 20:52:29 2007 +0200
@@ -1,3 +1,7 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
 module docgen.document.generator;
 
 import docgen.sourcelisting.writers;
@@ -6,10 +10,7 @@
 import docgen.misc.misc;
 import docgen.misc.parser;
 import docgen.config.configurator;
-import tango.core.Array;
 import tango.io.stream.FileStream;
-import tango.text.Ascii;
-import tango.text.Util : replace;
 import tango.io.FilePath;
 debug import tango.io.Stdout;
 
@@ -23,6 +24,7 @@
 
     GraphWriterFactory graphFactory;
     PageWriterFactory pageFactory;
+    DefaultListingWriterFactory listingFactory;
     
     Module[] modules;
     Edge[] edges;
@@ -34,6 +36,7 @@
 
       createGraphWriterFactory();
       createPageWriterFactory();
+      createListingWriterFactory();
 
       // create output dir
       (new FilePath(options.outputDir ~ "/" ~ genDir)).create();
@@ -47,6 +50,10 @@
       pageFactory = new DefaultPageWriterFactory(this);
     }
 
+    protected void createListingWriterFactory() {
+      listingFactory = new DefaultListingWriterFactory(this);
+    }
+
     protected char[] outPath(char[] file) {
       return options.outputDir ~ "/" ~ genDir ~ "/" ~ file;
     }
--- a/trunk/src/docgen/graphutils/dotwriter.d	Tue Oct 30 18:17:14 2007 +0100
+++ b/trunk/src/docgen/graphutils/dotwriter.d	Tue Oct 30 20:52:29 2007 +0200
@@ -50,25 +50,27 @@
         module_.name;
 
       image ~= sprint.format(
-        `  n{0} [label="{1}"{2}];`\n,
+        `  n{} [label="{}",style=filled,fillcolor={}];`\n,
         module_.id,
         nodeName,
-        (module_.isCyclic && factory.options.graph.highlightCyclicVertices ?
-          ",style=filled,fillcolor=" ~ factory.options.graph.nodeColor :
-          (module_.type == VertexType.UnlocatableModule ?
-            ",style=filled,fillcolor=" ~ factory.options.graph.unlocatableNodeColor :
-            ""
-          )
-        )
+        module_.isCyclic && factory.options.graph.highlightCyclicVertices ?
+          factory.options.graph.cyclicNodeColor :
+        module_.type == VertexType.UnlocatableModule ?
+          factory.options.graph.unlocatableNodeColor :
+          factory.options.graph.nodeColor
       );
     }
 
     foreach (edge; edges)
       image ~= sprint.format(
-        `  n{0} -> n{1}{2};`\n,
+        `  n{} -> n{}[color={}];`\n,
         edge.outgoing.id,
         edge.incoming.id,
-        (edge.isCyclic ? "[color=" ~ factory.options.graph.cyclicNodeColor ~ "]" : "")
+        edge.isCyclic ?
+          factory.options.graph.cyclicDepColor :
+        edge.type == EdgeType.PublicDependency ?
+          factory.options.graph.publicDepColor ~ ",style=bold" :
+          factory.options.graph.depColor
       );
 
     if (factory.options.graph.groupByPackageNames)
--- a/trunk/src/docgen/graphutils/primitives.d	Tue Oct 30 18:17:14 2007 +0100
+++ b/trunk/src/docgen/graphutils/primitives.d	Tue Oct 30 20:52:29 2007 +0200
@@ -9,17 +9,24 @@
   Aggregation,
   Association,
   Composition,
-  CyclicDependency,
   Dependency,
   Generalization,
   Inheritance,
-  Reserved // for the cycle algorithm
+  PublicDependency
+}
+
+enum CycleType {
+  Unspecified,
+  Cyclefree,
+  Cyclic,
+  Reserved
 }
 
 class Edge {
   Vertex outgoing;
   Vertex incoming;
   EdgeType type;
+  CycleType cycleType; // used by the cycle algorithm
 
   this(Vertex o, Vertex i, EdgeType type = EdgeType.Unspecified) {
     this.outgoing = o;
@@ -28,7 +35,7 @@
   }
 
   bool isCyclic() {
-    return type == EdgeType.CyclicDependency;
+    return cycleType == CycleType.Cyclic;
   }
 }
 
--- a/trunk/src/docgen/graphutils/writer.d	Tue Oct 30 18:17:14 2007 +0100
+++ b/trunk/src/docgen/graphutils/writer.d	Tue Oct 30 20:52:29 2007 +0200
@@ -33,36 +33,36 @@
   }
 
   bool visit(Edge edge) {
-    if (edge.type == EdgeType.Reserved) {
-      edge.type = EdgeType.CyclicDependency;
+    if (edge.cycleType == CycleType.Reserved) {
+      edge.cycleType = CycleType.Cyclic;
       version(VerboseDebug) p();
       return true;
     }
 
     bool wasCyclic = edge.isCyclic();
-    edge.type = EdgeType.Reserved;
+    edge.cycleType = CycleType.Reserved;
     version(VerboseDebug) p();
 
     foreach(edge2; edge.incoming.outgoingEdges)
       if (visit(edge2)) {
         if (edge.isCyclic()) {
-          edge.type = EdgeType.Reserved;
+          edge.cycleType = CycleType.Reserved;
           wasCyclic = true;
           version(VerboseDebug) p();
           continue;
         }
-        edge.type = EdgeType.CyclicDependency;
+        edge.cycleType = CycleType.Cyclic;
         return true;
       }
 
-    edge.type = wasCyclic ? EdgeType.CyclicDependency : EdgeType.Dependency;
+    edge.cycleType = wasCyclic ? CycleType.Cyclic : CycleType.Cyclefree;
     version(VerboseDebug) p();
     return false;
   }
 
   foreach(vertex; vertices)
     foreach(edge; vertex.outgoingEdges)
-      if (edge.type == EdgeType.Unspecified) {
+      if (edge.cycleType == CycleType.Unspecified) {
         visit(edge);
         debug Stderr("*\n");
       }
--- a/trunk/src/docgen/misc/misc.d	Tue Oct 30 18:17:14 2007 +0100
+++ b/trunk/src/docgen/misc/misc.d	Tue Oct 30 20:52:29 2007 +0200
@@ -55,6 +55,12 @@
   char[] cyclicNodeColor;
   /// unlocatable module color
   char[] unlocatableNodeColor;
+  /// color of the dependencies
+  char[] depColor;
+  /// color of the dependencies in cyclic dep relation
+  char[] cyclicDepColor;
+  /// color of the public dependencies
+  char[] publicDepColor;
   /// package color
   char[] clusterColor;
   /// include unlocatable modules to the dep graph
@@ -100,6 +106,8 @@
   char[][] strRegexps;
   /// comment format [comment parser]
   CommentFormat commentFormat;
+  /// maximum depth of dependencies
+  uint depth;
 }
 
 struct DocGeneratorOptions {
--- a/trunk/src/docgen/misc/parser.d	Tue Oct 30 18:17:14 2007 +0100
+++ b/trunk/src/docgen/misc/parser.d	Tue Oct 30 20:52:29 2007 +0200
@@ -12,6 +12,9 @@
 import tango.text.Util;
 debug import tango.io.Stdout;
 
+alias void delegate (char[] fqn, char[] path, Module module_) modDg;
+alias void delegate (Module imported, Module importer, bool isPublic) importDg;
+
 class Parser {
   private static char[] findModulePath(char[] moduleFQN, char[][] importPaths) {
     char[] modulePath;
@@ -50,9 +53,7 @@
    */
   public static void loadModules(char[] filePath, char[][] importPaths, char[][] strRegexps,
                                  bool IncludeUnlocatableModules, int recursionDepth,
-                                 void delegate (char[] fqn, char[] path, Module) mdg,
-                                 void delegate (Module imported, Module importer) idg,
-                                 out Module[] modules) {
+                                 modDg mdg, importDg idg, out Module[] modules) {
 
     loadModules([filePath], importPaths, strRegexps, IncludeUnlocatableModules,
       recursionDepth, mdg, idg, modules);
@@ -77,9 +78,7 @@
    */
   public static void loadModules(char[][] filePaths, char[][] importPaths, char[][] strRegexps,
                                  bool IncludeUnlocatableModules, int recursionDepth,
-                                 void delegate (char[] fqn, char[] path, Module) mdg,
-                                 void delegate (Module imported, Module importer) idg,
-                                 out Module[] modules) {
+                                 modDg mdg, importDg idg, out Module[] modules) {
     // Initialize regular expressions.
     RegExp[] regexps;
     foreach (strRegexp; strRegexps)
@@ -137,20 +136,21 @@
 
         mdg(FQN, moduleFQNPath, mod);
 
-        auto moduleFQNs = mod.getImports();
+        auto imports = mod.imports;
 
         // TODO: add public/private attribute to the dg parameters 
-        foreach (moduleFQN_; moduleFQNs) {
-          auto loaded_mod = loadModule(moduleFQN_, depth == -1 ? depth : depth-1);
+        foreach (importList; imports)
+          foreach(moduleFQN_; importList.getModuleFQNs(dirSep)) {
+            auto loaded_mod = loadModule(moduleFQN_, depth == -1 ? depth : depth-1);
 
-          if (loaded_mod !is null) {
-            idg(loaded_mod, mod);
-          } else if (IncludeUnlocatableModules) {
-            auto tmp = new Module(null, true);
-            tmp.moduleFQN = replace(moduleFQN_.dup, dirSep, '.');
-            idg(tmp, mod);
+            if (loaded_mod !is null) {
+              idg(loaded_mod, mod, importList.isPublic());
+            } else if (IncludeUnlocatableModules) {
+              auto tmp = new Module(null, true);
+              tmp.moduleFQN = replace(moduleFQN_.dup, dirSep, '.');
+              idg(tmp, mod, importList.isPublic());
+            }
           }
-        }
       }
 
       return mod;
--- a/trunk/src/docgen/tests/graphs.d	Tue Oct 30 18:17:14 2007 +0100
+++ b/trunk/src/docgen/tests/graphs.d	Tue Oct 30 20:52:29 2007 +0200
@@ -130,8 +130,10 @@
     (char[] fqn, char[] path, Module m) {
       vertices[m.moduleFQN] = new Vertex(m.moduleFQN, m.filePath, id++);
     },
-    (Module imported, Module importer) {
-      edges ~= vertices[imported.moduleFQN].addChild(vertices[importer.moduleFQN]);
+    (Module imported, Module importer, bool isPublic) {
+      auto edge = vertices[imported.moduleFQN].addChild(vertices[importer.moduleFQN]);
+      edge.type = isPublic ? EdgeType.PublicDependency : EdgeType.Dependency;
+      edges ~= edge;
     },
     modules
   );
--- a/trunk/src/docgen/tests/listing.d	Tue Oct 30 18:17:14 2007 +0100
+++ b/trunk/src/docgen/tests/listing.d	Tue Oct 30 20:52:29 2007 +0200
@@ -29,7 +29,7 @@
     [ "c" ], [ "docgen/teststuff/" ],
     null, true, -1,
     (char[] fqn, char[] path, Module m) {},
-    (Module imported, Module importer) {},
+    (Module imported, Module importer, bool isPublic) {},
     modules
   );
   
--- a/trunk/src/docgen/tests/parse.d	Tue Oct 30 18:17:14 2007 +0100
+++ b/trunk/src/docgen/tests/parse.d	Tue Oct 30 20:52:29 2007 +0200
@@ -30,7 +30,7 @@
       (char[] fqn, char[] path, Module m) {
         file.format("{0} = {1}\n", fqn, path);
       },
-      (Module imported, Module importer) {
+      (Module imported, Module importer, bool isPublic) {
         file.format("{0} <- {1}\n",
           imported ? imported.moduleFQN : "null"[],
           importer ? importer.moduleFQN : "null"[]
@@ -53,7 +53,7 @@
       (char[] fqn, char[] path, Module m) {
         file.format("{0} = {1}\n", fqn, path);
       },
-      (Module imported, Module importer) {
+      (Module imported, Module importer, bool isPublic) {
         file.format("{0} <- {1}\n",
           imported ? imported.moduleFQN : "null"[],
           importer ? importer.moduleFQN : "null"[]