Пример #1
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
}