Beispiel #1
0
func checkLastArg(handlerType *reflect.FuncType) bool {
	index := handlerType.NumIn() - 1
	if a0, ok := handlerType.In(index).(*reflect.ChanType); ok {
		typ := a0.Elem()
		if typ == reflect.Typeof(true) {
			return true
		}
	}
	return false
}
Beispiel #2
0
//should the context be passed to the handler?
func requiresContext(handlerType *reflect.FuncType) bool {
	//if the method doesn't take arguments, no
	if handlerType.NumIn() == 0 {
		return false
	}

	//if the first argument is not a pointer, no
	a0, ok := handlerType.In(0).(*reflect.PtrType)
	if !ok {
		return false
	}

	//if the first argument is a context, yes
	if a0.Elem() == contextType {
		return true
	}

	//another case -- the first argument is a method receiver, and the
	//second argument is a web.Context

	if handlerType.NumIn() > 1 {
		a1, ok := handlerType.In(1).(*reflect.PtrType)
		if !ok {
			return false
		}
		if a1.Elem() == contextType {
			return true
		}
	}

	return false
}
Beispiel #3
0
// arbitraryValues writes Values to args such that args contains Values
// suitable for calling f.
func arbitraryValues(args []reflect.Value, f *reflect.FuncType, config *Config, rand *rand.Rand) (err os.Error) {
	if config.Values != nil {
		config.Values(args, rand)
		return
	}

	for j := 0; j < len(args); j++ {
		var ok bool
		args[j], ok = Value(f.In(j), rand)
		if !ok {
			err = SetupError(fmt.Sprintf("cannot create arbitrary value of type %s for argument %d", f.In(j), j))
			return
		}
	}

	return
}
Beispiel #4
0
// Funkcja sprawdza zgodnosc typow argumentow. Jesli to konieczne konwertuje
// argumenty do typu interface{}. Jesli to potrzebna, funkcja odpowiednio
// dostosowuje args dla funkcji.
func argsMatch(ft *reflect.FuncType, args *[]reflect.Value, method int) int {
	// Liczba arguemntow akceptowanych przez funkcje/metode
	num_in := ft.NumIn() - method

	// Sprawdzamy zgodnosc liczby argumentow i obecnosc funkcji dotdotdot
	var head_args, tail_args []reflect.Value
	if ft.DotDotDot() {
		num_in--
		if len(*args) < num_in {
			return RUN_WRONG_ARG_NUM
		}
		head_args = (*args)[0:num_in]
		tail_args = (*args)[num_in:]
	} else {
		if num_in != len(*args) {
			return RUN_WRONG_ARG_NUM
		}
		head_args = *args
	}

	// Sprawdzamy zgodnosc typow poczatkowych argumentow funkcji
	for kk, av := range head_args {
		at := ft.In(kk + method)
		//fmt.Printf("DEB: ctx: %s, fun: %s\n", av.Type(), at)
		if at != av.Type() {
			// Sprawdzamy czy arguentem funkcji jest typ interface{}
			if it, ok := at.(*reflect.InterfaceType); ok && it.NumMethod() == 0 {
				// Zmieniamy typ argumentu przekazywanego do funkcji
				vi := av.Interface()
				head_args[kk] = reflect.NewValue(&vi).(*reflect.PtrValue).Elem()
			} else {
				return RUN_WRONG_ARG_TYP
			}
		}
	}

	if !ft.DotDotDot() {
		return RUN_OK
	}

	// Okreslamy typ argumentów zawartych w dotdotdot
	st := ft.In(ft.NumIn() - 1).(*reflect.SliceType)
	at := st.Elem()
	it, ok := at.(*reflect.InterfaceType)
	at_is_interface := (ok && it.NumMethod() == 0)
	// Przygotowujemy miejsce na argumenty
	ddd := reflect.MakeSlice(st, len(tail_args), cap(tail_args))
	for kk, av := range tail_args {
		if at != av.Type() {
			// Sprawdzamy czy arguentem funkcji jest typ interface{}
			if at_is_interface {
				// Zmieniamy typ argumentu przekazywanego do funkcji
				vi := av.Interface()
				tail_args[kk] = reflect.NewValue(&vi).(*reflect.PtrValue).Elem()
			} else {
				return RUN_WRONG_ARG_TYP
			}
		}
		// Umieszczamy argument w ddd
		ddd.Elem(kk).SetValue(av)
	}

	// Zwracamy zmodyfikowana tablice argumentow
	*args = append(head_args, ddd)

	return RUN_OK
}
// 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)
}