Beispiel #1
0
// 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
}
Beispiel #2
0
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
}
Beispiel #3
0
// 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
}
Beispiel #4
0
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,
	}
}
Beispiel #5
0
// 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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
// 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}
}