`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.
},
[]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.
`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`,
},
{"", "", "", 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},
}
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
// 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.