Esempio n. 1
0
func lookupType(ty reflect.Type, path ...string) (reflect.Type, bool) {
	if len(path) == 0 {
		return ty, true
	}

	switch ty.Kind() {
	case reflect.Slice, reflect.Array, reflect.Map:
		if hasIndex(path[0]) {
			return lookupType(ty.Elem(), path[1:]...)
		}
		// Aggregate.
		return lookupType(ty.Elem(), path...)
	case reflect.Ptr:
		return lookupType(ty.Elem(), path...)
	case reflect.Interface:
		// We can't know from here without a value. Let's just return this type.
		return ty, true
	case reflect.Struct:
		f, ok := ty.FieldByName(path[0])
		if ok {
			return lookupType(f.Type, path[1:]...)
		}
	}
	return nil, false
}
Esempio n. 2
0
func compileField(typ reflect.Type, name string, args []parse.Node, final reflect.Type) (fn lookupFn, elem reflect.Type) {
	if isNilType(typ) {
		fn = compileFieldDynamic(name, args)
		return
	}

	if m, exist := typ.MethodByName(name); exist {
		fn = compileMethodCall(typ, m.Func, args, final)
		elem = m.Type.Out(0)
		return
	}

	switch typ.Kind() {
	case reflect.Struct:
		structField, found := typ.FieldByName(name)
		if !found {
			panic(fmt.Errorf("%s has no field %s", typ, name))
		}
		fn = func(s state, v reflect.Value, final interface{}) reflect.Value {
			return v.FieldByIndex(structField.Index)
		}
		elem = structField.Type
		return
	case reflect.Map:
		k := reflect.ValueOf(name)
		fn = func(s state, v reflect.Value, final interface{}) reflect.Value {
			return v.MapIndex(k)
		}
		elem = typ.Key()
		return
	}
	panic(fmt.Errorf("struct or map expected, but got %s", typ))
}
Esempio n. 3
0
func (gfg *gofiguration) parseGofigureField(t reflect.Type) error {
	gf, ok := t.FieldByName("gofigure")
	if ok {
		tags := getStructTags(string(gf.Tag))
		for name, value := range tags {
			if name == "order" {
				oParts := strings.Split(value, ",")
				for _, p := range oParts {
					if _, ok := Sources[p]; !ok {
						return ErrInvalidOrder
					}
				}
				gfg.order = oParts
				continue
			}
			// Parse orderKey:"value" tags, e.g.
			// envPrefix, which gets split into
			//   gfg.params["env"]["prefix"] = "value"
			// gfg.params["env"] is then passed to
			// source registered with that key
			match := argRe.FindStringSubmatch(name)
			if len(match) > 1 {
				if _, ok := gfg.params[match[1]]; !ok {
					gfg.params[match[1]] = make(map[string]string)
				}
				gfg.params[match[1]][strings.ToLower(match[2])] = value
			}
		}
	}
	return nil
}
Esempio n. 4
0
// StructPtr generates pointers to a given struct type.
// rt has to be the reflect type of the struct, gens contains a map of field generators.
// Note that the result types of the generators in gen have to match the type of the correspoinding
// field in the struct. Also note that only public fields of a struct can be generated
func StructPtr(rt reflect.Type, gens map[string]gopter.Gen) gopter.Gen {
	if rt.Kind() == reflect.Ptr {
		rt = rt.Elem()
	}
	if rt.Kind() != reflect.Struct {
		return Fail(rt)
	}
	return func(genParams *gopter.GenParameters) *gopter.GenResult {
		result := reflect.New(rt)

		for name, gen := range gens {
			field, ok := rt.FieldByName(name)
			if !ok {
				continue
			}
			value, ok := gen(genParams).Retrieve()
			if !ok {
				return gopter.NewEmptyResult(rt)
			}
			result.Elem().FieldByIndex(field.Index).Set(reflect.ValueOf(value))
		}

		return gopter.NewGenResult(result.Interface(), gopter.NoShrinker)
	}
}
Esempio n. 5
0
func typeToParamsSpecFromPath(t reflect.Type, path string) (
	map[string]*ApiRequestParamSpec, error) {

	if t.Kind() != reflect.Struct {
		return nil, fmt.Errorf(
			"typeToParamsSpec: Only structs are supported, got: %v", t)
	}

	params := make(map[string]*ApiRequestParamSpec)
	pathKeys, err := parsePath(path)
	if err != nil {
		return nil, err
	}
	for _, k := range pathKeys {
		k = strings.Title(k)
		field, found := t.FieldByName(k)
		if !found {
			return nil, fmt.Errorf(
				"typeToParamsSpec: Can't find field %q in %v (from path %q)", k, t, path)
		}
		param, err := fieldToParamSpec(&field)
		if err != nil {
			return nil, err
		}
		param.Required = true
		params[field.Name] = param
	}
	return params, nil
}
Esempio n. 6
0
func isList(t reflect.Type) bool {
	if t.Kind() != reflect.Struct {
		return false
	}

	_, hasListMeta := t.FieldByName("ListMeta")
	return hasListMeta
}
Esempio n. 7
0
func CheckField(t *testing.T, typ reflect.Type, name string, typName string, typVal interface{}) {
	field, found := typ.FieldByName(name)
	if !found {
		t.Fatalf("Pas de champ '%s'", name)
	}
	if field.Type != reflect.TypeOf(typVal) {
		t.Fatalf("Le champ '%s' n'est pas de type %s", name, typName)
	}

}
Esempio n. 8
0
func getExportedField(t reflect.Type, field string) reflect.StructField {
	f, ok := t.FieldByName(field)
	if !ok {
		panic("field " + field + " is not found")
	}
	if len(f.PkgPath) != 0 {
		panic("field " + field + " is unexported")
	}
	return f
}
Esempio n. 9
0
// resolveKeyForField either returns lowercase version of the name if the field
// was found or the key found in a bson struct tag or "" if the field wasn't found
func resolveKeyForField(Struct reflect.Type, name string) string {
	if f, ok := Struct.FieldByName(name); ok {
		tag := f.Tag.Get("bson")
		parts := strings.Split(tag, ",")
		if len(parts) > 0 && parts[0] != "" && parts[0] != "-" {
			return parts[0]
		} else {
			return strings.ToLower(f.Name)
		}
	}
	return ""
}
Esempio n. 10
0
func columnToFieldIndex(m *DbMap, t reflect.Type, cols []string) ([][]int, error) {
	colToFieldIndex := make([][]int, len(cols))

	// check if type t is a mapped table - if so we'll
	// check the table for column aliasing below
	tableMapped := false
	table := tableOrNil(m, t)
	if table != nil {
		tableMapped = true
	}

	// Loop over column names and find field in i to bind to
	// based on column name. all returned columns must match
	// a field in the i struct
	missingColNames := []string{}
	for x := range cols {
		colName := strings.ToLower(cols[x])
		field, found := t.FieldByNameFunc(func(fieldName string) bool {
			field, _ := t.FieldByName(fieldName)
			cArguments := strings.Split(field.Tag.Get("db"), ",")
			fieldName = cArguments[0]

			if fieldName == "-" {
				return false
			} else if fieldName == "" {
				fieldName = field.Name
			}
			if tableMapped {
				colMap := colMapOrNil(table, fieldName)
				if colMap != nil {
					fieldName = colMap.ColumnName
				}
			}
			return colName == strings.ToLower(fieldName)
		})
		if found {
			colToFieldIndex[x] = field.Index
		}
		if colToFieldIndex[x] == nil {
			missingColNames = append(missingColNames, colName)
		}
	}
	if len(missingColNames) > 0 {
		return colToFieldIndex, &NoFieldInTypeError{
			TypeName:        t.Name(),
			MissingColNames: missingColNames,
		}
	}
	return colToFieldIndex, nil
}
Esempio n. 11
0
func writeAccessorMethods(rt reflect.Type) (accSrc string) {
	var (
		nameCases    []string
		sf           reflect.StructField
		sfType       reflect.Type
		isSid        bool
		sfName       string
		numCase, pos int
	)
	if _, hasSid := rt.FieldByName("HasSid"); !spref(rt.Name(), "ParamOrSid") {
		accSrc += sfmt("func (me *%s) AccessField(fn string) interface{} {\n\tswitch fn {\n", rt.Name())
		for i := 0; i < rt.NumField(); i++ {
			if sf = rt.Field(i); (len(sf.Name) > 0) && (sf.Name != "Def") && (sf.Name != "Kind") && !sf.Anonymous {
				if isSid, sfName, sfType = spref(sf.Type.Name(), "Sid"), sf.Name, sf.Type; isSid || (hasSid && (!anyOf(sfType, reflect.Invalid, reflect.Array, reflect.Chan, reflect.Func, reflect.Map, reflect.Slice, reflect.Struct, reflect.UnsafePointer)) && ((sfType.Kind() != reflect.Ptr) || elemType(sfType).Kind() != reflect.Struct)) {
					if numCase++; isSid {
						switch sfType.Name() {
						case "SidBool":
							sfName += ".B"
						case "SidString":
							sfName += ".S"
						case "SidVec3":
							sfName += ".Vec3"
						default:
							sfName += ".F"
						}
					}
					nameCases = append(nameCases, sf.Name)
					accSrc += sfmt("\tcase %#v:\n\t\treturn %sme.%s\n", sf.Name, ustr.Ifs(sfType.Kind() == reflect.Ptr, "", "&"), sfName)
				} else if pos = strings.Index(sfType.String(), "ParamOr"); pos > 0 {
					// numCase++
					switch sfType.String()[pos+len("ParamOr"):] {
					case "Bool":
					case "RefSid":
					case "Float":
					case "SidFloat":
					case "Float2":
					case "Int":
					}
					// println(rt.Name() + "." + sf.Name + " => " + sfType.String())
				}
			}
		}
		if accSrc += "\t}\n\treturn nil\n}\n\n"; numCase == 0 {
			accSrc = ""
		} else {
			accSrc = sfmt("//\tRefSidFielder implementation.\n//\tSupported field names: \"%v\".\n", strings.Join(nameCases, "\", \"")) + accSrc
		}
	}
	return
}
Esempio n. 12
0
func (g *conversionGenerator) generateConversionsForStruct(inType, outType reflect.Type) error {
	for i := 0; i < inType.NumField(); i++ {
		inField := inType.Field(i)
		outField, found := outType.FieldByName(inField.Name)
		if !found {
			return fmt.Errorf("couldn't find a corresponding field %v in %v", inField.Name, outType)
		}
		if isComplexType(inField.Type) {
			if err := g.generateConversionsBetween(inField.Type, outField.Type); err != nil {
				return err
			}
		}
	}
	return nil
}
Esempio n. 13
0
func findField(value reflect.Value, typ reflect.Type, k string, v string) (reflect.Value, reflect.StructField) {
	field := value.FieldByName(v)
	if field.IsValid() {
		tfield, _ := typ.FieldByName(v)
		return field, tfield
	}
	for ix := 0; ix < value.NumField(); ix++ {
		field := value.Field(ix)
		tfield := typ.Field(ix)
		if tfield.Tag.Get("AMI") == k && field.String() == v {
			return field, tfield
		}
	}
	return field, reflect.StructField{}
}
Esempio n. 14
0
func checkForInputError(fieldType reflect.Type, value interface{}) error {

	// We always want to check the pointer to the value (and never the
	// pointer to the pointer to the value) for interface matching.
	var emptyValue reflect.Value
	if fieldType.Kind() == reflect.Ptr {
		emptyValue = reflect.New(fieldType.Elem())
	} else {
		emptyValue = reflect.New(fieldType)
	}

	// A type switch would look cleaner here, but we want a very
	// specific order of preference for these interfaces.  A type
	// switch does not guarantee any preferred order, just that
	// one valid case will be executed.
	emptyInter := emptyValue.Interface()
	if validator, ok := emptyInter.(InputValidator); ok {
		return validator.ValidateInput(value)
	}
	if receiver, ok := emptyInter.(web_request_readers.RequestValueReceiver); ok {
		return receiver.Receive(value)
	}

	fieldTypeName := fieldType.Name()
	if fieldType.Kind() == reflect.Struct && strings.HasPrefix(fieldTypeName, SqlNullablePrefix) {
		// database/sql defines many Null* types,
		// where the fields are Valid (a bool) and the
		// name of the type (everything after Null).
		// We're trying to support them (somewhat)
		// here.
		typeName := fieldTypeName[len(SqlNullablePrefix):]
		nullField, ok := fieldType.FieldByName(typeName)
		if ok {
			// This is almost definitely an sql.Null* type.
			if value == nil {
				return nil
			}
			fieldType = nullField.Type
		}
	}
	if !reflect.TypeOf(value).ConvertibleTo(fieldType) {
		return errors.New("Input is of the wrong type and cannot be converted")
	}
	return nil
}
Esempio n. 15
0
File: gorp.go Progetto: robfig/gorp
func columnToFieldIndex(m *DbMap, t reflect.Type, cols []string) ([][]int, error) {
	colToFieldIndex := make([][]int, len(cols))

	// check if type t is a mapped table - if so we'll
	// check the table for column aliasing below
	tableMapped := false
	table := tableOrNil(m, t)
	if table != nil {
		tableMapped = true
	}

	// Loop over column names and find field in i to bind to
	// based on column name. all returned columns must match
	// a field in the i struct
	for x := range cols {
		colName := strings.ToLower(cols[x])

		field, found := t.FieldByNameFunc(func(fieldName string) bool {
			field, _ := t.FieldByName(fieldName)
			fieldName = field.Tag.Get("db")

			if fieldName == "-" {
				return false
			} else if fieldName == "" {
				fieldName = field.Name
			}
			if tableMapped {
				colMap := colMapOrNil(table, fieldName)
				if colMap != nil {
					fieldName = colMap.ColumnName
				}
			}

			return colName == strings.ToLower(fieldName)
		})
		if found {
			colToFieldIndex[x] = field.Index
		}
		if colToFieldIndex[x] == nil {
			return nil, fmt.Errorf("gorp: No field %s in type %s", colName, t.Name())
		}
	}
	return colToFieldIndex, nil
}
Esempio n. 16
0
func getStructFieldInfos(rt reflect.Type) (sis *structFieldInfos) {
	sis, ok := cachedStructFieldInfos[rt]
	if ok {
		return
	}

	cachedStructFieldInfosMutex.Lock()
	defer cachedStructFieldInfosMutex.Unlock()

	sis = new(structFieldInfos)

	var siInfo *structFieldInfo
	if f, ok := rt.FieldByName(structInfoFieldName); ok {
		siInfo = parseStructFieldInfo(structInfoFieldName, f.Tag.Get("msgpack"))
	}
	rgetStructFieldInfos(rt, nil, sis, siInfo)
	cachedStructFieldInfos[rt] = sis
	return
}
Esempio n. 17
0
func getFieldByNameInner(t reflect.Type, name string) (reflect.StructField, bool) {
	nameArray := Explode(name, ".")
	if len(nameArray) == 0 {
		return reflect.StructField{}, false
	}
	var isExist bool
	var resultStruct reflect.StructField
	resultIndex := []int{}
	for _, singleName := range nameArray {
		resultStruct, isExist = t.FieldByName(singleName)
		if !isExist {
			return reflect.StructField{}, false
		}
		resultIndex = append(resultIndex, resultStruct.Index...)
		t = resultStruct.Type
	}
	resultStruct.Index = resultIndex
	return resultStruct, true
}
Esempio n. 18
0
func (this *dbMap) columnsToFieldIndexList(meta reflect.Type, cols []string) ([][]int, error) {
	fieldIndexList := make([][]int, len(cols))

	table, ok := this.getTableByMeta(meta)
	if !ok {
		table = this.getOrAddPseudoTable(meta)
	}
	for i, colName := range cols {
		if col, ok := table.colDict[colName]; ok {
			if f, ok := meta.FieldByName(col.fieldName); ok {
				fieldIndexList[i] = f.Index
			}
		}
		if fieldIndexList[i] == nil {
			return nil, errfTableMetaNoField(colName, table.tableName)
		}
	}
	return fieldIndexList, nil
}
func (g *generator) generateConversionsForStruct(inType, outType reflect.Type) error {
	for i := 0; i < inType.NumField(); i++ {
		inField := inType.Field(i)
		outField, found := outType.FieldByName(inField.Name)
		if !found {
			return fmt.Errorf("couldn't find a corresponding field %v in %v", inField.Name, outType)
		}
		if inField.Type.Kind() != outField.Type.Kind() {
			return fmt.Errorf("cannot convert types of different kinds: %v %v", inField, outField)
		}
		if isComplexType(inField.Type) {
			if err := g.generateConversionsBetween(inField.Type, outField.Type); err != nil {
				return err
			}
		}
	}
	g.convertibles[inType] = outType
	return nil
}
Esempio n. 20
0
func nameToFieldName(t reflect.Type, name string) string {
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	} else if t.Kind() != reflect.Struct {
		return ""
	}

	// find a field matching "json" field tag
	if hasJsonTags(t) {
		return nameToFieldNameByJsonTag(t, name)
	}

	// do a fuzzy search using "tcpPort" => ["TcpPort", "TCPPort"]
	for _, goName := range nameToGo(name) {
		if f, ok := t.FieldByName(goName); ok {
			return f.Name
		}
	}
	return ""
}
Esempio n. 21
0
File: starter.go Progetto: ssrl/gon
func instantiateAndInjectController(context gon.WebContext, controllerType reflect.Type) reflect.Value {
	// Instantiate a controller
	conValue := reflect.New(controllerType)
	conIndirect := reflect.Indirect(conValue)

	// Inject Params
	conIndirect.FieldByName("Params").Set(reflect.ValueOf(context.GetParams()))

	//
	// Inject beans
	// This loop tends to be slow. We should loop over field names and look-up a bean.
	//
	for beanName, setterFunc := range bean.Registry() {
		if _, ok := controllerType.FieldByName(beanName); ok {
			if field := conIndirect.FieldByName(beanName); field.IsValid() {
				field.Set(reflect.ValueOf(setterFunc()))
			}
		}
	}
	return conValue
}
Esempio n. 22
0
func makeColToFieldIndex(t reflect.Type, cols []string) [][]int {
	var colToFieldIndex = make([][]int, len(cols))

	for x := range cols {
		colName := strings.ToLower(cols[x])
		field, found := t.FieldByNameFunc(func(fieldName string) bool {
			field, _ := t.FieldByName(fieldName)
			tags := strings.Split(field.Tag.Get("db"), ", ")
			dbNameFromTag := tags[0]
			if dbNameFromTag == "" {
				return strings.ToLower(field.Name) == colName
			}
			return colName == dbNameFromTag
		})
		if found {
			colToFieldIndex[x] = field.Index
		}
	}

	return colToFieldIndex
}
Esempio n. 23
0
func fieldValue(key string, typ reflect.Type) (mapFunc, reflect.Type) {
	depth := 0
	for typ.Kind() == reflect.Ptr {
		typ = typ.Elem()
		depth++
	}
	if typ.Kind() == reflect.Struct {
		if field, ok := typ.FieldByName(key); ok {
			fn := fieldValueFunc(field, depth)
			if fn != nil {
				fdepth := 0
				ft := field.Type
				for ft.Kind() == reflect.Ptr {
					ft = ft.Elem()
					fdepth++
				}
				switch fdepth {
				case 0:
				case 1:
					f := fn
					fn = func(h handle) handle {
						return getElem(f(h))
					}
				default:
					f := fn
					fn = func(h handle) handle {
						v := f(h)
						for ii := 0; ii < fdepth; ii++ {
							v = getElem(v)
						}
						return h
					}
					fn = f
				}
				return fn, ft
			}
		}
	}
	return nil, nil
}
func (g *conversionGenerator) generateConversionsForStruct(inType, outType reflect.Type) error {
	errs := []string{}
	for i := 0; i < inType.NumField(); i++ {
		inField := inType.Field(i)
		outField, found := outType.FieldByName(inField.Name)
		if !found {
			// aggregate the errors so we can return them at the end but still provide
			// best effort for generation for other fields in this type
			errs = append(errs, fmt.Sprintf("couldn't find a corresponding field %v in %v", inField.Name, outType))
			continue
		}
		if isComplexType(inField.Type) {
			if err := g.generateConversionsBetween(inField.Type, outField.Type); err != nil {
				return err
			}
		}
	}

	if len(errs) == 0 {
		return nil
	}
	return fmt.Errorf(strings.Join(errs, ","))
}
Esempio n. 25
0
func (g *schemaGenerator) javaInterfaces(t reflect.Type) []string {
	if _, ok := t.FieldByName("ObjectMeta"); t.Name() != "PodTemplateSpec" && ok {
		return []string{"io.fabric8.kubernetes.api.model.HasMetadata"}
	}

	_, hasItems := t.FieldByName("Items")
	_, hasListMeta := t.FieldByName("ListMeta")
	if hasItems && hasListMeta {
		return []string{"io.fabric8.kubernetes.api.model.KubernetesResource", "io.fabric8.kubernetes.api.model.KubernetesResourceList"}
	}
	return nil
}
Esempio n. 26
0
func checkCompositeLitStruct(lit *CompositeLit, t reflect.Type, env Env) (*CompositeLit, []error) {
	var errs, moreErrs []error

	// X{} is treated as if it has zero KeyValue'd elements, i.e. unspecified
	// elements are set to zero. This is always valid
	if len(lit.Elts) == 0 {
		return lit, nil
	}

	// gc first checks if there are ANY keys present, and then decides how
	// to process the initialisers.
	keysPresent := false
	for _, elt := range lit.CompositeLit.Elts {
		_, ok := elt.(*ast.KeyValueExpr)
		keysPresent = keysPresent || ok
	}

	if keysPresent {
		seen := make(map[string]bool, len(lit.Elts))
		mixed := false
		for i := 0; i < len(lit.Elts); i += 1 {
			kv, ok := lit.CompositeLit.Elts[i].(*ast.KeyValueExpr)
			if !ok {
				elt := fakeCheckExpr(lit.CompositeLit.Elts[i], env)
				lit.Elts[i] = elt
				if !mixed {
					// This error only gets reported once
					mixed = true
					errs = append(errs, ErrMixedStructValues{elt})
				}
				continue
			}

			key := fakeCheckExpr(kv.Key, env)
			var value Expr
			// Check the key is a struct member
			if ident, ok := key.(*Ident); !ok {
				value = fakeCheckExpr(kv.Value, env)
				errs = append(errs, ErrInvalidStructField{key})
			} else {
				name := ident.Name
				if field, ok := t.FieldByName(name); !ok {
					value = fakeCheckExpr(kv.Value, env)
					errs = append(errs, ErrUnknownStructField{key, t, name})
				} else {
					if seen[name] {
						errs = append(errs, ErrDuplicateStructField{ident, name})
					}
					seen[name] = true
					lit.fields = append(lit.fields, field.Index[0])
					value, moreErrs = checkStructField(kv.Value, field, env)
					if moreErrs != nil {
						errs = append(errs, moreErrs...)
					}
				}
			}
			lit.Elts[i] = &KeyValueExpr{KeyValueExpr: kv, Key: key, Value: value}
		}
	} else {
		numFields := t.NumField()
		var i int
		for i = 0; i < numFields && i < len(lit.Elts); i += 1 {
			field := t.Field(i)
			lit.Elts[i], moreErrs = checkStructField(lit.CompositeLit.Elts[i], field, env)
			if moreErrs != nil {
				errs = append(errs, moreErrs...)
			}
			lit.fields = append(lit.fields, i)
		}
		if numFields != len(lit.Elts) {
			errs = append(errs, ErrWrongNumberOfStructValues{lit})
		}
		// Remaining fields are type checked reguardless of use
		for ; i < len(lit.Elts); i += 1 {
			lit.Elts[i], moreErrs = CheckExpr(lit.CompositeLit.Elts[i], env)
			if moreErrs != nil {
				errs = append(errs, moreErrs...)
			}
		}
	}
	return lit, errs
}
Esempio n. 27
0
func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
	var ok bool
	x.mu.RLock()
	pti, ok = x.infos[rtid]
	x.mu.RUnlock()
	if ok {
		return
	}

	// do not hold lock while computing this.
	// it may lead to duplication, but that's ok.
	ti := typeInfo{rt: rt, rtid: rtid}
	ti.numMeth = uint16(rt.NumMethod())

	var indir int8
	if ok, indir = implementsIntf(rt, binaryMarshalerTyp); ok {
		ti.bm, ti.bmIndir = true, indir
	}
	if ok, indir = implementsIntf(rt, binaryUnmarshalerTyp); ok {
		ti.bunm, ti.bunmIndir = true, indir
	}
	if ok, indir = implementsIntf(rt, textMarshalerTyp); ok {
		ti.tm, ti.tmIndir = true, indir
	}
	if ok, indir = implementsIntf(rt, textUnmarshalerTyp); ok {
		ti.tunm, ti.tunmIndir = true, indir
	}
	if ok, indir = implementsIntf(rt, jsonMarshalerTyp); ok {
		ti.jm, ti.jmIndir = true, indir
	}
	if ok, indir = implementsIntf(rt, jsonUnmarshalerTyp); ok {
		ti.junm, ti.junmIndir = true, indir
	}
	if ok, indir = implementsIntf(rt, selferTyp); ok {
		ti.cs, ti.csIndir = true, indir
	}
	if ok, _ = implementsIntf(rt, mapBySliceTyp); ok {
		ti.mbs = true
	}

	pt := rt
	var ptIndir int8
	// for ; pt.Kind() == reflect.Ptr; pt, ptIndir = pt.Elem(), ptIndir+1 { }
	for pt.Kind() == reflect.Ptr {
		pt = pt.Elem()
		ptIndir++
	}
	if ptIndir == 0 {
		ti.base = rt
		ti.baseId = rtid
	} else {
		ti.base = pt
		ti.baseId = reflect.ValueOf(pt).Pointer()
		ti.baseIndir = ptIndir
	}

	if rt.Kind() == reflect.Struct {
		var omitEmpty bool
		if f, ok := rt.FieldByName(structInfoFieldName); ok {
			siInfo := parseStructFieldInfo(structInfoFieldName, x.structTag(f.Tag))
			ti.toArray = siInfo.toArray
			omitEmpty = siInfo.omitEmpty
		}
		pi := rgetPool.Get()
		pv := pi.(*rgetPoolT)
		pv.etypes[0] = ti.baseId
		vv := rgetT{pv.fNames[:0], pv.encNames[:0], pv.etypes[:1], pv.sfis[:0]}
		x.rget(rt, rtid, omitEmpty, nil, &vv)
		ti.sfip, ti.sfi = rgetResolveSFI(vv.sfis, pv.sfiidx[:0])
		rgetPool.Put(pi)
	}
	// sfi = sfip

	x.mu.Lock()
	if pti, ok = x.infos[rtid]; !ok {
		pti = &ti
		x.infos[rtid] = pti
	}
	x.mu.Unlock()
	return
}
Esempio n. 28
0
func getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
	var ok bool
	cachedTypeInfoMutex.RLock()
	pti, ok = cachedTypeInfo[rtid]
	cachedTypeInfoMutex.RUnlock()
	if ok {
		return
	}

	cachedTypeInfoMutex.Lock()
	defer cachedTypeInfoMutex.Unlock()
	if pti, ok = cachedTypeInfo[rtid]; ok {
		return
	}

	ti := typeInfo{rt: rt, rtid: rtid}
	pti = &ti

	var indir int8
	if ok, indir = implementsIntf(rt, binaryMarshalerTyp); ok {
		ti.m, ti.mIndir = true, indir
	}
	if ok, indir = implementsIntf(rt, binaryUnmarshalerTyp); ok {
		ti.unm, ti.unmIndir = true, indir
	}
	if ok, _ = implementsIntf(rt, mapBySliceTyp); ok {
		ti.mbs = true
	}

	pt := rt
	var ptIndir int8
	// for ; pt.Kind() == reflect.Ptr; pt, ptIndir = pt.Elem(), ptIndir+1 { }
	for pt.Kind() == reflect.Ptr {
		pt = pt.Elem()
		ptIndir++
	}
	if ptIndir == 0 {
		ti.base = rt
		ti.baseId = rtid
	} else {
		ti.base = pt
		ti.baseId = reflect.ValueOf(pt).Pointer()
		ti.baseIndir = ptIndir
	}

	if rt.Kind() == reflect.Struct {
		var siInfo *structFieldInfo
		if f, ok := rt.FieldByName(structInfoFieldName); ok {
			siInfo = parseStructFieldInfo(structInfoFieldName, f.Tag.Get(structTagName))
			ti.toArray = siInfo.toArray
		}
		sfip := make([]*structFieldInfo, 0, rt.NumField())
		rgetTypeInfo(rt, nil, make(map[string]bool), &sfip, siInfo)

		// // try to put all si close together
		// const tryToPutAllStructFieldInfoTogether = true
		// if tryToPutAllStructFieldInfoTogether {
		// 	sfip2 := make([]structFieldInfo, len(sfip))
		// 	for i, si := range sfip {
		// 		sfip2[i] = *si
		// 	}
		// 	for i := range sfip {
		// 		sfip[i] = &sfip2[i]
		// 	}
		// }

		ti.sfip = make([]*structFieldInfo, len(sfip))
		ti.sfi = make([]*structFieldInfo, len(sfip))
		copy(ti.sfip, sfip)
		sort.Sort(sfiSortedByEncName(sfip))
		copy(ti.sfi, sfip)
	}
	// sfi = sfip
	cachedTypeInfo[rtid] = pti
	return
}
Esempio n. 29
0
File: qbs.go Progetto: robfig/qbs
//Do a raw sql query and set the result values in dest parameter.
//The dest parameter can be either a struct pointer or a pointer of struct pointer.slice
//This method do not support pointer field in the struct.
func (q *Qbs) QueryStruct(dest interface{}, query string, args ...interface{}) error {
	query = q.Dialect.substituteMarkers(query)
	stmt, err := q.prepare(query)
	if err != nil {
		return q.updateTxError(err)
	}
	rows, err := stmt.Query(args...)
	if err != nil {
		return q.updateTxError(err)
	}
	defer rows.Close()
	outPtr := reflect.ValueOf(dest)
	outValue := outPtr.Elem()
	var structType reflect.Type
	var single bool
	if outValue.Kind() == reflect.Slice {
		structType = outValue.Type().Elem().Elem()
	} else {
		structType = outValue.Type()
		single = true
	}
	columns, _ := rows.Columns()
	fieldNames := make([]string, len(columns))
	for i, v := range columns {
		upper := snakeToUpperCamel(v)
		_, ok := structType.FieldByName(upper)
		if ok {
			fieldNames[i] = upper
		} else {
			fieldNames[i] = "-"
		}
	}
	for rows.Next() {
		var rowStructPointer reflect.Value
		if single { //query row
			rowStructPointer = outPtr
		} else { //query rows
			rowStructPointer = reflect.New(structType)
		}
		dests := make([]interface{}, len(columns))
		for i := 0; i < len(dests); i++ {
			fieldName := fieldNames[i]
			if fieldName == "-" {
				var placeholder interface{}
				dests[i] = &placeholder
			} else {
				field := rowStructPointer.Elem().FieldByName(fieldName)
				dests[i] = field.Addr().Interface()
			}
		}
		err = rows.Scan(dests...)
		if err != nil {
			return err
		}
		if single {
			return nil
		}
		outValue.Set(reflect.Append(outValue, rowStructPointer))
	}
	return nil
}
Esempio n. 30
0
func (g *conversionGenerator) writeConversionForStruct(b *buffer, inType, outType reflect.Type, indent int) error {
	for i := 0; i < inType.NumField(); i++ {
		inField := inType.Field(i)
		outField, _ := outType.FieldByName(inField.Name)

		existsConversion := g.scheme.Converter().HasConversionFunc(inField.Type, outField.Type)
		if existsConversion && !g.existsDedicatedConversionFunction(inField.Type, outField.Type) {
			// Use the conversion method that is already defined.
			assignFormat := "if err := s.Convert(&in.%s, &out.%s, 0); err != nil {\n"
			assignStmt := fmt.Sprintf(assignFormat, inField.Name, outField.Name)
			b.addLine(assignStmt, indent)
			b.addLine("return err\n", indent+1)
			b.addLine("}\n", indent)
			continue
		}

		switch inField.Type.Kind() {
		case reflect.Map:
			if err := g.writeConversionForMap(b, inField, outField, indent); err != nil {
				return err
			}
			continue
		case reflect.Ptr:
			if err := g.writeConversionForPtr(b, inField, outField, indent); err != nil {
				return err
			}
			continue
		case reflect.Slice:
			if err := g.writeConversionForSlice(b, inField, outField, indent); err != nil {
				return err
			}
			continue
		case reflect.Interface, reflect.Struct:
			// Don't copy these via assignment/conversion!
		default:
			// This should handle all simple types.
			if inField.Type.AssignableTo(outField.Type) {
				assignFormat := "out.%s = in.%s\n"
				assignStmt := fmt.Sprintf(assignFormat, outField.Name, inField.Name)
				b.addLine(assignStmt, indent)
				continue
			}
			if inField.Type.ConvertibleTo(outField.Type) {
				assignFormat := "out.%s = %s(in.%s)\n"
				assignStmt := fmt.Sprintf(assignFormat, outField.Name, g.typeName(outField.Type), inField.Name)
				b.addLine(assignStmt, indent)
				continue
			}
		}

		assignStmt := ""
		if g.existsDedicatedConversionFunction(inField.Type, outField.Type) {
			assignFormat := "if err := %s(&in.%s, &out.%s, s); err != nil {\n"
			funcName := g.conversionFunctionName(inField.Type, outField.Type)
			assignStmt = fmt.Sprintf(assignFormat, funcName, inField.Name, outField.Name)
		} else {
			assignFormat := "if err := s.Convert(&in.%s, &out.%s, 0); err != nil {\n"
			assignStmt = fmt.Sprintf(assignFormat, inField.Name, outField.Name)
		}
		b.addLine(assignStmt, indent)
		b.addLine("return err\n", indent+1)
		b.addLine("}\n", indent)
	}
	return nil
}