]> Cypherpunks repositories - gostls13.git/commitdiff
- also associate factory methods to a type in documentation
authorRobert Griesemer <gri@golang.org>
Wed, 1 Apr 2009 01:46:21 +0000 (18:46 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 1 Apr 2009 01:46:21 +0000 (18:46 -0700)
R=r
OCL=26974
CL=26976

usr/gri/pretty/docprinter.go
usr/gri/pretty/template.html

index 87449b3db8e6336de786b18c6a3bffed01ad2d4a..f724f7d5f6f90f2d483ddf4ab861230d3049ba27 100644 (file)
@@ -56,6 +56,7 @@ type funcDoc struct {
 
 type typeDoc struct {
        decl *ast.TypeDecl;
+       factories map[string] *funcDoc;
        methods map[string] *funcDoc;
 }
 
@@ -84,6 +85,61 @@ func (doc *PackageDoc) Init(name string) {
 }
 
 
+func baseTypeName(typ ast.Expr) string {
+       switch t := typ.(type) {
+       case *ast.Ident:
+               return string(t.Lit);
+       case *ast.StarExpr:
+               return baseTypeName(t.X);
+       }
+       return "";
+}
+
+
+func (doc *PackageDoc) lookupTypeDoc(typ ast.Expr) *typeDoc {
+       tdoc, found := doc.types[baseTypeName(typ)];
+       if found {
+               return tdoc;
+       }
+       return nil;
+}
+
+
+func (doc *PackageDoc) addFunc(fun *ast.FuncDecl) {
+       name := string(fun.Name.Lit);
+       fdoc := &funcDoc{fun};
+       
+       // determine if it should be associated with a type
+       var typ *typeDoc;
+       if fun.Recv != nil {
+               // method
+               typ = doc.lookupTypeDoc(fun.Recv.Type);
+               if typ != nil {
+                       typ.methods[name] = fdoc;
+                       return;
+               }
+       } else {
+               // perhaps a factory function
+               // determine result type, if any
+               if len(fun.Type.Results) >= 1 {
+                       res := fun.Type.Results[0];
+                       if len(res.Names) <= 1 {
+                               // exactly one (named or anonymous) result type
+                               typ = doc.lookupTypeDoc(res.Type);
+                               if typ != nil {
+                                       typ.factories[name] = fdoc;
+                                       return;
+                               }
+                       }
+               }
+       }
+       // TODO other heuristics (e.g. name is "NewTypename"?)
+       
+       // ordinary function
+       doc.funcs[name] = fdoc;
+}
+
+
 func (doc *PackageDoc) addDecl(decl ast.Decl) {
        switch d := decl.(type) {
        case *ast.ImportDecl:
@@ -95,7 +151,7 @@ func (doc *PackageDoc) addDecl(decl ast.Decl) {
                if isExported(d.Name) {
                        // TODO only add if not there already - or ignore?
                        name := string(d.Name.Lit);
-                       tdoc := &typeDoc{d, make(map[string] *funcDoc)};
+                       tdoc := &typeDoc{d, make(map[string] *funcDoc), make(map[string] *funcDoc)};
                        doc.types[name] = tdoc;
                }
 
@@ -105,28 +161,7 @@ func (doc *PackageDoc) addDecl(decl ast.Decl) {
 
        case *ast.FuncDecl:
                if isExported(d.Name) {
-                       if d.Recv != nil {
-                               // method
-                               // determine receiver type name
-                               var name string;
-                               switch t := d.Recv.Type.(type) {
-                               case *ast.Ident:
-                                       name = string(t.Lit);
-                               case *ast.StarExpr:
-                                       // recv must be of the form *name
-                                       name = string(t.X.(*ast.Ident).Lit)
-                               }
-                               typ, found := doc.types[name];
-                               if found {
-                                       fdoc := &funcDoc{d};
-                                       typ.methods[string(d.Name.Lit)] = fdoc;
-                               }
-                               // otherwise ignore
-                       } else {
-                               // ordinary function
-                               fdoc := &funcDoc{d};
-                               doc.funcs[string(d.Name.Lit)] = fdoc;
-                       }
+                       doc.addFunc(d);
                }
 
        case *ast.DeclList:
@@ -236,14 +271,14 @@ func (c *constDoc) printConsts(p *astPrinter.Printer) {
 }
 
 
-func (f *funcDoc) print(p *astPrinter.Printer) {
+func (f *funcDoc) print(p *astPrinter.Printer, hsize int) {
        d := f.decl;
        if d.Recv != nil {
-               p.Printf("<h3>func (");
+               p.Printf("<h%d>func (", hsize);
                p.Expr(d.Recv.Type);
-               p.Printf(") %s</h3>\n", d.Name.Lit);
+               p.Printf(") %s</h%d>\n", d.Name.Lit, hsize);
        } else {
-               p.Printf("<h2>func %s</h2>\n", d.Name.Lit);
+               p.Printf("<h%d>func %s</h%d>\n", hsize, d.Name.Lit, hsize);
        }
        p.Printf("<p><code>");
        p.DoFuncDecl(d);
@@ -265,8 +300,12 @@ func (t *typeDoc) print(p *astPrinter.Printer) {
        }
        
        // print associated methods, if any
+       for name, m := range t.factories {
+               m.print(p, 3);
+       }
+
        for name, m := range t.methods {
-               m.print(p);
+               m.print(p, 3);
        }
 }
 
@@ -348,9 +387,9 @@ func (doc *PackageDoc) Print(writer io.Write) {
 
                "FUNCTIONS-->" :
                        func() {
+                               p.Printf("<hr />\n");
                                for name, f := range doc.funcs {
-                                       p.Printf("<hr />\n");
-                                       f.print(&p);
+                                       f.print(&p, 2);
                                }
                        },
        });
index e4a7550dd75ba3628cac1cecdefe10f85f209258..ab415c92720834c97fb18397dca1a3a953c03bd3 100644 (file)
 
 <!--FUNCTIONS-->
 
-<hr />
-<h1>Implementation</h1>
-<font color=grey>Comments are currently not shown in the source.</font>
-
-<pre>
-<!--PACKAGE_BODY-->
-</pre>
-
 </div>  <!-- content -->
 </body>
 </html>