bind: generate reverse bindings for implicit Java types
Before this CL, Java types that were only implicitly referenced were represented as interface{}. However, if a value of such an implicit type were passed to Java, a runtime crash would occur because there would be no wrapper class to unwrap. Fix this by generating implicit types, fixing the crashes, gaining type safety, and removing the interface{} special case in the generator. While we're here, remove a redundant insert to the clsMap map in java.go. Change-Id: Ic50125da3d7cd6075899bf628d419b084c630490 Reviewed-on: https://go-review.googlesource.com/34777 Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
ff6f6e8d8e
commit
fe0977739a
@ -84,9 +84,6 @@ func (g *ClassGen) goType(t *java.Type, local bool) string {
|
||||
case java.Array:
|
||||
return "[]" + g.goType(t.Elem, local)
|
||||
case java.Object:
|
||||
if _, exists := g.imported[t.Class]; !exists {
|
||||
return "interface{}"
|
||||
}
|
||||
name := goClsName(t.Class)
|
||||
if !local {
|
||||
name = "Java." + name
|
||||
|
@ -114,12 +114,6 @@ public class ClassesTest extends InstrumentationTestCase {
|
||||
assertEquals("IOException message", Javapkg.IOExceptionMessage, exc.getMessage());
|
||||
}
|
||||
|
||||
public void testUnknownType() {
|
||||
GoObject o = new GoObject();
|
||||
o.toString(); // Set this
|
||||
assertTrue("GoObject.getClass not null", o.checkClass());
|
||||
}
|
||||
|
||||
public void testInnerClass() {
|
||||
Character.Subset s = new Character.Subset(""){};
|
||||
Character.Subset s2 = new GoSubset("");
|
||||
|
7
bind/testdata/classes.go
vendored
7
bind/testdata/classes.go
vendored
@ -8,6 +8,7 @@ import (
|
||||
gopkg "Java/go/java"
|
||||
"Java/java/io"
|
||||
"Java/java/lang"
|
||||
"Java/java/lang/System"
|
||||
"Java/java/util/Spliterators"
|
||||
"Java/java/util/concurrent"
|
||||
)
|
||||
@ -52,3 +53,9 @@ func innerClassTypes() {
|
||||
// for the return value as well as parameters.
|
||||
Spliterators.Iterator_Ljava_util_Spliterator_00024OfInt_2(nil)
|
||||
}
|
||||
|
||||
func returnType() {
|
||||
// Implicit types (java.io.Console) should be wrapped.
|
||||
cons := System.Console()
|
||||
cons.Flush()
|
||||
}
|
||||
|
175
bind/testdata/classes.go.golden
vendored
175
bind/testdata/classes.go.golden
vendored
@ -27,6 +27,9 @@ type Java_util_concurrent_TimeUnit interface {
|
||||
type Java_util_Spliterators interface {
|
||||
}
|
||||
|
||||
type Java_lang_System interface {
|
||||
}
|
||||
|
||||
type Go_java_Future interface {
|
||||
Get() (Java_lang_Object, error)
|
||||
Get2(a0 int64, a1 Java_util_concurrent_TimeUnit) (Java_lang_Object, error)
|
||||
@ -47,6 +50,16 @@ type Go_java_Runnable interface {
|
||||
Super() Go_java_Runnable
|
||||
}
|
||||
|
||||
type Java_util_PrimitiveIterator_OfInt interface {
|
||||
}
|
||||
|
||||
type Java_util_Spliterator_OfInt interface {
|
||||
}
|
||||
|
||||
type Java_io_Console interface {
|
||||
Flush() error
|
||||
}
|
||||
|
||||
// File is generated by gobind. Do not edit.
|
||||
|
||||
package gomobile_bind
|
||||
@ -70,10 +83,14 @@ import "Java/java/util/concurrent/Future"
|
||||
import "Java/java/lang/Object"
|
||||
import "Java/java/util/concurrent/TimeUnit"
|
||||
import "Java/java/util/Spliterators"
|
||||
import "Java/java/lang/System"
|
||||
import "Java/go/java/Future"
|
||||
import "Java/go/java/InputStream"
|
||||
import "Java/go/java/Object"
|
||||
import "Java/go/java/Runnable"
|
||||
import "Java/java/util/PrimitiveIterator/OfInt"
|
||||
import "Java/java/util/Spliterator/OfInt"
|
||||
import "Java/java/io/Console"
|
||||
import "unsafe"
|
||||
|
||||
import "reflect"
|
||||
@ -96,10 +113,14 @@ func initClasses() {
|
||||
init_java_lang_Object()
|
||||
init_java_util_concurrent_TimeUnit()
|
||||
init_java_util_Spliterators()
|
||||
init_java_lang_System()
|
||||
init_go_java_Future()
|
||||
init_go_java_InputStream()
|
||||
init_go_java_Object()
|
||||
init_go_java_Runnable()
|
||||
init_java_util_PrimitiveIterator_OfInt()
|
||||
init_java_util_Spliterator_OfInt()
|
||||
init_java_io_Console()
|
||||
}
|
||||
|
||||
var class_java_lang_Runnable C.jclass
|
||||
@ -324,19 +345,19 @@ func init_java_util_Spliterators() {
|
||||
C.free(unsafe.Pointer(fn))
|
||||
C.free(unsafe.Pointer(fd))
|
||||
if m != nil {
|
||||
Spliterators.Iterator_Ljava_util_Spliterator_00024OfInt_2 = func(a0 interface{}) interface{} {
|
||||
Spliterators.Iterator_Ljava_util_Spliterator_00024OfInt_2 = func(a0 Java.Java_util_Spliterator_OfInt) Java.Java_util_PrimitiveIterator_OfInt {
|
||||
var _a0 C.jint = _seq.NullRefNum
|
||||
if a0 != nil {
|
||||
_a0 = C.jint(_seq.ToRefNum(a0))
|
||||
}
|
||||
res := C.cproxy_s_java_util_Spliterators_iterator__Ljava_util_Spliterator_00024OfInt_2(clazz, m, _a0)
|
||||
var _res interface{}
|
||||
var _res Java.Java_util_PrimitiveIterator_OfInt
|
||||
_res_ref := _seq.FromRefNum(int32(res.res))
|
||||
if _res_ref != nil {
|
||||
if res.res < 0 { // go object
|
||||
_res = _res_ref.Get().(interface{})
|
||||
_res = _res_ref.Get().(Java.Java_util_PrimitiveIterator_OfInt)
|
||||
} else { // foreign object
|
||||
_res = _res_ref
|
||||
_res = (*proxy_class_java_util_PrimitiveIterator_OfInt)(_res_ref)
|
||||
}
|
||||
}
|
||||
var _exc error
|
||||
@ -368,6 +389,63 @@ type proxy_class_java_util_Spliterators _seq.Ref
|
||||
|
||||
func (p *proxy_class_java_util_Spliterators) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }
|
||||
|
||||
var class_java_lang_System C.jclass
|
||||
|
||||
func init_java_lang_System() {
|
||||
cls := C.CString("java/lang/System")
|
||||
clazz := C.go_seq_find_class(cls)
|
||||
C.free(unsafe.Pointer(cls))
|
||||
if clazz == nil {
|
||||
return
|
||||
}
|
||||
class_java_lang_System = clazz
|
||||
{
|
||||
fn := C.CString("console")
|
||||
fd := C.CString("()Ljava/io/Console;")
|
||||
m := C.go_seq_get_static_method_id(clazz, fn, fd)
|
||||
C.free(unsafe.Pointer(fn))
|
||||
C.free(unsafe.Pointer(fd))
|
||||
if m != nil {
|
||||
System.Console = func() Java.Java_io_Console {
|
||||
res := C.cproxy_s_java_lang_System_console(clazz, m)
|
||||
var _res Java.Java_io_Console
|
||||
_res_ref := _seq.FromRefNum(int32(res.res))
|
||||
if _res_ref != nil {
|
||||
if res.res < 0 { // go object
|
||||
_res = _res_ref.Get().(Java.Java_io_Console)
|
||||
} else { // foreign object
|
||||
_res = (*proxy_class_java_io_Console)(_res_ref)
|
||||
}
|
||||
}
|
||||
var _exc error
|
||||
_exc_ref := _seq.FromRefNum(int32(res.exc))
|
||||
if _exc_ref != nil {
|
||||
if res.exc < 0 { // go object
|
||||
_exc = _exc_ref.Get().(error)
|
||||
} else { // foreign object
|
||||
_exc = (*proxy_error)(_exc_ref)
|
||||
}
|
||||
}
|
||||
if (_exc != nil) { panic(_exc) }
|
||||
return _res
|
||||
}
|
||||
}
|
||||
}
|
||||
System.Cast = func(v interface{}) Java.Java_lang_System {
|
||||
t := reflect.TypeOf((*proxy_class_java_lang_System)(nil))
|
||||
cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_lang_System)
|
||||
ref := C.jint(_seq.ToRefNum(cv))
|
||||
if C.go_seq_isinstanceof(ref, class_java_lang_System) != 1 {
|
||||
panic(fmt.Errorf("%T is not an instance of %s", v, "java.lang.System"))
|
||||
}
|
||||
return cv
|
||||
}
|
||||
}
|
||||
|
||||
type proxy_class_java_lang_System _seq.Ref
|
||||
|
||||
func (p *proxy_class_java_lang_System) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }
|
||||
|
||||
var class_go_java_Future C.jclass
|
||||
|
||||
func init_go_java_Future() {
|
||||
@ -652,6 +730,95 @@ func (p *super_go_java_Runnable) Run() {
|
||||
if (_exc != nil) { panic(_exc) }
|
||||
}
|
||||
|
||||
var class_java_util_PrimitiveIterator_OfInt C.jclass
|
||||
|
||||
func init_java_util_PrimitiveIterator_OfInt() {
|
||||
cls := C.CString("java/util/PrimitiveIterator$OfInt")
|
||||
clazz := C.go_seq_find_class(cls)
|
||||
C.free(unsafe.Pointer(cls))
|
||||
if clazz == nil {
|
||||
return
|
||||
}
|
||||
class_java_util_PrimitiveIterator_OfInt = clazz
|
||||
OfInt.Cast = func(v interface{}) Java.Java_util_PrimitiveIterator_OfInt {
|
||||
t := reflect.TypeOf((*proxy_class_java_util_PrimitiveIterator_OfInt)(nil))
|
||||
cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_util_PrimitiveIterator_OfInt)
|
||||
ref := C.jint(_seq.ToRefNum(cv))
|
||||
if C.go_seq_isinstanceof(ref, class_java_util_PrimitiveIterator_OfInt) != 1 {
|
||||
panic(fmt.Errorf("%T is not an instance of %s", v, "java.util.PrimitiveIterator.OfInt"))
|
||||
}
|
||||
return cv
|
||||
}
|
||||
}
|
||||
|
||||
type proxy_class_java_util_PrimitiveIterator_OfInt _seq.Ref
|
||||
|
||||
func (p *proxy_class_java_util_PrimitiveIterator_OfInt) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }
|
||||
|
||||
var class_java_util_Spliterator_OfInt C.jclass
|
||||
|
||||
func init_java_util_Spliterator_OfInt() {
|
||||
cls := C.CString("java/util/Spliterator$OfInt")
|
||||
clazz := C.go_seq_find_class(cls)
|
||||
C.free(unsafe.Pointer(cls))
|
||||
if clazz == nil {
|
||||
return
|
||||
}
|
||||
class_java_util_Spliterator_OfInt = clazz
|
||||
OfInt.Cast = func(v interface{}) Java.Java_util_Spliterator_OfInt {
|
||||
t := reflect.TypeOf((*proxy_class_java_util_Spliterator_OfInt)(nil))
|
||||
cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_util_Spliterator_OfInt)
|
||||
ref := C.jint(_seq.ToRefNum(cv))
|
||||
if C.go_seq_isinstanceof(ref, class_java_util_Spliterator_OfInt) != 1 {
|
||||
panic(fmt.Errorf("%T is not an instance of %s", v, "java.util.Spliterator.OfInt"))
|
||||
}
|
||||
return cv
|
||||
}
|
||||
}
|
||||
|
||||
type proxy_class_java_util_Spliterator_OfInt _seq.Ref
|
||||
|
||||
func (p *proxy_class_java_util_Spliterator_OfInt) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }
|
||||
|
||||
var class_java_io_Console C.jclass
|
||||
|
||||
func init_java_io_Console() {
|
||||
cls := C.CString("java/io/Console")
|
||||
clazz := C.go_seq_find_class(cls)
|
||||
C.free(unsafe.Pointer(cls))
|
||||
if clazz == nil {
|
||||
return
|
||||
}
|
||||
class_java_io_Console = clazz
|
||||
Console.Cast = func(v interface{}) Java.Java_io_Console {
|
||||
t := reflect.TypeOf((*proxy_class_java_io_Console)(nil))
|
||||
cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_io_Console)
|
||||
ref := C.jint(_seq.ToRefNum(cv))
|
||||
if C.go_seq_isinstanceof(ref, class_java_io_Console) != 1 {
|
||||
panic(fmt.Errorf("%T is not an instance of %s", v, "java.io.Console"))
|
||||
}
|
||||
return cv
|
||||
}
|
||||
}
|
||||
|
||||
type proxy_class_java_io_Console _seq.Ref
|
||||
|
||||
func (p *proxy_class_java_io_Console) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }
|
||||
|
||||
func (p *proxy_class_java_io_Console) Flush() error {
|
||||
res := C.cproxy_java_io_Console_flush(C.jint(p.Bind_proxy_refnum__()))
|
||||
var _exc error
|
||||
_exc_ref := _seq.FromRefNum(int32(res))
|
||||
if _exc_ref != nil {
|
||||
if res < 0 { // go object
|
||||
_exc = _exc_ref.Get().(error)
|
||||
} else { // foreign object
|
||||
_exc = (*proxy_error)(_exc_ref)
|
||||
}
|
||||
}
|
||||
return _exc
|
||||
}
|
||||
|
||||
// Package gomobile_bind is an autogenerated binder stub for package java.
|
||||
// gobind -lang=go classes
|
||||
//
|
||||
|
41
bind/testdata/classes.java.c.golden
vendored
41
bind/testdata/classes.java.c.golden
vendored
@ -29,6 +29,21 @@ ret_jint cproxy_s_java_util_Spliterators_iterator__Ljava_util_Spliterator_00024O
|
||||
}
|
||||
|
||||
static jclass class_java_util_Spliterators;
|
||||
ret_jint cproxy_s_java_lang_System_console(jclass clazz, jmethodID m) {
|
||||
JNIEnv *env = go_seq_push_local_frame(0);
|
||||
jobject res = (*env)->CallStaticObjectMethod(env, clazz, m);
|
||||
jobject _exc = go_seq_get_exception(env);
|
||||
int32_t _exc_ref = go_seq_to_refnum(env, _exc);
|
||||
if (_exc != NULL) {
|
||||
res = NULL;
|
||||
}
|
||||
jint _res = go_seq_to_refnum(env, res);
|
||||
go_seq_pop_local_frame(env);
|
||||
ret_jint __res = {_res, _exc_ref};
|
||||
return __res;
|
||||
}
|
||||
|
||||
static jclass class_java_lang_System;
|
||||
static jclass class_go_java_Future;
|
||||
static jclass sclass_go_java_Future;
|
||||
static jmethodID m_go_java_Future_get__;
|
||||
@ -45,9 +60,13 @@ static jclass class_go_java_Runnable;
|
||||
static jclass sclass_go_java_Runnable;
|
||||
static jmethodID m_go_java_Runnable_run;
|
||||
static jmethodID sm_go_java_Runnable_run;
|
||||
static jclass class_java_util_PrimitiveIterator_OfInt;
|
||||
static jclass class_java_util_Spliterator_OfInt;
|
||||
static jclass class_java_io_Console;
|
||||
static jmethodID m_java_io_Console_flush;
|
||||
|
||||
void init_proxies() {
|
||||
JNIEnv *env = go_seq_push_local_frame(10);
|
||||
JNIEnv *env = go_seq_push_local_frame(14);
|
||||
jclass clazz;
|
||||
clazz = (*env)->FindClass(env, "java/lang/Runnable");
|
||||
class_java_lang_Runnable = (*env)->NewGlobalRef(env, clazz);
|
||||
@ -65,6 +84,8 @@ void init_proxies() {
|
||||
class_java_util_concurrent_TimeUnit = (*env)->NewGlobalRef(env, clazz);
|
||||
clazz = (*env)->FindClass(env, "java/util/Spliterators");
|
||||
class_java_util_Spliterators = (*env)->NewGlobalRef(env, clazz);
|
||||
clazz = (*env)->FindClass(env, "java/lang/System");
|
||||
class_java_lang_System = (*env)->NewGlobalRef(env, clazz);
|
||||
clazz = (*env)->FindClass(env, "go/java/Future");
|
||||
class_go_java_Future = (*env)->NewGlobalRef(env, clazz);
|
||||
sclass_go_java_Future = (*env)->GetSuperclass(env, clazz);
|
||||
@ -89,6 +110,13 @@ void init_proxies() {
|
||||
sclass_go_java_Runnable = (*env)->NewGlobalRef(env, sclass_go_java_Runnable);
|
||||
m_go_java_Runnable_run = go_seq_get_method_id(clazz, "run", "()V");
|
||||
sm_go_java_Runnable_run = go_seq_get_method_id(sclass_go_java_Runnable, "run", "()V");
|
||||
clazz = (*env)->FindClass(env, "java/util/PrimitiveIterator$OfInt");
|
||||
class_java_util_PrimitiveIterator_OfInt = (*env)->NewGlobalRef(env, clazz);
|
||||
clazz = (*env)->FindClass(env, "java/util/Spliterator$OfInt");
|
||||
class_java_util_Spliterator_OfInt = (*env)->NewGlobalRef(env, clazz);
|
||||
clazz = (*env)->FindClass(env, "java/io/Console");
|
||||
class_java_io_Console = (*env)->NewGlobalRef(env, clazz);
|
||||
m_java_io_Console_flush = go_seq_get_method_id(clazz, "flush", "()V");
|
||||
go_seq_pop_local_frame(env);
|
||||
}
|
||||
|
||||
@ -275,6 +303,17 @@ jint csuper_go_java_Runnable_run(jint this) {
|
||||
return _exc_ref;
|
||||
}
|
||||
|
||||
jint cproxy_java_io_Console_flush(jint this) {
|
||||
JNIEnv *env = go_seq_push_local_frame(1);
|
||||
// Must be a Java object
|
||||
jobject _this = go_seq_from_refnum(env, this, NULL, NULL);
|
||||
(*env)->CallVoidMethod(env, _this, m_java_io_Console_flush);
|
||||
jobject _exc = go_seq_get_exception(env);
|
||||
int32_t _exc_ref = go_seq_to_refnum(env, _exc);
|
||||
go_seq_pop_local_frame(env);
|
||||
return _exc_ref;
|
||||
}
|
||||
|
||||
// JNI functions for the Go <=> Java bridge.
|
||||
// gobind -lang=java classes
|
||||
//
|
||||
|
2
bind/testdata/classes.java.h.golden
vendored
2
bind/testdata/classes.java.h.golden
vendored
@ -58,7 +58,9 @@ extern ret_jint cproxy_go_java_InputStream_read__(jint this);
|
||||
extern ret_jint csuper_go_java_InputStream_read__(jint this);
|
||||
extern jint cproxy_go_java_Runnable_run(jint this);
|
||||
extern jint csuper_go_java_Runnable_run(jint this);
|
||||
extern jint cproxy_java_io_Console_flush(jint this);
|
||||
extern ret_jint cproxy_s_java_util_Spliterators_iterator__Ljava_util_Spliterator_00024OfInt_2(jclass clazz, jmethodID m, jint a0);
|
||||
extern ret_jint cproxy_s_java_lang_System_console(jclass clazz, jmethodID m);
|
||||
// JNI function headers for the Go <=> Java bridge.
|
||||
// gobind -lang=java classes
|
||||
//
|
||||
|
@ -92,14 +92,6 @@ func (o *GoObject) ToString(this gopkg.GoObject) string {
|
||||
return ToStringPrefix + this.Super().ToString()
|
||||
}
|
||||
|
||||
func (r *GoObject) CheckClass() bool {
|
||||
// Verify that GetClass returns interface{} because java.lang.Class
|
||||
// is unreferenced.
|
||||
var f func() interface{} = r.this.GetClass
|
||||
// But it should return a value
|
||||
return f() != nil
|
||||
}
|
||||
|
||||
func (_ *GoObject) HashCode() int32 {
|
||||
return 42
|
||||
}
|
||||
|
@ -196,16 +196,52 @@ func (j *Importer) Import(refs *importers.References) ([]*Class, error) {
|
||||
classes = append(classes, cls)
|
||||
j.clsMap[cls.Name] = cls
|
||||
}
|
||||
j.initClasses(classes, refs)
|
||||
// Include implicit classes that are used in parameter or return values.
|
||||
newClasses := classes
|
||||
for len(newClasses) > 0 {
|
||||
var impNames []string
|
||||
var impClasses []*Class
|
||||
for _, cls := range newClasses {
|
||||
for _, funcs := range [][]*Func{cls.Funcs, cls.AllMethods} {
|
||||
for _, f := range funcs {
|
||||
names := j.implicitFuncTypes(f)
|
||||
for _, name := range names {
|
||||
if _, exists := clsSet[name]; exists {
|
||||
continue
|
||||
}
|
||||
clsSet[name] = struct{}{}
|
||||
if cls, exists := j.clsMap[name]; exists {
|
||||
impClasses = append(impClasses, cls)
|
||||
} else {
|
||||
impNames = append(impNames, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
imports, err := j.importClasses(impNames, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
impClasses = append(impClasses, imports...)
|
||||
j.initClasses(impClasses, refs)
|
||||
classes = append(classes, impClasses...)
|
||||
newClasses = impClasses
|
||||
}
|
||||
j.fillThrowables(classes)
|
||||
return classes, nil
|
||||
}
|
||||
|
||||
func (j *Importer) initClasses(classes []*Class, refs *importers.References) {
|
||||
for _, cls := range classes {
|
||||
j.fillAllMethods(cls)
|
||||
}
|
||||
j.fillThrowables()
|
||||
for _, cls := range classes {
|
||||
j.mangleOverloads(cls.AllMethods)
|
||||
j.mangleOverloads(cls.Funcs)
|
||||
}
|
||||
j.filterReferences(classes, refs)
|
||||
return classes, nil
|
||||
}
|
||||
|
||||
func (v *Var) Constant() bool {
|
||||
@ -411,7 +447,7 @@ func (j *Importer) importClasses(names []string, allowMissingClasses bool) ([]*C
|
||||
classes = append(classes, cls)
|
||||
j.clsMap[name] = cls
|
||||
}
|
||||
// Include the methods from classes extended or implemented
|
||||
// Include methods from extended or implemented classes.
|
||||
unkCls := classes
|
||||
for {
|
||||
var unknown []string
|
||||
@ -425,14 +461,24 @@ func (j *Importer) importClasses(names []string, allowMissingClasses bool) ([]*C
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, cls := range newCls {
|
||||
j.clsMap[cls.Name] = cls
|
||||
}
|
||||
unkCls = newCls
|
||||
}
|
||||
return classes, nil
|
||||
}
|
||||
|
||||
func (j *Importer) implicitFuncTypes(f *Func) []string {
|
||||
var unk []string
|
||||
if rt := f.Ret; rt != nil && rt.Kind == Object {
|
||||
unk = append(unk, rt.Class)
|
||||
}
|
||||
for _, t := range f.Params {
|
||||
if t.Kind == Object {
|
||||
unk = append(unk, t.Class)
|
||||
}
|
||||
}
|
||||
return unk
|
||||
}
|
||||
|
||||
func (j *Importer) unknownSuperClasses(cls *Class, unk []string) []string {
|
||||
loop:
|
||||
for _, n := range cls.Supers {
|
||||
@ -727,14 +773,14 @@ func (j *Importer) scanMethod(decl, desc string, parenIdx int) (*Func, error) {
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (j *Importer) fillThrowables() {
|
||||
func (j *Importer) fillThrowables(classes []*Class) {
|
||||
thrCls, ok := j.clsMap["java.lang.Throwable"]
|
||||
if !ok {
|
||||
// If Throwable isn't in the class map
|
||||
// no imported class inherits from Throwable
|
||||
return
|
||||
}
|
||||
for _, cls := range j.clsMap {
|
||||
for _, cls := range classes {
|
||||
j.fillThrowableFor(cls, thrCls)
|
||||
}
|
||||
}
|
||||
@ -769,10 +815,7 @@ func (j *Importer) fillAllMethods(cls *Class) {
|
||||
for _, f := range super.AllMethods {
|
||||
if _, exists := methods[f.FuncSig]; !exists {
|
||||
methods[f.FuncSig] = struct{}{}
|
||||
// Copy function so each class can have its own
|
||||
// JNI name mangling.
|
||||
cpf := *f
|
||||
cls.AllMethods = append(cls.AllMethods, &cpf)
|
||||
cls.AllMethods = append(cls.AllMethods, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -788,8 +831,11 @@ func (j *Importer) fillAllMethods(cls *Class) {
|
||||
// the method signature is appended in JNI mangled form.
|
||||
func (j *Importer) mangleOverloads(allFuncs []*Func) {
|
||||
overloads := make(map[string][]*Func)
|
||||
for _, f := range allFuncs {
|
||||
overloads[f.Name] = append(overloads[f.Name], f)
|
||||
for i, f := range allFuncs {
|
||||
// Name mangling is per class so copy the function first.
|
||||
f := *f
|
||||
allFuncs[i] = &f
|
||||
overloads[f.Name] = append(overloads[f.Name], &f)
|
||||
}
|
||||
for _, funcs := range overloads {
|
||||
for _, f := range funcs {
|
||||
|
Loading…
x
Reference in New Issue
Block a user