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);
}
}
},