diff options
Diffstat (limited to 'src/pkg/go/doc/doc.go')
| -rw-r--r-- | src/pkg/go/doc/doc.go | 390 | 
1 files changed, 195 insertions, 195 deletions
| diff --git a/src/pkg/go/doc/doc.go b/src/pkg/go/doc/doc.go index b7cc8f3b0..be03ddfd6 100644 --- a/src/pkg/go/doc/doc.go +++ b/src/pkg/go/doc/doc.go @@ -6,11 +6,11 @@  package doc  import ( -	"container/vector"; -	"go/ast"; -	"go/token"; -	"regexp"; -	"sort"; +	"container/vector" +	"go/ast" +	"go/token" +	"regexp" +	"sort"  ) @@ -19,11 +19,11 @@ import (  type typeDoc struct {  	// len(decl.Specs) == 1, and the element type is *ast.TypeSpec  	// if the type declaration hasn't been seen yet, decl is nil -	decl	*ast.GenDecl; +	decl *ast.GenDecl  	// values, factory functions, and methods associated with the type -	values		*vector.Vector;	// list of *ast.GenDecl (consts and vars) -	factories	map[string]*ast.FuncDecl; -	methods		map[string]*ast.FuncDecl; +	values    *vector.Vector // list of *ast.GenDecl (consts and vars) +	factories map[string]*ast.FuncDecl +	methods   map[string]*ast.FuncDecl  } @@ -35,27 +35,27 @@ type typeDoc struct {  // printing the corresponding AST node).  //  type docReader struct { -	doc	*ast.CommentGroup;	// package documentation, if any -	pkgName	string; -	values	*vector.Vector;	// list of *ast.GenDecl (consts and vars) -	types	map[string]*typeDoc; -	funcs	map[string]*ast.FuncDecl; -	bugs	*vector.Vector;	// list of *ast.CommentGroup +	doc     *ast.CommentGroup // package documentation, if any +	pkgName string +	values  *vector.Vector // list of *ast.GenDecl (consts and vars) +	types   map[string]*typeDoc +	funcs   map[string]*ast.FuncDecl +	bugs    *vector.Vector // list of *ast.CommentGroup  }  func (doc *docReader) init(pkgName string) { -	doc.pkgName = pkgName; -	doc.values = new(vector.Vector); -	doc.types = make(map[string]*typeDoc); -	doc.funcs = make(map[string]*ast.FuncDecl); -	doc.bugs = new(vector.Vector); +	doc.pkgName = pkgName +	doc.values = new(vector.Vector) +	doc.types = make(map[string]*typeDoc) +	doc.funcs = make(map[string]*ast.FuncDecl) +	doc.bugs = new(vector.Vector)  }  func (doc *docReader) addType(decl *ast.GenDecl) { -	spec := decl.Specs[0].(*ast.TypeSpec); -	typ := doc.lookupTypeDoc(spec.Name.Value); +	spec := decl.Specs[0].(*ast.TypeSpec) +	typ := doc.lookupTypeDoc(spec.Name.Value)  	// typ should always be != nil since declared types  	// are always named - be conservative and check  	if typ != nil { @@ -68,15 +68,15 @@ func (doc *docReader) addType(decl *ast.GenDecl) {  func (doc *docReader) lookupTypeDoc(name string) *typeDoc {  	if name == "" { -		return nil	// no type docs for anonymous types +		return nil // no type docs for anonymous types  	}  	if tdoc, found := doc.types[name]; found {  		return tdoc  	}  	// type wasn't found - add one without declaration -	tdoc := &typeDoc{nil, new(vector.Vector), make(map[string]*ast.FuncDecl), make(map[string]*ast.FuncDecl)}; -	doc.types[name] = tdoc; -	return tdoc; +	tdoc := &typeDoc{nil, new(vector.Vector), make(map[string]*ast.FuncDecl), make(map[string]*ast.FuncDecl)} +	doc.types[name] = tdoc +	return tdoc  } @@ -91,7 +91,7 @@ func baseTypeName(typ ast.Expr) string {  	case *ast.StarExpr:  		return baseTypeName(t.X)  	} -	return ""; +	return ""  } @@ -100,12 +100,12 @@ func (doc *docReader) addValue(decl *ast.GenDecl) {  	// Heuristic: For each typed entry, determine the type name, if any.  	//            If there is exactly one type name that is sufficiently  	//            frequent, associate the decl with the respective type. -	domName := ""; -	domFreq := 0; -	prev := ""; +	domName := "" +	domFreq := 0 +	prev := ""  	for _, s := range decl.Specs {  		if v, ok := s.(*ast.ValueSpec); ok { -			name := ""; +			name := ""  			switch {  			case v.Type != nil:  				// a type is present; determine it's name @@ -122,38 +122,38 @@ func (doc *docReader) addValue(decl *ast.GenDecl) {  				if domName != "" && domName != name {  					// more than one type name - do not associate  					// with any type -					domName = ""; -					break; +					domName = "" +					break  				} -				domName = name; -				domFreq++; +				domName = name +				domFreq++  			} -			prev = name; +			prev = name  		}  	}  	// determine values list -	const threshold = 0.75; -	values := doc.values; +	const threshold = 0.75 +	values := doc.values  	if domName != "" && domFreq >= int(float(len(decl.Specs))*threshold) {  		// typed entries are sufficiently frequent -		typ := doc.lookupTypeDoc(domName); +		typ := doc.lookupTypeDoc(domName)  		if typ != nil { -			values = typ.values	// associate with that type +			values = typ.values // associate with that type  		}  	} -	values.Push(decl); +	values.Push(decl)  }  func (doc *docReader) addFunc(fun *ast.FuncDecl) { -	name := fun.Name.Value; +	name := fun.Name.Value  	// determine if it should be associated with a type  	if fun.Recv != nil {  		// method -		typ := doc.lookupTypeDoc(baseTypeName(fun.Recv.Type)); +		typ := doc.lookupTypeDoc(baseTypeName(fun.Recv.Type))  		if typ != nil {  			// exported receiver type  			typ.methods[name] = fun @@ -163,19 +163,19 @@ func (doc *docReader) addFunc(fun *ast.FuncDecl) {  		// that can be called because of exported values (consts, vars, or  		// function results) of that type. Could determine if that is the  		// case and then show those methods in an appropriate section. -		return; +		return  	}  	// perhaps a factory function  	// determine result type, if any  	if len(fun.Type.Results) >= 1 { -		res := fun.Type.Results[0]; +		res := fun.Type.Results[0]  		if len(res.Names) <= 1 {  			// exactly one (named or anonymous) result associated  			// with the first type in result signature (there may  			// be more than one result) -			tname := baseTypeName(res.Type); -			typ := doc.lookupTypeDoc(tname); +			tname := baseTypeName(res.Type) +			typ := doc.lookupTypeDoc(tname)  			if typ != nil {  				// named and exported result type @@ -187,18 +187,18 @@ func (doc *docReader) addFunc(fun *ast.FuncDecl) {  				if doc.pkgName == "os" && tname == "Error" &&  					name != "NewError" && name != "NewSyscallError" {  					// not a factory function for os.Error -					doc.funcs[name] = fun;	// treat as ordinary function -					return; +					doc.funcs[name] = fun // treat as ordinary function +					return  				} -				typ.factories[name] = fun; -				return; +				typ.factories[name] = fun +				return  			}  		}  	}  	// ordinary function -	doc.funcs[name] = fun; +	doc.funcs[name] = fun  } @@ -212,7 +212,7 @@ func (doc *docReader) addDecl(decl ast.Decl) {  				doc.addValue(d)  			case token.TYPE:  				// types are handled individually -				var noPos token.Position; +				var noPos token.Position  				for _, spec := range d.Specs {  					// make a (fake) GenDecl node for this TypeSpec  					// (we need to do this here - as opposed to just @@ -237,17 +237,17 @@ func (doc *docReader) addDecl(decl ast.Decl) {  func copyCommentList(list []*ast.Comment) []*ast.Comment { -	copy := make([]*ast.Comment, len(list)); +	copy := make([]*ast.Comment, len(list))  	for i, c := range list {  		copy[i] = c  	} -	return copy; +	return copy  }  var ( -	bug_markers	= regexp.MustCompile("^/[/*][ \t]*BUG\\(.*\\):[ \t]*");	// BUG(uid): -	bug_content	= regexp.MustCompile("[^ \n\r\t]+");			// at least one non-whitespace char +	bug_markers = regexp.MustCompile("^/[/*][ \t]*BUG\\(.*\\):[ \t]*") // BUG(uid): +	bug_content = regexp.MustCompile("[^ \n\r\t]+")                    // at least one non-whitespace char  ) @@ -262,8 +262,8 @@ func (doc *docReader) addFile(src *ast.File) {  		//           using ast.MergePackageFiles which handles these  		//           comments correctly (but currently looses BUG(...)  		//           comments). -		doc.doc = src.Doc; -		src.Doc = nil;	// doc consumed - remove from ast.File node +		doc.doc = src.Doc +		src.Doc = nil // doc consumed - remove from ast.File node  	}  	// add all declarations @@ -273,41 +273,41 @@ func (doc *docReader) addFile(src *ast.File) {  	// collect BUG(...) comments  	for c := src.Comments; c != nil; c = c.Next { -		text := c.List[0].Text; -		cstr := string(text); +		text := c.List[0].Text +		cstr := string(text)  		if m := bug_markers.ExecuteString(cstr); len(m) > 0 {  			// found a BUG comment; maybe empty  			if bstr := cstr[m[1]:]; bug_content.MatchString(bstr) {  				// non-empty BUG comment; collect comment without BUG prefix -				list := copyCommentList(c.List); -				list[0].Text = text[m[1]:]; -				doc.bugs.Push(&ast.CommentGroup{list, nil}); +				list := copyCommentList(c.List) +				list[0].Text = text[m[1]:] +				doc.bugs.Push(&ast.CommentGroup{list, nil})  			}  		}  	} -	src.Comments = nil;	// consumed unassociated comments - remove from ast.File node +	src.Comments = nil // consumed unassociated comments - remove from ast.File node  }  func NewFileDoc(file *ast.File) *PackageDoc { -	var r docReader; -	r.init(file.Name.Value); -	r.addFile(file); -	return r.newDoc("", "", nil); +	var r docReader +	r.init(file.Name.Value) +	r.addFile(file) +	return r.newDoc("", "", nil)  }  func NewPackageDoc(pkg *ast.Package, importpath string) *PackageDoc { -	var r docReader; -	r.init(pkg.Name); -	filenames := make([]string, len(pkg.Files)); -	i := 0; +	var r docReader +	r.init(pkg.Name) +	filenames := make([]string, len(pkg.Files)) +	i := 0  	for filename, f := range pkg.Files { -		r.addFile(f); -		filenames[i] = filename; -		i++; +		r.addFile(f) +		filenames[i] = filename +		i++  	} -	return r.newDoc(importpath, pkg.Path, filenames); +	return r.newDoc(importpath, pkg.Path, filenames)  } @@ -318,15 +318,15 @@ func NewPackageDoc(pkg *ast.Package, importpath string) *PackageDoc {  // values, either vars or consts.  //  type ValueDoc struct { -	Doc	string; -	Decl	*ast.GenDecl; -	order	int; +	Doc   string +	Decl  *ast.GenDecl +	order int  }  type sortValueDoc []*ValueDoc -func (p sortValueDoc) Len() int		{ return len(p) } -func (p sortValueDoc) Swap(i, j int)	{ p[i], p[j] = p[j], p[i] } +func (p sortValueDoc) Len() int      { return len(p) } +func (p sortValueDoc) Swap(i, j int) { p[i], p[j] = p[j], p[i] }  func declName(d *ast.GenDecl) string { @@ -341,7 +341,7 @@ func declName(d *ast.GenDecl) string {  		return v.Name.Value  	} -	return ""; +	return ""  } @@ -352,24 +352,24 @@ func (p sortValueDoc) Less(i, j int) bool {  	if ni, nj := declName(p[i].Decl), declName(p[j].Decl); ni != nj {  		return ni < nj  	} -	return p[i].order < p[j].order; +	return p[i].order < p[j].order  }  func makeValueDocs(v *vector.Vector, tok token.Token) []*ValueDoc { -	d := make([]*ValueDoc, v.Len());	// big enough in any case -	n := 0; +	d := make([]*ValueDoc, v.Len()) // big enough in any case +	n := 0  	for i := range d { -		decl := v.At(i).(*ast.GenDecl); +		decl := v.At(i).(*ast.GenDecl)  		if decl.Tok == tok { -			d[n] = &ValueDoc{CommentText(decl.Doc), decl, i}; -			n++; -			decl.Doc = nil;	// doc consumed - removed from AST +			d[n] = &ValueDoc{CommentText(decl.Doc), decl, i} +			n++ +			decl.Doc = nil // doc consumed - removed from AST  		}  	} -	d = d[0:n]; -	sort.Sort(sortValueDoc(d)); -	return d; +	d = d[0:n] +	sort.Sort(sortValueDoc(d)) +	return d  } @@ -377,36 +377,36 @@ func makeValueDocs(v *vector.Vector, tok token.Token) []*ValueDoc {  // either a top-level function or a method function.  //  type FuncDoc struct { -	Doc	string; -	Recv	ast.Expr;	// TODO(rsc): Would like string here -	Name	string; -	Decl	*ast.FuncDecl; +	Doc  string +	Recv ast.Expr // TODO(rsc): Would like string here +	Name string +	Decl *ast.FuncDecl  }  type sortFuncDoc []*FuncDoc -func (p sortFuncDoc) Len() int			{ return len(p) } -func (p sortFuncDoc) Swap(i, j int)		{ p[i], p[j] = p[j], p[i] } -func (p sortFuncDoc) Less(i, j int) bool	{ return p[i].Name < p[j].Name } +func (p sortFuncDoc) Len() int           { return len(p) } +func (p sortFuncDoc) Swap(i, j int)      { p[i], p[j] = p[j], p[i] } +func (p sortFuncDoc) Less(i, j int) bool { return p[i].Name < p[j].Name }  func makeFuncDocs(m map[string]*ast.FuncDecl) []*FuncDoc { -	d := make([]*FuncDoc, len(m)); -	i := 0; +	d := make([]*FuncDoc, len(m)) +	i := 0  	for _, f := range m { -		doc := new(FuncDoc); -		doc.Doc = CommentText(f.Doc); -		f.Doc = nil;	// doc consumed - remove from ast.FuncDecl node +		doc := new(FuncDoc) +		doc.Doc = CommentText(f.Doc) +		f.Doc = nil // doc consumed - remove from ast.FuncDecl node  		if f.Recv != nil {  			doc.Recv = f.Recv.Type  		} -		doc.Name = f.Name.Value; -		doc.Decl = f; -		d[i] = doc; -		i++; +		doc.Name = f.Name.Value +		doc.Decl = f +		d[i] = doc +		i++  	} -	sort.Sort(sortFuncDoc(d)); -	return d; +	sort.Sort(sortFuncDoc(d)) +	return d  } @@ -415,20 +415,20 @@ func makeFuncDocs(m map[string]*ast.FuncDecl) []*FuncDoc {  // Factories is a sorted list of factory functions that return that type.  // Methods is a sorted list of method functions on that type.  type TypeDoc struct { -	Doc		string; -	Type		*ast.TypeSpec; -	Consts		[]*ValueDoc; -	Vars		[]*ValueDoc; -	Factories	[]*FuncDoc; -	Methods		[]*FuncDoc; -	Decl		*ast.GenDecl; -	order		int; +	Doc       string +	Type      *ast.TypeSpec +	Consts    []*ValueDoc +	Vars      []*ValueDoc +	Factories []*FuncDoc +	Methods   []*FuncDoc +	Decl      *ast.GenDecl +	order     int  }  type sortTypeDoc []*TypeDoc -func (p sortTypeDoc) Len() int		{ return len(p) } -func (p sortTypeDoc) Swap(i, j int)	{ p[i], p[j] = p[j], p[i] } +func (p sortTypeDoc) Len() int      { return len(p) } +func (p sortTypeDoc) Swap(i, j int) { p[i], p[j] = p[j], p[i] }  func (p sortTypeDoc) Less(i, j int) bool {  	// sort by name  	// pull blocks (name = "") up to top @@ -436,7 +436,7 @@ func (p sortTypeDoc) Less(i, j int) bool {  	if ni, nj := p[i].Type.Name.Value, p[j].Type.Name.Value; ni != nj {  		return ni < nj  	} -	return p[i].order < p[j].order; +	return p[i].order < p[j].order  } @@ -444,32 +444,32 @@ func (p sortTypeDoc) Less(i, j int) bool {  // blocks, but the doc extractor above has split them into  // individual declarations.  func (doc *docReader) makeTypeDocs(m map[string]*typeDoc) []*TypeDoc { -	d := make([]*TypeDoc, len(m)); -	i := 0; +	d := make([]*TypeDoc, len(m)) +	i := 0  	for _, old := range m {  		// all typeDocs should have a declaration associated with  		// them after processing an entire package - be conservative  		// and check  		if decl := old.decl; decl != nil { -			typespec := decl.Specs[0].(*ast.TypeSpec); -			t := new(TypeDoc); -			doc := typespec.Doc; -			typespec.Doc = nil;	// doc consumed - remove from ast.TypeSpec node +			typespec := decl.Specs[0].(*ast.TypeSpec) +			t := new(TypeDoc) +			doc := typespec.Doc +			typespec.Doc = nil // doc consumed - remove from ast.TypeSpec node  			if doc == nil {  				// no doc associated with the spec, use the declaration doc, if any  				doc = decl.Doc  			} -			decl.Doc = nil;	// doc consumed - remove from ast.Decl node -			t.Doc = CommentText(doc); -			t.Type = typespec; -			t.Consts = makeValueDocs(old.values, token.CONST); -			t.Vars = makeValueDocs(old.values, token.VAR); -			t.Factories = makeFuncDocs(old.factories); -			t.Methods = makeFuncDocs(old.methods); -			t.Decl = old.decl; -			t.order = i; -			d[i] = t; -			i++; +			decl.Doc = nil // doc consumed - remove from ast.Decl node +			t.Doc = CommentText(doc) +			t.Type = typespec +			t.Consts = makeValueDocs(old.values, token.CONST) +			t.Vars = makeValueDocs(old.values, token.VAR) +			t.Factories = makeFuncDocs(old.factories) +			t.Methods = makeFuncDocs(old.methods) +			t.Decl = old.decl +			t.order = i +			d[i] = t +			i++  		} else {  			// no corresponding type declaration found - move any associated  			// values, factory functions, and methods back to the top-level @@ -477,7 +477,7 @@ func (doc *docReader) makeTypeDocs(m map[string]*typeDoc) []*TypeDoc {  			// file containing the explicit type declaration is missing or if  			// an unqualified type name was used after a "." import)  			// 1) move values -			doc.values.AppendVector(old.values); +			doc.values.AppendVector(old.values)  			// 2) move factory functions  			for name, f := range old.factories {  				doc.funcs[name] = f @@ -491,56 +491,56 @@ func (doc *docReader) makeTypeDocs(m map[string]*typeDoc) []*TypeDoc {  			}  		}  	} -	d = d[0:i];	// some types may have been ignored -	sort.Sort(sortTypeDoc(d)); -	return d; +	d = d[0:i] // some types may have been ignored +	sort.Sort(sortTypeDoc(d)) +	return d  }  func makeBugDocs(v *vector.Vector) []string { -	d := make([]string, v.Len()); +	d := make([]string, v.Len())  	for i := 0; i < v.Len(); i++ {  		d[i] = CommentText(v.At(i).(*ast.CommentGroup))  	} -	return d; +	return d  }  // PackageDoc is the documentation for an entire package.  //  type PackageDoc struct { -	PackageName	string; -	ImportPath	string; -	FilePath	string; -	Filenames	[]string; -	Doc		string; -	Consts		[]*ValueDoc; -	Types		[]*TypeDoc; -	Vars		[]*ValueDoc; -	Funcs		[]*FuncDoc; -	Bugs		[]string; +	PackageName string +	ImportPath  string +	FilePath    string +	Filenames   []string +	Doc         string +	Consts      []*ValueDoc +	Types       []*TypeDoc +	Vars        []*ValueDoc +	Funcs       []*FuncDoc +	Bugs        []string  }  // newDoc returns the accumulated documentation for the package.  //  func (doc *docReader) newDoc(importpath, filepath string, filenames []string) *PackageDoc { -	p := new(PackageDoc); -	p.PackageName = doc.pkgName; -	p.ImportPath = importpath; -	p.FilePath = filepath; -	sort.SortStrings(filenames); -	p.Filenames = filenames; -	p.Doc = CommentText(doc.doc); +	p := new(PackageDoc) +	p.PackageName = doc.pkgName +	p.ImportPath = importpath +	p.FilePath = filepath +	sort.SortStrings(filenames) +	p.Filenames = filenames +	p.Doc = CommentText(doc.doc)  	// makeTypeDocs may extend the list of doc.values and  	// doc.funcs and thus must be called before any other  	// function consuming those lists -	p.Types = doc.makeTypeDocs(doc.types); -	p.Consts = makeValueDocs(doc.values, token.CONST); -	p.Vars = makeValueDocs(doc.values, token.VAR); -	p.Funcs = makeFuncDocs(doc.funcs); -	p.Bugs = makeBugDocs(doc.bugs); -	return p; +	p.Types = doc.makeTypeDocs(doc.types) +	p.Consts = makeValueDocs(doc.values, token.CONST) +	p.Vars = makeValueDocs(doc.values, token.VAR) +	p.Funcs = makeFuncDocs(doc.funcs) +	p.Bugs = makeBugDocs(doc.bugs) +	return p  } @@ -549,7 +549,7 @@ func (doc *docReader) newDoc(importpath, filepath string, filenames []string) *P  // Does s look like a regular expression?  func isRegexp(s string) bool { -	metachars := ".(|)*+?^$[]"; +	metachars := ".(|)*+?^$[]"  	for _, c := range s {  		for _, m := range metachars {  			if c == m { @@ -557,7 +557,7 @@ func isRegexp(s string) bool {  			}  		}  	} -	return false; +	return false  } @@ -572,7 +572,7 @@ func match(s string, names []string) bool {  			return true  		}  	} -	return false; +	return false  } @@ -591,54 +591,54 @@ func matchDecl(d *ast.GenDecl, names []string) bool {  			}  		}  	} -	return false; +	return false  }  func filterValueDocs(a []*ValueDoc, names []string) []*ValueDoc { -	w := 0; +	w := 0  	for _, vd := range a {  		if matchDecl(vd.Decl, names) { -			a[w] = vd; -			w++; +			a[w] = vd +			w++  		}  	} -	return a[0:w]; +	return a[0:w]  }  func filterFuncDocs(a []*FuncDoc, names []string) []*FuncDoc { -	w := 0; +	w := 0  	for _, fd := range a {  		if match(fd.Name, names) { -			a[w] = fd; -			w++; +			a[w] = fd +			w++  		}  	} -	return a[0:w]; +	return a[0:w]  }  func filterTypeDocs(a []*TypeDoc, names []string) []*TypeDoc { -	w := 0; +	w := 0  	for _, td := range a { -		n := 0;	// number of matches +		n := 0 // number of matches  		if matchDecl(td.Decl, names) {  			n = 1  		} else {  			// type name doesn't match, but we may have matching consts, vars, factories or methods -			td.Consts = filterValueDocs(td.Consts, names); -			td.Vars = filterValueDocs(td.Vars, names); -			td.Factories = filterFuncDocs(td.Factories, names); -			td.Methods = filterFuncDocs(td.Methods, names); -			n += len(td.Consts) + len(td.Vars) + len(td.Factories) + len(td.Methods); +			td.Consts = filterValueDocs(td.Consts, names) +			td.Vars = filterValueDocs(td.Vars, names) +			td.Factories = filterFuncDocs(td.Factories, names) +			td.Methods = filterFuncDocs(td.Methods, names) +			n += len(td.Consts) + len(td.Vars) + len(td.Factories) + len(td.Methods)  		}  		if n > 0 { -			a[w] = td; -			w++; +			a[w] = td +			w++  		}  	} -	return a[0:w]; +	return a[0:w]  } @@ -648,9 +648,9 @@ func filterTypeDocs(a []*TypeDoc, names []string) []*TypeDoc {  // TODO(r): maybe precompile the regexps.  //  func (p *PackageDoc) Filter(names []string) { -	p.Consts = filterValueDocs(p.Consts, names); -	p.Vars = filterValueDocs(p.Vars, names); -	p.Types = filterTypeDocs(p.Types, names); -	p.Funcs = filterFuncDocs(p.Funcs, names); -	p.Doc = "";	// don't show top-level package doc +	p.Consts = filterValueDocs(p.Consts, names) +	p.Vars = filterValueDocs(p.Vars, names) +	p.Types = filterTypeDocs(p.Types, names) +	p.Funcs = filterFuncDocs(p.Funcs, names) +	p.Doc = "" // don't show top-level package doc  } | 
