diff --git a/usr/gri/pretty/docprinter.go b/usr/gri/pretty/docprinter.go index 87449b3db8e..f724f7d5f6f 100644 --- a/usr/gri/pretty/docprinter.go +++ b/usr/gri/pretty/docprinter.go @@ -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("

func ("); + p.Printf("func (", hsize); p.Expr(d.Recv.Type); - p.Printf(") %s

\n", d.Name.Lit); + p.Printf(") %s\n", d.Name.Lit, hsize); } else { - p.Printf("

func %s

\n", d.Name.Lit); + p.Printf("func %s\n", hsize, d.Name.Lit, hsize); } p.Printf("

"); 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("


\n"); for name, f := range doc.funcs { - p.Printf("
\n"); - f.print(&p); + f.print(&p, 2); } }, }); diff --git a/usr/gri/pretty/template.html b/usr/gri/pretty/template.html index e4a7550dd75..ab415c92720 100644 --- a/usr/gri/pretty/template.html +++ b/usr/gri/pretty/template.html @@ -13,14 +13,6 @@ -
-

Implementation

-Comments are currently not shown in the source. - -
-
-
-