bind: support underscores in identifiers
Fixes golang/go#18536
Change-Id: I82c5993547e4d1d0df14726ccc569e1f57128072
Reviewed-on: https://go-review.googlesource.com/101156
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/bind/bind_test.go b/bind/bind_test.go
index 0635bca..02bfe6d 100644
--- a/bind/bind_test.go
+++ b/bind/bind_test.go
@@ -44,6 +44,7 @@
"testdata/vars.go",
"testdata/ignore.go",
"testdata/doc.go",
+ "testdata/underscores.go",
}
var javaTests = []string{
diff --git a/bind/genjava.go b/bind/genjava.go
index 8991466..970dc81 100644
--- a/bind/genjava.go
+++ b/bind/genjava.go
@@ -749,10 +749,7 @@
g.Printf(jm.JNIName)
} else {
oName := javaNameReplacer(lowerFirst(o.Name()))
- if strings.HasSuffix(oName, "_") {
- oName += "1" // JNI doesn't like methods ending with underscore, needs the _1 suffixing
- }
- g.Printf(oName)
+ g.Printf(java.JNIMangle(oName))
}
g.Printf("(JNIEnv* env, ")
if sName != "" {
@@ -777,7 +774,7 @@
}
func (g *JavaGen) jniPkgName() string {
- return strings.Replace(g.javaPkgName(g.Pkg), ".", "_", -1)
+ return strings.Replace(java.JNIMangle(g.javaPkgName(g.Pkg)), ".", "_", -1)
}
var javaLetterDigitRE = regexp.MustCompile(`[0-9a-zA-Z$_]`)
@@ -1064,7 +1061,7 @@
n := java.JNIMangle(g.javaTypeName(o.Name()))
// setter
g.Printf("JNIEXPORT void JNICALL\n")
- g.Printf("Java_%s_%s_set%s(JNIEnv *env, jobject this, %s v) {\n", g.jniPkgName(), n, f.Name(), g.jniType(f.Type()))
+ g.Printf("Java_%s_%s_set%s(JNIEnv *env, jobject this, %s v) {\n", g.jniPkgName(), n, java.JNIMangle(f.Name()), g.jniType(f.Type()))
g.Indent()
g.Printf("int32_t o = go_seq_to_refnum_go(env, this);\n")
g.genJavaToC("v", f.Type(), modeRetained)
@@ -1075,7 +1072,7 @@
// getter
g.Printf("JNIEXPORT %s JNICALL\n", g.jniType(f.Type()))
- g.Printf("Java_%s_%s_get%s(JNIEnv *env, jobject this) {\n", g.jniPkgName(), n, f.Name())
+ g.Printf("Java_%s_%s_get%s(JNIEnv *env, jobject this) {\n", g.jniPkgName(), n, java.JNIMangle(f.Name()))
g.Indent()
g.Printf("int32_t o = go_seq_to_refnum_go(env, this);\n")
g.Printf("%s r0 = ", g.cgoType(f.Type()))
@@ -1471,7 +1468,7 @@
}
g.Printf("\n")
g.Printf("JNIEXPORT void JNICALL\n")
- g.Printf("Java_%s_%s__1init(JNIEnv *env, jclass _unused) {\n", g.jniPkgName(), g.className())
+ g.Printf("Java_%s_%s__1init(JNIEnv *env, jclass _unused) {\n", g.jniPkgName(), java.JNIMangle(g.className()))
g.Indent()
g.Printf("jclass clazz;\n")
for _, s := range g.structs {
diff --git a/bind/testdata/try.java.c.golden b/bind/testdata/try.java.c.golden
index 232822f..54023f5 100644
--- a/bind/testdata/try.java.c.golden
+++ b/bind/testdata/try.java.c.golden
@@ -11,12 +11,12 @@
JNIEXPORT void JNICALL
-Java_try__Try__1init(JNIEnv *env, jclass _unused) {
+Java_try_1_Try__1init(JNIEnv *env, jclass _unused) {
jclass clazz;
}
JNIEXPORT jstring JNICALL
-Java_try__Try_this_1(JNIEnv* env, jclass _clazz) {
+Java_try_1_Try_this_1(JNIEnv* env, jclass _clazz) {
nstring r0 = proxytry__This();
jstring _r0 = go_seq_to_java_string(env, r0);
return _r0;
diff --git a/bind/testdata/underscores.go b/bind/testdata/underscores.go
new file mode 100644
index 0000000..e13f25d
--- /dev/null
+++ b/bind/testdata/underscores.go
@@ -0,0 +1,13 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package underscore_pkg
+
+type Underscore_struct struct {
+ Underscore_field string
+}
+
+var Underscore_var int
+
+func Underscore_func() {}
diff --git a/bind/testdata/underscores.go.golden b/bind/testdata/underscores.go.golden
new file mode 100644
index 0000000..5fcf4be
--- /dev/null
+++ b/bind/testdata/underscores.go.golden
@@ -0,0 +1,60 @@
+// Package main is an autogenerated binder stub for package underscore_pkg.
+// gobind -lang=go underscores
+//
+// File is generated by gobind. Do not edit.
+package main
+
+/*
+#include <stdlib.h>
+#include <stdint.h>
+#include "seq.h"
+#include "underscore_pkg.h"
+
+*/
+import "C"
+
+import (
+ _seq "golang.org/x/mobile/bind/seq"
+ "underscores"
+)
+
+// suppress the error if seq ends up unused
+var _ = _seq.FromRefNum
+
+//export proxyunderscore_pkg_Underscore_struct_Underscore_field_Set
+func proxyunderscore_pkg_Underscore_struct_Underscore_field_Set(refnum C.int32_t, v C.nstring) {
+ ref := _seq.FromRefNum(int32(refnum))
+ _v := decodeString(v)
+ ref.Get().(*underscore_pkg.Underscore_struct).Underscore_field = _v
+}
+
+//export proxyunderscore_pkg_Underscore_struct_Underscore_field_Get
+func proxyunderscore_pkg_Underscore_struct_Underscore_field_Get(refnum C.int32_t) C.nstring {
+ ref := _seq.FromRefNum(int32(refnum))
+ v := ref.Get().(*underscore_pkg.Underscore_struct).Underscore_field
+ _v := encodeString(v)
+ return _v
+}
+
+//export new_underscore_pkg_Underscore_struct
+func new_underscore_pkg_Underscore_struct() C.int32_t {
+ return C.int32_t(_seq.ToRefNum(new(underscore_pkg.Underscore_struct)))
+}
+
+//export var_setunderscore_pkg_Underscore_var
+func var_setunderscore_pkg_Underscore_var(v C.nint) {
+ _v := int(v)
+ underscore_pkg.Underscore_var = _v
+}
+
+//export var_getunderscore_pkg_Underscore_var
+func var_getunderscore_pkg_Underscore_var() C.nint {
+ v := underscore_pkg.Underscore_var
+ _v := C.nint(v)
+ return _v
+}
+
+//export proxyunderscore_pkg__Underscore_func
+func proxyunderscore_pkg__Underscore_func() {
+ underscore_pkg.Underscore_func()
+}
diff --git a/bind/testdata/underscores.java.c.golden b/bind/testdata/underscores.java.c.golden
new file mode 100644
index 0000000..a9d18f7
--- /dev/null
+++ b/bind/testdata/underscores.java.c.golden
@@ -0,0 +1,61 @@
+// JNI functions for the Go <=> Java bridge.
+// gobind -lang=java underscores
+//
+// File is generated by gobind. Do not edit.
+
+#include <android/log.h>
+#include <stdint.h>
+#include "seq.h"
+#include "_cgo_export.h"
+#include "underscore_pkg.h"
+
+jclass proxy_class_underscore_pkg_Underscore_struct;
+jmethodID proxy_class_underscore_pkg_Underscore_struct_cons;
+
+JNIEXPORT void JNICALL
+Java_underscore_1pkg_Underscore_1pkg__1init(JNIEnv *env, jclass _unused) {
+ jclass clazz;
+ clazz = (*env)->FindClass(env, "underscore_pkg/Underscore_struct");
+ proxy_class_underscore_pkg_Underscore_struct = (*env)->NewGlobalRef(env, clazz);
+ proxy_class_underscore_pkg_Underscore_struct_cons = (*env)->GetMethodID(env, clazz, "<init>", "(Lgo/Seq$Ref;)V");
+}
+
+JNIEXPORT void JNICALL
+Java_underscore_1pkg_Underscore_pkg_underscore_1func(JNIEnv* env, jclass _clazz) {
+ proxyunderscore_pkg__Underscore_func();
+}
+
+JNIEXPORT jobject JNICALL
+Java_underscore_1pkg_Underscore_1struct__1_1New(JNIEnv *env, jclass clazz) {
+ int32_t refnum = new_underscore_pkg_Underscore_struct();
+ return go_seq_from_refnum(env, refnum, NULL, NULL);
+}
+
+JNIEXPORT void JNICALL
+Java_underscore_1pkg_Underscore_1struct_setUnderscore_1field(JNIEnv *env, jobject this, jstring v) {
+ int32_t o = go_seq_to_refnum_go(env, this);
+ nstring _v = go_seq_from_java_string(env, v);
+ proxyunderscore_pkg_Underscore_struct_Underscore_field_Set(o, _v);
+}
+
+JNIEXPORT jstring JNICALL
+Java_underscore_1pkg_Underscore_1struct_getUnderscore_1field(JNIEnv *env, jobject this) {
+ int32_t o = go_seq_to_refnum_go(env, this);
+ nstring r0 = proxyunderscore_pkg_Underscore_struct_Underscore_field_Get(o);
+ jstring _r0 = go_seq_to_java_string(env, r0);
+ return _r0;
+}
+
+JNIEXPORT void JNICALL
+Java_underscore_1pkg_Underscore_pkg_setUnderscore_1var(JNIEnv *env, jclass clazz, jlong v) {
+ nint _v = (nint)v;
+ var_setunderscore_pkg_Underscore_var(_v);
+}
+
+JNIEXPORT jlong JNICALL
+Java_underscore_1pkg_Underscore_pkg_getUnderscore_1var(JNIEnv *env, jclass clazz) {
+ nint r0 = var_getunderscore_pkg_Underscore_var();
+ jlong _r0 = (jlong)r0;
+ return _r0;
+}
+
diff --git a/bind/testdata/underscores.java.golden b/bind/testdata/underscores.java.golden
new file mode 100644
index 0000000..fa1f8da
--- /dev/null
+++ b/bind/testdata/underscores.java.golden
@@ -0,0 +1,85 @@
+// Java class underscore_pkg.Underscore_struct is a proxy for talking to a Go program.
+// gobind -lang=java underscores
+//
+// File is generated by gobind. Do not edit.
+package underscore_pkg;
+
+import go.Seq;
+
+public final class Underscore_struct implements Seq.Proxy {
+ static { Underscore_pkg.touch(); }
+
+ private final Seq.Ref ref;
+
+ @Override public final int incRefnum() {
+ int refnum = ref.refnum;
+ Seq.incGoRef(refnum);
+ return refnum;
+ }
+
+ Underscore_struct(Seq.Ref ref) { this.ref = ref; }
+
+ public Underscore_struct() { this.ref = __New(); }
+
+ private static native Seq.Ref __New();
+
+ public final native String getUnderscore_field();
+ public final native void setUnderscore_field(String v);
+
+ @Override public boolean equals(Object o) {
+ if (o == null || !(o instanceof Underscore_struct)) {
+ return false;
+ }
+ Underscore_struct that = (Underscore_struct)o;
+ String thisUnderscore_field = getUnderscore_field();
+ String thatUnderscore_field = that.getUnderscore_field();
+ if (thisUnderscore_field == null) {
+ if (thatUnderscore_field != null) {
+ return false;
+ }
+ } else if (!thisUnderscore_field.equals(thatUnderscore_field)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override public int hashCode() {
+ return java.util.Arrays.hashCode(new Object[] {getUnderscore_field()});
+ }
+
+ @Override public String toString() {
+ StringBuilder b = new StringBuilder();
+ b.append("Underscore_struct").append("{");
+ b.append("Underscore_field:").append(getUnderscore_field()).append(",");
+ return b.append("}").toString();
+ }
+}
+
+// Java class underscore_pkg.Underscore_pkg is a proxy for talking to a Go program.
+// gobind -lang=java underscores
+//
+// File is generated by gobind. Do not edit.
+package underscore_pkg;
+
+import go.Seq;
+
+public abstract class Underscore_pkg {
+ static {
+ Seq.touch(); // for loading the native library
+ _init();
+ }
+
+ private Underscore_pkg() {} // uninstantiable
+
+ // touch is called from other bound packages to initialize this package
+ public static void touch() {}
+
+ private static native void _init();
+
+
+
+ public static native void setUnderscore_var(long v);
+ public static native long getUnderscore_var();
+
+ public static native void underscore_func();
+}
diff --git a/bind/testdata/underscores.java.h.golden b/bind/testdata/underscores.java.h.golden
new file mode 100644
index 0000000..6bf8948
--- /dev/null
+++ b/bind/testdata/underscores.java.h.golden
@@ -0,0 +1,13 @@
+// JNI function headers for the Go <=> Java bridge.
+// gobind -lang=java underscores
+//
+// File is generated by gobind. Do not edit.
+
+#ifndef __Underscore_pkg_H__
+#define __Underscore_pkg_H__
+
+#include <jni.h>
+
+extern jclass proxy_class_underscore_pkg_Underscore_struct;
+extern jmethodID proxy_class_underscore_pkg_Underscore_struct_cons;
+#endif
diff --git a/bind/testdata/underscores.objc.go.h.golden b/bind/testdata/underscores.objc.go.h.golden
new file mode 100644
index 0000000..d7c8dfe
--- /dev/null
+++ b/bind/testdata/underscores.objc.go.h.golden
@@ -0,0 +1,11 @@
+// Objective-C API for talking to underscores Go package.
+// gobind -lang=objc underscores
+//
+// File is generated by gobind. Do not edit.
+
+#ifndef __GO_underscore_pkg_H__
+#define __GO_underscore_pkg_H__
+
+#include <stdint.h>
+#include <objc/objc.h>
+#endif
diff --git a/bind/testdata/underscores.objc.h.golden b/bind/testdata/underscores.objc.h.golden
new file mode 100644
index 0000000..783ef1a
--- /dev/null
+++ b/bind/testdata/underscores.objc.h.golden
@@ -0,0 +1,33 @@
+// Objective-C API for talking to underscores Go package.
+// gobind -lang=objc underscores
+//
+// File is generated by gobind. Do not edit.
+
+#ifndef __Underscore_pkg_H__
+#define __Underscore_pkg_H__
+
+@import Foundation;
+#include "Universe.objc.h"
+
+
+@class Underscore_pkgUnderscore_struct;
+
+@interface Underscore_pkgUnderscore_struct : NSObject <goSeqRefInterface> {
+}
+@property(strong, readonly) id _ref;
+
+- (instancetype)initWithRef:(id)ref;
+- (instancetype)init;
+- (NSString*)underscore_field;
+- (void)setUnderscore_field:(NSString*)v;
+@end
+
+@interface Underscore_pkg : NSObject
++ (long) underscore_var;
++ (void) setUnderscore_var:(long)v;
+
+@end
+
+FOUNDATION_EXPORT void Underscore_pkgUnderscore_func(void);
+
+#endif
diff --git a/bind/testdata/underscores.objc.m.golden b/bind/testdata/underscores.objc.m.golden
new file mode 100644
index 0000000..4cac5a5
--- /dev/null
+++ b/bind/testdata/underscores.objc.m.golden
@@ -0,0 +1,66 @@
+// Objective-C API for talking to underscores Go package.
+// gobind -lang=objc underscores
+//
+// File is generated by gobind. Do not edit.
+
+#include <Foundation/Foundation.h>
+#include "seq.h"
+#include "_cgo_export.h"
+#include "Underscore_pkg.objc.h"
+
+
+@implementation Underscore_pkgUnderscore_struct {
+}
+
+- (instancetype)initWithRef:(id)ref {
+ self = [super init];
+ if (self) { __ref = ref; }
+ return self;
+}
+
+- (instancetype)init {
+ self = [super init];
+ if (self) {
+ __ref = go_seq_from_refnum(new_underscore_pkg_Underscore_struct());
+ }
+ return self;
+}
+
+- (NSString*)underscore_field {
+ int32_t refnum = go_seq_go_to_refnum(self._ref);
+ nstring r0 = proxyunderscore_pkg_Underscore_struct_Underscore_field_Get(refnum);
+ NSString *_r0 = go_seq_to_objc_string(r0);
+ return _r0;
+}
+
+- (void)setUnderscore_field:(NSString*)v {
+ int32_t refnum = go_seq_go_to_refnum(self._ref);
+ nstring _v = go_seq_from_objc_string(v);
+ proxyunderscore_pkg_Underscore_struct_Underscore_field_Set(refnum, _v);
+}
+
+@end
+
+
+@implementation Underscore_pkg
++ (void) setUnderscore_var:(long)v {
+ nint _v = (nint)v;
+ var_setunderscore_pkg_Underscore_var(_v);
+}
+
++ (long) underscore_var {
+ nint r0 = var_getunderscore_pkg_Underscore_var();
+ long _r0 = (long)r0;
+ return _r0;
+}
+
+@end
+
+
+void Underscore_pkgUnderscore_func(void) {
+ proxyunderscore_pkg__Underscore_func();
+}
+
+__attribute__((constructor)) static void init() {
+ init_seq();
+}