changeset 733:a48255f547c1

Merged.
author Jari-Matti M?kel? <jmjm@iki.fi>
date Sun, 03 Feb 2008 21:39:42 +0200
parents 231c9a44ba8e (current diff) ca7607226caa (diff)
children b11d46260909
files
diffstat 6 files changed, 172 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trunk/src/cmd/DDoc.d	Sun Feb 03 21:39:42 2008 +0200
@@ -0,0 +1,94 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module cmd.DDoc;
+
+import dil.doc.Parser;
+import dil.doc.Macro;
+import dil.doc.Doc;
+import dil.ast.DefaultVisitor;
+import dil.semantic.Module;
+import dil.semantic.Pass1;
+import dil.semantic.Symbol;
+import dil.semantic.Symbols;
+import dil.Information;
+import dil.File;
+import common;
+
+import tango.stdc.time : time_t, time, ctime;
+import tango.stdc.string : strlen;
+
+void execute(string[] filePaths, string destDir, string[] macroPaths,
+             bool incUndoc, InfoManager infoMan)
+{
+  // Parse macro files.
+  MacroTable mtable;
+  MacroParser mparser;
+  foreach (macroPath; macroPaths)
+  {
+    auto macros = mparser.parse(loadFile(macroPath));
+    mtable = new MacroTable(mtable);
+    mtable.insert(macros);
+  }
+
+//   foreach (k, v; mtable.table)
+//     Stdout(k)("=")(v.text);
+
+  Module[] modules;
+  foreach (filePath; filePaths)
+  {
+    auto mod = new Module(filePath, infoMan);
+    modules ~= mod;
+    // Parse the file.
+    mod.parse();
+    if (mod.hasErrors)
+      continue;
+
+    // Start semantic analysis.
+    auto pass1 = new SemanticPass1(mod);
+    pass1.start();
+  }
+
+  foreach (mod; modules)
+    generateDocumentation(mod, mtable);
+}
+
+void generateDocumentation(Module mod, MacroTable mtable)
+{
+  // Create a macro environment for this module.
+  mtable = new MacroTable(mtable);
+  // Define runtime macros.
+  mtable.insert(new Macro("TITLE", mod.getFQN()));
+  mtable.insert(new Macro("DOCFILENAME", mod.getFQN()));
+
+  time_t time_val;
+  time(&time_val);
+  char* str = ctime(&time_val);
+  char[] time_str = str[0 .. strlen(str)];
+  mtable.insert(new Macro("DATETIME", time_str.dup));
+  mtable.insert(new Macro("YEAR", time_str[20..24].dup));
+
+  if (mod.moduleDecl)
+  {
+    auto ddocComment = getDDocComment(mod.moduleDecl);
+    if (auto copyright = ddocComment.getCopyright())
+      mtable.insert(new Macro("COPYRIGHT", copyright.text));
+  }
+
+  auto docEmitter = new DDocEmitter();
+  docEmitter.emit(mod);
+
+  mtable.insert(new Macro("BODY", docEmitter.text));
+  expandMacros(mtable, "$(DDOC)");
+}
+
+class DDocEmitter : DefaultVisitor
+{
+  char[] text;
+
+  char[] emit(Module mod)
+  {
+    return text;
+  }
+}
--- a/trunk/src/dil/SettingsLoader.d	Sun Feb 03 21:38:40 2008 +0200
+++ b/trunk/src/dil/SettingsLoader.d	Sun Feb 03 21:39:42 2008 +0200
@@ -57,7 +57,7 @@
       {
         foreach (value; array.values)
           if (auto str = value.Is!(StringExpression))
-            GlobalSettings.ddocFilePaths ~= str.getString();
+            GlobalSettings.ddocFilePaths ~= resolvePath(execPath, str.getString());
       }
       else
         throw new Exception("import_paths variable is set to "~e.classinfo.name~" instead of an ArrayInitializer.");
--- a/trunk/src/dil/ast/Visitor.d	Sun Feb 03 21:38:40 2008 +0200
+++ b/trunk/src/dil/ast/Visitor.d	Sun Feb 03 21:39:42 2008 +0200
@@ -45,17 +45,19 @@
 }
 
 /++
-  Generate functions which do the second dispatch.
-  E.g.:
-    Expression visitCommaExpression(Visitor visitor, CommaExpression c)
-    { visitor.visit(c); }
+  Generate functions which do the second dispatch.$(BR)
+  E.g.:$(BR)
+    $(D_CODE
+Expression visitCommaExpression(Visitor visitor, CommaExpression c)
+{ visitor.visit(c); })
 
-  The equivalent in the traditional visitor pattern would be:
-    class CommaExpression : Expression
-    {
-      void accept(Visitor visitor)
-      { visitor.visit(this); }
-    }
+  The equivalent in the traditional visitor pattern would be:$(BR)
+    $(D_CODE
+class CommaExpression : Expression
+{
+  void accept(Visitor visitor)
+  { visitor.visit(this); }
+})
 +/
 char[] generateDispatchFunctions()
 {
@@ -79,6 +81,7 @@
 }
 // pragma(msg, generateVTable());
 
+/// The visitor pattern.
 abstract class Visitor
 {
   mixin(generateVisitMethods());
--- a/trunk/src/dil/doc/Doc.d	Sun Feb 03 21:38:40 2008 +0200
+++ b/trunk/src/dil/doc/Doc.d	Sun Feb 03 21:39:42 2008 +0200
@@ -10,6 +10,8 @@
 import dil.Unicode;
 import common;
 
+import tango.text.Ascii : toLower;
+
 class DDocComment
 {
   Section[] sections;
@@ -22,6 +24,22 @@
     this.summary = summary;
     this.description = description;
   }
+
+  Section getCopyright()
+  {
+    foreach (section; sections)
+      if (toLower(section.name) == "copyright")
+        return section;
+    return null;
+  }
+}
+
+/// Returns a node's DDocComment.
+DDocComment getDDocComment(Node node)
+{
+  DDocParser p;
+  p.parse(getDDocText(getDocTokens(node)));
+  return new DDocComment(p.sections, p.summary, p.description);
 }
 
 struct DDocParser
@@ -171,8 +189,8 @@
 
 class MacrosSection : Section
 {
-  string[] macroNames; /// Parameter names.
-  string[] macroTexts; /// Parameter descriptions.
+  string[] macroNames; /// Macro names.
+  string[] macroTexts; /// Macro texts.
   this(string name, string text)
   {
     super(name, text);
--- a/trunk/src/dil/doc/Macro.d	Sun Feb 03 21:38:40 2008 +0200
+++ b/trunk/src/dil/doc/Macro.d	Sun Feb 03 21:39:42 2008 +0200
@@ -151,6 +151,8 @@
     switch (*p)
     {
     case ',':
+      if (level != 1) // Ignore comma if inside ().
+        break;
       // Add a new argument.
       args ~= makeString(argBegin, p);
       while (++p < textEnd && isspace(*p))
--- a/trunk/src/main.d	Sun Feb 03 21:38:40 2008 +0200
+++ b/trunk/src/main.d	Sun Feb 03 21:39:42 2008 +0200
@@ -28,12 +28,14 @@
 import cmd.Generate;
 import cmd.Statistics;
 import cmd.ImportGraph;
+import cmd.DDoc;
 import common;
 
 import Integer = tango.text.convert.Integer;
 import tango.io.File;
 import tango.text.Util;
 import tango.time.StopWatch;
+import tango.text.Ascii : toLower;
 
 void main(char[][] args)
 {
@@ -82,6 +84,31 @@
 
     printErrors(infoMan);
     break;
+  case "ddoc", "d":
+    if (args.length < 4)
+      return printHelp("ddoc");
+
+    auto destination = args[2];
+    auto macroPaths = GlobalSettings.ddocFilePaths;
+    char[][] filePaths;
+    bool incUndoc;
+    // Parse arguments.
+    foreach (arg; args[3..$])
+    {
+      if (arg == "-i")
+        incUndoc = true;
+      else if (arg.length > 5 && toLower(arg[$-4..$]) == "ddoc")
+        macroPaths ~= arg;
+      else
+        filePaths ~= arg;
+    }
+
+    auto infoMan = new InfoManager();
+    // Execute command.
+    cmd.DDoc.execute(filePaths, destination, macroPaths, incUndoc, infoMan);
+    if (infoMan.info.length)
+      return printErrors(infoMan);
+    break;
   case "gen", "generate":
     char[] fileName;
     DocOption options = DocOption.Tokens;
@@ -252,6 +279,7 @@
 
 const char[] COMMANDS =
   "  compile (c)\n"
+  "  ddoc (d)\n"
   "  generate (gen)\n"
   "  help (?)\n"
   "  importgraph (igraph)\n"
@@ -310,6 +338,20 @@
 Example:
   dil c src/main.d";
     break;
+  case "ddoc", "d":
+    msg = `Generate documentation from DDoc comments in D source files.
+Usage:
+  dil ddoc Destination file.d [file2.d, ...] [Options]
+
+  Destination is the folder where the documentation files are written to.
+  Files with the extension .ddoc are recognized as macro definition files.
+
+Options:
+  -i               : include undocumented symbols
+
+Example:
+  dil d doc/ src/main.d mymacros.ddoc -i`;
+    break;
   case "gen", "generate":
     msg = GetMsg(MID.HelpGenerate);
     break;