示例#1
0
//get the value with with the matching name inside v.
//This value can be a struct field, a method attached to a struct or a value in a map
func getReflectValue(v reflect.Value, valueName string) (value reflect.Value, ok bool) {

	// first check if input was a map and handle that.
	// otherwise input was a struct or pointer to a struct
	if v.Kind() == reflect.Map {
		value = v.MapIndex(reflect.ValueOf(valueName))
		if value.IsValid() {
			if value.Kind() == reflect.Func {
				value = getFuncSingleReturnValue(value)
			}
			ok = true
			return value, true
		}
	}

	value = reflect.Indirect(v).FieldByName(valueName)
	if value.IsValid() {
		if value.Kind() == reflect.Func {
			value = getFuncSingleReturnValue(value)
		}
		ok = true
		return
	}

	value = v.MethodByName(valueName)
	if value.IsValid() {
		value = getFuncSingleReturnValue(value)
		ok = true
		return
	}

	return
}
示例#2
0
文件: option.go 项目: chzyer/flagly
func GetMethod(s reflect.Value, name string) reflect.Value {
	method := s.MethodByName(name)
	if !method.IsValid() {
		method = s.Elem().MethodByName(name)
	}
	return method
}
示例#3
0
文件: bean.go 项目: gogap/aop
func (p *Bean) Invoke(methodName string, args Args, callback ...interface{}) (returnFunc func(), err error) {
	var beanValue reflect.Value

	beanValue = reflect.ValueOf(p.instance)

	inputs := make([]reflect.Value, len(args))

	for i := range args {
		inputs[i] = reflect.ValueOf(args[i])
	}

	values := beanValue.MethodByName(methodName).Call(inputs)

	if values != nil && len(values) > 0 {
		lastV := values[len(values)-1]
		if lastV.Interface() != nil {
			if errV, ok := lastV.Interface().(error); ok {
				if errV != nil {
					err = errV
					return
				}
			}
		}
	}

	if callback != nil && len(callback) > 0 {
		returnFunc = func() {
			reflect.ValueOf(callback[0]).Call(values)
		}
	}

	return
}
示例#4
0
func runMethodIfExists(v reflect.Value, name string, args ...interface{}) {
	method := v.MethodByName(name)
	if method.Kind() == reflect.Invalid {
		return
	}

	if method.Type().NumIn() != len(args) {
		panic(fmt.Sprintf(
			"%s: expected %d args, actually %d.",
			name,
			len(args),
			method.Type().NumIn()))
	}

	// Create a slice of reflect.Values to pass to the method. Simultaneously
	// check types.
	argVals := make([]reflect.Value, len(args))
	for i, arg := range args {
		argVal := reflect.ValueOf(arg)

		if argVal.Type() != method.Type().In(i) {
			panic(fmt.Sprintf(
				"%s: expected arg %d to have type %v.",
				name,
				i,
				argVal.Type()))
		}

		argVals[i] = argVal
	}

	method.Call(argVals)
}
示例#5
0
func applyToStruct(obj reflect.Value, head P, mid string, tail P, ctx *Context) error {
	if mid != "*" {
		result := obj.FieldByName(mid)

		if result.Kind() == reflect.Invalid {
			result = obj.MethodByName(mid)
		}

		if result.Kind() == reflect.Invalid {
			return fmt.Errorf("no field '%s' in type '%s' at '%s'", mid, obj.Type(), head)
		}

		return apply(result, append(head, mid), tail, ctx)
	}

	typ := obj.Type()

	for i := 0; i < typ.NumField() && !ctx.stop; i++ {
		if err := applyToStruct(obj, head, typ.Field(i).Name, tail, ctx); err != nil && err != ErrMissing {
			return err
		}
	}

	return nil
}
示例#6
0
文件: structs.go 项目: epek/structs
// from encoding/json
func isEmptyValue(v reflect.Value) bool {
	switch v.Kind() {
	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
		return v.Len() == 0
	case reflect.Bool:
		return !v.Bool()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return v.Uint() == 0
	case reflect.Float32, reflect.Float64:
		return v.Float() == 0
	case reflect.Interface, reflect.Ptr:
		return v.IsNil()
	}
	z := v.MethodByName("IsZero")
	if z.IsValid() {
		return z.Call(nil)[0].Interface().(bool)
	}
	// This shouldn't really happen...
	zero := reflect.Zero(v.Type()).Interface()
	current := v.Interface()
	return reflect.DeepEqual(current, zero)

}
示例#7
0
//get the value with with the matching name inside v.
//This value can be a struct field, a method attached to a struct or a value in a map
func getReflectValue(v reflect.Value, valueName string) (reflect.Value, bool) {
	value := reflect.Indirect(v).FieldByName(valueName)
	if value.IsValid() {
		if value.Kind() == reflect.Func {
			value = getFuncSingleReturnValue(value)
		}
		return value, true
	}

	if v.Kind() == reflect.Map {
		value = v.MapIndex(reflect.ValueOf(valueName))
		if value.IsValid() {
			if value.Kind() == reflect.Func {
				value = getFuncSingleReturnValue(value)
			}
			return value, true
		}
	}

	value = v.MethodByName(valueName)
	if value.IsValid() {
		value = getFuncSingleReturnValue(value)
		return value, true
	}

	return reflect.Value{}, false
}
示例#8
0
func getResult(method string, vResourcePtr *reflect.Value) (result interface{}) {
	defer func() {
		if r := recover(); r != nil {
			rstr := fmt.Sprintf("%s", r)
			result = internalError{
				where: lineInfo(3),
				why:   rstr + fullTrace(5, "\n\t"),
				code:  errorCode(rstr),
			}
		}
	}()

	methodName := strings.Title(strings.ToLower(method))
	if methodName == "Head" {
		methodName = "Get"
	}
	vMethod := vResourcePtr.MethodByName(methodName)
	if vMethod.IsValid() {
		result = vMethod.Call([]reflect.Value{})[0].Interface()
	}

	if result == nil {
		return methodNotAllowed{getAllowed(vResourcePtr)}
	}
	return
}
示例#9
0
// get public method by name
func MethodByName(v reflect.Value, name string) (m reflect.Value, ok bool) {
	m = v.MethodByName(strings.Title(name))
	if m.IsValid() && m.Kind() == reflect.Func {
		return m, true
	}
	return
}
示例#10
0
// getMethodValue the method value from the method context and method name
func getMethodValue(t *Task) (method reflect.Value, err error) {
	// Will look for the method on both a
	// pointer and a value receiver
	var ptr reflect.Value
	var val reflect.Value

	val = reflect.ValueOf(t.MethodState)

	if val.Type().Kind() == reflect.Ptr {
		ptr = val
		val = ptr.Elem()
	} else {
		ptr = reflect.New(val.Type())
		ptr.Elem().Set(val)
	}

	method = val.MethodByName(t.Method)
	if method.IsValid() {
		return
	}

	method = ptr.MethodByName(t.Method)
	if method.IsValid() {
		return
	}

	err = errors.New("Method not found")

	return
}
示例#11
0
文件: call.go 项目: ttthzy/qlang
func function2Func(in *reflect.Value, t reflect.Type) {

	fn := in.MethodByName("Call")
	wrap := func(args []reflect.Value) (results []reflect.Value) {
		ret := fn.Call(args)[0]
		n := t.NumOut()
		if n == 0 {
			return
		}
		if n == 1 {
			if t.Out(0) != typeIntf {
				ret = ret.Elem()
			}
			return []reflect.Value{ret}
		}
		if ret.Kind() != reflect.Slice || ret.Len() != n {
			panic(fmt.Sprintf("unexpected return value count, we need `%d` values", n))
		}
		results = make([]reflect.Value, n)
		for i := 0; i < n; i++ {
			result := ret.Index(i)
			if t.Out(i) != typeIntf {
				result = result.Elem()
			}
			results[i] = result
		}
		return
	}
	*in = reflect.MakeFunc(t, wrap)
}
示例#12
0
文件: app.go 项目: tempbottle/xweb
// safelyCall invokes `function` in recover block
func (a *App) SafelyCall(vc reflect.Value, method string, args []reflect.Value) (resp []reflect.Value, err error) {
	defer func() {
		if e := recover(); e != nil {
			if !a.Server.Config.RecoverPanic {
				// go back to panic
				panic(e)
			} else {
				resp = nil
				var content string
				content = fmt.Sprintf("Handler crashed with error: %v", e)
				for i := 1; ; i += 1 {
					_, file, line, ok := runtime.Caller(i)
					if !ok {
						break
					} else {
						content += "\n"
					}
					content += fmt.Sprintf("%v %v", file, line)
				}
				a.Error(content)
				err = errors.New(content)
				return
			}
		}
	}()
	function := vc.MethodByName(method)
	return function.Call(args), err
}
示例#13
0
文件: datalog.go 项目: ssokol/stratux
func structCanBeMarshalled(v reflect.Value) bool {
	m := v.MethodByName("String")
	if m.IsValid() && !m.IsNil() {
		return true
	}
	return false
}
示例#14
0
func (scope *Scope) callMethod(methodName string, reflectValue reflect.Value) {
	// Only get address from non-pointer
	if reflectValue.CanAddr() && reflectValue.Kind() != reflect.Ptr {
		reflectValue = reflectValue.Addr()
	}

	if methodValue := reflectValue.MethodByName(methodName); methodValue.IsValid() {
		switch method := methodValue.Interface().(type) {
		case func():
			method()
		case func(*Scope):
			method(scope)
		case func(*DB):
			newDB := scope.NewDB()
			method(newDB)
			scope.Err(newDB.Error)
		case func() error:
			scope.Err(method())
		case func(*Scope) error:
			scope.Err(method(scope))
		case func(*DB) error:
			newDB := scope.NewDB()
			scope.Err(method(newDB))
			scope.Err(newDB.Error)
		default:
			scope.Err(fmt.Errorf("unsupported function %v", methodName))
		}
	}
}
示例#15
0
func callGoMethod(L *lua.State, name string, st reflect.Value) {
	ret := st.MethodByName(name)
	if !ret.IsValid() {
		fmt.Println("whoops")
	}
	L.PushGoFunction(GoLuaFunc(L, ret))
}
示例#16
0
func applyToPtr(obj reflect.Value, head, tail P, ctx *Context) error {

	if result := obj.MethodByName(tail[0]); result.Kind() != reflect.Invalid {
		return apply(result, append(head, tail[0]), tail[1:], ctx)
	}

	return apply(obj.Elem(), head, tail, ctx)
}
示例#17
0
func FindMouseMoveActionMethod(v reflect.Value, name string) MouseMoveAction {
	m := v.MethodByName(name)
	if m.IsValid() {
		return MouseMoveAction(m.Interface().(func(glm.Vec2d, glm.Vec2d)))
	} else {
		return nil
	}
}
示例#18
0
func FindActionMethod(v reflect.Value, name string) Action {
	m := v.MethodByName(name)
	if m.IsValid() {
		return Action(m.Interface().(func()))
	} else {
		return nil
	}
}
示例#19
0
文件: curd.go 项目: kobeld/mgowrap
func callCollectionName(value reflect.Value) string {
	method := value.MethodByName("CollectionName")
	if !method.IsValid() {
		panic(value.String() + ` does not implement "CollectionName" method`)
	}

	return method.Call([]reflect.Value{})[0].String()
}
示例#20
0
func reflectValueFromPath(root reflect.Value, path []string) (reflect.Value, error) {
	v := root

	for _, name := range path {
		var p reflect.Value
		for v.Kind() == reflect.Ptr {
			p = v
			v = v.Elem()
		}

		// Try as field first.
		var f reflect.Value
		if v.Kind() == reflect.Struct {
			f = v.FieldByName(name)
		}
		if f.IsValid() {
			v = f
		} else {
			// No field, so let's see if we got a method.
			var m reflect.Value
			if p.IsValid() {
				// Try pointer receiver first.
				m = p.MethodByName(name)
			}

			if !m.IsValid() {
				// No pointer, try directly.
				m = v.MethodByName(name)
			}
			if !m.IsValid() {
				return v, fmt.Errorf("bad member: '%s'", strings.Join(path, "."))
			}

			// We assume it takes no args and returns one mandatory value plus
			// maybe an error.
			rvs := m.Call(nil)
			switch len(rvs) {
			case 1:
				v = rvs[0]

			case 2:
				rv2 := rvs[1].Interface()
				if err, ok := rv2.(error); ok {
					return v, err
				} else if rv2 != nil {
					return v, fmt.Errorf("Second method return value must implement error.")
				}

				v = rvs[0]

			default:
				return v, fmt.Errorf("Method must return a value plus optionally an error: %s", name)
			}
		}
	}

	return v, nil
}
示例#21
0
文件: rs.go 项目: justinsb/gova
func findFirstMethod(target *reflect.Value, methodNames []string) *reflect.Value {
	for _, methodName := range methodNames {
		method := target.MethodByName(methodName)
		if method.IsValid() {
			return &method
		}
	}
	return nil
}
示例#22
0
func toTimeUnix(v reflect.Value) int64 {
	if v.Kind() == reflect.Interface {
		return toTimeUnix(v.Elem())
	}
	if v.Type() != timeType {
		panic("coding error: argument must be time.Time type reflect Value")
	}
	return v.MethodByName("Unix").Call([]reflect.Value{})[0].Int()
}
示例#23
0
文件: gorp.go 项目: joeshaw/gorp
func runHook(name string, eptr reflect.Value, arg []reflect.Value) error {
	hook := eptr.MethodByName(name)
	if hook != zeroVal {
		ret := hook.Call(arg)
		if len(ret) > 0 && !ret[0].IsNil() {
			return ret[0].Interface().(error)
		}
	}
	return nil
}
示例#24
0
// getTableName get struct table name.
// If the struct implement the TableName, then get the result as tablename
// else use the struct name which will apply snakeString.
func getTableName(val reflect.Value) string {
	if fun := val.MethodByName("TableName"); fun.IsValid() {
		vals := fun.Call([]reflect.Value{})
		// has return and the first val is string
		if len(vals) > 0 && vals[0].Kind() == reflect.String {
			return vals[0].String()
		}
	}
	return snakeString(reflect.Indirect(val).Type().Name())
}
示例#25
0
// get table engine, mysiam or innodb.
func getTableEngine(val reflect.Value) string {
	fun := val.MethodByName("TableEngine")
	if fun.IsValid() {
		vals := fun.Call([]reflect.Value{})
		if len(vals) > 0 && vals[0].Kind() == reflect.String {
			return vals[0].String()
		}
	}
	return ""
}
示例#26
0
文件: packet.go 项目: kelixin/go.pkt
func compare_value(a, b reflect.Value) bool {
	if a.Type() != b.Type() {
		return false
	}

	m := a.MethodByName("Equal")
	if m.IsValid() {
		res := m.Call([]reflect.Value{b})
		return res[0].Bool()
	}

	switch a.Kind() {
	case reflect.Bool:
		return a.Bool() == b.Bool()

	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return a.Uint() == b.Uint()

	case reflect.Array:
		for i := 0; i < a.Len(); i++ {
			if !compare_value(a.Index(i), b.Index(i)) {
				return false
			}
		}

		return true

	case reflect.Slice:
		if a.IsNil() != b.IsNil() {
			return false
		}

		if a.Len() != b.Len() {
			return false
		}

		if a.Pointer() == b.Pointer() {
			return true
		}

		for i := 0; i < a.Len(); i++ {
			if !compare_value(a.Index(i), b.Index(i)) {
				return false
			}
		}

		return true

	case reflect.Interface:
		return true

	default:
		return false
	}
}
示例#27
0
文件: dot.go 项目: kooksee/gisp2
func (dot Dot) evalValue(env Env, val reflect.Value, name Atom) (interface{}, error) {
	if val.Kind() == reflect.Struct {
		if field := val.FieldByName(name.Name); field.IsValid() {
			return Value(field), nil
		}
	}
	if method := val.MethodByName(name.Name); method.IsValid() {
		return method, nil
	}
	return nil, NameInvalid{name.Name}
}
示例#28
0
func (this FakeDataParse) call(data reflect.Value, name string) string {
	// get a reflect.Value for the method
	methodVal := data.MethodByName(name)
	// turn that into an interface{}
	methodIface := methodVal.Interface()
	// turn that into a function that has the expected signature
	method := methodIface.(func() string)
	// call the method directly
	res := method()
	return res
}
示例#29
0
func (p *proxy) getMethod(key string, v reflect.Value) (reflect.Value, bool) {
	var r reflect.Value
	for _, name := range nameToGo(key) {
		r = v.MethodByName(name)
		if r.IsValid() {
			break
		}
	}

	return r, r.IsValid()
}
示例#30
0
func triggerRun(method string, sender reflect.Value, arg []reflect.Value) (err error) {
	m := sender.MethodByName(method)
	if !m.IsValid() {
		return
	}
	ret := m.Call(arg)
	if len(ret) <= 0 || ret[0].IsNil() {
		return
	}
	return ret[0].Interface().(error)
}