// tryOneFunction is the common code for tryMethod and tryFunction. func tryOneFunction(pkg, firstArg, name string, typ *reflect.FuncType, rfn *reflect.FuncValue, args []interface{}) { // Any results? if typ.NumOut() == 0 { return // Nothing to do. } // Right number of arguments + results? if typ.NumIn()+typ.NumOut() != len(args) { return } // Right argument and result types? for i, a := range args { if i < typ.NumIn() { if !compatible(a, typ.In(i)) { return } } else { if !compatible(a, typ.Out(i-typ.NumIn())) { return } } } // Build the call args. argsVal := make([]reflect.Value, typ.NumIn()+typ.NumOut()) for i, a := range args { argsVal[i] = reflect.NewValue(a) } // Call the function and see if the results are as expected. resultVal := rfn.Call(argsVal[:typ.NumIn()]) for i, v := range resultVal { if !reflect.DeepEqual(v.Interface(), args[i+typ.NumIn()]) { return } } // Present the result including a godoc command to get more information. firstIndex := 0 if firstArg != "" { fmt.Fprintf(output, "%s.%s(", firstArg, name) firstIndex = 1 } else { fmt.Fprintf(output, "%s.%s(", pkg, name) } for i := firstIndex; i < typ.NumIn(); i++ { if i > firstIndex { fmt.Fprint(output, ", ") } fmt.Fprintf(output, "%#v", args[i]) } fmt.Fprint(output, ") = ") if typ.NumOut() > 1 { fmt.Fprint(output, "(") } for i := 0; i < typ.NumOut(); i++ { if i > 0 { fmt.Fprint(output, ", ") } fmt.Fprintf(output, "%#v", resultVal[i].Interface()) } if typ.NumOut() > 1 { fmt.Fprint(output, ")") } fmt.Fprintf(output, " // godoc %s %s\n", pkg, name) }