changeset 799:fd719161e743

New ddoc emitter for XML type output.
author Jari-Matti M?kel? <jmjm@iki.fi>
date Sat, 01 Mar 2008 18:04:29 +0200
parents c24be8d4f6ab
children dcd30b0ba711
files trunk/dsss.conf trunk/src/cmd/DDoc.d trunk/src/cmd/DDocXML.d trunk/src/config.d trunk/src/predefined.ddoc trunk/src/predefined_xml.ddoc
diffstat 6 files changed, 481 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/trunk/dsss.conf	Sat Mar 01 02:53:06 2008 +0100
+++ b/trunk/dsss.conf	Sat Mar 01 18:04:29 2008 +0200
@@ -4,7 +4,7 @@
 type = binary
 target = dil
 version(GNU) {
-  buildflags = -Isrc/ -Ldsss_objs/G/cmd.DDoc.o
+  buildflags = -Isrc/ -Ldsss_objs/G/cmd.DDoc.o -Ldsss_objs/G/cmd.DDocXML.o
 } else {
   buildflags = -Isrc/
 }
--- a/trunk/src/cmd/DDoc.d	Sat Mar 01 02:53:06 2008 +0100
+++ b/trunk/src/cmd/DDoc.d	Sat Mar 01 18:04:29 2008 +0200
@@ -4,6 +4,7 @@
 +/
 module cmd.DDoc;
 
+import cmd.DDocXML;
 import cmd.Generate;
 import dil.doc.Parser;
 import dil.doc.Macro;
@@ -98,7 +99,7 @@
   mtable.insert("DATETIME", timeStr);
   mtable.insert("YEAR", Time.year(timeStr));
 
-  auto doc = new DDocEmitter(mod, mtable, incUndoc, tokenHL);
+  auto doc = new DDocXMLEmitter(mod, mtable, incUndoc, tokenHL);
   doc.emit();
   // Set BODY macro to the text produced by the DDocEmitter.
   mtable.insert("BODY", doc.text);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trunk/src/cmd/DDocXML.d	Sat Mar 01 18:04:29 2008 +0200
@@ -0,0 +1,378 @@
+/++
+  Author: Aziz Köksal & Jari-Matti Mäkelä
+  License: GPL3
++/
+module cmd.DDocXML;
+
+import cmd.DDoc;
+import cmd.Generate;
+import dil.doc.Parser;
+import dil.doc.Macro;
+import dil.doc.Doc;
+import dil.ast.Node;
+import dil.ast.Declarations,
+       dil.ast.Statements,
+       dil.ast.Expression,
+       dil.ast.Parameters,
+       dil.ast.Types;
+import dil.ast.DefaultVisitor;
+import dil.lexer.Token;
+import dil.lexer.Funcs;
+import dil.semantic.Module;
+import dil.semantic.Pass1;
+import dil.semantic.Symbol;
+import dil.semantic.Symbols;
+import dil.Compilation;
+import dil.Information;
+import dil.Converter;
+import dil.SourceText;
+import dil.Enums;
+import dil.Time;
+import common;
+
+import tango.text.Ascii : toUpper;
+import tango.io.File;
+import tango.io.FilePath;
+
+/// Traverses the syntax tree and writes DDoc macros to a string buffer.
+class DDocXMLEmitter : DDocEmitter
+{
+  this(Module modul, MacroTable mtable, bool includeUndocumented,
+       TokenHighlighter tokenHL)
+  {
+    super(modul, mtable, includeUndocumented, tokenHL);
+  }
+
+  /// Writes params to the text buffer.
+  void writeParams(Parameters params)
+  {
+    if (!params.items.length)
+      return;
+
+    write("$(PARAMS ");
+    auto lastParam = params.items[$-1];
+    foreach (param; params.items)
+    {
+      if (param.isCVariadic)
+        write("...");
+      else
+      {
+        assert(param.type);
+        // Write storage classes.
+        auto typeBegin = param.type.baseType.begin;
+        if (typeBegin !is param.begin) // Write storage classes.
+          write(textSpan(param.begin, typeBegin.prevNWS), " ");
+        write(escape(textSpan(typeBegin, param.type.end))); // Write type.
+        if (param.name)
+          write(" $(DDOC_PARAM ", param.name.str, ")");
+        if (param.isDVariadic)
+          write("...");
+        if (param.defValue)
+          write(" = ", escape(textSpan(param.defValue.begin, param.defValue.end)));
+      }
+      if (param !is lastParam)
+        write(", ");
+    }
+    write(")");
+  }
+
+  /// Writes the current template parameters to the text buffer.
+  void writeTemplateParams()
+  {
+    if (!tparams)
+      return;
+    write("$(TEMPLATE_PARAMS ", escape(textSpan(tparams.begin, tparams.end))[1..$-1], ")");
+    tparams = null;
+  }
+
+  /// Writes bases to the text buffer.
+  void writeInheritanceList(BaseClassType[] bases)
+  {
+    if (bases.length == 0)
+      return;
+    auto basesBegin = bases[0].begin.prevNWS;
+    if (basesBegin.kind == TOK.Colon)
+      basesBegin = bases[0].begin;
+    write("$(PARENTS ", escape(textSpan(basesBegin, bases[$-1].end)), ")");
+  }
+
+  /// Writes a symbol to the text buffer. E.g: $&#40;SYMBOL Buffer, 123&#41;
+  void SYMBOL(char[] name, Declaration d)
+  {
+    auto loc = d.begin.getRealLocation();
+    auto str = Format("$(SYMBOL {}, {})", name, loc.lineNum);
+    write(str);
+    // write("$(DDOC_PSYMBOL ", name, ")");
+  }
+
+  /// Writes a declaration to the text buffer.
+  void DECL(void delegate() dg, Declaration d, bool writeSemicolon = true)
+  {
+    if (cmntIsDitto)
+    { alias prevDeclOffset offs;
+      assert(offs != 0);
+      auto savedText = text;
+      text = "";
+      write("\n$(DDOC_DECL ");
+      dg();
+      writeAttributes(d);
+      write(")");
+      // Insert text at offset.
+      auto len = text.length;
+      text = savedText[0..offs] ~ text ~ savedText[offs..$];
+      offs += len; // Add length of the inserted text to the offset.
+      return;
+    }
+    write("\n$(DDOC_DECL ");
+    dg();
+    writeAttributes(d);
+    write(")");
+    prevDeclOffset = text.length;
+  }
+
+
+  /// Writes a class or interface declaration.
+  void writeClassOrInterface(T)(T d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({
+      write(d.begin.srcText, ", ");
+      SYMBOL(d.name.str, d);
+      writeTemplateParams();
+      writeInheritanceList(d.bases);
+    }, d);
+    DESC({
+      writeComment();
+      MEMBERS(is(T == ClassDeclaration) ? "CLASS" : "INTERFACE", {
+        scope s = new Scope();
+/*FIXME*/        d.decls && DefaultVisitor.visit(d.decls);
+      });
+    });
+  }
+
+  /// Writes a struct or union declaration.
+  void writeStructOrUnion(T)(T d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({
+      write(d.begin.srcText, d.name ? ", " : "");
+      if (d.name)
+        SYMBOL(d.name.str, d);
+      writeTemplateParams();
+    }, d);
+    DESC({
+      writeComment();
+      MEMBERS(is(T == StructDeclaration) ? "STRUCT" : "UNION", {
+        scope s = new Scope();
+/*FIXME*/        d.decls && DefaultVisitor.visit(d.decls);
+      });
+    });
+  }
+
+  /// Writes an alias or typedef declaration.
+  void writeAliasOrTypedef(T)(T d)
+  {
+    auto prefix = is(T == AliasDeclaration) ? "alias " : "typedef ";
+    if (auto vd = d.decl.Is!(VariablesDeclaration))
+    {
+      auto type = textSpan(vd.typeNode.baseType.begin, vd.typeNode.end);
+      foreach (name; vd.names)
+        DECL({ write(prefix, ", "); write(escape(type), " "); SYMBOL(name.str, d); }, d);
+    }
+    else if (auto fd = d.decl.Is!(FunctionDeclaration))
+    {}
+    // DECL({ write(textSpan(d.begin, d.end)); }, false);
+    DESC({ writeComment(); });
+  }
+
+  /// Writes the attributes of a declaration in brackets.
+  void writeAttributes(Declaration d)
+  {
+    char[][] attributes;
+
+    if (d.prot != Protection.None)
+      attributes ~= "$(PROT " ~ .toString(d.prot) ~ ")";
+
+    auto stc = d.stc;
+    stc &= ~StorageClass.Auto; // Ignore auto.
+    foreach (stcStr; .toStrings(stc))
+      attributes ~= "$(STC " ~ stcStr ~ ")";
+
+    LinkageType ltype;
+    if (auto vd = d.Is!(VariablesDeclaration))
+      ltype = vd.linkageType;
+    else if (auto fd = d.Is!(FunctionDeclaration))
+      ltype = fd.linkageType;
+
+    if (ltype != LinkageType.None)
+      attributes ~= "$(LINKAGE extern(" ~ .toString(ltype) ~ "))";
+
+    if (!attributes.length)
+      return;
+
+    write("$(ATTRIBUTES ");
+    foreach (attribute; attributes)
+      write(attribute);
+    write(")");
+  }
+
+  alias Declaration D;
+
+//  alias DDocEmitter.visit visit;
+
+  D visit(EnumDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({
+      write("enum, ", d.name ? " " : "");
+      d.name && SYMBOL(d.name.str, d);
+    }, d);
+    DESC({
+      writeComment();
+/*FIXME*/      MEMBERS("ENUM", { scope s = new Scope(); DefaultVisitor.visit(d); });
+    });
+    return d;
+  }
+
+  D visit(EnumMemberDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("member, "); SYMBOL(d.name.str, d); }, d, false);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(TemplateDeclaration d)
+  {
+    this.tparams = d.tparams;
+    if (d.begin.kind != TOK.Template)
+    { // This is a templatized class/interface/struct/union/function.
+/*FIXME*/      DefaultVisitor.visit(d.decls);
+      this.tparams = null;
+      return d;
+    }
+    if (!ddoc(d))
+      return d;
+    DECL({
+      write("template, ");
+      SYMBOL(d.name.str, d);
+      writeTemplateParams();
+    }, d);
+    DESC({
+      writeComment();
+      MEMBERS("TEMPLATE", {
+        scope s = new Scope();
+/*FIXME*/        DefaultVisitor.visit(d.decls);
+      });
+    });
+    return d;
+  }
+
+
+  D visit(ConstructorDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("constructor, "); SYMBOL("this", d); writeParams(d.params); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(StaticConstructorDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("static constructor, "); SYMBOL("this", d); write("()"); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(DestructorDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("destructor, ~"); SYMBOL("this", d); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(StaticDestructorDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("static destructor, ~"); SYMBOL("this", d); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(FunctionDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    auto type = textSpan(d.returnType.baseType.begin, d.returnType.end);
+    DECL({
+      write("function, ");
+      write("$(TYPE ");
+      write("$(RETURNS ", escape(type), ")");
+      writeTemplateParams();
+      writeParams(d.params);
+      write(")");
+      SYMBOL(d.name.str, d);
+    }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(NewDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("new, "); SYMBOL("new", d); writeParams(d.params); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(DeleteDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("delete, "); SYMBOL("delete", d); writeParams(d.params); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(VariablesDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    char[] type = "auto";
+    if (d.typeNode)
+      type = textSpan(d.typeNode.baseType.begin, d.typeNode.end);
+    foreach (name; d.names)
+      DECL({ write("variable, "); write("$(TYPE ", escape(type), ")"); SYMBOL(name.str, d); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(InvariantDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("invariant, "); SYMBOL("invariant", d); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(UnittestDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("unittest, "); SYMBOL("unittest", d); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+}
--- a/trunk/src/config.d	Sat Mar 01 02:53:06 2008 +0100
+++ b/trunk/src/config.d	Sat Mar 01 18:04:29 2008 +0200
@@ -14,7 +14,7 @@
 var import_paths = []; /// E.g.: ["src/", "import/"]
 
 /// DDoc macro file paths.
-var ddoc_files = ["predefined.ddoc"]; /// E.g.: ["src/mymacros.ddoc", "othermacros.ddoc"]
+var ddoc_files = ["predefined_xml.ddoc"]; /// E.g.: ["src/mymacros.ddoc", "othermacros.ddoc"]
 
 var xml_map = "xml_map.d";
 var html_map = "html_map.d";
--- a/trunk/src/predefined.ddoc	Sat Mar 01 02:53:06 2008 +0100
+++ b/trunk/src/predefined.ddoc	Sat Mar 01 18:04:29 2008 +0200
@@ -106,3 +106,4 @@
 PROT = $0
 STC = $0
 LINKAGE = $0
+SYMBOL = $1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trunk/src/predefined_xml.ddoc	Sat Mar 01 18:04:29 2008 +0200
@@ -0,0 +1,98 @@
+DDOC = <root>
+<module>$(TITLE)</module>
+$(BODY)
+<copyright>$(COPYRIGHT)</copyright>
+<generator>dil $(DDOC_VERSION) $(LINK http://code.google.com/p/dil)
+  <date>$(DATETIME)</date>
+</generator>
+</root>
+
+B = <b>$0</b>
+I = <i>$0</i>
+U = <u>$0</u>
+P = <p>$0</p>
+DL = <dl>$0</dl>
+DT = <dt>$0</dt>
+DD = <dd>$0</dd>
+TABLE = <table>$0</table>
+TR = <tr>$0</tr>
+TH = <th>$0</th>
+TD = <td>$0</td>
+OL = <ol>$0</ol>
+UL = <ul>$0</ul>
+LI = <li>$0</li>
+BIG = <big>$0</big>
+SMALL = <small>$0</small>
+BR = <br />
+LINK = <link href="$0">$0</link>
+LINK2 = <link href="$1">$+</link>
+
+RED = <font color="red">$0</font>
+BLUE = <font color="blue">$0</font>
+GREEN = <font color="green">$0</font>
+YELLOW = <font color="yellow">$0</font>
+BLACK = <font color="black">$0</font>
+WHITE = <font color="white">$0</font>
+
+D_CODE    = <dcode>$0</dcode>
+D_COMMENT = <dcomment>$0</dcomment>
+D_STRING  = <dstring>$0</dstring>
+D_COMMENT = <dkeyword>$0</dkeyword>
+D_PSYMBOL = <dpsymbol>$0</dpsymbol>
+D_PARAM   = <dparam>$0</dparam>
+
+DDOC_COMMENT   = <!-- $0 -->
+DDOC_DECL      = <declaration type="$1">$2</declaration>
+DDOC_DECL_DD   = $0
+DDOC_DITTO     = $0
+
+DDOC_SECTIONS    = <description>$0</description>
+DDOC_SECTION_T   = <section name="$1">$2</section>
+DDOC_SUMMARY     = $(DDOC_SECTION_T summary, $0)
+DDOC_DESCRIPTION = $(DDOC_SECTION_T description, $0)
+DDOC_AUTHORS     = $(DDOC_SECTION_T authors, $0)
+DDOC_BUGS        = $(DDOC_SECTION_T bugs, $0)
+DDOC_COPYRIGHT   = $(DDOC_SECTION_T copyright, $0)
+DDOC_DATE        = $(DDOC_SECTION_T date, $0)
+DDOC_DEPRECATED  = $(DDOC_SECTION_T deprecated, $0)
+DDOC_EXAMPLES    = $(DDOC_SECTION_T examples, $0)
+DDOC_HISTORY     = $(DDOC_SECTION_T history, $0)
+DDOC_LICENSE     = $(DDOC_SECTION_T license, $0)
+DDOC_RETURNS     = $(DDOC_SECTION_T returns, $0)
+DDOC_SEE_ALSO    = $(DDOC_SECTION_T seealso, $0)
+DDOC_STANDARDS   = $(DDOC_SECTION_T standards, $0)
+DDOC_THROWS      = $(DDOC_SECTION_T throws, $0)
+DDOC_VERSION     = $(DDOC_SECTION_T version, $0)
+DDOC_SECTION_H   = $(B $0)$(BR)
+DDOC_SECTION     = $0
+
+DDOC_MEMBERS           = <members>$0</members>
+DDOC_MODULE_MEMBERS    = $(DDOC_MEMBERS $0)
+DDOC_CLASS_MEMBERS     = $(DDOC_MEMBERS $0)
+DDOC_INTERFACE_MEMBERS = $(DDOC_MEMBERS $0)
+DDOC_STRUCT_MEMBERS    = $(DDOC_MEMBERS $0)
+DDOC_UNION_MEMBERS     = $(DDOC_MEMBERS $0)
+DDOC_TEMPLATE_MEMBERS  = $(DDOC_MEMBERS $0)
+DDOC_ENUM_MEMBERS      = $(DDOC_MEMBERS $0)
+
+DDOC_PARAMS     = <params>$0</params>
+DDOC_PARAM_ROW  = <param>$0</param>
+DDOC_PARAM_ID   = <name>$0</name>
+DDOC_PARAM_DESC = <description>$0</description>
+DDOC_BLANKLINE  = <newline />
+
+DDOC_PSYMBOL = $(U $0)
+DDOC_KEYWORD = $(B $0)
+DDOC_PARAM   = $0
+
+ATTRIBUTES      = <attributes>$0</attributes>
+ATTRIBUTE       = <attribute type="$1">$2</attribute>
+PROT            = $(ATTRIBUTE protection, $0)
+STC             = $(ATTRIBUTE storage, $0)
+LINKAGE         = $(ATTRIBUTE linkage, $0)
+SYMBOL          = $1
+PARENTS         = <parents>$0</parents>
+TYPE            = <type>$0</type>
+PARAMS          = <params>$0</params>
+RETURNS         = <returns>$0</returns>
+TEMPLATE_PARAMS = <templateparams>$0</templateparams>