// filterFieldList removes unexported fields (field names) from the field list // in place and returns true if fields were removed. Anonymous fields are // recorded with the parent type. filterType is called with the types of // all remaining fields. // func (r *reader) filterFieldList(parent *namedType, fields *ast.FieldList) (removedFields bool) { if fields == nil { return } list := fields.List j := 0 for _, field := range list { keepField := false if n := len(field.Names); n == 0 { // anonymous field name := r.recordAnonymousField(parent, field.Type) if ast.IsExported(name) { keepField = true } } else { field.Names = filterIdentList(field.Names) if len(field.Names) < n { removedFields = true } if len(field.Names) > 0 { keepField = true } } if keepField { r.filterType(nil, field.Type) list[j] = field j++ } } if j < len(list) { removedFields = true } fields.List = list[0:j] return }
func (p *parser) parseParams(n *parse.Node, scope *ast.Scope) *ast.FieldList { fieldList := ast.FieldList{ Opening: token.Pos(n.Child(0).Pos()), Closing: token.Pos(n.LastChild().Pos()), } if n.Child(1).Is(parameterList) { eachListItem(parameterDecl, n.Child(1), func(item *parse.Node) { fieldList.List = append(fieldList.List, p.parseParamDecl(item, scope)) }) } return &fieldList }
// removeFieldNames removes names from the FieldList in place. // This is used to remove names from return values func removeFieldNames(fl *ast.FieldList) { l := []*ast.Field{} for _, f := range fl.List { if f.Names == nil { l = append(l, f) } else { for range f.Names { nf := *f nf.Names = nil l = append(l, &nf) } } } fl.List = l }
func (p *parser) parseInterfaceType(n *parse.Node) ast.Expr { keywordPos := token.Pos(n.Child(0).Pos()) n = n.Child(1) specs := ast.FieldList{ Opening: token.Pos(n.Child(0).Pos()), Closing: token.Pos(n.LastChild().Pos()), } if n.ChildCount() > 2 { eachListItem(methodSpec, n.Child(1), func(item *parse.Node) { specs.List = append(specs.List, p.parseMethodSpec(item)) }) } return &ast.InterfaceType{ Interface: keywordPos, Methods: &specs, } }
// filterFieldList removes unexported fields (field names) from the field list // in place and returns true if fields were removed. Removed fields that are // anonymous (embedded) fields are added as embedded types to base. filterType // is called with the types of all remaining fields. // func (r *reader) filterFieldList(base *baseType, fields *ast.FieldList) (removedFields bool) { if fields == nil { return } list := fields.List j := 0 for _, field := range list { keepField := false if n := len(field.Names); n == 0 { // anonymous field name, imp := baseTypeName(field.Type) if ast.IsExported(name) { // we keep the field - in this case r.readDecl // will take care of adding the embedded type keepField = true } else if base != nil && !imp { // we don't keep the field - add it as an embedded // type so we won't loose its methods, if any if embedded := r.lookupType(name); embedded != nil { _, ptr := field.Type.(*ast.StarExpr) base.addEmbeddedType(embedded, ptr) } } } else { field.Names = filterIdentList(field.Names) if len(field.Names) < n { removedFields = true } if len(field.Names) > 0 { keepField = true } } if keepField { r.filterType(nil, field.Type) list[j] = field j++ } } if j < len(list) { removedFields = true } fields.List = list[0:j] return }
// filterFieldList removes unexported fields (field names) from the field list // in place and returns true if fields were removed. Anonymous fields are // recorded with the parent type. filterType is called with the types of // all remaining fields. // func (r *reader) filterFieldList(parent *namedType, fields *ast.FieldList, ityp *ast.InterfaceType) (removedFields bool) { if fields == nil { return } list := fields.List j := 0 for _, field := range list { keepField := false if n := len(field.Names); n == 0 { // anonymous field fname := r.recordAnonymousField(parent, field.Type) if ast.IsExported(fname) { keepField = true } else if ityp != nil && fname == "error" { // possibly the predeclared error interface; keep // it for now but remember this interface so that // it can be fixed if error is also defined locally keepField = true r.remember(ityp) } } else { field.Names = filterIdentList(field.Names, false) if len(field.Names) < n { removedFields = true } if len(field.Names) > 0 { keepField = true } } if keepField { r.filterType(nil, field.Type) list[j] = field j++ } } if j < len(list) { removedFields = true } fields.List = list[0:j] return }
// Struct creates a struct{} expression. The arguments are a series // of name/type/tag tuples. Name must be of type *ast.Ident, type // must be of type ast.Expr, and tag must be of type *ast.BasicLit, // The number of arguments must be a multiple of 3, or a run-time // panic will occur. func Struct(args ...ast.Expr) *ast.StructType { fields := new(ast.FieldList) if len(args)%3 != 0 { panic("Number of args to FieldList must be a multiple of 3, got " + strconv.Itoa(len(args))) } for i := 0; i < len(args); i += 3 { var field ast.Field name, typ, tag := args[i], args[i+1], args[i+2] if name != nil { field.Names = []*ast.Ident{name.(*ast.Ident)} } if typ != nil { field.Type = typ } if tag != nil { field.Tag = tag.(*ast.BasicLit) } fields.List = append(fields.List, &field) } return &ast.StructType{Fields: fields} }