mirror of
https://github.com/netbirdio/gomobile-tvos-fork.git
synced 2026-05-22 18:43:29 -07:00
bind: preserve no-arg Java constructors
When the Java class parser began culling unused constructors, the logic for determining whether a given Java class has a no-arg constructor broke when the no-arg constructor is culled. Add an explicit field for tracking the no-arg constructor property. Change-Id: Ib68929ae1108bd6fa1fd23de1d134332eb0d97a2 Reviewed-on: https://go-review.googlesource.com/29875 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
+9
-13
@@ -34,8 +34,8 @@ type javaClassInfo struct {
|
||||
// All Java classes and interfaces this class extends and implements.
|
||||
supers []*java.Class
|
||||
methods map[string]*java.Func
|
||||
// Does the extended class include a noarg constructor
|
||||
hasNoargCon bool
|
||||
// Does the class need a default no-arg constructor
|
||||
genNoargCon bool
|
||||
// Constructors for the type, on the form
|
||||
// func New<Type>(...) *Type
|
||||
cons []*types.Func
|
||||
@@ -57,7 +57,7 @@ func (g *JavaGen) Init(classes []*java.Class) {
|
||||
}
|
||||
inf := &javaClassInfo{
|
||||
methods: make(map[string]*java.Func),
|
||||
hasNoargCon: true, // java.lang.Object has a noarg constructor
|
||||
genNoargCon: true, // java.lang.Object has a no-arg constructor
|
||||
}
|
||||
for _, n := range classes {
|
||||
cls := g.clsMap[n]
|
||||
@@ -76,13 +76,7 @@ func (g *JavaGen) Init(classes []*java.Class) {
|
||||
g.errorf("%s embeds final Java class %s", s.obj, cls.Name)
|
||||
}
|
||||
inf.extends = cls
|
||||
inf.hasNoargCon = false
|
||||
for _, f := range cls.Funcs {
|
||||
if f.Constructor && len(f.Params) == 0 {
|
||||
inf.hasNoargCon = true
|
||||
break
|
||||
}
|
||||
}
|
||||
inf.genNoargCon = cls.HasNoArgCon
|
||||
}
|
||||
}
|
||||
g.jstructs[s.obj] = inf
|
||||
@@ -91,6 +85,8 @@ func (g *JavaGen) Init(classes []*java.Class) {
|
||||
if t := g.constructorType(f); t != nil {
|
||||
jinf := g.jstructs[t]
|
||||
if jinf != nil {
|
||||
sig := f.Type().(*types.Signature)
|
||||
jinf.genNoargCon = jinf.genNoargCon && sig.Params().Len() > 0
|
||||
jinf.cons = append(jinf.cons, f)
|
||||
}
|
||||
}
|
||||
@@ -181,7 +177,7 @@ func (g *JavaGen) genStruct(s structInfo) {
|
||||
}
|
||||
g.genConstructor(f, n)
|
||||
}
|
||||
if jinf.hasNoargCon {
|
||||
if jinf.genNoargCon {
|
||||
// Generate constructor for Go instantiated instances.
|
||||
g.Printf("%s(Seq.Ref ref) { this.ref = ref; }\n\n", n)
|
||||
// Generate default no-arg constructor
|
||||
@@ -1279,7 +1275,7 @@ func (g *JavaGen) GenC() error {
|
||||
if jinf, ok := g.jstructs[s.obj]; ok {
|
||||
// Leave the class and constructor NULL for Java classes with no
|
||||
// default constructor.
|
||||
if !jinf.hasNoargCon {
|
||||
if !jinf.genNoargCon {
|
||||
continue
|
||||
}
|
||||
}
|
||||
@@ -1328,7 +1324,7 @@ func (g *JavaGen) GenC() error {
|
||||
for _, f := range jinf.cons {
|
||||
g.genJNIConstructor(f, sName)
|
||||
}
|
||||
if jinf.hasNoargCon {
|
||||
if jinf.genNoargCon {
|
||||
g.Printf("JNIEXPORT jobject JNICALL\n")
|
||||
g.Printf("Java_%s_%s_%s(JNIEnv *env, jclass clazz) {\n", g.jniPkgName(), sName, java.JNIMangle("__New"))
|
||||
g.Indent()
|
||||
|
||||
Vendored
+9
@@ -125,6 +125,9 @@ Java_go_java_Java__1init(JNIEnv *env, jclass _unused) {
|
||||
clazz = (*env)->FindClass(env, "go/java/Future");
|
||||
proxy_class_java_Future = (*env)->NewGlobalRef(env, clazz);
|
||||
proxy_class_java_Future_cons = (*env)->GetMethodID(env, clazz, "<init>", "(Lgo/Seq$Ref;)V");
|
||||
clazz = (*env)->FindClass(env, "go/java/Object");
|
||||
proxy_class_java_Object = (*env)->NewGlobalRef(env, clazz);
|
||||
proxy_class_java_Object_cons = (*env)->GetMethodID(env, clazz, "<init>", "(Lgo/Seq$Ref;)V");
|
||||
clazz = (*env)->FindClass(env, "go/java/Runnable");
|
||||
proxy_class_java_Runnable = (*env)->NewGlobalRef(env, clazz);
|
||||
proxy_class_java_Runnable_cons = (*env)->GetMethodID(env, clazz, "<init>", "(Lgo/Seq$Ref;)V");
|
||||
@@ -207,6 +210,12 @@ Java_go_java_InputStream_getInputStream(JNIEnv *env, jobject this) {
|
||||
return _r0;
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_go_java_Object__1_1New(JNIEnv *env, jclass clazz) {
|
||||
int32_t refnum = new_java_Object();
|
||||
return go_seq_from_refnum(env, refnum, NULL, NULL);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_go_java_Object_setObject(JNIEnv *env, jobject this, jobject v) {
|
||||
int32_t o = go_seq_to_refnum(env, this);
|
||||
|
||||
Vendored
+6
@@ -75,6 +75,12 @@ public final class Object extends java.lang.Object implements Seq.GoObject {
|
||||
|
||||
private final Seq.Ref ref;
|
||||
|
||||
Object(Seq.Ref ref) { this.ref = ref; }
|
||||
|
||||
public Object() { this.ref = __New(); }
|
||||
|
||||
private static native Seq.Ref __New();
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
int refnum = ref.refnum;
|
||||
Seq.incGoRef(refnum);
|
||||
|
||||
@@ -145,3 +145,7 @@ func NewJavaObject() lang.Object {
|
||||
func NewJavaInteger() lang.Integer {
|
||||
return Integer.New_I(42)
|
||||
}
|
||||
|
||||
type NoargConstructor struct {
|
||||
util.BitSet // An otherwise unused class with a no-arg constructor
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ type Class struct {
|
||||
Abstract bool
|
||||
Interface bool
|
||||
Throwable bool
|
||||
// Whether the class has a no-arg constructor
|
||||
HasNoArgCon bool
|
||||
}
|
||||
|
||||
// Func is a Java static function or method or constructor.
|
||||
@@ -444,8 +446,12 @@ func (j *importer) scanClass(s *bufio.Scanner, name string) (*Class, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(cls.Supers) == 0 && name != "java.lang.Object" {
|
||||
cls.Supers = append(cls.Supers, "java.lang.Object")
|
||||
if len(cls.Supers) == 0 {
|
||||
if name == "java.lang.Object" {
|
||||
cls.HasNoArgCon = true
|
||||
} else {
|
||||
cls.Supers = append(cls.Supers, "java.lang.Object")
|
||||
}
|
||||
}
|
||||
cls.JNIName = JNIMangle(cls.Name)
|
||||
clsElems := strings.Split(cls.Name, ".")
|
||||
@@ -503,6 +509,7 @@ func (j *importer) scanClass(s *bufio.Scanner, name string) (*Class, error) {
|
||||
f.Final = final
|
||||
f.Constructor = f.Name == cls.FindName
|
||||
if f.Constructor {
|
||||
cls.HasNoArgCon = cls.HasNoArgCon || len(f.Params) == 0
|
||||
f.Public = f.Public && !cls.Abstract
|
||||
f.Name = "new"
|
||||
f.Ret = &Type{Class: name, Kind: Object}
|
||||
|
||||
Reference in New Issue
Block a user