func (r *ReflectRouter) CallFunc(context *HttpContext, funcName string, option *RouterOption) (returnValue interface{}, statusCode HttpStatus, err error) { if index, ok := r.checkFuncName[funcName]; ok { statusCode = Status200 var controller reflect.Value if reflect.Invalid != option.RouterDataRefVal.Kind() { controller = option.RouterDataRefVal } else { controller = r.ctlRefVal } refMet := controller.Method(index) // get params args := r.getFuncArgs(refMet.Type(), context) // call method reVals := refMet.Call(args) if 0 != len(reVals) { returnValue = reVals[0].Interface() } } else { statusCode = Status404 err = NewLeafveinError("(" + r.typestr + ") not found func name: " + funcName) } return }
// Evaluate interfaces and pointers looking for a value that can look up the name, via a // struct field, method, or map key, and return the result of the lookup. func (t *Template) lookup(st *state, v reflect.Value, name string) reflect.Value { for v != nil { typ := v.Type() if n := v.Type().NumMethod(); n > 0 { for i := 0; i < n; i++ { m := typ.Method(i) mtyp := m.Type if m.Name == name && mtyp.NumIn() == 1 && mtyp.NumOut() == 1 { if !isExported(name) { t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type()) } return v.Method(i).Call(nil)[0] } } } switch av := v.(type) { case *reflect.PtrValue: v = av.Elem() case *reflect.InterfaceValue: v = av.Elem() case *reflect.StructValue: if !isExported(name) { t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type()) } return av.FieldByName(name) case *reflect.MapValue: return av.Elem(reflect.NewValue(name)) default: return nil } } return v }
func (s *Scrubber) collectMethods(v reflect.Value, path Path, callbackMap map[string]Path) { for i := 0; i < v.NumMethod(); i++ { if v.Type().Method(i).PkgPath == "" { // exported name := v.Type().Method(i).Name name = strings.ToLower(name[0:1]) + name[1:] s.registerCallback(v.Method(i), append(path, name), callbackMap) } } }
// TODO: delete when reflect's own MethodByName is released. func methodByName(receiver reflect.Value, name string) (reflect.Value, bool) { typ := receiver.Type() for i := 0; i < typ.NumMethod(); i++ { if typ.Method(i).Name == name { return receiver.Method(i), true // This value includes the receiver. } } return zero, false }
func (pgv *pgValue) getValue(v reflect.Value) reflect.Value { switch pgv.Source.(type) { case reflect.StructField: return v.FieldByIndex(pgv.Index) case reflect.Method: return v.Method(pgv.Index[0]).Call(nil)[0] default: panic("not reached") } }
func init() { var opcode Opcode var opcodeType reflect.Type = reflect.TypeOf(opcode) var opcodeValue reflect.Value = reflect.ValueOf(opcode) numMethods := opcodeType.NumMethod() for i := 0; i < numMethods; i++ { funcName := opcodeType.Method(i).Name funcValue := opcodeValue.Method(i) funcTable[funcName] = funcValue } }
func (ctx *Context) pushStructMethods(obj int, t reflect.Type, v reflect.Value) { mCount := t.NumMethod() for i := 0; i < mCount; i++ { methodName := t.Method(i).Name if !isExported(methodName) { continue } ctx.PushGoFunction(v.Method(i).Interface()) ctx.PutPropString(obj, nameToJavaScript(methodName)) } }
// methods walks over a structure and scrubs its exported methods. func (s *Scrubber) methods(rv reflect.Value, path Path, callbacks map[string]Path) { for i := 0; i < rv.NumMethod(); i++ { if rv.Type().Method(i).PkgPath == "" { // exported cb, ok := rv.Method(i).Interface().(func(*Partial)) if !ok { continue } name := rv.Type().Method(i).Name name = strings.ToLower(name[0:1]) + name[1:] s.register(cb, append(path, name), callbacks) } } }
// Return the result of calling the Iter method on v, or nil. func iter(v reflect.Value) *reflect.ChanValue { for j := 0; j < v.Type().NumMethod(); j++ { mth := v.Type().Method(j) fv := v.Method(j) ft := fv.Type().(*reflect.FuncType) // TODO(rsc): NumIn() should return 0 here, because ft is from a curried FuncValue. if mth.Name != "Iter" || ft.NumIn() != 1 || ft.NumOut() != 1 { continue } ct, ok := ft.Out(0).(*reflect.ChanType) if !ok || ct.Dir()&reflect.RecvDir == 0 { continue } return fv.Call(nil)[0].(*reflect.ChanValue) } return nil }
// Return the result of calling the Iter method on v, or nil. func iter(v reflect.Value) reflect.Value { for j := 0; j < v.Type().NumMethod(); j++ { mth := v.Type().Method(j) fv := v.Method(j) ft := fv.Type() // TODO(rsc): NumIn() should return 0 here, because ft is from a curried FuncValue. if mth.Name != "Iter" || ft.NumIn() != 1 || ft.NumOut() != 1 { continue } ct := ft.Out(0) if ct.Kind() != reflect.Chan || ct.ChanDir()&reflect.RecvDir == 0 { continue } return fv.Call(nil)[0] } return reflect.Value{} }
func findHttpMethod(rcti reflect.Type, rcvi reflect.Value) map[string][]filterMethod { rcvhm := make(map[string][]filterMethod) for i := 0; i < rcti.NumMethod(); i++ { mName := rcti.Method(i).Name if hpos := strings.Index(mName, "Http_"); hpos != -1 { hpMname := mName[hpos+len("Http_"):] if mpos := strings.Index(hpMname, "_"); mpos != -1 { httpMethod := hpMname[:mpos] //len("_") == 1 objMethod := hpMname[mpos+1:] rcvhm[objMethod] = append(rcvhm[objMethod], filterMethod{ method: httpMethod, rcvm: rcvi.Method(i), }) } } } return rcvhm }
// Evaluate interfaces and pointers looking for a value that can look up the name, via a // struct field, method, or map key, and return the result of the lookup. func (t *Template) lookup(st *state, v reflect.Value, name string) reflect.Value { for v.IsValid() { typ := v.Type() if n := v.Type().NumMethod(); n > 0 { for i := 0; i < n; i++ { m := typ.Method(i) mtyp := m.Type if m.Name == name && mtyp.NumIn() == 1 && mtyp.NumOut() == 1 { if !isExported(name) { t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type()) } return v.Method(i).Call(nil)[0] } } } switch av := v; av.Kind() { case reflect.Ptr: v = av.Elem() case reflect.Interface: v = av.Elem() case reflect.Struct: if !isExported(name) { t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type()) } return av.FieldByName(name) case reflect.Map: if v := av.MapIndex(reflect.ValueOf(name)); v.IsValid() { return v } return reflect.Zero(typ.Elem()) default: return reflect.Value{} } } return v }
func newMethod(receiver reflect.Value, i int) *methodType { return &methodType{receiver.Method(i), receiver.Type().Method(i)} }
// Funkcja zwraca wartosc zmiennej o podanej nazwie lub indeksie. Jesli zmienna // jest funkcja, wczesniej wywoluje ja z podanymi argumentami. Funkcja // przeprowadza niezbedne dereferencje tak aby zwrocic zmienna, ktora nie jest // ani wskaznikiem, ani interfejsem lub zwrocic wskaznik lub interface do takiej // zmiennej. Uwaga! Funkcja moze modyfikowac wartosci args! func getVarFun(ctx, name reflect.Value, args []reflect.Value, fun bool) ( ret reflect.Value, stat int) { if !ctx.IsValid() { stat = RUN_NIL_CTX return } // Dereferencja nazwy dereference(&name) // Dereferencja jesli kontekst jest interfejsem if ctx.Kind() == reflect.Interface { ctx = ctx.Elem() } // Jesli nazwa jest stringiem probujemy znalezc metode o tej nazwie if name.Kind() == reflect.String { tt := ctx.Type() //nm := tt.NumMethod() for ii := 0; ii < tt.NumMethod(); ii++ { method := tt.Method(ii) // Sprawdzamy zgodnosc nazwy metody oraz typu receiver'a if method.Name == name.String() && tt == method.Type.In(0) { stat = argsMatch(method.Type, args, 1) if stat != RUN_OK { return } // Zwracamy pierwsza wartosc zwrocona przez metode ctx = ctx.Method(ii).Call(args)[0] // Nie pozwalamy na dalsza analize nazwy name = reflect.Value{} // Nie pozwalamy na traktowanie zwroconej zmiennej jak funkcji args = nil fun = false break } } } // Jesli name zawiera wartosc operujemy na nazwanej zmiennej z kontekstu, // w przeciwnym razie operujemy na samym kontekscie jako zmiennej. if name.IsValid() { // Pelna dereferencja kontekstu dereference(&ctx) // Pobieramy wartosc switch ctx.Kind() { case reflect.Struct: switch name.Kind() { case reflect.String: // Zwracamy pole struktury o podanej nazwie ft, ok := ctx.Type().FieldByName(name.String()) if !ok { stat = RUN_NOT_FOUND return } if ft.PkgPath != "" { stat = RUN_UNEXPORTED return } ctx = ctx.FieldByIndex(ft.Index) case reflect.Int: // Zwracamy pole sruktury o podanym indeksie fi := int(name.Int()) if fi < 0 || fi >= ctx.NumField() { stat = RUN_INDEX_OOR return } if ctx.Type().Field(fi).PkgPath != "" { stat = RUN_UNEXPORTED return } ctx = ctx.Field(fi) default: stat = RUN_NOT_FOUND return } case reflect.Map: kt := ctx.Type().Key() if !name.Type().AssignableTo(kt) { stat = RUN_NOT_FOUND } ctx = ctx.MapIndex(name) if !ctx.IsValid() { stat = RUN_NOT_FOUND return } case reflect.Array, reflect.Slice: switch name.Kind() { case reflect.Int: // Zwracamy element tablicy o podanym indeksie ei := int(name.Int()) if ei < 0 || ei >= ctx.Len() { stat = RUN_INDEX_OOR return } ctx = ctx.Index(ei) default: stat = RUN_NOT_FOUND return } case reflect.Invalid: stat = RUN_NIL_CTX return default: stat = RUN_UNK_TYPE return } } // Jesli mamy wywolanie funkcji to robimy pelna dereferencje. if fun { dereference(&ctx) } // Sprawdzenie czy ctx odnosi sie do funkcji. if ctx.Kind() == reflect.Func { ft := ctx.Type() if fun || ft.NumIn() == 0 { // Sprawdzamy zgodnosc liczby argumentow stat = argsMatch(ft, args, 0) if stat != RUN_OK { return } // Zwracamy pierwsza wrtosc zwrocaona przez funkcje. ctx = ctx.Call(args)[0] } } else if fun { stat = RUN_NOT_FUNC return } //fmt.Println("DEB getvar.ret:", reflect.Typeof(ctx.Interface())) return ctx, RUN_OK }
func (m *method) AppendValue(dst []byte, v reflect.Value, quote bool) []byte { mv := v.Method(m.Index).Call(nil)[0] return m.appender(dst, mv, quote) }
// Funkcja zwraca wartosc zmiennej o podanej nazwie lub indeksie. Jesli zmienna // jest funkcja, wczesniej wywoluje ja z podanymi argumentami. Funkcja // przeprowadza niezbedne dereferencje tak aby zwrocic zmienna, ktora nie jest // ani wskaznikiem, ani interfejsem lub zwrocic wskaznik lub interface do takiej // zmiennej. Uwaga! Funkcja moze modyfikowac wartosci args! func getVarFun(ctx, name reflect.Value, args []reflect.Value, fun bool) ( reflect.Value, int) { if ctx == nil { return nil, RUN_NIL_CTX } // Dereferencja nazwy dereference(&name) // Dereferencja jesli kontekst jest interfejsem if vi, ok := ctx.(*reflect.InterfaceValue); ok { ctx = vi.Elem() } // Jesli nazwa jest stringiem probujemy znalezc metode o tej nazwie if id, ok := name.(*reflect.StringValue); ok { tt := ctx.Type() for ii := 0; ii < tt.NumMethod(); ii++ { method := tt.Method(ii) // Sprawdzamy zgodnosc nazwy metody i typu receiver'a if method.Name == id.Get() && tt == method.Type.In(0) { stat := argsMatch(method.Type, &args, 1) if stat != RUN_OK { return nil, stat } // Zwracamy pierwsza wartosc zwrocona przez metode ctx = ctx.Method(ii).Call(args)[0] name = nil args = nil fun = false break } } } // Jesli name != nil operujemy na nazwanej zmiennej z kontekstu, // w przeciwnym razie operujemy na samym kontekscie jako zmiennej. if name != nil { // Pelna dereferencja kontekstu dereference(&ctx) // Pobieramy wartosc switch vt := ctx.(type) { case *reflect.StructValue: switch id := name.(type) { case *reflect.StringValue: // Zwracamy pole struktury o podanej nazwie ctx = vt.FieldByName(id.Get()) if ctx == nil { return nil, RUN_NOT_FOUND } case *reflect.IntValue: // Zwracamy pole sruktury o podanym indeksie fi := int(id.Get()) if fi >= vt.NumField() { return nil, RUN_INDEX_OOR } if fi < 0 { fi += vt.NumField() if fi < 0 { return nil, RUN_INDEX_OOR } } ctx = vt.Field(fi) default: return nil, RUN_NOT_FOUND } case reflect.ArrayOrSliceValue: switch id := name.(type) { case *reflect.IntValue: // Zwracamy element tablicy o podanym indeksie ei := int(id.Get()) if ei >= vt.Len() { return nil, RUN_INDEX_OOR } if ei < 0 { ei += vt.Len() if ei < 0 { return nil, RUN_INDEX_OOR } } ctx = vt.Elem(ei) default: return nil, RUN_NOT_FOUND } case *reflect.MapValue: kt := vt.Type().(*reflect.MapType).Key() if name.Type() != kt { if it, ok := kt.(*reflect.InterfaceType); ok && it.NumMethod() == 0 { // Jesli mapa posiada klucz typu interface{} to // przeksztalcamy indeks na typ interface{} vi := name.Interface() name = reflect.NewValue(&vi).(*reflect.PtrValue).Elem() } else { return nil, RUN_NOT_FOUND } } ctx = vt.Elem(name) if ctx == nil { return nil, RUN_NOT_FOUND } case nil: return nil, RUN_NIL_CTX default: return nil, RUN_UNK_TYPE } } // Jesli mamy wywolanie funkcji to robimy pelna dereferencje. if fun { dereference(&ctx) } // Sprawdzenie czy ctx odnosi sie do funkcji. if vt, ok := ctx.(*reflect.FuncValue); ok { ft := vt.Type().(*reflect.FuncType) // Sprawdzamy zgodnosc liczby argumentow stat := argsMatch(ft, &args, 0) if stat != RUN_OK { return nil, stat } // Zwracamy pierwsza wrtosc zwrocaona przez funkcje. ctx = vt.Call(args)[0] } else if fun { return nil, RUN_NOT_FUNC } //fmt.Println("DEB getvar.ret:", reflect.Typeof(ctx.Interface())) return ctx, RUN_OK }
func formatQuery(dst, src []byte, params []interface{}) ([]byte, error) { if len(params) == 0 { return append(dst, src...), nil } var structptr, structv reflect.Value var fields map[string][]int var methods map[string]int var paramInd int p := &parser{b: src} for p.Valid() { if ch := p.Next(); ch != '?' { dst = append(dst, ch) continue } var value interface{} name := p.ReadName() if name != "" { // Lazily initialize named params. if fields == nil { if len(params) == 0 { return nil, errorf("pg: expected at least one parameter, got nothing") } structptr = reflect.ValueOf(params[len(params)-1]) params = params[:len(params)-1] if structptr.Kind() == reflect.Ptr { structv = structptr.Elem() } else { structv = structptr } if structv.Kind() != reflect.Struct { return nil, errorf("pg: expected struct, got %s", structv.Kind()) } fields = structs.Fields(structv.Type()) methods = structs.Methods(structptr.Type()) } if indx, ok := fields[name]; ok { value = structv.FieldByIndex(indx).Interface() } else if indx, ok := methods[name]; ok { value = structptr.Method(indx).Call(nil)[0].Interface() } else { return nil, errorf("pg: cannot map %q", name) } } else { if paramInd >= len(params) { return nil, errorf( "pg: expected at least %d parameters, got %d", paramInd+1, len(params), ) } value = params[paramInd] paramInd++ } dst = appendIface(dst, value) } if paramInd < len(params) { return nil, errorf("pg: expected %d parameters, got %d", paramInd, len(params)) } return dst, nil }