func fieldListToIdentList(fl *ast.FieldList) []ast.Expr { var fs []ast.Expr for _, f := range fl.List { for _, name := range f.Names { x := ast.Expr(ast.NewIdent(name.Name)) fs = append(fs, x) } } return fs }
// typeOfExpr gets a type corresponding to an expression. func typeOfExpr(expr ast.Expr) (reflect.Type, error) { switch expr := expr.(type) { default: return nil, fmt.Errorf("unexpected expression: %T", expr) case *ast.ArrayType: switch expr.Len { case ast.Expr(nil): // Slice sub, err := typeOfExpr(expr.Elt) if err != nil { return nil, err } return reflect.SliceOf(sub), nil default: // Parse length expression lexpr, ok := expr.Len.(*ast.BasicLit) if !ok { return nil, fmt.Errorf("invalid array size expression") } if lexpr.Kind != token.INT { return nil, fmt.Errorf("invalid array size type") } len, err := strconv.Atoi(lexpr.Value) if err != nil { return nil, err } // Parse elem type expression sub, err := typeOfExpr(expr.Elt) if err != nil { return nil, err } return arrayOf(len, sub), nil } case *ast.Ident: // Primitive types typ, ok := typeMap[expr.Name] if !ok { return nil, fmt.Errorf("unknown type %s", expr.Name) } return typ, nil case *ast.StarExpr: // Pointer sub, err := typeOfExpr(expr.X) if err != nil { return nil, err } return reflect.PtrTo(sub), nil case *ast.ChanType: return nil, fmt.Errorf("channel type not allowed") case *ast.MapType: return nil, fmt.Errorf("map type not allowed") } }