Example #1
0
func isDirectlyConvertible(in, out *types.Type, preexisting conversions) bool {
	// If one of the types is Alias, resolve it.
	if in.Kind == types.Alias {
		return isConvertible(in.Underlying, out, preexisting)
	}
	if out.Kind == types.Alias {
		return isConvertible(in, out.Underlying, preexisting)
	}

	if in.Kind != out.Kind {
		return false
	}
	switch in.Kind {
	case types.Builtin, types.Struct, types.Map, types.Slice, types.Pointer:
	default:
		// We don't support conversion of other types yet.
		return false
	}
	switch out.Kind {
	case types.Builtin, types.Struct, types.Map, types.Slice, types.Pointer:
	default:
		// We don't support conversion of other types yet.
		return false
	}

	switch in.Kind {
	case types.Builtin:
		if in == out {
			return true
		}
		// TODO: Support more conversion types.
		return types.IsInteger(in) && types.IsInteger(out)
	case types.Struct:
		convertible := true
		for _, inMember := range in.Members {
			// Check if there is an out member with that name.
			outMember, found := findMember(out, inMember.Name)
			if !found {
				// Check if the member doesn't have comment:
				// "+ genconversion=false"
				// comment to ignore this field for conversion.
				// TODO: Switch to SecondClosestCommentLines.
				if types.ExtractCommentTags("+", inMember.CommentLines)["genconversion"] == "false" {
					continue
				}
				return false
			}
			convertible = convertible && isConvertible(inMember.Type, outMember.Type, preexisting)
		}
		return convertible
	case types.Map:
		return isConvertible(in.Key, out.Key, preexisting) && isConvertible(in.Elem, out.Elem, preexisting)
	case types.Slice:
		return isConvertible(in.Elem, out.Elem, preexisting)
	case types.Pointer:
		return isConvertible(in.Elem, out.Elem, preexisting)
	}
	glog.Fatalf("All other types should be filtered before")
	return false
}
Example #2
0
func isDirectlyConvertible(in, out *types.Type, manualConversions conversionFuncMap) bool {
	// If one of the types is Alias, resolve it.
	if in.Kind == types.Alias {
		return isConvertible(in.Underlying, out, manualConversions)
	}
	if out.Kind == types.Alias {
		return isConvertible(in, out.Underlying, manualConversions)
	}

	if in == out {
		return true
	}
	if in.Kind != out.Kind {
		return false
	}
	switch in.Kind {
	case types.Builtin, types.Struct, types.Map, types.Slice, types.Pointer:
	default:
		// We don't support conversion of other types yet.
		return false
	}

	switch in.Kind {
	case types.Builtin:
		// TODO: Support more conversion types.
		return types.IsInteger(in) && types.IsInteger(out)
	case types.Struct:
		convertible := true
		for _, inMember := range in.Members {
			// Check if there is an out member with that name.
			outMember, found := findMember(out, inMember.Name)
			if !found {
				// Check if the member has opted out with:
				//   "+k8s:conversion-gen=false"
				// TODO: Switch to SecondClosestCommentLines.
				if tagvals := extractTag(inMember.CommentLines); tagvals != nil && tagvals[0] == "false" {
					glog.V(5).Infof("field %v.%s requests no conversion generation, skipping", in, inMember.Name)
					continue
				}
				return false
			}
			convertible = convertible && isConvertible(inMember.Type, outMember.Type, manualConversions)
		}
		return convertible
	case types.Map:
		return isConvertible(in.Key, out.Key, manualConversions) && isConvertible(in.Elem, out.Elem, manualConversions)
	case types.Slice:
		return isConvertible(in.Elem, out.Elem, manualConversions)
	case types.Pointer:
		return isConvertible(in.Elem, out.Elem, manualConversions)
	}
	glog.Fatalf("All other types should be filtered before")
	return false
}
Example #3
0
func isDirectlyConvertible(in, out *types.Type, preexisting conversions) bool {
	// If one of the types is Alias, resolve it.
	if in.Kind == types.Alias {
		return isConvertible(in.Underlying, out, preexisting)
	}
	if out.Kind == types.Alias {
		return isConvertible(in, out.Underlying, preexisting)
	}

	if in.Kind != out.Kind {
		return false
	}
	switch in.Kind {
	case types.Builtin, types.Struct, types.Map, types.Slice, types.Pointer:
	default:
		// We don't support conversion of other types yet.
		return false
	}
	switch out.Kind {
	case types.Builtin, types.Struct, types.Map, types.Slice, types.Pointer:
	default:
		// We don't support conversion of other types yet.
		return false
	}

	switch in.Kind {
	case types.Builtin:
		if in == out {
			return true
		}
		// TODO: Support more conversion types.
		return types.IsInteger(in) && types.IsInteger(out)
	case types.Struct:
		convertible := true
		for _, inMember := range in.Members {
			// Check if there is an out member with that name.
			outMember, found := findMember(out, inMember.Name)
			if !found {
				return false
			}
			convertible = convertible && isConvertible(inMember.Type, outMember.Type, preexisting)
		}
		return convertible
	case types.Map:
		return isConvertible(in.Key, out.Key, preexisting) && isConvertible(in.Elem, out.Elem, preexisting)
	case types.Slice:
		return isConvertible(in.Elem, out.Elem, preexisting)
	case types.Pointer:
		return isConvertible(in.Elem, out.Elem, preexisting)
	}
	glog.Fatalf("All other types should be filtered before")
	return false
}
Example #4
0
func isDirectlyConvertible(in, out *types.Type, manualConversions conversionFuncMap) bool {
	// If one of the types is Alias, resolve it.
	if in.Kind == types.Alias {
		return isConvertible(in.Underlying, out, manualConversions)
	}
	if out.Kind == types.Alias {
		return isConvertible(in, out.Underlying, manualConversions)
	}

	if in == out {
		return true
	}
	if in.Kind != out.Kind {
		return false
	}
	switch in.Kind {
	case types.Builtin, types.Struct, types.Map, types.Slice, types.Pointer:
	default:
		// We don't support conversion of other types yet.
		return false
	}

	switch in.Kind {
	case types.Builtin:
		// TODO: Support more conversion types.
		return types.IsInteger(in) && types.IsInteger(out)
	case types.Struct:
		convertible := true
		for _, inMember := range in.Members {
			// Check if this member is excluded from conversion
			if tagvals := extractTag(inMember.CommentLines); tagvals != nil && tagvals[0] == "false" {
				continue
			}
			// Check if there is an out member with that name.
			outMember, found := findMember(out, inMember.Name)
			if !found {
				glog.V(5).Infof("%s.%s is not directly convertible to %s because the destination struct field did not exist", in.Name, inMember.Name, out.Name)
				return false
			}
			convertible = convertible && isConvertible(inMember.Type, outMember.Type, manualConversions)
		}
		return convertible
	case types.Map:
		return isConvertible(in.Key, out.Key, manualConversions) && isConvertible(in.Elem, out.Elem, manualConversions)
	case types.Slice:
		return isConvertible(in.Elem, out.Elem, manualConversions)
	case types.Pointer:
		return isConvertible(in.Elem, out.Elem, manualConversions)
	}
	glog.Fatalf("All other types should be filtered before")
	return false
}