bind: ignore unsupported basic types

Before this change, binding unsupported basic types such as
uint failed with an error. Instead, add them to the list of
ignored types so that no error is generated and a comment is
generated explaining why the offending function, constant or
variable was skipped.

Unsigned integers are probably easy to support in ObjC, but
leave them unsupported for now.

While here, improve the printing of the ignored types in the
explaining comments.

Fixes golang/go#24762

Change-Id: I0d9ab471b2245728270f6ee588f554d4a105d500
Reviewed-on: https://go-review.googlesource.com/105377
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
diff --git a/bind/gen.go b/bind/gen.go
index c072499..74646c1 100644
--- a/bind/gen.go
+++ b/bind/gen.go
@@ -484,7 +484,19 @@
 	}
 	switch t := t.(type) {
 	case *types.Basic:
-		return true
+		switch t.Kind() {
+		case types.Bool, types.UntypedBool,
+			types.Int,
+			types.Int8, types.Uint8, // types.Byte
+			types.Int16,
+			types.Int32, types.UntypedRune, // types.Rune
+			types.Int64, types.UntypedInt,
+			types.Float32,
+			types.Float64, types.UntypedFloat,
+			types.String, types.UntypedString:
+			return true
+		}
+		return false
 	case *types.Slice:
 		switch e := t.Elem().(type) {
 		case *types.Basic:
diff --git a/bind/gengo.go b/bind/gengo.go
index 4b6a22e..4ab7219 100644
--- a/bind/gengo.go
+++ b/bind/gengo.go
@@ -206,7 +206,7 @@
 
 	for _, f := range fields {
 		if t := f.Type(); !g.isSupported(t) {
-			g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", obj.Name(), f.Name(), t)
+			g.Printf("// skipped field %s.%s with unsupported type: %s\n\n", obj.Name(), f.Name(), t)
 			continue
 		}
 		g.Printf("//export proxy%s_%s_%s_Set\n", g.pkgPrefix, obj.Name(), f.Name())
@@ -253,7 +253,7 @@
 
 func (g *goGen) genVar(o *types.Var) {
 	if t := o.Type(); !g.isSupported(t) {
-		g.Printf("// skipped variable %s with unsupported type %T\n\n", o.Name(), t)
+		g.Printf("// skipped variable %s with unsupported type %s\n\n", o.Name(), t)
 		return
 	}
 	// TODO(hyangah): non-struct pointer types (*int), struct type.
diff --git a/bind/genjava.go b/bind/genjava.go
index 970dc81..545f04f 100644
--- a/bind/genjava.go
+++ b/bind/genjava.go
@@ -313,7 +313,7 @@
 
 	for _, f := range fields {
 		if t := f.Type(); !g.isSupported(t) {
-			g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", n, f.Name(), t)
+			g.Printf("// skipped field %s.%s with unsupported type: %s\n\n", n, f.Name(), t)
 			continue
 		}
 
@@ -465,7 +465,7 @@
 	g.Printf("%s that = (%s)o;\n", n, n)
 	for _, f := range fields {
 		if t := f.Type(); !g.isSupported(t) {
-			g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", n, f.Name(), t)
+			g.Printf("// skipped field %s.%s with unsupported type: %s\n\n", n, f.Name(), t)
 			continue
 		}
 		nf := f.Name()
@@ -840,7 +840,7 @@
 
 func (g *JavaGen) genVar(o *types.Var) {
 	if t := o.Type(); !g.isSupported(t) {
-		g.Printf("// skipped variable %s with unsupported type: %T\n\n", o.Name(), t)
+		g.Printf("// skipped variable %s with unsupported type: %s\n\n", o.Name(), t)
 		return
 	}
 	jType := g.javaType(o.Type())
@@ -1020,8 +1020,8 @@
 }
 
 func (g *JavaGen) genConst(o *types.Const) {
-	if _, ok := o.Type().(*types.Basic); !ok {
-		g.Printf("// skipped const %s with unsupported type: %T\n\n", o.Name(), o)
+	if _, ok := o.Type().(*types.Basic); !ok || !g.isSupported(o.Type()) {
+		g.Printf("// skipped const %s with unsupported type: %s\n\n", o.Name(), o.Type())
 		return
 	}
 	// TODO(hyangah): should const names use upper cases + "_"?
@@ -1055,7 +1055,7 @@
 
 func (g *JavaGen) genJNIField(o *types.TypeName, f *types.Var) {
 	if t := f.Type(); !g.isSupported(t) {
-		g.Printf("// skipped field %s with unsupported type: %T\n\n", o.Name(), t)
+		g.Printf("// skipped field %s with unsupported type: %s\n\n", o.Name(), t)
 		return
 	}
 	n := java.JNIMangle(g.javaTypeName(o.Name()))
@@ -1085,7 +1085,7 @@
 
 func (g *JavaGen) genJNIVar(o *types.Var) {
 	if t := o.Type(); !g.isSupported(t) {
-		g.Printf("// skipped variable %s with unsupported type: %T\n\n", o.Name(), t)
+		g.Printf("// skipped variable %s with unsupported type: %s\n\n", o.Name(), t)
 		return
 	}
 	n := java.JNIMangle(g.javaTypeName(o.Name()))
diff --git a/bind/genobjc.go b/bind/genobjc.go
index 2edb401..d24a87d 100644
--- a/bind/genobjc.go
+++ b/bind/genobjc.go
@@ -190,8 +190,8 @@
 	// const
 	// TODO: prefix with k?, or use a class method?
 	for _, obj := range g.constants {
-		if _, ok := obj.Type().(*types.Basic); !ok {
-			g.Printf("// skipped const %s with unsupported type: %T\n\n", obj.Name(), obj)
+		if _, ok := obj.Type().(*types.Basic); !ok || !g.isSupported(obj.Type()) {
+			g.Printf("// skipped const %s with unsupported type: %s\n\n", obj.Name(), obj.Type())
 			continue
 		}
 		g.objcdoc(g.docs[obj.Name()].Doc())
@@ -211,7 +211,7 @@
 		g.Printf("@interface %s : NSObject\n", g.namePrefix)
 		for _, obj := range g.vars {
 			if t := obj.Type(); !g.isSupported(t) {
-				g.Printf("// skipped variable %s with unsupported type: %T\n\n", obj.Name(), t)
+				g.Printf("// skipped variable %s with unsupported type: %s\n\n", obj.Name(), t)
 				continue
 			}
 			objcType := g.objcType(obj.Type())
@@ -338,7 +338,7 @@
 
 func (g *ObjcGen) genVarM(o *types.Var) {
 	if t := o.Type(); !g.isSupported(t) {
-		g.Printf("// skipped variable %s with unsupported type: %T\n\n", o.Name(), t)
+		g.Printf("// skipped variable %s with unsupported type: %s\n\n", o.Name(), t)
 		return
 	}
 	objcType := g.objcType(o.Type())
@@ -364,8 +364,8 @@
 }
 
 func (g *ObjcGen) genConstM(o *types.Const) {
-	if _, ok := o.Type().(*types.Basic); !ok {
-		g.Printf("// skipped const %s with unsupported type: %T\n\n", o.Name(), o)
+	if _, ok := o.Type().(*types.Basic); !ok || !g.isSupported(o.Type()) {
+		g.Printf("// skipped const %s with unsupported type: %s\n\n", o.Name(), o.Type())
 		return
 	}
 	cName := fmt.Sprintf("%s%s", g.namePrefix, o.Name())
@@ -1114,7 +1114,7 @@
 	// accessors to exported fields.
 	for _, f := range exportedFields(t) {
 		if t := f.Type(); !g.isSupported(t) {
-			g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", obj.Name(), f.Name(), t)
+			g.Printf("// skipped field %s.%s with unsupported type: %s\n\n", obj.Name(), f.Name(), t)
 			continue
 		}
 		name, typ := f.Name(), g.objcFieldType(f.Type())
@@ -1184,7 +1184,7 @@
 
 	for _, f := range fields {
 		if !g.isSupported(f.Type()) {
-			g.Printf("// skipped unsupported field %s with type %T\n\n", f.Name(), f)
+			g.Printf("// skipped unsupported field %s with type %s\n\n", f.Name(), f.Type())
 			continue
 		}
 		g.genGetter(obj.Name(), f)
diff --git a/bind/testdata/ignore.go b/bind/testdata/ignore.go
index f51e901..2d3e1a6 100644
--- a/bind/testdata/ignore.go
+++ b/bind/testdata/ignore.go
@@ -43,3 +43,17 @@
 	Argument(_ interface{})
 	Result() interface{}
 }
+
+var (
+	Uint   uint
+	Uint32 uint32
+	Uint64 uint64
+	C64    complex64  = 0
+	C128   complex128 = 0
+)
+
+const (
+	Cuint   uint   = 0
+	Cuint32 uint32 = 0
+	Cuint64 uint64 = 0
+)
diff --git a/bind/testdata/ignore.go.golden b/bind/testdata/ignore.go.golden
index ed73288..abcdb91 100644
--- a/bind/testdata/ignore.go.golden
+++ b/bind/testdata/ignore.go.golden
@@ -21,7 +21,7 @@
 // suppress the error if seq ends up unused
 var _ = _seq.FromRefNum
 
-// skipped field S.F with unsupported type: *types.Interface
+// skipped field S.F with unsupported type: interface{}
 
 // skipped method S.Argument with unsupported parameter or return types
 
@@ -42,9 +42,19 @@
 
 // skipped method I.Argument with unsupported parameter or result types
 // skipped method I.Result with unsupported parameter or result types
-// skipped variable V with unsupported type *types.Interface
+// skipped variable C128 with unsupported type complex128
 
-// skipped variable Var with unsupported type *types.Interface
+// skipped variable C64 with unsupported type complex64
+
+// skipped variable Uint with unsupported type uint
+
+// skipped variable Uint32 with unsupported type uint32
+
+// skipped variable Uint64 with unsupported type uint64
+
+// skipped variable V with unsupported type interface{}
+
+// skipped variable Var with unsupported type interface{}
 
 // skipped function Argument with unsupported parameter or result types
 // skipped function Result with unsupported parameter or result types
diff --git a/bind/testdata/ignore.java.c.golden b/bind/testdata/ignore.java.c.golden
index 9be1408..6a29ff0 100644
--- a/bind/testdata/ignore.java.c.golden
+++ b/bind/testdata/ignore.java.c.golden
@@ -49,7 +49,7 @@
 
 // skipped function S.Result with unsupported parameter or return types
 
-// skipped field S with unsupported type: *types.Interface
+// skipped field S with unsupported type: interface{}
 
 // skipped function I.Argument with unsupported parameter or return types
 
@@ -59,7 +59,17 @@
 
 // skipped method I with unsupported parameter or return types
 
-// skipped variable V with unsupported type: *types.Interface
+// skipped variable C128 with unsupported type: complex128
 
-// skipped variable Var with unsupported type: *types.Interface
+// skipped variable C64 with unsupported type: complex64
+
+// skipped variable Uint with unsupported type: uint
+
+// skipped variable Uint32 with unsupported type: uint32
+
+// skipped variable Uint64 with unsupported type: uint64
+
+// skipped variable V with unsupported type: interface{}
+
+// skipped variable Var with unsupported type: interface{}
 
diff --git a/bind/testdata/ignore.java.golden b/bind/testdata/ignore.java.golden
index 6255635..d00b3b7 100644
--- a/bind/testdata/ignore.java.golden
+++ b/bind/testdata/ignore.java.golden
@@ -23,7 +23,7 @@
     
     private static native Seq.Ref __New();
     
-    // skipped field S.F with unsupported type: *types.Interface
+    // skipped field S.F with unsupported type: interface{}
     
     // skipped method S.Argument with unsupported parameter or return types
     
@@ -34,7 +34,7 @@
             return false;
         }
         S that = (S)o;
-        // skipped field S.F with unsupported type: *types.Interface
+        // skipped field S.F with unsupported type: interface{}
         
         return true;
     }
@@ -104,12 +104,28 @@
         
     }
     
-    // skipped const NamedConst with unsupported type: *types.Const
+    // skipped const Cuint with unsupported type: uint
+    
+    // skipped const Cuint32 with unsupported type: uint32
+    
+    // skipped const Cuint64 with unsupported type: uint64
+    
+    // skipped const NamedConst with unsupported type: ignore.NamedString
     
     
-    // skipped variable V with unsupported type: *types.Interface
+    // skipped variable C128 with unsupported type: complex128
     
-    // skipped variable Var with unsupported type: *types.Interface
+    // skipped variable C64 with unsupported type: complex64
+    
+    // skipped variable Uint with unsupported type: uint
+    
+    // skipped variable Uint32 with unsupported type: uint32
+    
+    // skipped variable Uint64 with unsupported type: uint64
+    
+    // skipped variable V with unsupported type: interface{}
+    
+    // skipped variable Var with unsupported type: interface{}
     
     // skipped function Argument with unsupported parameter or return types
     
diff --git a/bind/testdata/ignore.objc.h.golden b/bind/testdata/ignore.objc.h.golden
index 38656b9..3004348 100644
--- a/bind/testdata/ignore.objc.h.golden
+++ b/bind/testdata/ignore.objc.h.golden
@@ -27,7 +27,7 @@
 
 - (instancetype)initWithRef:(id)ref;
 - (instancetype)init;
-// skipped field S.F with unsupported type: *types.Interface
+// skipped field S.F with unsupported type: interface{}
 
 // skipped method S.Argument with unsupported parameter or return types
 
@@ -35,13 +35,29 @@
 
 @end
 
-// skipped const NamedConst with unsupported type: *types.Const
+// skipped const Cuint with unsupported type: uint
+
+// skipped const Cuint32 with unsupported type: uint32
+
+// skipped const Cuint64 with unsupported type: uint64
+
+// skipped const NamedConst with unsupported type: ignore.NamedString
 
 
 @interface Ignore : NSObject
-// skipped variable V with unsupported type: *types.Interface
+// skipped variable C128 with unsupported type: complex128
 
-// skipped variable Var with unsupported type: *types.Interface
+// skipped variable C64 with unsupported type: complex64
+
+// skipped variable Uint with unsupported type: uint
+
+// skipped variable Uint32 with unsupported type: uint32
+
+// skipped variable Uint64 with unsupported type: uint64
+
+// skipped variable V with unsupported type: interface{}
+
+// skipped variable Var with unsupported type: interface{}
 
 @end
 
diff --git a/bind/testdata/ignore.objc.m.golden b/bind/testdata/ignore.objc.m.golden
index 2e536c7..074cbce 100644
--- a/bind/testdata/ignore.objc.m.golden
+++ b/bind/testdata/ignore.objc.m.golden
@@ -26,7 +26,7 @@
 	return self;
 }
 
-// skipped unsupported field F with type *types.Var
+// skipped unsupported field F with type interface{}
 
 // skipped method S.Argument with unsupported parameter or return types
 
@@ -51,13 +51,29 @@
 @end
 
 
-// skipped const NamedConst with unsupported type: *types.Const
+// skipped const Cuint with unsupported type: uint
+
+// skipped const Cuint32 with unsupported type: uint32
+
+// skipped const Cuint64 with unsupported type: uint64
+
+// skipped const NamedConst with unsupported type: ignore.NamedString
 
 
 @implementation Ignore
-// skipped variable V with unsupported type: *types.Interface
+// skipped variable C128 with unsupported type: complex128
 
-// skipped variable Var with unsupported type: *types.Interface
+// skipped variable C64 with unsupported type: complex64
+
+// skipped variable Uint with unsupported type: uint
+
+// skipped variable Uint32 with unsupported type: uint32
+
+// skipped variable Uint64 with unsupported type: uint64
+
+// skipped variable V with unsupported type: interface{}
+
+// skipped variable Var with unsupported type: interface{}
 
 @end