示例#1
0
func invokeByName(obj interface{}, name string, in ...reflect.Value) []reflect.Value {
	ov := reflect.NewValue(obj)
	ot := ov.Type()
	var fn *reflect.FuncValue = nil
	for i := 0; i < ot.NumMethod(); i++ {
		if ot.Method(i).Name == name {
			fn = ot.Method(i).Func
			break
		}
	}
	if fn == nil {
		return []reflect.Value{reflect.NewValue(nil)}
	}
	params := make([]reflect.Value, len(in)+1)
	params[0] = ov
	for i := 1; i < len(params); i++ {
		params[i] = in[i-1]
	}
	return fn.Call(params)
}
示例#2
0
文件: web.go 项目: kylelemons/web.go
//Calls a function with recover block
func (s *Server) safelyCall(function *reflect.FuncValue, args []reflect.Value) (resp []reflect.Value, e interface{}) {
	defer func() {
		if err := recover(); err != nil {
			if !s.Config.RecoverPanic {
				// go back to panic
				panic(err)
			} else {
				e = err
				resp = nil
				s.Logger.Println("Handler crashed with error", err)
				for i := 1; ; i += 1 {
					_, file, line, ok := runtime.Caller(i)
					if !ok {
						break
					}
					s.Logger.Println(file, line)
				}
			}
		}
	}()
	return function.Call(args), nil
}
示例#3
0
文件: thread.go 项目: gaxxx/funx
func newThread(route []interface{}) *Thread {
	if len(route) == 0 {
		return nil
	}
	first := reflect.NewValue(route[0])
	args := make([]reflect.Value, 0, 8)
	canStop := true
	ok := false
	var fv *reflect.FuncValue
	switch first.(type) {
	case *reflect.PtrValue:
		{
			if len(route) < 2 {
				return nil
			}
			if str, typeok := route[1].(string); typeok {
				fv = getMemFunc(first.(*reflect.PtrValue), str)
				typ := fv.Type().(*reflect.FuncType)
				needArgs := typ.NumIn()
				actualArgs := len(route) - 1
				if needArgs == actualArgs {
					ok = true
					canStop = false
				} else if needArgs == actualArgs+1 {
					canStop = true
					ok = checkLastArg(typ)
				}
				if ok {
					args = append(args, first)
					for _, i := range route[2:] {
						args = append(args, reflect.NewValue(i))
					}
				}
			}
		}
	case *reflect.FuncValue:
		{
			fv = first.(*reflect.FuncValue)
			typ := fv.Type().(*reflect.FuncType)
			needArgs := typ.NumIn()
			actualArgs := len(route) - 1
			if needArgs == actualArgs {
				ok = true
				canStop = false
			} else if needArgs == actualArgs+1 {
				canStop = true
				ok = checkLastArg(typ)
			}
			if ok {
				for _, i := range route[1:] {
					args = append(args, reflect.NewValue(i))
				}
			}
		}
	}

	if ok {
		t := new(Thread)
		t.fv = fv
		t.canStop = canStop
		t.args = args
		return t
	}
	return nil
}
示例#4
0
// 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)
}
示例#5
0
文件: gocheck.go 项目: nuin/ampify
func (c *C) logArgPanic(funcValue *reflect.FuncValue, expectedType string) {
	c.logf("... Panic: %s argument should be %s",
		niceFuncName(funcValue.Get()), expectedType)
}