Commit 83c7b60f authored by Rob Pike's avatar Rob Pike

cmd/doc: trim unexported methods from interfaces

Fixes #10856.

Change-Id: I5de65b8dd94eec3451ee0ba9c75698cdd88f5fea
Reviewed-on: https://go-review.googlesource.com/10088Reviewed-by: default avatarAndrew Gerrand <adg@golang.org>
parent fb7e2449
...@@ -345,7 +345,7 @@ func (pkg *Package) symbolDoc(symbol string) { ...@@ -345,7 +345,7 @@ func (pkg *Package) symbolDoc(symbol string) {
} }
decl := typ.Decl decl := typ.Decl
spec := pkg.findTypeSpec(decl, typ.Name) spec := pkg.findTypeSpec(decl, typ.Name)
trimUnexportedFields(spec) trimUnexportedElems(spec)
// If there are multiple types defined, reduce to just this one. // If there are multiple types defined, reduce to just this one.
if len(decl.Specs) > 1 { if len(decl.Specs) > 1 {
decl.Specs = []ast.Spec{spec} decl.Specs = []ast.Spec{spec}
...@@ -366,22 +366,26 @@ func (pkg *Package) symbolDoc(symbol string) { ...@@ -366,22 +366,26 @@ func (pkg *Package) symbolDoc(symbol string) {
} }
} }
// trimUnexportedFields modifies spec in place to elide unexported fields (unless // trimUnexportedElems modifies spec in place to elide unexported fields from
// the unexported flag is set). If spec is not a structure declartion, nothing happens. // structs and methods from interfaces (unless the unexported flag is set).
func trimUnexportedFields(spec *ast.TypeSpec) { func trimUnexportedElems(spec *ast.TypeSpec) {
if *unexported { if *unexported {
// We're printing all fields. return fields
return
} }
// It must be a struct for us to care. (We show unexported methods in interfaces.) switch typ := spec.Type.(type) {
structType, ok := spec.Type.(*ast.StructType) case *ast.StructType:
if !ok { typ.Fields = trimUnexportedFields(typ.Fields, "fields")
return case *ast.InterfaceType:
typ.Methods = trimUnexportedFields(typ.Methods, "methods")
} }
}
// trimUnexportedFields returns the field list trimmed of unexported fields.
func trimUnexportedFields(fields *ast.FieldList, what string) *ast.FieldList {
trimmed := false trimmed := false
list := make([]*ast.Field, 0, len(structType.Fields.List)) list := make([]*ast.Field, 0, len(fields.List))
for _, field := range structType.Fields.List { for _, field := range fields.List {
// Trims if any is unexported. Fine in practice. // Trims if any is unexported. Good enough in practice.
ok := true ok := true
for _, name := range field.Names { for _, name := range field.Names {
if !isExported(name.Name) { if !isExported(name.Name) {
...@@ -394,19 +398,23 @@ func trimUnexportedFields(spec *ast.TypeSpec) { ...@@ -394,19 +398,23 @@ func trimUnexportedFields(spec *ast.TypeSpec) {
list = append(list, field) list = append(list, field)
} }
} }
if trimmed { if !trimmed {
unexportedField := &ast.Field{ return fields
Type: ast.NewIdent(""), // Hack: printer will treat this as a field with a named type. }
Comment: &ast.CommentGroup{ unexportedField := &ast.Field{
List: []*ast.Comment{ Type: ast.NewIdent(""), // Hack: printer will treat this as a field with a named type.
&ast.Comment{ Comment: &ast.CommentGroup{
Text: "// Has unexported fields.\n", List: []*ast.Comment{
}, &ast.Comment{
Text: fmt.Sprintf("// Has unexported %s.\n", what),
}, },
}, },
} },
list = append(list, unexportedField) }
structType.Fields.List = list return &ast.FieldList{
Opening: fields.Opening,
List: append(list, unexportedField),
Closing: fields.Closing,
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment