From 2d543d0c14e03e6a1cbd1ed74152f4018ce505de Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 2 Apr 2009 10:16:17 -0700 Subject: [PATCH] Adjustements related to AST changes. R=r OCL=27026 CL=27028 --- usr/gri/pretty/astprinter.go | 96 ++++++++++++----------------- usr/gri/pretty/docprinter.go | 114 +++++++++++++++-------------------- 2 files changed, 88 insertions(+), 122 deletions(-) diff --git a/usr/gri/pretty/astprinter.go b/usr/gri/pretty/astprinter.go index ddc5e52d27..828ec5ad98 100644 --- a/usr/gri/pretty/astprinter.go +++ b/usr/gri/pretty/astprinter.go @@ -1112,11 +1112,7 @@ func (P *Printer) DoBadDecl(d *ast.BadDecl) { } -func (P *Printer) DoImportDecl(d *ast.ImportDecl) { - if d.Pos().Offset > 0 { - P.Token(d.Pos(), token.IMPORT); - P.separator = blank; - } +func (P *Printer) importSpec(d *ast.ImportSpec) { if d.Name != nil { P.Expr(d.Name); } else { @@ -1124,19 +1120,12 @@ func (P *Printer) DoImportDecl(d *ast.ImportDecl) { } P.separator = tab; // TODO fix for longer package names - if len(d.Path) > 1 { - panic(); - } P.HtmlPackageName(d.Path[0].Pos(), string(d.Path[0].Lit)); P.newlines = 2; } -func (P *Printer) DoConstDecl(d *ast.ConstDecl) { - if d.Pos().Offset > 0 { - P.Token(d.Pos(), token.CONST); - P.separator = blank; - } +func (P *Printer) valueSpec(d *ast.ValueSpec) { P.Idents(d.Names, P.full); if d.Type != nil { P.separator = blank; // TODO switch to tab? (indentation problem with structs) @@ -1152,11 +1141,7 @@ func (P *Printer) DoConstDecl(d *ast.ConstDecl) { } -func (P *Printer) DoTypeDecl(d *ast.TypeDecl) { - if d.Pos().Offset > 0 { - P.Token(d.Pos(), token.TYPE); - P.separator = blank; - } +func (P *Printer) typeSpec(d *ast.TypeSpec) { P.Expr(d.Name); P.separator = blank; // TODO switch to tab? (but indentation problem with structs) P.Expr(d.Type); @@ -1164,24 +1149,43 @@ func (P *Printer) DoTypeDecl(d *ast.TypeDecl) { } -func (P *Printer) DoVarDecl(d *ast.VarDecl) { - if d.Pos().Offset > 0 { - P.Token(d.Pos(), token.VAR); - P.separator = blank; +func (P *Printer) spec(d ast.Spec) { + switch s := d.(type) { + case *ast.ImportSpec: P.importSpec(s); + case *ast.ValueSpec: P.valueSpec(s); + case *ast.TypeSpec: P.typeSpec(s); + default: panic("unreachable"); } - P.Idents(d.Names, P.full); - if d.Type != nil { - P.separator = blank; // TODO switch to tab? (indentation problem with structs) - P.Expr(d.Type); - //P.separator = P.Type(d.Type); +} + + +func (P *Printer) DoGenDecl(d *ast.GenDecl) { + P.Token(d.Pos(), d.Tok); + P.separator = blank; + + if d.Lparen.Line > 0 { + // group of parenthesized declarations + P.state = opening_scope; + P.Token(d.Lparen, token.LPAREN); + if len(d.Specs) > 0 { + P.newlines = 1; + for i := 0; i < len(d.Specs); i++ { + if i > 0 { + P.separator = semicolon; + } + P.spec(d.Specs[i]); + P.newlines = 1; + } + } + P.state = closing_scope; + P.Token(d.Rparen, token.RPAREN); + P.opt_semi = true; + P.newlines = 2; + + } else { + // single declaration + P.spec(d.Specs[0]); } - if d.Values != nil { - P.separator = tab; - P.Token(noPos, token.ASSIGN); - P.separator = blank; - P.Exprs(d.Values); - } - P.newlines = 2; } @@ -1209,30 +1213,6 @@ func (P *Printer) DoFuncDecl(d *ast.FuncDecl) { } -func (P *Printer) DoDeclList(d *ast.DeclList) { - P.Token(d.Pos(), d.Tok); - P.separator = blank; - - // group of parenthesized declarations - P.state = opening_scope; - P.Token(noPos, token.LPAREN); - if len(d.List) > 0 { - P.newlines = 1; - for i := 0; i < len(d.List); i++ { - if i > 0 { - P.separator = semicolon; - } - P.Decl(d.List[i]); - P.newlines = 1; - } - } - P.state = closing_scope; - P.Token(d.Rparen, token.RPAREN); - P.opt_semi = true; - P.newlines = 2; -} - - func (P *Printer) Decl(d ast.Decl) { d.Visit(P); } diff --git a/usr/gri/pretty/docprinter.go b/usr/gri/pretty/docprinter.go index aa72687044..05b8f3e50a 100644 --- a/usr/gri/pretty/docprinter.go +++ b/usr/gri/pretty/docprinter.go @@ -38,12 +38,10 @@ func hasExportedNames(names []*ast.Ident) bool { } -func hasExportedDecls(decl []ast.Decl) bool { - for i, d := range decl { - switch t := d.(type) { - case *ast.ConstDecl: - return hasExportedNames(t.Names); - } +func hasExportedSpecs(specs []ast.Spec) bool { + for i, s := range specs { + // only called for []astSpec lists of *ast.ValueSpec + return hasExportedNames(s.(*ast.ValueSpec).Names); } return false; } @@ -51,13 +49,8 @@ func hasExportedDecls(decl []ast.Decl) bool { // ---------------------------------------------------------------------------- -type constDoc struct { - decl *ast.DeclList; -} - - -type varDoc struct { - decl *ast.DeclList; +type valueDoc struct { + decl *ast.GenDecl; // len(decl.Specs) >= 1, and the element type is *ast.ValueSpec } @@ -67,7 +60,7 @@ type funcDoc struct { type typeDoc struct { - decl *ast.TypeDecl; + decl *ast.GenDecl; // len(decl.Specs) == 1, and the element type is *ast.TypeSpec factories map[string] *funcDoc; methods map[string] *funcDoc; } @@ -76,9 +69,9 @@ type typeDoc struct { type PackageDoc struct { name string; // package name doc ast.Comments; // package documentation, if any - consts *vector.Vector; // list of *ast.DeclList with Tok == token.CONST - vars *vector.Vector; // list of *ast.DeclList with Tok == token.CONST + consts *vector.Vector; // list of *valueDoc types map[string] *typeDoc; + vars *vector.Vector; // list of *valueDoc funcs map[string] *funcDoc; } @@ -116,9 +109,10 @@ func (doc *PackageDoc) lookupTypeDoc(typ ast.Expr) *typeDoc { } -func (doc *PackageDoc) addType(typ *ast.TypeDecl) { +func (doc *PackageDoc) addType(decl *ast.GenDecl) { + typ := decl.Specs[0].(*ast.TypeSpec); name := string(typ.Name.Lit); - tdoc := &typeDoc{typ, make(map[string] *funcDoc), make(map[string] *funcDoc)}; + tdoc := &typeDoc{decl, make(map[string] *funcDoc), make(map[string] *funcDoc)}; doc.types[name] = tdoc; } @@ -160,41 +154,40 @@ func (doc *PackageDoc) addFunc(fun *ast.FuncDecl) { func (doc *PackageDoc) addDecl(decl ast.Decl) { switch d := decl.(type) { - case *ast.ConstDecl: - if hasExportedNames(d.Names) { - // TODO + case *ast.GenDecl: + if len(d.Specs) > 0 { + switch d.Tok { + case token.IMPORT: + // ignore + case token.CONST: + // constants are always handled as a group + if hasExportedSpecs(d.Specs) { + doc.consts.Push(&valueDoc{d}); + } + case token.TYPE: + // types are handled individually + for i, spec := range d.Specs { + s := spec.(*ast.TypeSpec); + if isExported(s.Name) { + // make a (fake) GenDecl node for this TypeSpec + // (we need to do this here - as opposed to just + // for printing - so we don't loose the GenDecl + // documentation) + var noPos token.Position; + doc.addType(&ast.GenDecl{d.Doc, d.Pos(), token.TYPE, noPos, []ast.Spec{s}, noPos}); + } + } + case token.VAR: + // variables are always handled as a group + if hasExportedSpecs(d.Specs) { + doc.vars.Push(&valueDoc{d}); + } + } } - - case *ast.TypeDecl: - if isExported(d.Name) { - doc.addType(d); - } - - case *ast.VarDecl: - if hasExportedNames(d.Names) { - // TODO - } - case *ast.FuncDecl: if isExported(d.Name) { doc.addFunc(d); } - - case *ast.DeclList: - switch d.Tok { - case token.IMPORT, token.TYPE: - for i, decl := range d.List { - doc.addDecl(decl); - } - case token.CONST: - if hasExportedDecls(d.List) { - doc.consts.Push(&constDoc{d}); - } - case token.VAR: - if hasExportedDecls(d.List) { - doc.consts.Push(&varDoc{d}); - } - } } } @@ -214,7 +207,7 @@ func (doc *PackageDoc) AddProgram(prog *ast.Program) { doc.doc = prog.Doc } - // add all declarations + // add all exported declarations for i, decl := range prog.Decls { doc.addDecl(decl); } @@ -381,18 +374,10 @@ func printComments(p *astPrinter.Printer, comment ast.Comments) { } -func (c *constDoc) print(p *astPrinter.Printer) { +func (c *valueDoc) print(p *astPrinter.Printer) { printComments(p, c.decl.Doc); p.Printf("
");
-	p.DoDeclList(c.decl);
-	p.Printf("
\n"); -} - - -func (c *varDoc) print(p *astPrinter.Printer) { - printComments(p, c.decl.Doc); - p.Printf("
");
-	p.DoDeclList(c.decl);
+	p.DoGenDecl(c.decl);
 	p.Printf("
\n"); } @@ -415,11 +400,12 @@ func (f *funcDoc) print(p *astPrinter.Printer, hsize int) { func (t *typeDoc) print(p *astPrinter.Printer) { d := t.decl; - p.Printf("

type %s

\n", string(d.Name.Lit)); + s := d.Specs[0].(*ast.TypeSpec); + p.Printf("

type %s

\n", string(s.Name.Lit)); p.Printf("

");
-	p.DoTypeDecl(d);
+	p.DoGenDecl(d);
 	p.Printf("

\n"); - printComments(p, d.Doc); + printComments(p, s.Doc); // print associated methods, if any for name, m := range t.factories { @@ -458,7 +444,7 @@ func (doc *PackageDoc) Print(writer io.Write) { fmt.Fprintln(writer, "
"); fmt.Fprintln(writer, "

Constants

"); for i := 0; i < doc.consts.Len(); i++ { - doc.consts.At(i).(*constDoc).print(&p); + doc.consts.At(i).(*valueDoc).print(&p); } } }, @@ -477,7 +463,7 @@ func (doc *PackageDoc) Print(writer io.Write) { fmt.Fprintln(writer, "
"); fmt.Fprintln(writer, "

Variables

"); for i := 0; i < doc.vars.Len(); i++ { - doc.vars.At(i).(*varDoc).print(&p); + doc.vars.At(i).(*valueDoc).print(&p); } } },