Commit 10821845 authored by Rob Pike's avatar Rob Pike

cmd/doc: handle embedded fields properly

The structure of the code meant that an embedded field was never
checked for export status. We need to check the name of the type,
which is either of type T or type *T, and T might be unexported.

Fixes #14356.

Change-Id: I56f468e9b8ae67e9ed7509ed0b91d860507baed2
Reviewed-on: https://go-review.googlesource.com/19701Reviewed-by: default avatarRobert Griesemer <gri@golang.org>
parent a4b83394
......@@ -221,6 +221,7 @@ var tests = []test{
`type ExportedType struct`, // Type definition.
`Comment before exported field.*\n.*ExportedField +int` +
`.*Comment on line with exported field.`,
`ExportedEmbeddedType.*Comment on line with exported embedded field.`,
`Has unexported fields`,
`func \(ExportedType\) ExportedMethod\(a int\) bool`,
`const ExportedTypedConstant ExportedType = iota`, // Must include associated constant.
......@@ -228,6 +229,7 @@ var tests = []test{
},
[]string{
`unexportedField`, // No unexported field.
`int.*embedded`, // No unexported embedded field.
`Comment about exported method.`, // No comment about exported method.
`unexportedMethod`, // No unexported method.
`unexportedTypedConstant`, // No unexported constant.
......@@ -241,7 +243,11 @@ var tests = []test{
`Comment about exported type`, // Include comment.
`type ExportedType struct`, // Type definition.
`Comment before exported field.*\n.*ExportedField +int`,
`unexportedField int.*Comment on line with unexported field.`,
`unexportedField.*int.*Comment on line with unexported field.`,
`ExportedEmbeddedType.*Comment on line with exported embedded field.`,
`\*ExportedEmbeddedType.*Comment on line with exported embedded \*field.`,
`unexportedType.*Comment on line with unexported embedded field.`,
`\*unexportedType.*Comment on line with unexported embedded \*field.`,
`func \(ExportedType\) unexportedMethod\(a int\) bool`,
`unexportedTypedConstant`,
},
......@@ -448,7 +454,6 @@ var trimTests = []trimTest{
{"", "", "", true},
{"/usr/gopher", "/usr/gopher", "/usr/gopher", true},
{"/usr/gopher/bar", "/usr/gopher", "bar", true},
{"/usr/gopher", "/usr/gopher", "/usr/gopher", true},
{"/usr/gopherflakes", "/usr/gopher", "/usr/gopherflakes", false},
{"/usr/gopher/bar", "/usr/zot", "/usr/gopher/bar", false},
}
......
......@@ -487,9 +487,27 @@ func trimUnexportedFields(fields *ast.FieldList, what string) *ast.FieldList {
trimmed := false
list := make([]*ast.Field, 0, len(fields.List))
for _, field := range fields.List {
names := field.Names
if len(names) == 0 {
// Embedded type. Use the name of the type. It must be of type ident or *ident.
// Nothing else is allowed.
switch ident := field.Type.(type) {
case *ast.Ident:
names = []*ast.Ident{ident}
case *ast.StarExpr:
// Must have the form *identifier.
if ident, ok := ident.X.(*ast.Ident); ok {
names = []*ast.Ident{ident}
}
}
if names == nil {
// Can only happen if AST is incorrect. Safe to continue with a nil list.
log.Print("invalid program: unexpected type for embedded field")
}
}
// Trims if any is unexported. Good enough in practice.
ok := true
for _, name := range field.Names {
for _, name := range names {
if !isExported(name.Name) {
trimmed = true
ok = false
......
......@@ -60,8 +60,12 @@ func internalFunc(a int) bool
// Comment about exported type.
type ExportedType struct {
// Comment before exported field.
ExportedField int // Comment on line with exported field.
unexportedField int // Comment on line with unexported field.
ExportedField int // Comment on line with exported field.
unexportedField int // Comment on line with unexported field.
ExportedEmbeddedType // Comment on line with exported embedded field.
*ExportedEmbeddedType // Comment on line with exported embedded *field.
unexportedType // Comment on line with unexported embedded field.
*unexportedType // Comment on line with unexported embedded *field.
}
// Comment about exported method.
......
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