Ejemplo n.º 1
0
func (g *ObjcGen) genWrite(varName string, t types.Type, mode varMode) {
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.String:
			g.Printf("nstring _%s = go_seq_from_objc_string(%s);\n", varName, varName)
		default:
			g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName)
		}
	case *types.Slice:
		switch e := t.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				g.Printf("nbyteslice _%s = go_seq_from_objc_bytearray(%s, %d);\n", varName, varName, toCFlag(mode == modeRetained))
			default:
				g.errorf("unsupported type: %s", t)
			}
		default:
			g.errorf("unsupported type: %s", t)
		}
	case *types.Named:
		switch u := t.Underlying().(type) {
		case *types.Interface:
			g.genRefWrite(varName)
		default:
			g.errorf("unsupported named type: %s / %T", u, u)
		}
	case *types.Pointer:
		g.genRefWrite(varName)
	default:
		g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName)
	}
}
Ejemplo n.º 2
0
// zeroConst returns a new "zero" constant of the specified type,
// which must not be an array or struct type: the zero values of
// aggregates are well-defined but cannot be represented by Const.
//
func zeroConst(t types.Type) *Const {
	switch t := t.(type) {
	case *types.Basic:
		switch {
		case t.Info()&types.IsBoolean != 0:
			return NewConst(exact.MakeBool(false), t)
		case t.Info()&types.IsNumeric != 0:
			return NewConst(exact.MakeInt64(0), t)
		case t.Info()&types.IsString != 0:
			return NewConst(exact.MakeString(""), t)
		case t.Kind() == types.UnsafePointer:
			fallthrough
		case t.Kind() == types.UntypedNil:
			return nilConst(t)
		default:
			panic(fmt.Sprint("zeroConst for unexpected type:", t))
		}
	case *types.Pointer, *types.Slice, *types.Interface, *types.Chan, *types.Map, *types.Signature:
		return nilConst(t)
	case *types.Named:
		return NewConst(zeroConst(t.Underlying()).Value, t)
	case *types.Array, *types.Struct, *types.Tuple:
		panic(fmt.Sprint("zeroConst applied to aggregate:", t))
	}
	panic(fmt.Sprint("zeroConst: unexpected ", t))
}
Ejemplo n.º 3
0
func asmKindForType(t types.Type, size int) asmKind {
	switch t := t.Underlying().(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.String:
			return asmString
		case types.Complex64, types.Complex128:
			return asmComplex
		}
		return asmKind(size)
	case *types.Pointer, *types.Chan, *types.Map, *types.Signature:
		return asmKind(size)
	case *types.Struct:
		return asmStruct
	case *types.Interface:
		if t.Empty() {
			return asmEmptyInterface
		}
		return asmInterface
	case *types.Array:
		return asmArray
	case *types.Slice:
		return asmSlice
	}
	panic("unreachable")
}
Ejemplo n.º 4
0
// javaTypeDefault returns a string that represents the default value of the mapped java type.
// TODO(hyangah): Combine javaType and javaTypeDefault?
func (g *javaGen) javaTypeDefault(T types.Type) string {
	switch T := T.(type) {
	case *types.Basic:
		switch T.Kind() {
		case types.Bool:
			return "false"
		case types.Int, types.Int8, types.Int16, types.Int32,
			types.Int64, types.Uint8:
			return "0"
		case types.Float32, types.Float64:
			return "0.0"
		case types.String:
			return "null"
		default:
			g.errorf("unsupported return type: %s", T)
			return "TODO"
		}
	case *types.Slice, *types.Pointer, *types.Named:
		return "null"

	default:
		g.errorf("unsupported javaType: %#+v, %s\n", T, T)
		return "TODO"
	}
}
Ejemplo n.º 5
0
Archivo: gen.go Proyecto: ych1/mobile
// cgoType returns the name of a Cgo type suitable for converting a value of
// the given type.
func (g *generator) cgoType(t types.Type) string {
	if isErrorType(t) {
		return g.cgoType(types.Typ[types.String])
	}
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.Bool, types.UntypedBool:
			return "char"
		case types.Int:
			return "nint"
		case types.Int8:
			return "int8_t"
		case types.Int16:
			return "int16_t"
		case types.Int32, types.UntypedRune: // types.Rune
			return "int32_t"
		case types.Int64, types.UntypedInt:
			return "int64_t"
		case types.Uint8: // types.Byte
			return "uint8_t"
		// TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64:
		case types.Float32:
			return "float"
		case types.Float64, types.UntypedFloat:
			return "double"
		case types.String:
			return "nstring"
		default:
			g.errorf("unsupported basic type: %s", t)
		}
	case *types.Slice:
		switch e := t.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				return "nbyteslice"
			default:
				g.errorf("unsupported slice type: %s", t)
			}
		default:
			g.errorf("unsupported slice type: %s", t)
		}
	case *types.Pointer:
		if _, ok := t.Elem().(*types.Named); ok {
			return g.cgoType(t.Elem())
		}
		g.errorf("unsupported pointer to type: %s", t)
	case *types.Named:
		return "int32_t"
	default:
		g.errorf("unsupported type: %s", t)
	}
	return "TODO"
}
Ejemplo n.º 6
0
Archivo: gengo.go Proyecto: ych1/mobile
func (g *goGen) genWrite(toVar, fromVar string, t types.Type, mode varMode) {
	if isErrorType(t) {
		g.Printf("var %s_str string\n", toVar)
		g.Printf("if %s == nil {\n", fromVar)
		g.Printf("    %s_str = \"\"\n", toVar)
		g.Printf("} else {\n")
		g.Printf("    %s_str = %s.Error()\n", toVar, fromVar)
		g.Printf("}\n")
		g.genWrite(toVar, toVar+"_str", types.Typ[types.String], mode)
		return
	}
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.String:
			g.Printf("%s := encodeString(%s)\n", toVar, fromVar)
		case types.Bool:
			g.Printf("var %s C.%s = 0\n", toVar, g.cgoType(t))
			g.Printf("if %s { %s = 1 }\n", fromVar, toVar)
		default:
			g.Printf("%s := C.%s(%s)\n", toVar, g.cgoType(t), fromVar)
		}
	case *types.Slice:
		switch e := t.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				g.Printf("%s := fromSlice(%s, %v)\n", toVar, fromVar, mode == modeRetained)
			default:
				g.errorf("unsupported type: %s", t)
			}
		default:
			g.errorf("unsupported type: %s", t)
		}
	case *types.Pointer:
		// TODO(crawshaw): test *int
		// TODO(crawshaw): test **Generator
		switch t := t.Elem().(type) {
		case *types.Named:
			g.genToRefNum(toVar, fromVar)
		default:
			g.errorf("unsupported type %s", t)
		}
	case *types.Named:
		switch u := t.Underlying().(type) {
		case *types.Interface, *types.Pointer:
			g.genToRefNum(toVar, fromVar)
		default:
			g.errorf("unsupported, direct named type %s: %s", t, u)
		}
	default:
		g.errorf("unsupported type %s", t)
	}
}
Ejemplo n.º 7
0
// javaType returns a string that can be used as a Java type.
func (g *javaGen) javaType(T types.Type) string {
	switch T := T.(type) {
	case *types.Basic:
		switch T.Kind() {
		case types.Bool:
			return "boolean"
		case types.Int:
			return "long"
		case types.Int8:
			return "byte"
		case types.Int16:
			return "short"
		case types.Int32:
			return "int"
		case types.Int64:
			return "long"
		case types.Uint8:
			// TODO(crawshaw): Java bytes are signed, so this is
			// questionable, but vital.
			return "byte"
		// TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64:
		case types.Float32:
			return "float"
		case types.Float64:
			return "double"
		case types.String:
			return "String"
		default:
			g.errorf("unsupported return type: %s", T)
			return "TODO"
		}
	case *types.Slice:
		elem := g.javaType(T.Elem())
		return elem + "[]"

	case *types.Pointer:
		if _, ok := T.Elem().(*types.Named); ok {
			return g.javaType(T.Elem())
		}
		panic(fmt.Sprintf("unsupporter pointer to type: %s", T))
	case *types.Named:
		n := T.Obj()
		if n.Pkg() != g.pkg {
			panic(fmt.Sprintf("type %s is in package %s, must be defined in package %s", n.Name(), n.Pkg().Name(), g.pkg.Name()))
		}
		// TODO(crawshaw): more checking here
		return n.Name()
	default:
		g.errorf("unsupported javaType: %#+v, %s\n", T, T)
		return "TODO"
	}
}
Ejemplo n.º 8
0
// jniType returns a string that can be used as a JNI type.
func (g *javaGen) jniType(T types.Type) string {
	if isErrorType(T) {
		// The error type is usually translated into an exception in
		// Java, however the type can be exposed in other ways, such
		// as an exported field.
		return g.jniType(types.Typ[types.String])
	}
	switch T := T.(type) {
	case *types.Basic:
		switch T.Kind() {
		case types.Bool, types.UntypedBool:
			return "jboolean"
		case types.Int:
			return "jlong"
		case types.Int8:
			return "jbyte"
		case types.Int16:
			return "jshort"
		case types.Int32, types.UntypedRune: // types.Rune
			return "jint"
		case types.Int64, types.UntypedInt:
			return "jlong"
		case types.Uint8: // types.Byte
			// TODO(crawshaw): Java bytes are signed, so this is
			// questionable, but vital.
			return "jbyte"
		// TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64:
		case types.Float32:
			return "jfloat"
		case types.Float64, types.UntypedFloat:
			return "jdouble"
		case types.String, types.UntypedString:
			return "jstring"
		default:
			g.errorf("unsupported basic type: %s", T)
			return "TODO"
		}
	case *types.Slice:
		return "jbyteArray"

	case *types.Pointer:
		if _, ok := T.Elem().(*types.Named); ok {
			return g.jniType(T.Elem())
		}
		g.errorf("unsupported pointer to type: %s", T)
	case *types.Named:
		return "jobject"
	default:
		g.errorf("unsupported jniType: %#+v, %s\n", T, T)
	}
	return "TODO"
}
Ejemplo n.º 9
0
func (g *javaGen) genCToJava(toName, fromName string, t types.Type, mode varMode) {
	if isErrorType(t) {
		g.genCToJava(toName, fromName, types.Typ[types.String], mode)
		return
	}
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.String:
			g.Printf("jstring %s = go_seq_to_java_string(env, %s);\n", toName, fromName)
		case types.Bool:
			g.Printf("jboolean %s = %s ? JNI_TRUE : JNI_FALSE;\n", toName, fromName)
		default:
			g.Printf("%s %s = (%s)%s;\n", g.jniType(t), toName, g.jniType(t), fromName)
		}
	case *types.Slice:
		switch e := t.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				g.Printf("jbyteArray %s = go_seq_to_java_bytearray(env, %s, %d);\n", toName, fromName, g.toCFlag(mode == modeRetained))
			default:
				g.errorf("unsupported type: %s", t)
			}
		default:
			g.errorf("unsupported type: %s", t)
		}
	case *types.Pointer:
		// TODO(crawshaw): test *int
		// TODO(crawshaw): test **Generator
		switch t := t.Elem().(type) {
		case *types.Named:
			g.genFromRefnum(toName, fromName, t, t.Obj())
		default:
			g.errorf("unsupported type %s", t)
		}
	case *types.Named:
		switch t.Underlying().(type) {
		case *types.Interface, *types.Pointer:
			g.genFromRefnum(toName, fromName, t, t.Obj())
		default:
			g.errorf("unsupported, direct named type %s", t)
		}
	default:
		g.Printf("%s %s = (%s)%s;\n", g.jniType(t), toName, g.jniType(t), fromName)
	}
}
Ejemplo n.º 10
0
// jniType returns a string that can be used as a JNI type.
func (g *JavaGen) jniType(T types.Type) string {
	switch T := T.(type) {
	case *types.Basic:
		switch T.Kind() {
		case types.Bool, types.UntypedBool:
			return "jboolean"
		case types.Int:
			return "jlong"
		case types.Int8:
			return "jbyte"
		case types.Int16:
			return "jshort"
		case types.Int32, types.UntypedRune: // types.Rune
			return "jint"
		case types.Int64, types.UntypedInt:
			return "jlong"
		case types.Uint8: // types.Byte
			// TODO(crawshaw): Java bytes are signed, so this is
			// questionable, but vital.
			return "jbyte"
		// TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64:
		case types.Float32:
			return "jfloat"
		case types.Float64, types.UntypedFloat:
			return "jdouble"
		case types.String, types.UntypedString:
			return "jstring"
		default:
			g.errorf("unsupported basic type: %s", T)
			return "TODO"
		}
	case *types.Slice:
		return "jbyteArray"

	case *types.Pointer:
		if _, ok := T.Elem().(*types.Named); ok {
			return g.jniType(T.Elem())
		}
		g.errorf("unsupported pointer to type: %s", T)
	case *types.Named:
		return "jobject"
	default:
		g.errorf("unsupported jniType: %#+v, %s\n", T, T)
	}
	return "TODO"
}
Ejemplo n.º 11
0
func (g *objcGen) genRead(toName, fromName string, t types.Type, mode varMode) {
	if isErrorType(t) {
		g.genRead(toName, fromName, types.Typ[types.String], mode)
		return
	}
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.String:
			g.Printf("NSString *%s = go_seq_to_objc_string(%s);\n", toName, fromName)
		case types.Bool:
			g.Printf("BOOL %s = %s ? YES : NO;\n", toName, fromName)
		default:
			g.Printf("%s %s = (%s)%s;\n", g.objcType(t), toName, g.objcType(t), fromName)
		}
	case *types.Slice:
		switch e := t.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				g.Printf("NSData *%s = go_seq_to_objc_bytearray(%s, %d);\n", toName, fromName, g.toCFlag(mode == modeRetained))
			default:
				g.errorf("unsupported type: %s", t)
			}
		default:
			g.errorf("unsupported type: %s", t)
		}
	case *types.Pointer:
		switch t := t.Elem().(type) {
		case *types.Named:
			g.genRefRead(toName, fromName, types.NewPointer(t))
		default:
			g.errorf("unsupported type %s", t)
		}
	case *types.Named:
		switch t.Underlying().(type) {
		case *types.Interface, *types.Pointer:
			g.genRefRead(toName, fromName, t)
		default:
			g.errorf("unsupported, direct named type %s", t)
		}
	default:
		g.Printf("%s %s = (%s)%s;\n", g.objcType(t), toName, g.objcType(t), fromName)
	}
}
Ejemplo n.º 12
0
func (g *javaGen) jniSigType(T types.Type) string {
	if isErrorType(T) {
		return g.jniSigType(types.Typ[types.String])
	}
	switch T := T.(type) {
	case *types.Basic:
		switch T.Kind() {
		case types.Bool, types.UntypedBool:
			return "Z"
		case types.Int:
			return "J"
		case types.Int8:
			return "B"
		case types.Int16:
			return "S"
		case types.Int32, types.UntypedRune: // types.Rune
			return "I"
		case types.Int64, types.UntypedInt:
			return "J"
		case types.Uint8: // types.Byte
			return "B"
		case types.Float32:
			return "F"
		case types.Float64, types.UntypedFloat:
			return "D"
		case types.String, types.UntypedString:
			return "Ljava/lang/String;"
		default:
			g.errorf("unsupported basic type: %s", T)
			return "TODO"
		}
	case *types.Slice:
		return "[" + g.jniSigType(T.Elem())
	case *types.Pointer:
		if _, ok := T.Elem().(*types.Named); ok {
			return g.jniSigType(T.Elem())
		}
		g.errorf("unsupported pointer to type: %s", T)
	case *types.Named:
		return "L" + g.jniClassSigPrefix(T.Obj().Pkg()) + T.Obj().Name() + ";"
	default:
		g.errorf("unsupported jniType: %#+v, %s\n", T, T)
	}
	return "TODO"
}
Ejemplo n.º 13
0
func (f *File) validResultType(typ types.Type) *Error {
	switch typ.(type) {
	default:
		name := typ.String()
		if named, ok := typ.(*types.Named); ok {
			name = named.Obj().Name()
		}
		return &Error{errors.New(fmt.Sprint("Invalid result type:", name)), 0}
	case *types.Basic:
		typ := typ.(*types.Basic)
		switch typ.Kind() {
		default:

			return &Error{errors.New(fmt.Sprint("Invalid basic type for result type :", typ.Info())), 0}
		case types.Bool:
			return nil
		case types.Int:
			return nil
		case types.Int8:
			return nil
		case types.Int16:
			return nil
		case types.Int32:
			return nil
		case types.Int64:
			return nil
		case types.Uint:
			return nil
		case types.Uint8:
			return nil
		case types.Uint16:
			return nil
		case types.Uint32:
			return nil
		case types.Uint64:
			return nil
		case types.Float32:
			return nil
		case types.Float64:
			return nil
		}
	}
}
Ejemplo n.º 14
0
func (g *javaGen) jniCallType(t types.Type) string {
	if isErrorType(t) {
		return g.jniCallType(types.Typ[types.String])
	}
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.Bool, types.UntypedBool:
			return "Boolean"
		case types.Int:
			return "Long"
		case types.Int8, types.Uint8: // types.Byte
			return "Byte"
		case types.Int16:
			return "Short"
		case types.Int32, types.UntypedRune: // types.Rune
			return "Int"
		case types.Int64, types.UntypedInt:
			return "Long"
		case types.Float32:
			return "Float"
		case types.Float64, types.UntypedFloat:
			return "Double"
		case types.String, types.UntypedString:
			return "Object"
		default:
			g.errorf("unsupported basic type: %s", t)
		}
	case *types.Slice:
		return "Object"
	case *types.Pointer:
		if _, ok := t.Elem().(*types.Named); ok {
			return g.jniCallType(t.Elem())
		}
		g.errorf("unsupported pointer to type: %s", t)
	case *types.Named:
		return "Object"
	default:
		return "Object"
	}
	return "TODO"
}
Ejemplo n.º 15
0
func (g *javaGen) genJavaToC(varName string, t types.Type, mode varMode) {
	if isErrorType(t) {
		g.genJavaToC(varName, types.Typ[types.String], mode)
		return
	}
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.String:
			g.Printf("nstring _%s = go_seq_from_java_string(env, %s);\n", varName, varName)
		default:
			g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName)
		}
	case *types.Slice:
		switch e := t.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				g.Printf("nbyteslice _%s = go_seq_from_java_bytearray(env, %s, %d);\n", varName, varName, g.toCFlag(mode == modeRetained))
			default:
				g.errorf("unsupported type: %s", t)
			}
		default:
			g.errorf("unsupported type: %s", t)
		}
	case *types.Named:
		switch u := t.Underlying().(type) {
		case *types.Interface:
			g.Printf("int32_t _%s = go_seq_to_refnum(env, %s);\n", varName, varName)
		default:
			g.errorf("unsupported named type: %s / %T", u, u)
		}
	case *types.Pointer:
		g.Printf("int32_t _%s = go_seq_to_refnum(env, %s);\n", varName, varName)
	default:
		g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName)
	}
}
Ejemplo n.º 16
0
// matchArgTypeInternal is the internal version of matchArgType. It carries a map
// remembering what types are in progress so we don't recur when faced with recursive
// types or mutually recursive types.
func (f *File) matchArgTypeInternal(t printfArgType, typ types.Type, arg ast.Expr, inProgress map[types.Type]bool) bool {
	// %v, %T accept any argument type.
	if t == anyType {
		return true
	}
	if typ == nil {
		// external call
		typ = f.pkg.types[arg].Type
		if typ == nil {
			return true // probably a type check problem
		}
	}
	// If the type implements fmt.Formatter, we have nothing to check.
	if f.isFormatter(typ) {
		return true
	}
	// If we can use a string, might arg (dynamically) implement the Stringer or Error interface?
	if t&argString != 0 {
		if types.AssertableTo(errorType, typ) || stringerType != nil && types.AssertableTo(stringerType, typ) {
			return true
		}
	}

	typ = typ.Underlying()
	if inProgress[typ] {
		// We're already looking at this type. The call that started it will take care of it.
		return true
	}
	inProgress[typ] = true

	switch typ := typ.(type) {
	case *types.Signature:
		return t&argPointer != 0

	case *types.Map:
		// Recur: map[int]int matches %d.
		return t&argPointer != 0 ||
			(f.matchArgTypeInternal(t, typ.Key(), arg, inProgress) && f.matchArgTypeInternal(t, typ.Elem(), arg, inProgress))

	case *types.Chan:
		return t&argPointer != 0

	case *types.Array:
		// Same as slice.
		if types.Identical(typ.Elem().Underlying(), types.Typ[types.Byte]) && t&argString != 0 {
			return true // %s matches []byte
		}
		// Recur: []int matches %d.
		return t&argPointer != 0 || f.matchArgTypeInternal(t, typ.Elem().Underlying(), arg, inProgress)

	case *types.Slice:
		// Same as array.
		if types.Identical(typ.Elem().Underlying(), types.Typ[types.Byte]) && t&argString != 0 {
			return true // %s matches []byte
		}
		// Recur: []int matches %d. But watch out for
		//	type T []T
		// If the element is a pointer type (type T[]*T), it's handled fine by the Pointer case below.
		return t&argPointer != 0 || f.matchArgTypeInternal(t, typ.Elem(), arg, inProgress)

	case *types.Pointer:
		// Ugly, but dealing with an edge case: a known pointer to an invalid type,
		// probably something from a failed import.
		if typ.Elem().String() == "invalid type" {
			if *verbose {
				f.Warnf(arg.Pos(), "printf argument %v is pointer to invalid or unknown type", f.gofmt(arg))
			}
			return true // special case
		}
		// If it's actually a pointer with %p, it prints as one.
		if t == argPointer {
			return true
		}
		// If it's pointer to struct, that's equivalent in our analysis to whether we can print the struct.
		if str, ok := typ.Elem().Underlying().(*types.Struct); ok {
			return f.matchStructArgType(t, str, arg, inProgress)
		}
		// The rest can print with %p as pointers, or as integers with %x etc.
		return t&(argInt|argPointer) != 0

	case *types.Struct:
		return f.matchStructArgType(t, typ, arg, inProgress)

	case *types.Interface:
		// There's little we can do.
		// Whether any particular verb is valid depends on the argument.
		// The user may have reasonable prior knowledge of the contents of the interface.
		return true

	case *types.Basic:
		switch typ.Kind() {
		case types.UntypedBool,
			types.Bool:
			return t&argBool != 0

		case types.UntypedInt,
			types.Int,
			types.Int8,
			types.Int16,
			types.Int32,
			types.Int64,
			types.Uint,
			types.Uint8,
			types.Uint16,
			types.Uint32,
			types.Uint64,
			types.Uintptr:
			return t&argInt != 0

		case types.UntypedFloat,
			types.Float32,
			types.Float64:
			return t&argFloat != 0

		case types.UntypedComplex,
			types.Complex64,
			types.Complex128:
			return t&argComplex != 0

		case types.UntypedString,
			types.String:
			return t&argString != 0

		case types.UnsafePointer:
			return t&(argPointer|argInt) != 0

		case types.UntypedRune:
			return t&(argInt|argRune) != 0

		case types.UntypedNil:
			return t&argPointer != 0 // TODO?

		case types.Invalid:
			if *verbose {
				f.Warnf(arg.Pos(), "printf argument %v has invalid or unknown type", f.gofmt(arg))
			}
			return true // Probably a type check problem.
		}
		panic("unreachable")
	}

	return false
}
Ejemplo n.º 17
0
func (g *ObjcGen) objcType(typ types.Type) string {
	if isErrorType(typ) {
		return "NSError*"
	}

	switch typ := typ.(type) {
	case *types.Basic:
		switch typ.Kind() {
		case types.Bool, types.UntypedBool:
			return "BOOL"
		case types.Int:
			return "long"
		case types.Int8:
			return "int8_t"
		case types.Int16:
			return "int16_t"
		case types.Int32, types.UntypedRune: // types.Rune
			return "int32_t"
		case types.Int64, types.UntypedInt:
			return "int64_t"
		case types.Uint8:
			// byte is an alias of uint8, and the alias is lost.
			return "byte"
		case types.Uint16:
			return "uint16_t"
		case types.Uint32:
			return "uint32_t"
		case types.Uint64:
			return "uint64_t"
		case types.Float32:
			return "float"
		case types.Float64, types.UntypedFloat:
			return "double"
		case types.String, types.UntypedString:
			return "NSString*"
		default:
			g.errorf("unsupported type: %s", typ)
			return "TODO"
		}
	case *types.Slice:
		elem := g.objcType(typ.Elem())
		// Special case: NSData seems to be a better option for byte slice.
		if elem == "byte" {
			return "NSData*"
		}
		// TODO(hyangah): support other slice types: NSArray or CFArrayRef.
		// Investigate the performance implication.
		g.errorf("unsupported type: %s", typ)
		return "TODO"
	case *types.Pointer:
		if _, ok := typ.Elem().(*types.Named); ok {
			return g.objcType(typ.Elem()) + "*"
		}
		g.errorf("unsupported pointer to type: %s", typ)
		return "TODO"
	case *types.Named:
		n := typ.Obj()
		if isObjcType(typ) {
			w := g.wrapMap[n.Name()]
			return w.ObjcType()
		}
		if !isErrorType(typ) && !g.validPkg(n.Pkg()) {
			g.errorf("type %s is in package %s, which is not bound", n.Name(), n.Pkg().Name())
			return "TODO"
		}
		switch t := typ.Underlying().(type) {
		case *types.Interface:
			if makeIfaceSummary(t).implementable {
				return "id<" + g.namePrefixOf(n.Pkg()) + n.Name() + ">"
			} else {
				return g.namePrefixOf(n.Pkg()) + n.Name() + "*"
			}
		case *types.Struct:
			return g.namePrefixOf(n.Pkg()) + n.Name()
		}
		g.errorf("unsupported, named type %s", typ)
		return "TODO"
	default:
		g.errorf("unsupported type: %#+v, %s", typ, typ)
		return "TODO"
	}
}
Ejemplo n.º 18
0
// javaType returns a string that can be used as a Java type.
func (g *javaGen) javaType(T types.Type) string {
	if isErrorType(T) {
		// The error type is usually translated into an exception in
		// Java, however the type can be exposed in other ways, such
		// as an exported field.
		return "String"
	}
	switch T := T.(type) {
	case *types.Basic:
		switch T.Kind() {
		case types.Bool, types.UntypedBool:
			return "boolean"
		case types.Int:
			return "long"
		case types.Int8:
			return "byte"
		case types.Int16:
			return "short"
		case types.Int32, types.UntypedRune: // types.Rune
			return "int"
		case types.Int64, types.UntypedInt:
			return "long"
		case types.Uint8: // types.Byte
			// TODO(crawshaw): Java bytes are signed, so this is
			// questionable, but vital.
			return "byte"
		// TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64:
		case types.Float32:
			return "float"
		case types.Float64, types.UntypedFloat:
			return "double"
		case types.String, types.UntypedString:
			return "String"
		default:
			g.errorf("unsupported basic type: %s", T)
			return "TODO"
		}
	case *types.Slice:
		elem := g.javaType(T.Elem())
		return elem + "[]"

	case *types.Pointer:
		if _, ok := T.Elem().(*types.Named); ok {
			return g.javaType(T.Elem())
		}
		panic(fmt.Sprintf("unsupported pointer to type: %s", T))
	case *types.Named:
		n := T.Obj()
		if n.Pkg() != g.pkg {
			nPkgName := "<nilpkg>"
			if nPkg := n.Pkg(); nPkg != nil {
				nPkgName = nPkg.Name()
			}
			panic(fmt.Sprintf("type %s is in package %s, must be defined in package %s", n.Name(), nPkgName, g.pkg.Name()))
		}
		// TODO(crawshaw): more checking here
		return n.Name()
	default:
		g.errorf("unsupported javaType: %#+v, %s\n", T, T)
		return "TODO"
	}
}
Ejemplo n.º 19
0
func (w *Walker) writeType(buf *bytes.Buffer, typ types.Type) {
	switch typ := typ.(type) {
	case *types.Basic:
		s := typ.Name()
		switch typ.Kind() {
		case types.UnsafePointer:
			s = "unsafe.Pointer"
		case types.UntypedBool:
			s = "ideal-bool"
		case types.UntypedInt:
			s = "ideal-int"
		case types.UntypedRune:
			// "ideal-char" for compatibility with old tool
			// TODO(gri) change to "ideal-rune"
			s = "ideal-char"
		case types.UntypedFloat:
			s = "ideal-float"
		case types.UntypedComplex:
			s = "ideal-complex"
		case types.UntypedString:
			s = "ideal-string"
		case types.UntypedNil:
			panic("should never see untyped nil type")
		default:
			switch s {
			case "byte":
				s = "uint8"
			case "rune":
				s = "int32"
			}
		}
		buf.WriteString(s)

	case *types.Array:
		fmt.Fprintf(buf, "[%d]", typ.Len())
		w.writeType(buf, typ.Elem())

	case *types.Slice:
		buf.WriteString("[]")
		w.writeType(buf, typ.Elem())

	case *types.Struct:
		buf.WriteString("struct")

	case *types.Pointer:
		buf.WriteByte('*')
		w.writeType(buf, typ.Elem())

	case *types.Tuple:
		panic("should never see a tuple type")

	case *types.Signature:
		buf.WriteString("func")
		w.writeSignature(buf, typ)

	case *types.Interface:
		buf.WriteString("interface{")
		if typ.NumMethods() > 0 {
			buf.WriteByte(' ')
			buf.WriteString(strings.Join(sortedMethodNames(typ), ", "))
			buf.WriteByte(' ')
		}
		buf.WriteString("}")

	case *types.Map:
		buf.WriteString("map[")
		w.writeType(buf, typ.Key())
		buf.WriteByte(']')
		w.writeType(buf, typ.Elem())

	case *types.Chan:
		var s string
		switch typ.Dir() {
		case types.SendOnly:
			s = "chan<- "
		case types.RecvOnly:
			s = "<-chan "
		case types.SendRecv:
			s = "chan "
		default:
			panic("unreachable")
		}
		buf.WriteString(s)
		w.writeType(buf, typ.Elem())

	case *types.Named:
		obj := typ.Obj()
		pkg := obj.Pkg()
		if pkg != nil && pkg != w.current {
			buf.WriteString(pkg.Name())
			buf.WriteByte('.')
		}
		buf.WriteString(typ.Obj().Name())

	default:
		panic(fmt.Sprintf("unknown type %T", typ))
	}
}
Ejemplo n.º 20
0
func (g *objcGen) objcType(typ types.Type) string {
	if isErrorType(typ) {
		return "NSError*"
	}

	switch typ := typ.(type) {
	case *types.Basic:
		switch typ.Kind() {
		case types.Bool:
			return "BOOL"
		case types.Int:
			return "int"
		case types.Int8:
			return "int8_t"
		case types.Int16:
			return "int16_t"
		case types.Int32:
			return "int32_t"
		case types.Int64:
			return "int64_t"
		case types.Uint8:
			// byte is an alias of uint8, and the alias is lost.
			return "byte"
		case types.Uint16:
			return "uint16_t"
		case types.Uint32:
			return "uint32_t"
		case types.Uint64:
			return "uint64_t"
		case types.Float32:
			return "float"
		case types.Float64:
			return "double"
		case types.String:
			return "NSString*"
		default:
			g.errorf("unsupported type: %s", typ)
			return "TODO"
		}
	case *types.Slice:
		elem := g.objcType(typ.Elem())
		// Special case: NSData seems to be a better option for byte slice.
		if elem == "byte" {
			return "NSData*"
		}
		// TODO(hyangah): support other slice types: NSArray or CFArrayRef.
		// Investigate the performance implication.
		g.errorf("unsupported type: %s", typ)
		return "TODO"
	case *types.Pointer:
		if _, ok := typ.Elem().(*types.Named); ok {
			return g.objcType(typ.Elem()) + "*"
		}
		g.errorf("unsupported pointer to type: %s", typ)
		return "TODO"
	case *types.Named:
		n := typ.Obj()
		if n.Pkg() != g.pkg {
			g.errorf("type %s is in package %s; only types defined in package %s is supported", n.Name(), n.Pkg().Name(), g.pkg.Name())
			return "TODO"
		}
		switch typ.Underlying().(type) {
		case *types.Interface:
			return "id<" + g.namePrefix + n.Name() + ">"
		case *types.Struct:
			return g.namePrefix + n.Name()
		}
		g.errorf("unsupported, named type %s", typ)
		return "TODO"
	default:
		g.errorf("unsupported type: %#+v, %s", typ, typ)
		return "TODO"
	}
}
Ejemplo n.º 21
0
// seqType returns a string that can be used for reading and writing a
// type using the seq library.
// TODO(hyangah): avoid panic; gobind needs to output the problematic code location.
func seqType(t types.Type) string {
	if isErrorType(t) {
		return "String"
	}
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.Bool:
			return "Bool"
		case types.Int:
			return "Int"
		case types.Int8:
			return "Int8"
		case types.Int16:
			return "Int16"
		case types.Int32:
			return "Int32"
		case types.Int64:
			return "Int64"
		case types.Uint8: // Byte.
			// TODO(crawshaw): questionable, but vital?
			return "Byte"
		// TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64:
		case types.Float32:
			return "Float32"
		case types.Float64:
			return "Float64"
		case types.String:
			return "String"
		default:
			// Should be caught earlier in processing.
			panic(fmt.Sprintf("unsupported basic seqType: %s", t))
		}
	case *types.Named:
		switch u := t.Underlying().(type) {
		case *types.Interface:
			return "Ref"
		default:
			panic(fmt.Sprintf("unsupported named seqType: %s / %T", u, u))
		}
	case *types.Slice:
		switch e := t.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				return "ByteArray"
			default:
				panic(fmt.Sprintf("unsupported seqType: %s(%s) / %T(%T)", t, e, t, e))
			}
		default:
			panic(fmt.Sprintf("unsupported seqType: %s(%s) / %T(%T)", t, e, t, e))
		}
	// TODO: let the types.Array case handled like types.Slice?
	case *types.Pointer:
		if _, ok := t.Elem().(*types.Named); ok {
			return "Ref"
		}
		panic(fmt.Sprintf("not supported yet, pointer type: %s / %T", t, t))

	default:
		panic(fmt.Sprintf("unsupported seqType: %s / %T", t, t))
	}
}
Ejemplo n.º 22
0
Archivo: ops.go Proyecto: tsandall/opa
// zero returns a new "zero" value of the specified type.
func zero(t types.Type) value {
	switch t := t.(type) {
	case *types.Basic:
		if t.Kind() == types.UntypedNil {
			panic("untyped nil has no zero value")
		}
		if t.Info()&types.IsUntyped != 0 {
			// TODO(adonovan): make it an invariant that
			// this is unreachable.  Currently some
			// constants have 'untyped' types when they
			// should be defaulted by the typechecker.
			t = ssa.DefaultType(t).(*types.Basic)
		}
		switch t.Kind() {
		case types.Bool:
			return false
		case types.Int:
			return int(0)
		case types.Int8:
			return int8(0)
		case types.Int16:
			return int16(0)
		case types.Int32:
			return int32(0)
		case types.Int64:
			return int64(0)
		case types.Uint:
			return uint(0)
		case types.Uint8:
			return uint8(0)
		case types.Uint16:
			return uint16(0)
		case types.Uint32:
			return uint32(0)
		case types.Uint64:
			return uint64(0)
		case types.Uintptr:
			return uintptr(0)
		case types.Float32:
			return float32(0)
		case types.Float64:
			return float64(0)
		case types.Complex64:
			return complex64(0)
		case types.Complex128:
			return complex128(0)
		case types.String:
			return ""
		case types.UnsafePointer:
			return unsafe.Pointer(nil)
		default:
			panic(fmt.Sprint("zero for unexpected type:", t))
		}
	case *types.Pointer:
		return (*value)(nil)
	case *types.Array:
		a := make(array, t.Len())
		for i := range a {
			a[i] = zero(t.Elem())
		}
		return a
	case *types.Named:
		return zero(t.Underlying())
	case *types.Interface:
		return iface{} // nil type, methodset and value
	case *types.Slice:
		return []value(nil)
	case *types.Struct:
		s := make(structure, t.NumFields())
		for i := range s {
			s[i] = zero(t.Field(i).Type())
		}
		return s
	case *types.Tuple:
		if t.Len() == 1 {
			return zero(t.At(0).Type())
		}
		s := make(tuple, t.Len())
		for i := range s {
			s[i] = zero(t.At(i).Type())
		}
		return s
	case *types.Chan:
		return chan value(nil)
	case *types.Map:
		if usesBuiltinMap(t.Key()) {
			return map[value]value(nil)
		}
		return (*hashmap)(nil)
	case *types.Signature:
		return (*ssa.Function)(nil)
	}
	panic(fmt.Sprint("zero: unexpected ", t))
}
Ejemplo n.º 23
0
func equalType(x, y types.Type) error {
	if reflect.TypeOf(x) != reflect.TypeOf(y) {
		return fmt.Errorf("unequal kinds: %T vs %T", x, y)
	}
	switch x := x.(type) {
	case *types.Interface:
		y := y.(*types.Interface)
		// TODO(gri): enable separate emission of Embedded interfaces
		// and ExplicitMethods then use this logic.
		// if x.NumEmbeddeds() != y.NumEmbeddeds() {
		// 	return fmt.Errorf("unequal number of embedded interfaces: %d vs %d",
		// 		x.NumEmbeddeds(), y.NumEmbeddeds())
		// }
		// for i := 0; i < x.NumEmbeddeds(); i++ {
		// 	xi := x.Embedded(i)
		// 	yi := y.Embedded(i)
		// 	if xi.String() != yi.String() {
		// 		return fmt.Errorf("mismatched %th embedded interface: %s vs %s",
		// 			i, xi, yi)
		// 	}
		// }
		// if x.NumExplicitMethods() != y.NumExplicitMethods() {
		// 	return fmt.Errorf("unequal methods: %d vs %d",
		// 		x.NumExplicitMethods(), y.NumExplicitMethods())
		// }
		// for i := 0; i < x.NumExplicitMethods(); i++ {
		// 	xm := x.ExplicitMethod(i)
		// 	ym := y.ExplicitMethod(i)
		// 	if xm.Name() != ym.Name() {
		// 		return fmt.Errorf("mismatched %th method: %s vs %s", i, xm, ym)
		// 	}
		// 	if err := equalType(xm.Type(), ym.Type()); err != nil {
		// 		return fmt.Errorf("mismatched %s method: %s", xm.Name(), err)
		// 	}
		// }
		if x.NumMethods() != y.NumMethods() {
			return fmt.Errorf("unequal methods: %d vs %d",
				x.NumMethods(), y.NumMethods())
		}
		for i := 0; i < x.NumMethods(); i++ {
			xm := x.Method(i)
			ym := y.Method(i)
			if xm.Name() != ym.Name() {
				return fmt.Errorf("mismatched %dth method: %s vs %s", i, xm, ym)
			}
			if err := equalType(xm.Type(), ym.Type()); err != nil {
				return fmt.Errorf("mismatched %s method: %s", xm.Name(), err)
			}
		}
	case *types.Array:
		y := y.(*types.Array)
		if x.Len() != y.Len() {
			return fmt.Errorf("unequal array lengths: %d vs %d", x.Len(), y.Len())
		}
		if err := equalType(x.Elem(), y.Elem()); err != nil {
			return fmt.Errorf("array elements: %s", err)
		}
	case *types.Basic:
		y := y.(*types.Basic)
		if x.Kind() != y.Kind() {
			return fmt.Errorf("unequal basic types: %s vs %s", x, y)
		}
	case *types.Chan:
		y := y.(*types.Chan)
		if x.Dir() != y.Dir() {
			return fmt.Errorf("unequal channel directions: %d vs %d", x.Dir(), y.Dir())
		}
		if err := equalType(x.Elem(), y.Elem()); err != nil {
			return fmt.Errorf("channel elements: %s", err)
		}
	case *types.Map:
		y := y.(*types.Map)
		if err := equalType(x.Key(), y.Key()); err != nil {
			return fmt.Errorf("map keys: %s", err)
		}
		if err := equalType(x.Elem(), y.Elem()); err != nil {
			return fmt.Errorf("map values: %s", err)
		}
	case *types.Named:
		y := y.(*types.Named)
		if x.String() != y.String() {
			return fmt.Errorf("unequal named types: %s vs %s", x, y)
		}
	case *types.Pointer:
		y := y.(*types.Pointer)
		if err := equalType(x.Elem(), y.Elem()); err != nil {
			return fmt.Errorf("pointer elements: %s", err)
		}
	case *types.Signature:
		y := y.(*types.Signature)
		if err := equalType(x.Params(), y.Params()); err != nil {
			return fmt.Errorf("parameters: %s", err)
		}
		if err := equalType(x.Results(), y.Results()); err != nil {
			return fmt.Errorf("results: %s", err)
		}
		if x.Variadic() != y.Variadic() {
			return fmt.Errorf("unequal varidicity: %t vs %t",
				x.Variadic(), y.Variadic())
		}
		if (x.Recv() != nil) != (y.Recv() != nil) {
			return fmt.Errorf("unequal receivers: %s vs %s", x.Recv(), y.Recv())
		}
		if x.Recv() != nil {
			// TODO(adonovan): fix: this assertion fires for interface methods.
			// The type of the receiver of an interface method is a named type
			// if the Package was loaded from export data, or an unnamed (interface)
			// type if the Package was produced by type-checking ASTs.
			// if err := equalType(x.Recv().Type(), y.Recv().Type()); err != nil {
			// 	return fmt.Errorf("receiver: %s", err)
			// }
		}
	case *types.Slice:
		y := y.(*types.Slice)
		if err := equalType(x.Elem(), y.Elem()); err != nil {
			return fmt.Errorf("slice elements: %s", err)
		}
	case *types.Struct:
		y := y.(*types.Struct)
		if x.NumFields() != y.NumFields() {
			return fmt.Errorf("unequal struct fields: %d vs %d",
				x.NumFields(), y.NumFields())
		}
		for i := 0; i < x.NumFields(); i++ {
			xf := x.Field(i)
			yf := y.Field(i)
			if xf.Name() != yf.Name() {
				return fmt.Errorf("mismatched fields: %s vs %s", xf, yf)
			}
			if err := equalType(xf.Type(), yf.Type()); err != nil {
				return fmt.Errorf("struct field %s: %s", xf.Name(), err)
			}
			if x.Tag(i) != y.Tag(i) {
				return fmt.Errorf("struct field %s has unequal tags: %q vs %q",
					xf.Name(), x.Tag(i), y.Tag(i))
			}
		}
	case *types.Tuple:
		y := y.(*types.Tuple)
		if x.Len() != y.Len() {
			return fmt.Errorf("unequal tuple lengths: %d vs %d", x.Len(), y.Len())
		}
		for i := 0; i < x.Len(); i++ {
			if err := equalType(x.At(i).Type(), y.At(i).Type()); err != nil {
				return fmt.Errorf("tuple element %d: %s", i, err)
			}
		}
	}
	return nil
}
Ejemplo n.º 24
0
// hashFor computes the hash of t.
func (h Hasher) hashFor(t types.Type) uint32 {
	// See Identical for rationale.
	switch t := t.(type) {
	case *types.Basic:
		return uint32(t.Kind())

	case *types.Array:
		return 9043 + 2*uint32(t.Len()) + 3*h.Hash(t.Elem())

	case *types.Slice:
		return 9049 + 2*h.Hash(t.Elem())

	case *types.Struct:
		var hash uint32 = 9059
		for i, n := 0, t.NumFields(); i < n; i++ {
			f := t.Field(i)
			if f.Anonymous() {
				hash += 8861
			}
			hash += hashString(t.Tag(i))
			hash += hashString(f.Name()) // (ignore f.Pkg)
			hash += h.Hash(f.Type())
		}
		return hash

	case *types.Pointer:
		return 9067 + 2*h.Hash(t.Elem())

	case *types.Signature:
		var hash uint32 = 9091
		if t.Variadic() {
			hash *= 8863
		}
		return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results())

	case *types.Interface:
		var hash uint32 = 9103
		for i, n := 0, t.NumMethods(); i < n; i++ {
			// See go/types.identicalMethods for rationale.
			// Method order is not significant.
			// Ignore m.Pkg().
			m := t.Method(i)
			hash += 3*hashString(m.Name()) + 5*h.Hash(m.Type())
		}
		return hash

	case *types.Map:
		return 9109 + 2*h.Hash(t.Key()) + 3*h.Hash(t.Elem())

	case *types.Chan:
		return 9127 + 2*uint32(t.Dir()) + 3*h.Hash(t.Elem())

	case *types.Named:
		// Not safe with a copying GC; objects may move.
		return uint32(reflect.ValueOf(t.Obj()).Pointer())

	case *types.Tuple:
		return h.hashTuple(t)
	}
	panic(t)
}
Ejemplo n.º 25
0
func reflectKind(t types.Type) reflect.Kind {
	switch t := t.(type) {
	case *types.Named:
		return reflectKind(t.Underlying())
	case *types.Basic:
		switch t.Kind() {
		case types.Bool:
			return reflect.Bool
		case types.Int:
			return reflect.Int
		case types.Int8:
			return reflect.Int8
		case types.Int16:
			return reflect.Int16
		case types.Int32:
			return reflect.Int32
		case types.Int64:
			return reflect.Int64
		case types.Uint:
			return reflect.Uint
		case types.Uint8:
			return reflect.Uint8
		case types.Uint16:
			return reflect.Uint16
		case types.Uint32:
			return reflect.Uint32
		case types.Uint64:
			return reflect.Uint64
		case types.Uintptr:
			return reflect.Uintptr
		case types.Float32:
			return reflect.Float32
		case types.Float64:
			return reflect.Float64
		case types.Complex64:
			return reflect.Complex64
		case types.Complex128:
			return reflect.Complex128
		case types.String:
			return reflect.String
		case types.UnsafePointer:
			return reflect.UnsafePointer
		}
	case *types.Array:
		return reflect.Array
	case *types.Chan:
		return reflect.Chan
	case *types.Signature:
		return reflect.Func
	case *types.Interface:
		return reflect.Interface
	case *types.Map:
		return reflect.Map
	case *types.Pointer:
		return reflect.Ptr
	case *types.Slice:
		return reflect.Slice
	case *types.Struct:
		return reflect.Struct
	}
	panic(fmt.Sprint("unexpected type: ", t))
}