genjava.go 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732
  1. // Copyright 2014 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package bind
  5. import (
  6. "fmt"
  7. "go/constant"
  8. "go/types"
  9. "html"
  10. "math"
  11. "reflect"
  12. "regexp"
  13. "strings"
  14. "golang.org/x/mobile/internal/importers/java"
  15. )
  16. // TODO(crawshaw): disallow basic android java type names in exported symbols.
  17. // TODO(crawshaw): consider introducing Java functions for casting to and from interfaces at runtime.
  18. type JavaGen struct {
  19. // JavaPkg is the Java package prefix for the generated classes. The prefix is prepended to the Go
  20. // package name to create the full Java package name.
  21. JavaPkg string
  22. *Generator
  23. jstructs map[*types.TypeName]*javaClassInfo
  24. clsMap map[string]*java.Class
  25. // Constructors is a map from Go struct types to a list
  26. // of exported constructor functions for the type, on the form
  27. // func New<Type>(...) *Type
  28. constructors map[*types.TypeName][]*types.Func
  29. }
  30. type javaClassInfo struct {
  31. // The Java class this class extends.
  32. extends *java.Class
  33. // All Java classes and interfaces this class extends and implements.
  34. supers []*java.Class
  35. methods map[string]*java.FuncSet
  36. // Does the class need a default no-arg constructor
  37. genNoargCon bool
  38. }
  39. // Init intializes the embedded Generator and initializes the Java class information
  40. // needed to generate structs that extend Java classes and interfaces.
  41. func (g *JavaGen) Init(classes []*java.Class) {
  42. g.Generator.Init()
  43. g.clsMap = make(map[string]*java.Class)
  44. for _, cls := range classes {
  45. g.clsMap[cls.Name] = cls
  46. }
  47. g.jstructs = make(map[*types.TypeName]*javaClassInfo)
  48. g.constructors = make(map[*types.TypeName][]*types.Func)
  49. for _, s := range g.structs {
  50. classes := embeddedJavaClasses(s.t)
  51. if len(classes) == 0 {
  52. continue
  53. }
  54. inf := &javaClassInfo{
  55. methods: make(map[string]*java.FuncSet),
  56. genNoargCon: true, // java.lang.Object has a no-arg constructor
  57. }
  58. for _, n := range classes {
  59. cls := g.clsMap[n]
  60. for _, fs := range cls.AllMethods {
  61. hasMeth := false
  62. for _, f := range fs.Funcs {
  63. if !f.Final {
  64. hasMeth = true
  65. }
  66. }
  67. if hasMeth {
  68. inf.methods[fs.GoName] = fs
  69. }
  70. }
  71. inf.supers = append(inf.supers, cls)
  72. if !cls.Interface {
  73. if inf.extends != nil {
  74. g.errorf("%s embeds more than one Java class; only one is allowed.", s.obj)
  75. }
  76. if cls.Final {
  77. g.errorf("%s embeds final Java class %s", s.obj, cls.Name)
  78. }
  79. inf.extends = cls
  80. inf.genNoargCon = cls.HasNoArgCon
  81. }
  82. }
  83. g.jstructs[s.obj] = inf
  84. }
  85. for _, f := range g.funcs {
  86. if t := g.constructorType(f); t != nil {
  87. jinf := g.jstructs[t]
  88. if jinf != nil {
  89. sig := f.Type().(*types.Signature)
  90. jinf.genNoargCon = jinf.genNoargCon && sig.Params().Len() > 0
  91. }
  92. g.constructors[t] = append(g.constructors[t], f)
  93. }
  94. }
  95. }
  96. func (j *javaClassInfo) toJavaType(T types.Type) *java.Type {
  97. switch T := T.(type) {
  98. case *types.Basic:
  99. var kind java.TypeKind
  100. switch T.Kind() {
  101. case types.Bool, types.UntypedBool:
  102. kind = java.Boolean
  103. case types.Uint8:
  104. kind = java.Byte
  105. case types.Int16:
  106. kind = java.Short
  107. case types.Int32, types.UntypedRune: // types.Rune
  108. kind = java.Int
  109. case types.Int64, types.UntypedInt:
  110. kind = java.Long
  111. case types.Float32:
  112. kind = java.Float
  113. case types.Float64, types.UntypedFloat:
  114. kind = java.Double
  115. case types.String, types.UntypedString:
  116. kind = java.String
  117. default:
  118. return nil
  119. }
  120. return &java.Type{Kind: kind}
  121. case *types.Slice:
  122. switch e := T.Elem().(type) {
  123. case *types.Basic:
  124. switch e.Kind() {
  125. case types.Uint8: // Byte.
  126. return &java.Type{Kind: java.Array, Elem: &java.Type{Kind: java.Byte}}
  127. }
  128. }
  129. return nil
  130. case *types.Named:
  131. if isJavaType(T) {
  132. return &java.Type{Kind: java.Object, Class: classNameFor(T)}
  133. }
  134. }
  135. return nil
  136. }
  137. // lookupMethod searches the Java class descriptor for a method
  138. // that matches the Go method.
  139. func (j *javaClassInfo) lookupMethod(m *types.Func, hasThis bool) *java.Func {
  140. jm := j.methods[m.Name()]
  141. if jm == nil {
  142. // If an exact match is not found, try the method with trailing underscores
  143. // stripped. This way, name clashes can be avoided when overriding multiple
  144. // overloaded methods from Go.
  145. base := strings.TrimRight(m.Name(), "_")
  146. jm = j.methods[base]
  147. if jm == nil {
  148. return nil
  149. }
  150. }
  151. // A name match was found. Now use the parameter and return types to locate
  152. // the correct variant.
  153. sig := m.Type().(*types.Signature)
  154. params := sig.Params()
  155. // Convert Go parameter types to their Java counterparts, if possible.
  156. var jparams []*java.Type
  157. i := 0
  158. if hasThis {
  159. i = 1
  160. }
  161. for ; i < params.Len(); i++ {
  162. jparams = append(jparams, j.toJavaType(params.At(i).Type()))
  163. }
  164. var ret *java.Type
  165. var throws bool
  166. if results := sig.Results(); results.Len() > 0 {
  167. ret = j.toJavaType(results.At(0).Type())
  168. if results.Len() > 1 {
  169. throws = isErrorType(results.At(1).Type())
  170. }
  171. }
  172. loop:
  173. for _, f := range jm.Funcs {
  174. if len(f.Params) != len(jparams) {
  175. continue
  176. }
  177. if throws != (f.Throws != "") {
  178. continue
  179. }
  180. if !reflect.DeepEqual(ret, f.Ret) {
  181. continue
  182. }
  183. for i, p := range f.Params {
  184. if !reflect.DeepEqual(p, jparams[i]) {
  185. continue loop
  186. }
  187. }
  188. return f
  189. }
  190. return nil
  191. }
  192. // ClassNames returns the list of names of the generated Java classes and interfaces.
  193. func (g *JavaGen) ClassNames() []string {
  194. var names []string
  195. for _, s := range g.structs {
  196. names = append(names, g.javaTypeName(s.obj.Name()))
  197. }
  198. for _, iface := range g.interfaces {
  199. names = append(names, g.javaTypeName(iface.obj.Name()))
  200. }
  201. return names
  202. }
  203. func (g *JavaGen) GenClass(idx int) error {
  204. ns := len(g.structs)
  205. if idx < ns {
  206. s := g.structs[idx]
  207. g.genStruct(s)
  208. } else {
  209. iface := g.interfaces[idx-ns]
  210. g.genInterface(iface)
  211. }
  212. if len(g.err) > 0 {
  213. return g.err
  214. }
  215. return nil
  216. }
  217. func (g *JavaGen) genProxyImpl(name string) {
  218. g.Printf("private final int refnum;\n\n")
  219. g.Printf("@Override public final int incRefnum() {\n")
  220. g.Printf(" Seq.incGoRef(refnum, this);\n")
  221. g.Printf(" return refnum;\n")
  222. g.Printf("}\n\n")
  223. }
  224. func (g *JavaGen) genStruct(s structInfo) {
  225. pkgPath := ""
  226. if g.Pkg != nil {
  227. pkgPath = g.Pkg.Path()
  228. }
  229. n := g.javaTypeName(s.obj.Name())
  230. g.Printf(javaPreamble, g.javaPkgName(g.Pkg), n, g.gobindOpts(), pkgPath)
  231. fields := exportedFields(s.t)
  232. methods := exportedMethodSet(types.NewPointer(s.obj.Type()))
  233. var impls []string
  234. jinf := g.jstructs[s.obj]
  235. if jinf != nil {
  236. impls = append(impls, "Seq.GoObject")
  237. for _, cls := range jinf.supers {
  238. if cls.Interface {
  239. impls = append(impls, g.javaTypeName(cls.Name))
  240. }
  241. }
  242. } else {
  243. impls = append(impls, "Seq.Proxy")
  244. }
  245. pT := types.NewPointer(s.obj.Type())
  246. for _, iface := range g.allIntf {
  247. if types.AssignableTo(pT, iface.obj.Type()) {
  248. n := iface.obj.Name()
  249. if p := iface.obj.Pkg(); p != g.Pkg {
  250. if n == JavaClassName(p) {
  251. n = n + "_"
  252. }
  253. n = fmt.Sprintf("%s.%s", g.javaPkgName(p), n)
  254. } else {
  255. n = g.javaTypeName(n)
  256. }
  257. impls = append(impls, n)
  258. }
  259. }
  260. doc := g.docs[n]
  261. g.javadoc(doc.Doc())
  262. g.Printf("public final class %s", n)
  263. if jinf != nil {
  264. if jinf.extends != nil {
  265. g.Printf(" extends %s", g.javaTypeName(jinf.extends.Name))
  266. }
  267. }
  268. if len(impls) > 0 {
  269. g.Printf(" implements %s", strings.Join(impls, ", "))
  270. }
  271. g.Printf(" {\n")
  272. g.Indent()
  273. g.Printf("static { %s.touch(); }\n\n", g.className())
  274. g.genProxyImpl(n)
  275. cons := g.constructors[s.obj]
  276. for _, f := range cons {
  277. if !g.isConsSigSupported(f.Type()) {
  278. g.Printf("// skipped constructor %s.%s with unsupported parameter or return types\n\n", n, f.Name())
  279. continue
  280. }
  281. g.genConstructor(f, n, jinf != nil)
  282. }
  283. if jinf == nil || jinf.genNoargCon {
  284. // constructor for Go instantiated instances.
  285. g.Printf("%s(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }\n\n", n)
  286. if len(cons) == 0 {
  287. // Generate default no-arg constructor
  288. g.Printf("public %s() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }\n\n", n)
  289. g.Printf("private static native int __New();\n\n")
  290. }
  291. }
  292. for _, f := range fields {
  293. if t := f.Type(); !g.isSupported(t) {
  294. g.Printf("// skipped field %s.%s with unsupported type: %s\n\n", n, f.Name(), t)
  295. continue
  296. }
  297. fdoc := doc.Member(f.Name())
  298. g.javadoc(fdoc)
  299. g.Printf("public final native %s get%s();\n", g.javaType(f.Type()), f.Name())
  300. g.javadoc(fdoc)
  301. g.Printf("public final native void set%s(%s v);\n\n", f.Name(), g.javaType(f.Type()))
  302. }
  303. var isStringer bool
  304. for _, m := range methods {
  305. if !g.isSigSupported(m.Type()) {
  306. g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", n, m.Name())
  307. continue
  308. }
  309. g.javadoc(doc.Member(m.Name()))
  310. var jm *java.Func
  311. hasThis := false
  312. if jinf != nil {
  313. hasThis = g.hasThis(n, m)
  314. jm = jinf.lookupMethod(m, hasThis)
  315. if jm != nil {
  316. g.Printf("@Override ")
  317. }
  318. }
  319. g.Printf("public native ")
  320. g.genFuncSignature(m, jm, hasThis)
  321. t := m.Type().(*types.Signature)
  322. isStringer = isStringer || (m.Name() == "String" && t.Params().Len() == 0 && t.Results().Len() == 1 &&
  323. types.Identical(t.Results().At(0).Type(), types.Typ[types.String]))
  324. }
  325. if jinf == nil {
  326. g.genObjectMethods(n, fields, isStringer)
  327. }
  328. g.Outdent()
  329. g.Printf("}\n\n")
  330. }
  331. // isConsSigSupported reports whether the generators can handle a given
  332. // constructor signature.
  333. func (g *JavaGen) isConsSigSupported(t types.Type) bool {
  334. if !g.isSigSupported(t) {
  335. return false
  336. }
  337. // Skip constructors taking a single int32 argument
  338. // since they clash with the proxy constructors that
  339. // take a refnum.
  340. params := t.(*types.Signature).Params()
  341. if params.Len() != 1 {
  342. return true
  343. }
  344. if t, ok := params.At(0).Type().(*types.Basic); ok {
  345. switch t.Kind() {
  346. case types.Int32, types.Uint32:
  347. return false
  348. }
  349. }
  350. return true
  351. }
  352. // javaTypeName returns the class name of a given Go type name. If
  353. // the type name clashes with the package class name, an underscore is
  354. // appended.
  355. func (g *JavaGen) javaTypeName(n string) string {
  356. if n == JavaClassName(g.Pkg) {
  357. return n + "_"
  358. }
  359. return n
  360. }
  361. func (g *JavaGen) javadoc(doc string) {
  362. if doc == "" {
  363. return
  364. }
  365. // JavaDoc expects HTML-escaped documentation.
  366. g.Printf("/**\n * %s */\n", html.EscapeString(doc))
  367. }
  368. // hasThis reports whether a method has an implicit "this" parameter.
  369. func (g *JavaGen) hasThis(sName string, m *types.Func) bool {
  370. sig := m.Type().(*types.Signature)
  371. params := sig.Params()
  372. if params.Len() == 0 {
  373. return false
  374. }
  375. v := params.At(0)
  376. if v.Name() != "this" {
  377. return false
  378. }
  379. t, ok := v.Type().(*types.Named)
  380. if !ok {
  381. return false
  382. }
  383. obj := t.Obj()
  384. pkg := obj.Pkg()
  385. if pkgFirstElem(pkg) != "Java" {
  386. return false
  387. }
  388. clsName := classNameFor(t)
  389. exp := g.javaPkgName(g.Pkg) + "." + sName
  390. if clsName != exp {
  391. g.errorf("the type %s of the `this` argument to method %s.%s is not %s", clsName, sName, m.Name(), exp)
  392. return false
  393. }
  394. return true
  395. }
  396. func (g *JavaGen) genConstructor(f *types.Func, n string, jcls bool) {
  397. g.javadoc(g.docs[f.Name()].Doc())
  398. g.Printf("public %s(", n)
  399. g.genFuncArgs(f, nil, false)
  400. g.Printf(") {\n")
  401. g.Indent()
  402. sig := f.Type().(*types.Signature)
  403. params := sig.Params()
  404. if jcls {
  405. g.Printf("super(")
  406. for i := 0; i < params.Len(); i++ {
  407. if i > 0 {
  408. g.Printf(", ")
  409. }
  410. g.Printf(g.paramName(params, i))
  411. }
  412. g.Printf(");\n")
  413. }
  414. g.Printf("this.refnum = ")
  415. g.Printf("__%s(", f.Name())
  416. for i := 0; i < params.Len(); i++ {
  417. if i > 0 {
  418. g.Printf(", ")
  419. }
  420. g.Printf(g.paramName(params, i))
  421. }
  422. g.Printf(");\n")
  423. g.Printf("Seq.trackGoRef(refnum, this);\n")
  424. g.Outdent()
  425. g.Printf("}\n\n")
  426. g.Printf("private static native int __%s(", f.Name())
  427. g.genFuncArgs(f, nil, false)
  428. g.Printf(");\n\n")
  429. }
  430. // genFuncArgs generated Java function arguments declaration for the function f.
  431. // If the supplied overridden java function is supplied, genFuncArgs omits the implicit
  432. // this argument.
  433. func (g *JavaGen) genFuncArgs(f *types.Func, jm *java.Func, hasThis bool) {
  434. sig := f.Type().(*types.Signature)
  435. params := sig.Params()
  436. first := 0
  437. if hasThis {
  438. // Skip the implicit this argument to the Go method
  439. first = 1
  440. }
  441. for i := first; i < params.Len(); i++ {
  442. if i > first {
  443. g.Printf(", ")
  444. }
  445. v := params.At(i)
  446. name := g.paramName(params, i)
  447. jt := g.javaType(v.Type())
  448. g.Printf("%s %s", jt, name)
  449. }
  450. }
  451. func (g *JavaGen) genObjectMethods(n string, fields []*types.Var, isStringer bool) {
  452. g.Printf("@Override public boolean equals(Object o) {\n")
  453. g.Indent()
  454. g.Printf("if (o == null || !(o instanceof %s)) {\n return false;\n}\n", n)
  455. g.Printf("%s that = (%s)o;\n", n, n)
  456. for _, f := range fields {
  457. if t := f.Type(); !g.isSupported(t) {
  458. g.Printf("// skipped field %s.%s with unsupported type: %s\n\n", n, f.Name(), t)
  459. continue
  460. }
  461. nf := f.Name()
  462. g.Printf("%s this%s = get%s();\n", g.javaType(f.Type()), nf, nf)
  463. g.Printf("%s that%s = that.get%s();\n", g.javaType(f.Type()), nf, nf)
  464. if isJavaPrimitive(f.Type()) {
  465. g.Printf("if (this%s != that%s) {\n return false;\n}\n", nf, nf)
  466. } else {
  467. g.Printf("if (this%s == null) {\n", nf)
  468. g.Indent()
  469. g.Printf("if (that%s != null) {\n return false;\n}\n", nf)
  470. g.Outdent()
  471. g.Printf("} else if (!this%s.equals(that%s)) {\n return false;\n}\n", nf, nf)
  472. }
  473. }
  474. g.Printf("return true;\n")
  475. g.Outdent()
  476. g.Printf("}\n\n")
  477. g.Printf("@Override public int hashCode() {\n")
  478. g.Printf(" return java.util.Arrays.hashCode(new Object[] {")
  479. idx := 0
  480. for _, f := range fields {
  481. if t := f.Type(); !g.isSupported(t) {
  482. continue
  483. }
  484. if idx > 0 {
  485. g.Printf(", ")
  486. }
  487. idx++
  488. g.Printf("get%s()", f.Name())
  489. }
  490. g.Printf("});\n")
  491. g.Printf("}\n\n")
  492. g.Printf("@Override public String toString() {\n")
  493. g.Indent()
  494. if isStringer {
  495. g.Printf("return string();\n")
  496. } else {
  497. g.Printf("StringBuilder b = new StringBuilder();\n")
  498. g.Printf(`b.append("%s").append("{");`, n)
  499. g.Printf("\n")
  500. for _, f := range fields {
  501. if t := f.Type(); !g.isSupported(t) {
  502. continue
  503. }
  504. n := f.Name()
  505. g.Printf(`b.append("%s:").append(get%s()).append(",");`, n, n)
  506. g.Printf("\n")
  507. }
  508. g.Printf(`return b.append("}").toString();`)
  509. g.Printf("\n")
  510. }
  511. g.Outdent()
  512. g.Printf("}\n")
  513. }
  514. func (g *JavaGen) genInterface(iface interfaceInfo) {
  515. pkgPath := ""
  516. if g.Pkg != nil {
  517. pkgPath = g.Pkg.Path()
  518. }
  519. g.Printf(javaPreamble, g.javaPkgName(g.Pkg), g.javaTypeName(iface.obj.Name()), g.gobindOpts(), pkgPath)
  520. var exts []string
  521. numM := iface.t.NumMethods()
  522. for _, other := range g.allIntf {
  523. // Only extend interfaces with fewer methods to avoid circular references
  524. if other.t.NumMethods() < numM && types.AssignableTo(iface.t, other.t) {
  525. n := other.obj.Name()
  526. if p := other.obj.Pkg(); p != g.Pkg {
  527. if n == JavaClassName(p) {
  528. n = n + "_"
  529. }
  530. n = fmt.Sprintf("%s.%s", g.javaPkgName(p), n)
  531. } else {
  532. n = g.javaTypeName(n)
  533. }
  534. exts = append(exts, n)
  535. }
  536. }
  537. doc := g.docs[iface.obj.Name()]
  538. g.javadoc(doc.Doc())
  539. g.Printf("public interface %s", g.javaTypeName(iface.obj.Name()))
  540. if len(exts) > 0 {
  541. g.Printf(" extends %s", strings.Join(exts, ", "))
  542. }
  543. g.Printf(" {\n")
  544. g.Indent()
  545. for _, m := range iface.summary.callable {
  546. if !g.isSigSupported(m.Type()) {
  547. g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", iface.obj.Name(), m.Name())
  548. continue
  549. }
  550. g.javadoc(doc.Member(m.Name()))
  551. g.Printf("public ")
  552. g.genFuncSignature(m, nil, false)
  553. }
  554. g.Printf("\n")
  555. g.Outdent()
  556. g.Printf("}\n\n")
  557. }
  558. func isJavaPrimitive(T types.Type) bool {
  559. b, ok := T.(*types.Basic)
  560. if !ok {
  561. return false
  562. }
  563. switch b.Kind() {
  564. case types.Bool, types.Uint8, types.Float32, types.Float64,
  565. types.Int, types.Int8, types.Int16, types.Int32, types.Int64:
  566. return true
  567. }
  568. return false
  569. }
  570. // jniType returns a string that can be used as a JNI type.
  571. func (g *JavaGen) jniType(T types.Type) string {
  572. switch T := T.(type) {
  573. case *types.Basic:
  574. switch T.Kind() {
  575. case types.Bool, types.UntypedBool:
  576. return "jboolean"
  577. case types.Int:
  578. return "jlong"
  579. case types.Int8:
  580. return "jbyte"
  581. case types.Int16:
  582. return "jshort"
  583. case types.Int32, types.UntypedRune: // types.Rune
  584. return "jint"
  585. case types.Int64, types.UntypedInt:
  586. return "jlong"
  587. case types.Uint8: // types.Byte
  588. // TODO(crawshaw): Java bytes are signed, so this is
  589. // questionable, but vital.
  590. return "jbyte"
  591. // TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64:
  592. case types.Float32:
  593. return "jfloat"
  594. case types.Float64, types.UntypedFloat:
  595. return "jdouble"
  596. case types.String, types.UntypedString:
  597. return "jstring"
  598. default:
  599. g.errorf("unsupported basic type: %s", T)
  600. return "TODO"
  601. }
  602. case *types.Slice:
  603. return "jbyteArray"
  604. case *types.Pointer:
  605. if _, ok := T.Elem().(*types.Named); ok {
  606. return g.jniType(T.Elem())
  607. }
  608. g.errorf("unsupported pointer to type: %s", T)
  609. case *types.Named:
  610. return "jobject"
  611. default:
  612. g.errorf("unsupported jniType: %#+v, %s\n", T, T)
  613. }
  614. return "TODO"
  615. }
  616. func (g *JavaGen) javaBasicType(T *types.Basic) string {
  617. switch T.Kind() {
  618. case types.Bool, types.UntypedBool:
  619. return "boolean"
  620. case types.Int:
  621. return "long"
  622. case types.Int8:
  623. return "byte"
  624. case types.Int16:
  625. return "short"
  626. case types.Int32, types.UntypedRune: // types.Rune
  627. return "int"
  628. case types.Int64, types.UntypedInt:
  629. return "long"
  630. case types.Uint8: // types.Byte
  631. // TODO(crawshaw): Java bytes are signed, so this is
  632. // questionable, but vital.
  633. return "byte"
  634. // TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64:
  635. case types.Float32:
  636. return "float"
  637. case types.Float64, types.UntypedFloat:
  638. return "double"
  639. case types.String, types.UntypedString:
  640. return "String"
  641. default:
  642. g.errorf("unsupported basic type: %s", T)
  643. return "TODO"
  644. }
  645. }
  646. // javaType returns a string that can be used as a Java type.
  647. func (g *JavaGen) javaType(T types.Type) string {
  648. if isErrorType(T) {
  649. // The error type is usually translated into an exception in
  650. // Java, however the type can be exposed in other ways, such
  651. // as an exported field.
  652. return "java.lang.Exception"
  653. } else if isJavaType(T) {
  654. return classNameFor(T)
  655. }
  656. switch T := T.(type) {
  657. case *types.Basic:
  658. return g.javaBasicType(T)
  659. case *types.Slice:
  660. elem := g.javaType(T.Elem())
  661. return elem + "[]"
  662. case *types.Pointer:
  663. if _, ok := T.Elem().(*types.Named); ok {
  664. return g.javaType(T.Elem())
  665. }
  666. g.errorf("unsupported pointer to type: %s", T)
  667. case *types.Named:
  668. n := T.Obj()
  669. nPkg := n.Pkg()
  670. if !isErrorType(T) && !g.validPkg(nPkg) {
  671. g.errorf("type %s is in %s, which is not bound", n.Name(), nPkg)
  672. break
  673. }
  674. // TODO(crawshaw): more checking here
  675. clsName := n.Name()
  676. if nPkg != g.Pkg {
  677. if clsName == JavaClassName(nPkg) {
  678. clsName += "_"
  679. }
  680. return fmt.Sprintf("%s.%s", g.javaPkgName(nPkg), clsName)
  681. } else {
  682. return g.javaTypeName(clsName)
  683. }
  684. default:
  685. g.errorf("unsupported javaType: %#+v, %s\n", T, T)
  686. }
  687. return "TODO"
  688. }
  689. func (g *JavaGen) genJNIFuncSignature(o *types.Func, sName string, jm *java.Func, proxy, isjava bool) {
  690. sig := o.Type().(*types.Signature)
  691. res := sig.Results()
  692. var ret string
  693. switch res.Len() {
  694. case 2:
  695. ret = g.jniType(res.At(0).Type())
  696. case 1:
  697. if isErrorType(res.At(0).Type()) {
  698. ret = "void"
  699. } else {
  700. ret = g.jniType(res.At(0).Type())
  701. }
  702. case 0:
  703. ret = "void"
  704. default:
  705. g.errorf("too many result values: %s", o)
  706. return
  707. }
  708. g.Printf("JNIEXPORT %s JNICALL\n", ret)
  709. g.Printf("Java_%s_", g.jniPkgName())
  710. if sName != "" {
  711. if proxy {
  712. g.Printf(java.JNIMangle(g.className()))
  713. // 0024 is the mangled form of $, for naming inner classes.
  714. g.Printf("_00024proxy%s", sName)
  715. } else {
  716. g.Printf(java.JNIMangle(g.javaTypeName(sName)))
  717. }
  718. } else {
  719. g.Printf(java.JNIMangle(g.className()))
  720. }
  721. g.Printf("_")
  722. if jm != nil {
  723. g.Printf(jm.JNIName)
  724. } else {
  725. oName := javaNameReplacer(lowerFirst(o.Name()))
  726. g.Printf(java.JNIMangle(oName))
  727. }
  728. g.Printf("(JNIEnv* env, ")
  729. if sName != "" {
  730. g.Printf("jobject __this__")
  731. } else {
  732. g.Printf("jclass _clazz")
  733. }
  734. params := sig.Params()
  735. i := 0
  736. if isjava && params.Len() > 0 && params.At(0).Name() == "this" {
  737. // Skip the implicit this argument, if any.
  738. i = 1
  739. }
  740. for ; i < params.Len(); i++ {
  741. g.Printf(", ")
  742. v := sig.Params().At(i)
  743. name := g.paramName(params, i)
  744. jt := g.jniType(v.Type())
  745. g.Printf("%s %s", jt, name)
  746. }
  747. g.Printf(")")
  748. }
  749. func (g *JavaGen) jniPkgName() string {
  750. return strings.Replace(java.JNIMangle(g.javaPkgName(g.Pkg)), ".", "_", -1)
  751. }
  752. var javaLetterDigitRE = regexp.MustCompile(`[0-9a-zA-Z$_]`)
  753. func (g *JavaGen) paramName(params *types.Tuple, pos int) string {
  754. name := basicParamName(params, pos)
  755. if !javaLetterDigitRE.MatchString(name) {
  756. name = fmt.Sprintf("p%d", pos)
  757. }
  758. return javaNameReplacer(name)
  759. }
  760. func (g *JavaGen) genFuncSignature(o *types.Func, jm *java.Func, hasThis bool) {
  761. sig := o.Type().(*types.Signature)
  762. res := sig.Results()
  763. var returnsError bool
  764. var ret string
  765. switch res.Len() {
  766. case 2:
  767. if !isErrorType(res.At(1).Type()) {
  768. g.errorf("second result value must be of type error: %s", o)
  769. return
  770. }
  771. returnsError = true
  772. ret = g.javaType(res.At(0).Type())
  773. case 1:
  774. if isErrorType(res.At(0).Type()) {
  775. returnsError = true
  776. ret = "void"
  777. } else {
  778. ret = g.javaType(res.At(0).Type())
  779. }
  780. case 0:
  781. ret = "void"
  782. default:
  783. g.errorf("too many result values: %s", o)
  784. return
  785. }
  786. g.Printf("%s ", ret)
  787. if jm != nil {
  788. g.Printf(jm.Name)
  789. } else {
  790. g.Printf(javaNameReplacer(lowerFirst(o.Name())))
  791. }
  792. g.Printf("(")
  793. g.genFuncArgs(o, jm, hasThis)
  794. g.Printf(")")
  795. if returnsError {
  796. if jm != nil {
  797. if jm.Throws == "" {
  798. g.errorf("%s declares an error return value but the overridden method does not throw", o)
  799. return
  800. }
  801. g.Printf(" throws %s", jm.Throws)
  802. } else {
  803. g.Printf(" throws Exception")
  804. }
  805. }
  806. g.Printf(";\n")
  807. }
  808. func (g *JavaGen) genVar(o *types.Var) {
  809. if t := o.Type(); !g.isSupported(t) {
  810. g.Printf("// skipped variable %s with unsupported type: %s\n\n", o.Name(), t)
  811. return
  812. }
  813. jType := g.javaType(o.Type())
  814. doc := g.docs[o.Name()].Doc()
  815. // setter
  816. g.javadoc(doc)
  817. g.Printf("public static native void set%s(%s v);\n", o.Name(), jType)
  818. // getter
  819. g.javadoc(doc)
  820. g.Printf("public static native %s get%s();\n\n", jType, o.Name())
  821. }
  822. // genCRetClear clears the result value from a JNI call if an exception was
  823. // raised.
  824. func (g *JavaGen) genCRetClear(varName string, t types.Type, exc string) {
  825. g.Printf("if (%s != NULL) {\n", exc)
  826. g.Indent()
  827. switch t := t.(type) {
  828. case *types.Basic:
  829. switch t.Kind() {
  830. case types.String:
  831. g.Printf("%s = NULL;\n", varName)
  832. default:
  833. g.Printf("%s = 0;\n", varName)
  834. }
  835. case *types.Slice, *types.Named, *types.Pointer:
  836. g.Printf("%s = NULL;\n", varName)
  837. }
  838. g.Outdent()
  839. g.Printf("}\n")
  840. }
  841. func (g *JavaGen) genJavaToC(varName string, t types.Type, mode varMode) {
  842. switch t := t.(type) {
  843. case *types.Basic:
  844. switch t.Kind() {
  845. case types.String:
  846. g.Printf("nstring _%s = go_seq_from_java_string(env, %s);\n", varName, varName)
  847. default:
  848. g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName)
  849. }
  850. case *types.Slice:
  851. switch e := t.Elem().(type) {
  852. case *types.Basic:
  853. switch e.Kind() {
  854. case types.Uint8: // Byte.
  855. g.Printf("nbyteslice _%s = go_seq_from_java_bytearray(env, %s, %d);\n", varName, varName, toCFlag(mode == modeRetained))
  856. default:
  857. g.errorf("unsupported type: %s", t)
  858. }
  859. default:
  860. g.errorf("unsupported type: %s", t)
  861. }
  862. case *types.Named:
  863. switch u := t.Underlying().(type) {
  864. case *types.Interface:
  865. g.Printf("int32_t _%s = go_seq_to_refnum(env, %s);\n", varName, varName)
  866. default:
  867. g.errorf("unsupported named type: %s / %T", u, u)
  868. }
  869. case *types.Pointer:
  870. g.Printf("int32_t _%s = go_seq_to_refnum(env, %s);\n", varName, varName)
  871. default:
  872. g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName)
  873. }
  874. }
  875. func (g *JavaGen) genCToJava(toName, fromName string, t types.Type, mode varMode) {
  876. switch t := t.(type) {
  877. case *types.Basic:
  878. switch t.Kind() {
  879. case types.String:
  880. g.Printf("jstring %s = go_seq_to_java_string(env, %s);\n", toName, fromName)
  881. case types.Bool:
  882. g.Printf("jboolean %s = %s ? JNI_TRUE : JNI_FALSE;\n", toName, fromName)
  883. default:
  884. g.Printf("%s %s = (%s)%s;\n", g.jniType(t), toName, g.jniType(t), fromName)
  885. }
  886. case *types.Slice:
  887. switch e := t.Elem().(type) {
  888. case *types.Basic:
  889. switch e.Kind() {
  890. case types.Uint8: // Byte.
  891. g.Printf("jbyteArray %s = go_seq_to_java_bytearray(env, %s, %d);\n", toName, fromName, toCFlag(mode == modeRetained))
  892. default:
  893. g.errorf("unsupported type: %s", t)
  894. }
  895. default:
  896. g.errorf("unsupported type: %s", t)
  897. }
  898. case *types.Pointer:
  899. // TODO(crawshaw): test *int
  900. // TODO(crawshaw): test **Generator
  901. switch t := t.Elem().(type) {
  902. case *types.Named:
  903. g.genFromRefnum(toName, fromName, t, t.Obj())
  904. default:
  905. g.errorf("unsupported type %s", t)
  906. }
  907. case *types.Named:
  908. switch t.Underlying().(type) {
  909. case *types.Interface, *types.Pointer:
  910. g.genFromRefnum(toName, fromName, t, t.Obj())
  911. default:
  912. g.errorf("unsupported, direct named type %s", t)
  913. }
  914. default:
  915. g.Printf("%s %s = (%s)%s;\n", g.jniType(t), toName, g.jniType(t), fromName)
  916. }
  917. }
  918. func (g *JavaGen) genFromRefnum(toName, fromName string, t types.Type, o *types.TypeName) {
  919. oPkg := o.Pkg()
  920. isJava := isJavaType(o.Type())
  921. if !isErrorType(o.Type()) && !g.validPkg(oPkg) && !isJava {
  922. g.errorf("type %s is defined in package %s, which is not bound", t, oPkg)
  923. return
  924. }
  925. p := pkgPrefix(oPkg)
  926. g.Printf("jobject %s = go_seq_from_refnum(env, %s, ", toName, fromName)
  927. if isJava {
  928. g.Printf("NULL, NULL")
  929. } else {
  930. g.Printf("proxy_class_%s_%s, proxy_class_%s_%s_cons", p, o.Name(), p, o.Name())
  931. }
  932. g.Printf(");\n")
  933. }
  934. func (g *JavaGen) gobindOpts() string {
  935. opts := []string{"-lang=java"}
  936. if g.JavaPkg != "" {
  937. opts = append(opts, "-javapkg="+g.JavaPkg)
  938. }
  939. return strings.Join(opts, " ")
  940. }
  941. var javaNameReplacer = newNameSanitizer([]string{
  942. "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char",
  943. "class", "const", "continue", "default", "do", "double", "else", "enum",
  944. "extends", "final", "finally", "float", "for", "goto", "if", "implements",
  945. "import", "instanceof", "int", "interface", "long", "native", "new", "package",
  946. "private", "protected", "public", "return", "short", "static", "strictfp",
  947. "super", "switch", "synchronized", "this", "throw", "throws", "transient",
  948. "try", "void", "volatile", "while", "false", "null", "true"})
  949. func (g *JavaGen) javaPkgName(pkg *types.Package) string {
  950. return JavaPkgName(g.JavaPkg, pkg)
  951. }
  952. // JavaPkgName returns the Java package name for a Go package
  953. // given a pkg prefix. If the prefix is empty, "go" is used
  954. // instead.
  955. func JavaPkgName(pkgPrefix string, pkg *types.Package) string {
  956. if pkg == nil {
  957. return "go"
  958. }
  959. s := javaNameReplacer(pkg.Name())
  960. if pkgPrefix == "" {
  961. return s
  962. }
  963. return pkgPrefix + "." + s
  964. }
  965. func (g *JavaGen) className() string {
  966. return JavaClassName(g.Pkg)
  967. }
  968. // JavaClassName returns the name of the Java class that
  969. // contains Go package level identifiers.
  970. func JavaClassName(pkg *types.Package) string {
  971. if pkg == nil {
  972. return "Universe"
  973. }
  974. return javaNameReplacer(strings.Title(pkg.Name()))
  975. }
  976. func (g *JavaGen) genConst(o *types.Const) {
  977. if _, ok := o.Type().(*types.Basic); !ok || !g.isSupported(o.Type()) {
  978. g.Printf("// skipped const %s with unsupported type: %s\n\n", o.Name(), o.Type())
  979. return
  980. }
  981. // TODO(hyangah): should const names use upper cases + "_"?
  982. // TODO(hyangah): check invalid names.
  983. jType := g.javaType(o.Type())
  984. val := o.Val().ExactString()
  985. switch b := o.Type().(*types.Basic); b.Kind() {
  986. case types.Int64, types.UntypedInt:
  987. i, exact := constant.Int64Val(o.Val())
  988. if !exact {
  989. g.errorf("const value %s for %s cannot be represented as %s", val, o.Name(), jType)
  990. return
  991. }
  992. val = fmt.Sprintf("%dL", i)
  993. case types.Float32:
  994. f, _ := constant.Float32Val(o.Val())
  995. val = fmt.Sprintf("%gf", f)
  996. case types.Float64, types.UntypedFloat:
  997. f, _ := constant.Float64Val(o.Val())
  998. if math.IsInf(f, 0) || math.Abs(f) > math.MaxFloat64 {
  999. g.errorf("const value %s for %s cannot be represented as %s", val, o.Name(), jType)
  1000. return
  1001. }
  1002. val = fmt.Sprintf("%g", f)
  1003. }
  1004. g.javadoc(g.docs[o.Name()].Doc())
  1005. g.Printf("public static final %s %s = %s;\n", g.javaType(o.Type()), o.Name(), val)
  1006. }
  1007. func (g *JavaGen) genJNIField(o *types.TypeName, f *types.Var) {
  1008. if t := f.Type(); !g.isSupported(t) {
  1009. g.Printf("// skipped field %s with unsupported type: %s\n\n", o.Name(), t)
  1010. return
  1011. }
  1012. n := java.JNIMangle(g.javaTypeName(o.Name()))
  1013. // setter
  1014. g.Printf("JNIEXPORT void JNICALL\n")
  1015. 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()))
  1016. g.Indent()
  1017. g.Printf("int32_t o = go_seq_to_refnum_go(env, this);\n")
  1018. g.genJavaToC("v", f.Type(), modeRetained)
  1019. g.Printf("proxy%s_%s_%s_Set(o, _v);\n", g.pkgPrefix, o.Name(), f.Name())
  1020. g.genRelease("v", f.Type(), modeRetained)
  1021. g.Outdent()
  1022. g.Printf("}\n\n")
  1023. // getter
  1024. g.Printf("JNIEXPORT %s JNICALL\n", g.jniType(f.Type()))
  1025. g.Printf("Java_%s_%s_get%s(JNIEnv *env, jobject this) {\n", g.jniPkgName(), n, java.JNIMangle(f.Name()))
  1026. g.Indent()
  1027. g.Printf("int32_t o = go_seq_to_refnum_go(env, this);\n")
  1028. g.Printf("%s r0 = ", g.cgoType(f.Type()))
  1029. g.Printf("proxy%s_%s_%s_Get(o);\n", g.pkgPrefix, o.Name(), f.Name())
  1030. g.genCToJava("_r0", "r0", f.Type(), modeRetained)
  1031. g.Printf("return _r0;\n")
  1032. g.Outdent()
  1033. g.Printf("}\n\n")
  1034. }
  1035. func (g *JavaGen) genJNIVar(o *types.Var) {
  1036. if t := o.Type(); !g.isSupported(t) {
  1037. g.Printf("// skipped variable %s with unsupported type: %s\n\n", o.Name(), t)
  1038. return
  1039. }
  1040. n := java.JNIMangle(g.javaTypeName(o.Name()))
  1041. // setter
  1042. g.Printf("JNIEXPORT void JNICALL\n")
  1043. g.Printf("Java_%s_%s_set%s(JNIEnv *env, jclass clazz, %s v) {\n", g.jniPkgName(), java.JNIMangle(g.className()), n, g.jniType(o.Type()))
  1044. g.Indent()
  1045. g.genJavaToC("v", o.Type(), modeRetained)
  1046. g.Printf("var_set%s_%s(_v);\n", g.pkgPrefix, o.Name())
  1047. g.genRelease("v", o.Type(), modeRetained)
  1048. g.Outdent()
  1049. g.Printf("}\n\n")
  1050. // getter
  1051. g.Printf("JNIEXPORT %s JNICALL\n", g.jniType(o.Type()))
  1052. g.Printf("Java_%s_%s_get%s(JNIEnv *env, jclass clazz) {\n", g.jniPkgName(), java.JNIMangle(g.className()), n)
  1053. g.Indent()
  1054. g.Printf("%s r0 = ", g.cgoType(o.Type()))
  1055. g.Printf("var_get%s_%s();\n", g.pkgPrefix, o.Name())
  1056. g.genCToJava("_r0", "r0", o.Type(), modeRetained)
  1057. g.Printf("return _r0;\n")
  1058. g.Outdent()
  1059. g.Printf("}\n\n")
  1060. }
  1061. func (g *JavaGen) genJNIConstructor(f *types.Func, sName string) {
  1062. if !g.isConsSigSupported(f.Type()) {
  1063. return
  1064. }
  1065. sig := f.Type().(*types.Signature)
  1066. res := sig.Results()
  1067. g.Printf("JNIEXPORT jint JNICALL\n")
  1068. g.Printf("Java_%s_%s_%s(JNIEnv *env, jclass clazz", g.jniPkgName(), java.JNIMangle(g.javaTypeName(sName)), java.JNIMangle("__"+f.Name()))
  1069. params := sig.Params()
  1070. for i := 0; i < params.Len(); i++ {
  1071. v := params.At(i)
  1072. jt := g.jniType(v.Type())
  1073. g.Printf(", %s %s", jt, g.paramName(params, i))
  1074. }
  1075. g.Printf(") {\n")
  1076. g.Indent()
  1077. for i := 0; i < params.Len(); i++ {
  1078. name := g.paramName(params, i)
  1079. g.genJavaToC(name, params.At(i).Type(), modeTransient)
  1080. }
  1081. // Constructors always return a mandatory *T and an optional error
  1082. if res.Len() == 1 {
  1083. g.Printf("int32_t refnum = proxy%s__%s(", g.pkgPrefix, f.Name())
  1084. } else {
  1085. g.Printf("struct proxy%s__%s_return res = proxy%s__%s(", g.pkgPrefix, f.Name(), g.pkgPrefix, f.Name())
  1086. }
  1087. for i := 0; i < params.Len(); i++ {
  1088. if i > 0 {
  1089. g.Printf(", ")
  1090. }
  1091. g.Printf("_%s", g.paramName(params, i))
  1092. }
  1093. g.Printf(");\n")
  1094. for i := 0; i < params.Len(); i++ {
  1095. g.genRelease(g.paramName(params, i), params.At(i).Type(), modeTransient)
  1096. }
  1097. // Extract multi returns and handle errors
  1098. if res.Len() == 2 {
  1099. g.Printf("int32_t refnum = res.r0;\n")
  1100. g.genCToJava("_err", "res.r1", res.At(1).Type(), modeRetained)
  1101. g.Printf("go_seq_maybe_throw_exception(env, _err);\n")
  1102. }
  1103. g.Printf("return refnum;\n")
  1104. g.Outdent()
  1105. g.Printf("}\n\n")
  1106. }
  1107. func (g *JavaGen) genJNIFunc(o *types.Func, sName string, jm *java.Func, proxy, isjava bool) {
  1108. if !g.isSigSupported(o.Type()) {
  1109. n := o.Name()
  1110. if sName != "" {
  1111. n = sName + "." + n
  1112. }
  1113. g.Printf("// skipped function %s with unsupported parameter or return types\n\n", n)
  1114. return
  1115. }
  1116. g.genJNIFuncSignature(o, sName, jm, proxy, isjava)
  1117. g.Printf(" {\n")
  1118. g.Indent()
  1119. g.genJNIFuncBody(o, sName, jm, isjava)
  1120. g.Outdent()
  1121. g.Printf("}\n\n")
  1122. }
  1123. func (g *JavaGen) genJNIFuncBody(o *types.Func, sName string, jm *java.Func, isjava bool) {
  1124. sig := o.Type().(*types.Signature)
  1125. res := sig.Results()
  1126. if sName != "" {
  1127. g.Printf("int32_t o = go_seq_to_refnum_go(env, __this__);\n")
  1128. }
  1129. params := sig.Params()
  1130. first := 0
  1131. if isjava && params.Len() > 0 && params.At(0).Name() == "this" {
  1132. // Start after the implicit this argument.
  1133. first = 1
  1134. g.Printf("int32_t _%s = go_seq_to_refnum(env, __this__);\n", g.paramName(params, 0))
  1135. }
  1136. for i := first; i < params.Len(); i++ {
  1137. name := g.paramName(params, i)
  1138. g.genJavaToC(name, params.At(i).Type(), modeTransient)
  1139. }
  1140. resPrefix := ""
  1141. if res.Len() > 0 {
  1142. if res.Len() == 1 {
  1143. g.Printf("%s r0 = ", g.cgoType(res.At(0).Type()))
  1144. } else {
  1145. resPrefix = "res."
  1146. g.Printf("struct proxy%s_%s_%s_return res = ", g.pkgPrefix, sName, o.Name())
  1147. }
  1148. }
  1149. g.Printf("proxy%s_%s_%s(", g.pkgPrefix, sName, o.Name())
  1150. if sName != "" {
  1151. g.Printf("o")
  1152. }
  1153. // Pass all arguments, including the implicit this argument.
  1154. for i := 0; i < params.Len(); i++ {
  1155. if i > 0 || sName != "" {
  1156. g.Printf(", ")
  1157. }
  1158. g.Printf("_%s", g.paramName(params, i))
  1159. }
  1160. g.Printf(");\n")
  1161. for i := first; i < params.Len(); i++ {
  1162. g.genRelease(g.paramName(params, i), params.At(i).Type(), modeTransient)
  1163. }
  1164. for i := 0; i < res.Len(); i++ {
  1165. tn := fmt.Sprintf("_r%d", i)
  1166. t := res.At(i).Type()
  1167. g.genCToJava(tn, fmt.Sprintf("%sr%d", resPrefix, i), t, modeRetained)
  1168. }
  1169. // Go backwards so that any exception is thrown before
  1170. // the return.
  1171. for i := res.Len() - 1; i >= 0; i-- {
  1172. t := res.At(i).Type()
  1173. if !isErrorType(t) {
  1174. g.Printf("return _r%d;\n", i)
  1175. } else {
  1176. g.Printf("go_seq_maybe_throw_exception(env, _r%d);\n", i)
  1177. }
  1178. }
  1179. }
  1180. // genRelease cleans up arguments that weren't copied in genJavaToC.
  1181. func (g *JavaGen) genRelease(varName string, t types.Type, mode varMode) {
  1182. switch t := t.(type) {
  1183. case *types.Basic:
  1184. case *types.Slice:
  1185. switch e := t.Elem().(type) {
  1186. case *types.Basic:
  1187. switch e.Kind() {
  1188. case types.Uint8: // Byte.
  1189. if mode == modeTransient {
  1190. g.Printf("go_seq_release_byte_array(env, %s, _%s.ptr);\n", varName, varName)
  1191. }
  1192. }
  1193. }
  1194. }
  1195. }
  1196. func (g *JavaGen) genMethodInterfaceProxy(oName string, m *types.Func) {
  1197. if !g.isSigSupported(m.Type()) {
  1198. g.Printf("// skipped method %s with unsupported parameter or return types\n\n", oName)
  1199. return
  1200. }
  1201. sig := m.Type().(*types.Signature)
  1202. params := sig.Params()
  1203. res := sig.Results()
  1204. g.genInterfaceMethodSignature(m, oName, false, g.paramName)
  1205. g.Indent()
  1206. g.Printf("JNIEnv *env = go_seq_push_local_frame(%d);\n", params.Len())
  1207. g.Printf("jobject o = go_seq_from_refnum(env, refnum, proxy_class_%s_%s, proxy_class_%s_%s_cons);\n", g.pkgPrefix, oName, g.pkgPrefix, oName)
  1208. for i := 0; i < params.Len(); i++ {
  1209. pn := g.paramName(params, i)
  1210. g.genCToJava("_"+pn, pn, params.At(i).Type(), modeTransient)
  1211. }
  1212. if res.Len() > 0 && !isErrorType(res.At(0).Type()) {
  1213. t := res.At(0).Type()
  1214. g.Printf("%s res = (*env)->Call%sMethod(env, o, ", g.jniType(t), g.jniCallType(t))
  1215. } else {
  1216. g.Printf("(*env)->CallVoidMethod(env, o, ")
  1217. }
  1218. g.Printf("mid_%s_%s", oName, m.Name())
  1219. for i := 0; i < params.Len(); i++ {
  1220. g.Printf(", _%s", g.paramName(params, i))
  1221. }
  1222. g.Printf(");\n")
  1223. var retName string
  1224. if res.Len() > 0 {
  1225. t := res.At(0).Type()
  1226. if res.Len() == 2 || isErrorType(t) {
  1227. g.Printf("jobject exc = go_seq_get_exception(env);\n")
  1228. errType := types.Universe.Lookup("error").Type()
  1229. g.genJavaToC("exc", errType, modeRetained)
  1230. retName = "_exc"
  1231. }
  1232. if !isErrorType(t) {
  1233. if res.Len() == 2 {
  1234. g.genCRetClear("res", t, "exc")
  1235. }
  1236. g.genJavaToC("res", t, modeRetained)
  1237. retName = "_res"
  1238. }
  1239. if res.Len() > 1 {
  1240. g.Printf("cproxy%s_%s_%s_return sres = {\n", g.pkgPrefix, oName, m.Name())
  1241. g.Printf(" _res, _exc\n")
  1242. g.Printf("};\n")
  1243. retName = "sres"
  1244. }
  1245. }
  1246. g.Printf("go_seq_pop_local_frame(env);\n")
  1247. if retName != "" {
  1248. g.Printf("return %s;\n", retName)
  1249. }
  1250. g.Outdent()
  1251. g.Printf("}\n\n")
  1252. }
  1253. func (g *JavaGen) GenH() error {
  1254. pkgPath := ""
  1255. if g.Pkg != nil {
  1256. pkgPath = g.Pkg.Path()
  1257. }
  1258. g.Printf(hPreamble, g.gobindOpts(), pkgPath, g.className())
  1259. for _, iface := range g.interfaces {
  1260. g.Printf("extern jclass proxy_class_%s_%s;\n", g.pkgPrefix, iface.obj.Name())
  1261. g.Printf("extern jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, iface.obj.Name())
  1262. g.Printf("\n")
  1263. for _, m := range iface.summary.callable {
  1264. if !g.isSigSupported(m.Type()) {
  1265. g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", iface.obj.Name(), m.Name())
  1266. continue
  1267. }
  1268. g.genInterfaceMethodSignature(m, iface.obj.Name(), true, g.paramName)
  1269. g.Printf("\n")
  1270. }
  1271. }
  1272. for _, s := range g.structs {
  1273. g.Printf("extern jclass proxy_class_%s_%s;\n", g.pkgPrefix, s.obj.Name())
  1274. g.Printf("extern jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, s.obj.Name())
  1275. }
  1276. g.Printf("#endif\n")
  1277. if len(g.err) > 0 {
  1278. return g.err
  1279. }
  1280. return nil
  1281. }
  1282. func (g *JavaGen) jniCallType(t types.Type) string {
  1283. switch t := t.(type) {
  1284. case *types.Basic:
  1285. switch t.Kind() {
  1286. case types.Bool, types.UntypedBool:
  1287. return "Boolean"
  1288. case types.Int:
  1289. return "Long"
  1290. case types.Int8, types.Uint8: // types.Byte
  1291. return "Byte"
  1292. case types.Int16:
  1293. return "Short"
  1294. case types.Int32, types.UntypedRune: // types.Rune
  1295. return "Int"
  1296. case types.Int64, types.UntypedInt:
  1297. return "Long"
  1298. case types.Float32:
  1299. return "Float"
  1300. case types.Float64, types.UntypedFloat:
  1301. return "Double"
  1302. case types.String, types.UntypedString:
  1303. return "Object"
  1304. default:
  1305. g.errorf("unsupported basic type: %s", t)
  1306. }
  1307. case *types.Slice:
  1308. return "Object"
  1309. case *types.Pointer:
  1310. if _, ok := t.Elem().(*types.Named); ok {
  1311. return g.jniCallType(t.Elem())
  1312. }
  1313. g.errorf("unsupported pointer to type: %s", t)
  1314. case *types.Named:
  1315. return "Object"
  1316. default:
  1317. return "Object"
  1318. }
  1319. return "TODO"
  1320. }
  1321. func (g *JavaGen) jniClassSigPrefix(pkg *types.Package) string {
  1322. return strings.Replace(g.javaPkgName(pkg), ".", "/", -1) + "/"
  1323. }
  1324. func (g *JavaGen) jniSigType(T types.Type) string {
  1325. if isErrorType(T) {
  1326. return "Ljava/lang/Exception;"
  1327. }
  1328. switch T := T.(type) {
  1329. case *types.Basic:
  1330. switch T.Kind() {
  1331. case types.Bool, types.UntypedBool:
  1332. return "Z"
  1333. case types.Int:
  1334. return "J"
  1335. case types.Int8:
  1336. return "B"
  1337. case types.Int16:
  1338. return "S"
  1339. case types.Int32, types.UntypedRune: // types.Rune
  1340. return "I"
  1341. case types.Int64, types.UntypedInt:
  1342. return "J"
  1343. case types.Uint8: // types.Byte
  1344. return "B"
  1345. case types.Float32:
  1346. return "F"
  1347. case types.Float64, types.UntypedFloat:
  1348. return "D"
  1349. case types.String, types.UntypedString:
  1350. return "Ljava/lang/String;"
  1351. default:
  1352. g.errorf("unsupported basic type: %s", T)
  1353. return "TODO"
  1354. }
  1355. case *types.Slice:
  1356. return "[" + g.jniSigType(T.Elem())
  1357. case *types.Pointer:
  1358. if _, ok := T.Elem().(*types.Named); ok {
  1359. return g.jniSigType(T.Elem())
  1360. }
  1361. g.errorf("unsupported pointer to type: %s", T)
  1362. case *types.Named:
  1363. return "L" + g.jniClassSigPrefix(T.Obj().Pkg()) + g.javaTypeName(T.Obj().Name()) + ";"
  1364. default:
  1365. g.errorf("unsupported jniType: %#+v, %s\n", T, T)
  1366. }
  1367. return "TODO"
  1368. }
  1369. func (g *JavaGen) GenC() error {
  1370. var pkgName, pkgPath string
  1371. if g.Pkg != nil {
  1372. pkgName = g.Pkg.Name()
  1373. pkgPath = g.Pkg.Path()
  1374. } else {
  1375. pkgName = "universe"
  1376. }
  1377. g.Printf(cPreamble, g.gobindOpts(), pkgPath)
  1378. g.Printf("#include %q\n", pkgName+".h")
  1379. if g.Pkg != nil {
  1380. for _, pkg := range g.Pkg.Imports() {
  1381. if g.validPkg(pkg) {
  1382. g.Printf("#include \"%s.h\"\n", pkg.Name())
  1383. }
  1384. }
  1385. }
  1386. g.Printf("\n")
  1387. for _, iface := range g.interfaces {
  1388. g.Printf("jclass proxy_class_%s_%s;\n", g.pkgPrefix, iface.obj.Name())
  1389. g.Printf("jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, iface.obj.Name())
  1390. for _, m := range iface.summary.callable {
  1391. if !g.isSigSupported(m.Type()) {
  1392. g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", iface.obj.Name(), m.Name())
  1393. continue
  1394. }
  1395. g.Printf("static jmethodID mid_%s_%s;\n", iface.obj.Name(), m.Name())
  1396. }
  1397. }
  1398. for _, s := range g.structs {
  1399. g.Printf("jclass proxy_class_%s_%s;\n", g.pkgPrefix, s.obj.Name())
  1400. g.Printf("jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, s.obj.Name())
  1401. }
  1402. g.Printf("\n")
  1403. g.Printf("JNIEXPORT void JNICALL\n")
  1404. g.Printf("Java_%s_%s__1init(JNIEnv *env, jclass _unused) {\n", g.jniPkgName(), java.JNIMangle(g.className()))
  1405. g.Indent()
  1406. g.Printf("jclass clazz;\n")
  1407. for _, s := range g.structs {
  1408. if jinf, ok := g.jstructs[s.obj]; ok {
  1409. // Leave the class and constructor NULL for Java classes with no
  1410. // default constructor.
  1411. if !jinf.genNoargCon {
  1412. continue
  1413. }
  1414. }
  1415. g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(s.obj.Pkg())+g.javaTypeName(s.obj.Name()))
  1416. g.Printf("proxy_class_%s_%s = (*env)->NewGlobalRef(env, clazz);\n", g.pkgPrefix, s.obj.Name())
  1417. g.Printf("proxy_class_%s_%s_cons = (*env)->GetMethodID(env, clazz, \"<init>\", \"(I)V\");\n", g.pkgPrefix, s.obj.Name())
  1418. }
  1419. for _, iface := range g.interfaces {
  1420. pkg := iface.obj.Pkg()
  1421. g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(pkg)+JavaClassName(pkg)+"$proxy"+iface.obj.Name())
  1422. g.Printf("proxy_class_%s_%s = (*env)->NewGlobalRef(env, clazz);\n", g.pkgPrefix, iface.obj.Name())
  1423. g.Printf("proxy_class_%s_%s_cons = (*env)->GetMethodID(env, clazz, \"<init>\", \"(I)V\");\n", g.pkgPrefix, iface.obj.Name())
  1424. if isErrorType(iface.obj.Type()) {
  1425. // As a special case, Java Exceptions are passed to Go pretending to implement the Go error interface.
  1426. // To complete the illusion, use the Throwable.getMessage method for proxied calls to the error.Error method.
  1427. g.Printf("clazz = (*env)->FindClass(env, \"java/lang/Throwable\");\n")
  1428. g.Printf("mid_error_Error = (*env)->GetMethodID(env, clazz, \"getMessage\", \"()Ljava/lang/String;\");\n")
  1429. continue
  1430. }
  1431. g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(pkg)+g.javaTypeName(iface.obj.Name()))
  1432. for _, m := range iface.summary.callable {
  1433. if !g.isSigSupported(m.Type()) {
  1434. g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", iface.obj.Name(), m.Name())
  1435. continue
  1436. }
  1437. sig := m.Type().(*types.Signature)
  1438. res := sig.Results()
  1439. retSig := "V"
  1440. if res.Len() > 0 {
  1441. if t := res.At(0).Type(); !isErrorType(t) {
  1442. retSig = g.jniSigType(t)
  1443. }
  1444. }
  1445. var jniParams string
  1446. params := sig.Params()
  1447. for i := 0; i < params.Len(); i++ {
  1448. jniParams += g.jniSigType(params.At(i).Type())
  1449. }
  1450. g.Printf("mid_%s_%s = (*env)->GetMethodID(env, clazz, %q, \"(%s)%s\");\n",
  1451. iface.obj.Name(), m.Name(), javaNameReplacer(lowerFirst(m.Name())), jniParams, retSig)
  1452. }
  1453. g.Printf("\n")
  1454. }
  1455. g.Outdent()
  1456. g.Printf("}\n\n")
  1457. for _, f := range g.funcs {
  1458. g.genJNIFunc(f, "", nil, false, false)
  1459. }
  1460. for _, s := range g.structs {
  1461. sName := s.obj.Name()
  1462. cons := g.constructors[s.obj]
  1463. jinf := g.jstructs[s.obj]
  1464. for _, f := range cons {
  1465. g.genJNIConstructor(f, sName)
  1466. }
  1467. if len(cons) == 0 && (jinf == nil || jinf.genNoargCon) {
  1468. g.Printf("JNIEXPORT jint JNICALL\n")
  1469. g.Printf("Java_%s_%s_%s(JNIEnv *env, jclass clazz) {\n", g.jniPkgName(), java.JNIMangle(g.javaTypeName(sName)), java.JNIMangle("__New"))
  1470. g.Indent()
  1471. g.Printf("return new_%s_%s();\n", g.pkgPrefix, sName)
  1472. g.Outdent()
  1473. g.Printf("}\n\n")
  1474. }
  1475. for _, m := range exportedMethodSet(types.NewPointer(s.obj.Type())) {
  1476. var jm *java.Func
  1477. if jinf != nil {
  1478. jm = jinf.lookupMethod(m, g.hasThis(s.obj.Name(), m))
  1479. }
  1480. g.genJNIFunc(m, sName, jm, false, jinf != nil)
  1481. }
  1482. for _, f := range exportedFields(s.t) {
  1483. g.genJNIField(s.obj, f)
  1484. }
  1485. }
  1486. for _, iface := range g.interfaces {
  1487. for _, m := range iface.summary.callable {
  1488. g.genJNIFunc(m, iface.obj.Name(), nil, true, false)
  1489. g.genMethodInterfaceProxy(iface.obj.Name(), m)
  1490. }
  1491. }
  1492. for _, v := range g.vars {
  1493. g.genJNIVar(v)
  1494. }
  1495. if len(g.err) > 0 {
  1496. return g.err
  1497. }
  1498. return nil
  1499. }
  1500. func (g *JavaGen) GenJava() error {
  1501. pkgPath := ""
  1502. if g.Pkg != nil {
  1503. pkgPath = g.Pkg.Path()
  1504. }
  1505. g.Printf(javaPreamble, g.javaPkgName(g.Pkg), g.className(), g.gobindOpts(), pkgPath)
  1506. g.Printf("public abstract class %s {\n", g.className())
  1507. g.Indent()
  1508. g.Printf("static {\n")
  1509. g.Indent()
  1510. g.Printf("Seq.touch(); // for loading the native library\n")
  1511. if g.Pkg != nil {
  1512. for _, p := range g.Pkg.Imports() {
  1513. if g.validPkg(p) {
  1514. g.Printf("%s.%s.touch();\n", g.javaPkgName(p), JavaClassName(p))
  1515. }
  1516. }
  1517. }
  1518. g.Printf("_init();\n")
  1519. g.Outdent()
  1520. g.Printf("}\n\n")
  1521. g.Printf("private %s() {} // uninstantiable\n\n", g.className())
  1522. g.Printf("// touch is called from other bound packages to initialize this package\n")
  1523. g.Printf("public static void touch() {}\n\n")
  1524. g.Printf("private static native void _init();\n\n")
  1525. for _, iface := range g.interfaces {
  1526. n := iface.obj.Name()
  1527. g.Printf("private static final class proxy%s", n)
  1528. if isErrorType(iface.obj.Type()) {
  1529. g.Printf(" extends Exception")
  1530. }
  1531. g.Printf(" implements Seq.Proxy, %s {\n", g.javaTypeName(n))
  1532. g.Indent()
  1533. g.genProxyImpl("proxy" + n)
  1534. g.Printf("proxy%s(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }\n\n", n)
  1535. if isErrorType(iface.obj.Type()) {
  1536. g.Printf("@Override public String getMessage() { return error(); }\n\n")
  1537. }
  1538. for _, m := range iface.summary.callable {
  1539. if !g.isSigSupported(m.Type()) {
  1540. g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", n, m.Name())
  1541. continue
  1542. }
  1543. g.Printf("public native ")
  1544. g.genFuncSignature(m, nil, false)
  1545. }
  1546. g.Outdent()
  1547. g.Printf("}\n")
  1548. }
  1549. g.Printf("\n")
  1550. for _, c := range g.constants {
  1551. g.genConst(c)
  1552. }
  1553. g.Printf("\n")
  1554. for _, v := range g.vars {
  1555. g.genVar(v)
  1556. }
  1557. for _, f := range g.funcs {
  1558. if !g.isSigSupported(f.Type()) {
  1559. g.Printf("// skipped function %s with unsupported parameter or return types\n\n", f.Name())
  1560. continue
  1561. }
  1562. g.javadoc(g.docs[f.Name()].Doc())
  1563. g.Printf("public static native ")
  1564. g.genFuncSignature(f, nil, false)
  1565. }
  1566. g.Outdent()
  1567. g.Printf("}\n")
  1568. if len(g.err) > 0 {
  1569. return g.err
  1570. }
  1571. return nil
  1572. }
  1573. // embeddedJavaClasses returns the possible empty list of Java types embedded
  1574. // in the given struct type.
  1575. func embeddedJavaClasses(t *types.Struct) []string {
  1576. clsSet := make(map[string]struct{})
  1577. var classes []string
  1578. for i := 0; i < t.NumFields(); i++ {
  1579. f := t.Field(i)
  1580. if !f.Exported() {
  1581. continue
  1582. }
  1583. if t := f.Type(); isJavaType(t) {
  1584. cls := classNameFor(t)
  1585. if _, exists := clsSet[cls]; !exists {
  1586. clsSet[cls] = struct{}{}
  1587. classes = append(classes, cls)
  1588. }
  1589. }
  1590. }
  1591. return classes
  1592. }
  1593. func classNameFor(t types.Type) string {
  1594. obj := t.(*types.Named).Obj()
  1595. pkg := obj.Pkg()
  1596. return strings.Replace(pkg.Path()[len("Java/"):], "/", ".", -1) + "." + obj.Name()
  1597. }
  1598. func isJavaType(t types.Type) bool {
  1599. return typePkgFirstElem(t) == "Java"
  1600. }
  1601. const (
  1602. javaPreamble = gobindPreamble + `// Java class %[1]s.%[2]s is a proxy for talking to a Go program.
  1603. //
  1604. // autogenerated by gobind %[3]s %[4]s
  1605. package %[1]s;
  1606. import go.Seq;
  1607. `
  1608. cPreamble = gobindPreamble + `// JNI functions for the Go <=> Java bridge.
  1609. //
  1610. // autogenerated by gobind %[1]s %[2]s
  1611. #include <android/log.h>
  1612. #include <stdint.h>
  1613. #include "seq.h"
  1614. #include "_cgo_export.h"
  1615. `
  1616. hPreamble = gobindPreamble + `// JNI function headers for the Go <=> Java bridge.
  1617. //
  1618. // autogenerated by gobind %[1]s %[2]s
  1619. #ifndef __%[3]s_H__
  1620. #define __%[3]s_H__
  1621. #include <jni.h>
  1622. `
  1623. )