genobjc.go 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428
  1. // Copyright 2015 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. "math"
  10. "strings"
  11. "golang.org/x/mobile/internal/importers/objc"
  12. )
  13. // TODO(hyangah): handle method name conflicts.
  14. // - struct with SetF method and exported F field.
  15. // - method names conflicting with NSObject methods. e.g. Init
  16. // - interface type with InitWithRef.
  17. // TODO(hyangah): error code/domain propagation
  18. type ObjcGen struct {
  19. Prefix string // prefix arg passed by flag.
  20. *Generator
  21. // fields set by init.
  22. namePrefix string
  23. // Map of all wrapped Objc types
  24. wrapMap map[string]*objc.Named
  25. // Structs that embeds Objc wrapper types.
  26. ostructs map[*types.TypeName]*objcClassInfo
  27. modules []string
  28. // Constructors is a map from Go struct types to a list
  29. // of exported constructor functions for the type, on the form
  30. // func New<Type>(...) *Type
  31. constructors map[*types.TypeName][]*types.Func
  32. }
  33. type objcClassInfo struct {
  34. // The Objc class this class extends.
  35. extends *objc.Named
  36. // All classes and protocols this class extends and conforms to.
  37. supers []*objc.Named
  38. methods map[string]*objc.Func
  39. }
  40. func (g *ObjcGen) Init(wrappers []*objc.Named) {
  41. g.Generator.Init()
  42. g.namePrefix = g.namePrefixOf(g.Pkg)
  43. g.wrapMap = make(map[string]*objc.Named)
  44. g.constructors = make(map[*types.TypeName][]*types.Func)
  45. modMap := make(map[string]struct{})
  46. for _, w := range wrappers {
  47. g.wrapMap[w.GoName] = w
  48. if _, exists := modMap[w.Module]; !exists {
  49. if !w.Generated {
  50. g.modules = append(g.modules, w.Module)
  51. }
  52. modMap[w.Module] = struct{}{}
  53. }
  54. }
  55. if _, exists := modMap["Foundation"]; !exists {
  56. g.modules = append(g.modules, "Foundation")
  57. }
  58. g.ostructs = make(map[*types.TypeName]*objcClassInfo)
  59. for _, s := range g.structs {
  60. embds := embeddedObjcTypes(s.t)
  61. if len(embds) == 0 {
  62. continue
  63. }
  64. inf := &objcClassInfo{
  65. methods: make(map[string]*objc.Func),
  66. }
  67. for _, n := range embds {
  68. t := g.wrapMap[n]
  69. for _, f := range t.AllMethods {
  70. inf.methods[f.GoName] = f
  71. }
  72. inf.supers = append(inf.supers, t)
  73. if !t.Protocol {
  74. if inf.extends != nil {
  75. g.errorf("%s embeds more than one ObjC class; only one is allowed.", s.obj)
  76. }
  77. inf.extends = t
  78. }
  79. }
  80. g.ostructs[s.obj] = inf
  81. }
  82. for _, f := range g.funcs {
  83. if t := g.constructorType(f); t != nil {
  84. g.constructors[t] = append(g.constructors[t], f)
  85. }
  86. }
  87. }
  88. func (g *ObjcGen) namePrefixOf(pkg *types.Package) string {
  89. if pkg == nil {
  90. return "Universe"
  91. }
  92. p := g.Prefix
  93. return p + strings.Title(pkg.Name())
  94. }
  95. func (g *ObjcGen) GenGoH() error {
  96. var pkgPath string
  97. if g.Pkg != nil {
  98. pkgPath = g.Pkg.Path()
  99. }
  100. g.Printf(objcPreamble, pkgPath, g.gobindOpts(), pkgPath)
  101. g.Printf("#ifndef __GO_%s_H__\n", g.pkgName)
  102. g.Printf("#define __GO_%s_H__\n\n", g.pkgName)
  103. g.Printf("#include <stdint.h>\n")
  104. g.Printf("#include <objc/objc.h>\n")
  105. for _, i := range g.interfaces {
  106. if !i.summary.implementable {
  107. continue
  108. }
  109. for _, m := range i.summary.callable {
  110. if !g.isSigSupported(m.Type()) {
  111. g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", i.obj.Name(), m.Name())
  112. continue
  113. }
  114. g.genInterfaceMethodSignature(m, i.obj.Name(), true, g.paramName)
  115. g.Printf("\n")
  116. }
  117. }
  118. g.Printf("#endif\n")
  119. if len(g.err) > 0 {
  120. return g.err
  121. }
  122. return nil
  123. }
  124. func (g *ObjcGen) GenH() error {
  125. var pkgPath string
  126. if g.Pkg != nil {
  127. pkgPath = g.Pkg.Path()
  128. }
  129. g.Printf(objcPreamble, pkgPath, g.gobindOpts(), pkgPath)
  130. g.Printf("#ifndef __%s_H__\n", g.namePrefix)
  131. g.Printf("#define __%s_H__\n", g.namePrefix)
  132. g.Printf("\n")
  133. for _, m := range g.modules {
  134. g.Printf("@import %s;\n", m)
  135. }
  136. g.Printf("#include \"ref.h\"\n")
  137. if g.Pkg != nil {
  138. g.Printf("#include \"Universe.objc.h\"\n\n")
  139. }
  140. if g.Pkg != nil {
  141. for _, pkg := range g.Pkg.Imports() {
  142. if g.validPkg(pkg) {
  143. g.Printf("#include %q\n", g.namePrefixOf(pkg)+".objc.h")
  144. }
  145. }
  146. }
  147. g.Printf("\n")
  148. // Forward declaration of @class and @protocol
  149. for _, s := range g.structs {
  150. g.Printf("@class %s%s;\n", g.namePrefix, s.obj.Name())
  151. }
  152. for _, i := range g.interfaces {
  153. g.Printf("@protocol %s%s;\n", g.namePrefix, i.obj.Name())
  154. if i.summary.implementable {
  155. g.Printf("@class %s%s;\n", g.namePrefix, i.obj.Name())
  156. // Forward declaration for other cases will be handled at the beginning of GenM.
  157. }
  158. }
  159. if len(g.structs) > 0 || len(g.interfaces) > 0 {
  160. g.Printf("\n")
  161. }
  162. // @interfaces
  163. for _, i := range g.interfaces {
  164. g.genInterfaceH(i.obj, i.t)
  165. g.Printf("\n")
  166. }
  167. for _, s := range g.structs {
  168. g.genStructH(s.obj, s.t)
  169. g.Printf("\n")
  170. }
  171. // const
  172. // TODO: prefix with k?, or use a class method?
  173. for _, obj := range g.constants {
  174. if _, ok := obj.Type().(*types.Basic); !ok || !g.isSupported(obj.Type()) {
  175. g.Printf("// skipped const %s with unsupported type: %s\n\n", obj.Name(), obj.Type())
  176. continue
  177. }
  178. g.objcdoc(g.docs[obj.Name()].Doc())
  179. switch b := obj.Type().(*types.Basic); b.Kind() {
  180. case types.String, types.UntypedString:
  181. g.Printf("FOUNDATION_EXPORT NSString* _Nonnull const %s%s;\n", g.namePrefix, obj.Name())
  182. default:
  183. g.Printf("FOUNDATION_EXPORT const %s %s%s;\n", g.objcType(obj.Type()), g.namePrefix, obj.Name())
  184. }
  185. }
  186. if len(g.constants) > 0 {
  187. g.Printf("\n")
  188. }
  189. // var
  190. if len(g.vars) > 0 {
  191. g.Printf("@interface %s : NSObject\n", g.namePrefix)
  192. for _, obj := range g.vars {
  193. if t := obj.Type(); !g.isSupported(t) {
  194. g.Printf("// skipped variable %s with unsupported type: %s\n\n", obj.Name(), t)
  195. continue
  196. }
  197. objcType := g.objcType(obj.Type())
  198. g.objcdoc(g.docs[obj.Name()].Doc())
  199. g.Printf("+ (%s) %s;\n", objcType, objcNameReplacer(lowerFirst(obj.Name())))
  200. g.Printf("+ (void) set%s:(%s)v;\n", obj.Name(), objcType)
  201. g.Printf("\n")
  202. }
  203. g.Printf("@end\n\n")
  204. }
  205. // static functions.
  206. for _, obj := range g.funcs {
  207. g.genFuncH(obj)
  208. g.Printf("\n")
  209. }
  210. for _, i := range g.interfaces {
  211. if i.summary.implementable {
  212. g.Printf("@class %s%s;\n\n", g.namePrefix, i.obj.Name())
  213. }
  214. }
  215. for _, i := range g.interfaces {
  216. if i.summary.implementable {
  217. // @interface Interface -- similar to what genStructH does.
  218. g.genInterfaceInterface(i.obj, i.summary, true)
  219. g.Printf("\n")
  220. }
  221. }
  222. g.Printf("#endif\n")
  223. if len(g.err) > 0 {
  224. return g.err
  225. }
  226. return nil
  227. }
  228. func (g *ObjcGen) gobindOpts() string {
  229. opts := []string{"-lang=objc"}
  230. if g.Prefix != "" {
  231. opts = append(opts, fmt.Sprintf("-prefix=%q", g.Prefix))
  232. }
  233. return strings.Join(opts, " ")
  234. }
  235. func (g *ObjcGen) GenM() error {
  236. var pkgPath string
  237. if g.Pkg != nil {
  238. pkgPath = g.Pkg.Path()
  239. }
  240. g.Printf(objcPreamble, pkgPath, g.gobindOpts(), pkgPath)
  241. g.Printf("#include <Foundation/Foundation.h>\n")
  242. g.Printf("#include \"seq.h\"\n")
  243. g.Printf("#include \"_cgo_export.h\"\n")
  244. g.Printf("#include %q\n", g.namePrefix+".objc.h")
  245. g.Printf("\n")
  246. // struct
  247. for _, s := range g.structs {
  248. g.genStructM(s.obj, s.t)
  249. g.Printf("\n")
  250. }
  251. // interface
  252. var needProxy []*types.TypeName
  253. for _, i := range g.interfaces {
  254. if g.genInterfaceM(i.obj, i.t) {
  255. needProxy = append(needProxy, i.obj)
  256. }
  257. g.Printf("\n")
  258. }
  259. // const
  260. for _, o := range g.constants {
  261. g.genConstM(o)
  262. }
  263. if len(g.constants) > 0 {
  264. g.Printf("\n")
  265. }
  266. // vars
  267. if len(g.vars) > 0 {
  268. g.Printf("@implementation %s\n", g.namePrefix)
  269. for _, o := range g.vars {
  270. g.genVarM(o)
  271. }
  272. g.Printf("@end\n\n")
  273. }
  274. g.Printf("\n")
  275. for _, obj := range g.funcs {
  276. if !g.isSigSupported(obj.Type()) {
  277. g.Printf("// skipped function %s with unsupported parameter or return types\n\n", obj.Name())
  278. continue
  279. }
  280. g.genFuncM(obj)
  281. g.Printf("\n")
  282. }
  283. for _, i := range g.interfaces {
  284. for _, m := range i.summary.callable {
  285. if !g.isSigSupported(m.Type()) {
  286. g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", i.obj.Name(), m.Name())
  287. continue
  288. }
  289. g.genInterfaceMethodProxy(i.obj, m)
  290. }
  291. }
  292. g.Printf("__attribute__((constructor)) static void init() {\n")
  293. g.Indent()
  294. g.Printf("init_seq();\n")
  295. g.Outdent()
  296. g.Printf("}\n")
  297. if len(g.err) > 0 {
  298. return g.err
  299. }
  300. return nil
  301. }
  302. func (g *ObjcGen) genVarM(o *types.Var) {
  303. if t := o.Type(); !g.isSupported(t) {
  304. g.Printf("// skipped variable %s with unsupported type: %s\n\n", o.Name(), t)
  305. return
  306. }
  307. objcType := g.objcType(o.Type())
  308. // setter
  309. g.Printf("+ (void) set%s:(%s)v {\n", o.Name(), objcType)
  310. g.Indent()
  311. g.genWrite("v", o.Type(), modeRetained)
  312. g.Printf("var_set%s_%s(_v);\n", g.pkgPrefix, o.Name())
  313. g.genRelease("v", o.Type(), modeRetained)
  314. g.Outdent()
  315. g.Printf("}\n\n")
  316. // getter
  317. g.Printf("+ (%s) %s {\n", objcType, objcNameReplacer(lowerFirst(o.Name())))
  318. g.Indent()
  319. g.Printf("%s r0 = ", g.cgoType(o.Type()))
  320. g.Printf("var_get%s_%s();\n", g.pkgPrefix, o.Name())
  321. g.genRead("_r0", "r0", o.Type(), modeRetained)
  322. g.Printf("return _r0;\n")
  323. g.Outdent()
  324. g.Printf("}\n\n")
  325. }
  326. func (g *ObjcGen) genConstM(o *types.Const) {
  327. if _, ok := o.Type().(*types.Basic); !ok || !g.isSupported(o.Type()) {
  328. g.Printf("// skipped const %s with unsupported type: %s\n\n", o.Name(), o.Type())
  329. return
  330. }
  331. cName := fmt.Sprintf("%s%s", g.namePrefix, o.Name())
  332. objcType := g.objcType(o.Type())
  333. switch b := o.Type().(*types.Basic); b.Kind() {
  334. case types.Bool, types.UntypedBool:
  335. v := "NO"
  336. if constant.BoolVal(o.Val()) {
  337. v = "YES"
  338. }
  339. g.Printf("const BOOL %s = %s;\n", cName, v)
  340. case types.String, types.UntypedString:
  341. g.Printf("NSString* const %s = @%s;\n", cName, o.Val().ExactString())
  342. case types.Int, types.Int8, types.Int16, types.Int32:
  343. g.Printf("const %s %s = %s;\n", objcType, cName, o.Val())
  344. case types.Int64, types.UntypedInt:
  345. i, exact := constant.Int64Val(o.Val())
  346. if !exact {
  347. g.errorf("const value %s for %s cannot be represented as %s", o.Val(), o.Name(), objcType)
  348. return
  349. }
  350. if i == math.MinInt64 {
  351. // -9223372036854775808LL does not work because 922337203685477508 is
  352. // larger than max int64.
  353. g.Printf("const int64_t %s = %dLL-1;\n", cName, i+1)
  354. } else {
  355. g.Printf("const int64_t %s = %dLL;\n", cName, i)
  356. }
  357. case types.Float32, types.Float64, types.UntypedFloat:
  358. f, _ := constant.Float64Val(o.Val())
  359. if math.IsInf(f, 0) || math.Abs(f) > math.MaxFloat64 {
  360. g.errorf("const value %s for %s cannot be represented as double", o.Val(), o.Name())
  361. return
  362. }
  363. g.Printf("const %s %s = %g;\n", objcType, cName, f)
  364. default:
  365. g.errorf("unsupported const type %s for %s", b, o.Name())
  366. }
  367. }
  368. type funcSummary struct {
  369. name string
  370. goname string
  371. ret string
  372. sig *types.Signature
  373. params, retParams []paramInfo
  374. hasself bool
  375. initName string
  376. }
  377. type paramInfo struct {
  378. typ types.Type
  379. name string
  380. }
  381. func (g *ObjcGen) funcSummary(obj *types.TypeName, f *types.Func) *funcSummary {
  382. sig := f.Type().(*types.Signature)
  383. s := &funcSummary{goname: f.Name(), sig: sig}
  384. var om *objc.Func
  385. var sigElems []string
  386. oinf := g.ostructs[obj]
  387. if oinf != nil {
  388. om = oinf.methods[f.Name()]
  389. }
  390. if om != nil {
  391. sigElems = strings.Split(om.Sig, ":")
  392. s.name = sigElems[0]
  393. } else {
  394. s.name = f.Name()
  395. }
  396. params := sig.Params()
  397. first := 0
  398. if oinf != nil {
  399. if params.Len() > 0 {
  400. v := params.At(0)
  401. if v.Name() == "self" {
  402. t := v.Type()
  403. if t, ok := t.(*types.Named); ok {
  404. if pkg := t.Obj().Pkg(); pkgFirstElem(pkg) == "ObjC" {
  405. s.hasself = true
  406. module := pkg.Path()[len("ObjC/"):]
  407. typName := module + "." + t.Obj().Name()
  408. exp := g.namePrefix + "." + obj.Name()
  409. if typName != exp {
  410. g.errorf("the type %s of the `this` argument to method %s is not %s", typName, f.Name(), exp)
  411. }
  412. }
  413. }
  414. }
  415. }
  416. }
  417. for i := first; i < params.Len(); i++ {
  418. p := params.At(i)
  419. v := paramInfo{
  420. typ: p.Type(),
  421. }
  422. if om != nil {
  423. v.name = sigElems[i-first]
  424. } else {
  425. v.name = g.paramName(params, i)
  426. }
  427. s.params = append(s.params, v)
  428. }
  429. if obj != nil {
  430. if pref := "New" + obj.Name(); strings.Index(f.Name(), pref) != -1 {
  431. s.initName = "init" + f.Name()[len(pref):]
  432. }
  433. }
  434. res := sig.Results()
  435. switch res.Len() {
  436. case 0:
  437. s.ret = "void"
  438. case 1:
  439. p := res.At(0)
  440. if isErrorType(p.Type()) {
  441. s.retParams = append(s.retParams, paramInfo{
  442. typ: p.Type(),
  443. name: "error",
  444. })
  445. s.ret = "BOOL"
  446. } else {
  447. name := p.Name()
  448. if name == "" || paramRE.MatchString(name) {
  449. name = "ret0_"
  450. }
  451. typ := p.Type()
  452. s.retParams = append(s.retParams, paramInfo{typ: typ, name: name})
  453. s.ret = g.objcType(typ)
  454. }
  455. case 2:
  456. name := res.At(0).Name()
  457. if name == "" || paramRE.MatchString(name) {
  458. name = "ret0_"
  459. }
  460. typ := res.At(0).Type()
  461. s.retParams = append(s.retParams, paramInfo{
  462. typ: typ,
  463. name: name,
  464. })
  465. if isNullableType(typ) {
  466. s.ret = g.objcType(typ) // Return is nullable, so satisfies the ObjC/Swift error protocol
  467. } else {
  468. s.ret = "BOOL" // Return is not nullable, must use an output parameter and return bool
  469. }
  470. if !isErrorType(res.At(1).Type()) {
  471. g.errorf("second result value must be of type error: %s", f)
  472. return nil
  473. }
  474. s.retParams = append(s.retParams, paramInfo{
  475. typ: res.At(1).Type(),
  476. name: "error", // TODO(hyangah): name collision check.
  477. })
  478. default:
  479. // TODO(hyangah): relax the constraint on multiple return params.
  480. g.errorf("too many result values: %s", f)
  481. return nil
  482. }
  483. return s
  484. }
  485. func (s *funcSummary) asFunc(g *ObjcGen) string {
  486. var params []string
  487. for _, p := range s.params {
  488. params = append(params, g.objcParamType(p.typ)+" "+p.name)
  489. }
  490. skip := 0
  491. if s.returnsVal() {
  492. skip = 1
  493. }
  494. for _, p := range s.retParams[skip:] {
  495. params = append(params, g.objcType(p.typ)+"* _Nullable "+p.name)
  496. }
  497. paramContents := "void"
  498. if len(params) > 0 {
  499. paramContents = strings.Join(params, ", ")
  500. }
  501. return fmt.Sprintf("%s %s%s(%s)", s.ret, g.namePrefix, s.name, paramContents)
  502. }
  503. func (s *funcSummary) asMethod(g *ObjcGen) string {
  504. return fmt.Sprintf("(%s)%s%s", s.ret, objcNameReplacer(lowerFirst(s.name)), s.asSignature(g))
  505. }
  506. func (s *funcSummary) asSignature(g *ObjcGen) string {
  507. var params []string
  508. skip := 0
  509. if s.hasself {
  510. skip = 1
  511. }
  512. for i, p := range s.params[skip:] {
  513. var key string
  514. if i != 0 {
  515. key = p.name
  516. }
  517. params = append(params, fmt.Sprintf("%s:(%s)%s", key, g.objcParamType(p.typ), p.name))
  518. }
  519. skip = 0
  520. if s.returnsVal() {
  521. skip = 1
  522. }
  523. for _, p := range s.retParams[skip:] {
  524. var key string
  525. if len(params) > 0 {
  526. key = p.name
  527. }
  528. params = append(params, fmt.Sprintf("%s:(%s)%s", key, g.objcType(p.typ)+"* _Nullable", p.name))
  529. }
  530. return strings.Join(params, " ")
  531. }
  532. func (s *funcSummary) asInitSignature(g *ObjcGen) string {
  533. var params []string
  534. for i, p := range s.params {
  535. var key string
  536. if i > 0 {
  537. key = p.name
  538. }
  539. params = append(params, fmt.Sprintf("%s:(%s)%s", key, g.objcParamType(p.typ), p.name))
  540. }
  541. return strings.Join(params, " ")
  542. }
  543. func (s *funcSummary) callMethod(g *ObjcGen) string {
  544. var params []string
  545. for i, p := range s.params {
  546. var key string
  547. if i != 0 {
  548. key = p.name
  549. }
  550. params = append(params, fmt.Sprintf("%s:_%s", key, p.name))
  551. }
  552. skip := 0
  553. if s.returnsVal() {
  554. skip = 1
  555. }
  556. for _, p := range s.retParams[skip:] {
  557. var key string
  558. if len(params) > 0 {
  559. key = p.name
  560. }
  561. params = append(params, fmt.Sprintf("%s:&%s", key, p.name))
  562. }
  563. return fmt.Sprintf("%s%s", objcNameReplacer(lowerFirst(s.name)), strings.Join(params, " "))
  564. }
  565. func (s *funcSummary) returnsVal() bool {
  566. return (len(s.retParams) == 1 && !isErrorType(s.retParams[0].typ)) || (len(s.retParams) == 2 && isNullableType(s.retParams[0].typ))
  567. }
  568. func (g *ObjcGen) paramName(params *types.Tuple, pos int) string {
  569. name := basicParamName(params, pos)
  570. return objcNameReplacer(name)
  571. }
  572. func (g *ObjcGen) genFuncH(obj *types.Func) {
  573. if !g.isSigSupported(obj.Type()) {
  574. g.Printf("// skipped function %s with unsupported parameter or return types\n\n", obj.Name())
  575. return
  576. }
  577. if s := g.funcSummary(nil, obj); s != nil {
  578. g.objcdoc(g.docs[obj.Name()].Doc())
  579. g.Printf("FOUNDATION_EXPORT %s;\n", s.asFunc(g))
  580. }
  581. }
  582. func (g *ObjcGen) genFuncM(obj *types.Func) {
  583. s := g.funcSummary(nil, obj)
  584. if s == nil {
  585. return
  586. }
  587. g.Printf("%s {\n", s.asFunc(g))
  588. g.Indent()
  589. g.genFunc(s, "")
  590. g.Outdent()
  591. g.Printf("}\n")
  592. }
  593. func (g *ObjcGen) genGetter(oName string, f *types.Var) {
  594. t := f.Type()
  595. g.Printf("- (%s)%s {\n", g.objcType(t), objcNameReplacer(lowerFirst(f.Name())))
  596. g.Indent()
  597. g.Printf("int32_t refnum = go_seq_go_to_refnum(self._ref);\n")
  598. g.Printf("%s r0 = ", g.cgoType(f.Type()))
  599. g.Printf("proxy%s_%s_%s_Get(refnum);\n", g.pkgPrefix, oName, f.Name())
  600. g.genRead("_r0", "r0", f.Type(), modeRetained)
  601. g.Printf("return _r0;\n")
  602. g.Outdent()
  603. g.Printf("}\n\n")
  604. }
  605. func (g *ObjcGen) genSetter(oName string, f *types.Var) {
  606. t := f.Type()
  607. g.Printf("- (void)set%s:(%s)v {\n", f.Name(), g.objcType(t))
  608. g.Indent()
  609. g.Printf("int32_t refnum = go_seq_go_to_refnum(self._ref);\n")
  610. g.genWrite("v", f.Type(), modeRetained)
  611. g.Printf("proxy%s_%s_%s_Set(refnum, _v);\n", g.pkgPrefix, oName, f.Name())
  612. g.genRelease("v", f.Type(), modeRetained)
  613. g.Outdent()
  614. g.Printf("}\n\n")
  615. }
  616. func (g *ObjcGen) genWrite(varName string, t types.Type, mode varMode) {
  617. switch t := t.(type) {
  618. case *types.Basic:
  619. switch t.Kind() {
  620. case types.String:
  621. g.Printf("nstring _%s = go_seq_from_objc_string(%s);\n", varName, varName)
  622. default:
  623. g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName)
  624. }
  625. case *types.Slice:
  626. switch e := t.Elem().(type) {
  627. case *types.Basic:
  628. switch e.Kind() {
  629. case types.Uint8: // Byte.
  630. g.Printf("nbyteslice _%s = go_seq_from_objc_bytearray(%s, %d);\n", varName, varName, toCFlag(mode == modeRetained))
  631. default:
  632. g.errorf("unsupported type: %s", t)
  633. }
  634. default:
  635. g.errorf("unsupported type: %s", t)
  636. }
  637. case *types.Named:
  638. switch u := t.Underlying().(type) {
  639. case *types.Interface:
  640. g.genRefWrite(varName)
  641. default:
  642. g.errorf("unsupported named type: %s / %T", u, u)
  643. }
  644. case *types.Pointer:
  645. g.genRefWrite(varName)
  646. default:
  647. g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName)
  648. }
  649. }
  650. func (g *ObjcGen) genRefWrite(varName string) {
  651. g.Printf("int32_t _%s;\n", varName)
  652. g.Printf("if ([%s conformsToProtocol:@protocol(goSeqRefInterface)]) {\n", varName)
  653. g.Indent()
  654. g.Printf("id<goSeqRefInterface> %[1]s_proxy = (id<goSeqRefInterface>)(%[1]s);\n", varName)
  655. g.Printf("_%s = go_seq_go_to_refnum(%s_proxy._ref);\n", varName, varName)
  656. g.Outdent()
  657. g.Printf("} else {\n")
  658. g.Indent()
  659. g.Printf("_%s = go_seq_to_refnum(%s);\n", varName, varName)
  660. g.Outdent()
  661. g.Printf("}\n")
  662. }
  663. func (g *ObjcGen) genRefRead(toName, fromName string, t types.Type) {
  664. ptype := g.refTypeBase(t)
  665. g.Printf("%s* %s = nil;\n", ptype, toName)
  666. g.Printf("GoSeqRef* %s_ref = go_seq_from_refnum(%s);\n", toName, fromName)
  667. g.Printf("if (%s_ref != NULL) {\n", toName)
  668. g.Printf(" %s = %s_ref.obj;\n", toName, toName)
  669. g.Printf(" if (%s == nil) {\n", toName)
  670. if isObjcType(t) {
  671. g.Printf(" LOG_FATAL(@\"unexpected NULL reference\");\n")
  672. } else {
  673. g.Printf(" %s = [[%s alloc] initWithRef:%s_ref];\n", toName, ptype, toName)
  674. }
  675. g.Printf(" }\n")
  676. g.Printf("}\n")
  677. }
  678. func (g *ObjcGen) genRead(toName, fromName string, t types.Type, mode varMode) {
  679. switch t := t.(type) {
  680. case *types.Basic:
  681. switch t.Kind() {
  682. case types.String:
  683. g.Printf("NSString *%s = go_seq_to_objc_string(%s);\n", toName, fromName)
  684. case types.Bool:
  685. g.Printf("BOOL %s = %s ? YES : NO;\n", toName, fromName)
  686. default:
  687. g.Printf("%s %s = (%s)%s;\n", g.objcType(t), toName, g.objcType(t), fromName)
  688. }
  689. case *types.Slice:
  690. switch e := t.Elem().(type) {
  691. case *types.Basic:
  692. switch e.Kind() {
  693. case types.Uint8: // Byte.
  694. g.Printf("NSData *%s = go_seq_to_objc_bytearray(%s, %d);\n", toName, fromName, toCFlag(mode == modeRetained))
  695. default:
  696. g.errorf("unsupported type: %s", t)
  697. }
  698. default:
  699. g.errorf("unsupported type: %s", t)
  700. }
  701. case *types.Pointer:
  702. switch t := t.Elem().(type) {
  703. case *types.Named:
  704. g.genRefRead(toName, fromName, types.NewPointer(t))
  705. default:
  706. g.errorf("unsupported type %s", t)
  707. }
  708. case *types.Named:
  709. switch t.Underlying().(type) {
  710. case *types.Interface, *types.Pointer:
  711. g.genRefRead(toName, fromName, t)
  712. default:
  713. g.errorf("unsupported, direct named type %s", t)
  714. }
  715. default:
  716. g.Printf("%s %s = (%s)%s;\n", g.objcType(t), toName, g.objcType(t), fromName)
  717. }
  718. }
  719. func (g *ObjcGen) genFunc(s *funcSummary, objName string) {
  720. skip := 0
  721. if objName != "" {
  722. g.Printf("int32_t refnum = go_seq_go_to_refnum(self._ref);\n")
  723. if s.hasself {
  724. skip = 1
  725. g.Printf("int32_t _self = go_seq_to_refnum(self);\n")
  726. }
  727. }
  728. for _, p := range s.params[skip:] {
  729. g.genWrite(p.name, p.typ, modeTransient)
  730. }
  731. resPrefix := ""
  732. if len(s.retParams) > 0 {
  733. if len(s.retParams) == 1 {
  734. g.Printf("%s r0 = ", g.cgoType(s.retParams[0].typ))
  735. } else {
  736. resPrefix = "res."
  737. g.Printf("struct proxy%s_%s_%s_return res = ", g.pkgPrefix, objName, s.goname)
  738. }
  739. }
  740. g.Printf("proxy%s_%s_%s(", g.pkgPrefix, objName, s.goname)
  741. if objName != "" {
  742. g.Printf("refnum")
  743. if s.hasself {
  744. g.Printf(", _self")
  745. }
  746. }
  747. for i, p := range s.params[skip:] {
  748. if i > 0 || objName != "" {
  749. g.Printf(", ")
  750. }
  751. g.Printf("_%s", p.name)
  752. }
  753. g.Printf(");\n")
  754. for _, p := range s.params {
  755. g.genRelease(p.name, p.typ, modeTransient)
  756. }
  757. for i, r := range s.retParams {
  758. g.genRead("_"+r.name, fmt.Sprintf("%sr%d", resPrefix, i), r.typ, modeRetained)
  759. }
  760. skip = 0
  761. if s.returnsVal() {
  762. skip = 1
  763. }
  764. for _, p := range s.retParams[skip:] {
  765. if isErrorType(p.typ) {
  766. g.Printf("if (_%s != nil && %s != nil) {\n", p.name, p.name)
  767. g.Indent()
  768. g.Printf("*%s = _%s;\n", p.name, p.name)
  769. g.Outdent()
  770. g.Printf("}\n")
  771. } else {
  772. g.Printf("*%s = _%s;\n", p.name, p.name)
  773. }
  774. }
  775. if n := len(s.retParams); n > 0 {
  776. var (
  777. first = s.retParams[0]
  778. last = s.retParams[n-1]
  779. )
  780. if (n == 1 && isErrorType(last.typ)) || (n == 2 && !isNullableType(first.typ) && isErrorType(last.typ)) {
  781. g.Printf("return (_%s == nil);\n", last.name)
  782. } else {
  783. if s.returnsVal() && isErrorType(last.typ) {
  784. g.Printf("if (_%s != nil) {\n", last.name)
  785. g.Indent()
  786. g.Printf("return nil;\n")
  787. g.Outdent()
  788. g.Printf("}\n")
  789. }
  790. g.Printf("return _%s;\n", first.name)
  791. }
  792. }
  793. }
  794. func (g *ObjcGen) genInterfaceInterface(obj *types.TypeName, summary ifaceSummary, isProtocol bool) {
  795. doc := g.docs[obj.Name()]
  796. g.objcdoc(doc.Doc())
  797. g.Printf("@interface %[1]s%[2]s : ", g.namePrefix, obj.Name())
  798. if isErrorType(obj.Type()) {
  799. g.Printf("NSError")
  800. } else {
  801. g.Printf("NSObject")
  802. }
  803. prots := []string{"goSeqRefInterface"}
  804. if isProtocol {
  805. prots = append(prots, fmt.Sprintf("%[1]s%[2]s", g.namePrefix, obj.Name()))
  806. }
  807. g.Printf(" <%s>", strings.Join(prots, ", "))
  808. g.Printf(" {\n}\n")
  809. g.Printf("@property(strong, readonly) _Nonnull id _ref;\n")
  810. g.Printf("\n")
  811. g.Printf("- (nonnull instancetype)initWithRef:(_Nonnull id)ref;\n")
  812. for _, m := range summary.callable {
  813. if !g.isSigSupported(m.Type()) {
  814. g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name())
  815. continue
  816. }
  817. s := g.funcSummary(nil, m)
  818. g.objcdoc(doc.Member(m.Name()))
  819. g.Printf("- %s;\n", s.asMethod(g))
  820. }
  821. g.Printf("@end\n")
  822. }
  823. func (g *ObjcGen) genInterfaceH(obj *types.TypeName, t *types.Interface) {
  824. doc := g.docs[obj.Name()]
  825. summary := makeIfaceSummary(t)
  826. if !summary.implementable {
  827. g.genInterfaceInterface(obj, summary, false)
  828. return
  829. }
  830. g.Printf("@protocol %s%s <NSObject>\n", g.namePrefix, obj.Name())
  831. for _, m := range makeIfaceSummary(t).callable {
  832. if !g.isSigSupported(m.Type()) {
  833. g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name())
  834. continue
  835. }
  836. s := g.funcSummary(nil, m)
  837. g.objcdoc(doc.Member(m.Name()))
  838. g.Printf("- %s;\n", s.asMethod(g))
  839. }
  840. g.Printf("@end\n")
  841. }
  842. func (g *ObjcGen) genInterfaceM(obj *types.TypeName, t *types.Interface) bool {
  843. summary := makeIfaceSummary(t)
  844. // @implementation Interface -- similar to what genStructM does.
  845. g.Printf("@implementation %s%s {\n", g.namePrefix, obj.Name())
  846. g.Printf("}\n")
  847. g.Printf("\n")
  848. g.Printf("- (nonnull instancetype)initWithRef:(id)ref {\n")
  849. g.Indent()
  850. if isErrorType(obj.Type()) {
  851. g.Printf("if (self) {\n")
  852. g.Printf(" __ref = ref;\n")
  853. g.Printf(" self = [super initWithDomain:@\"go\" code:1 userInfo:@{NSLocalizedDescriptionKey: [self error]}];\n")
  854. g.Printf("}\n")
  855. } else {
  856. g.Printf("self = [super init];\n")
  857. g.Printf("if (self) { __ref = ref; }\n")
  858. }
  859. g.Printf("return self;\n")
  860. g.Outdent()
  861. g.Printf("}\n")
  862. g.Printf("\n")
  863. for _, m := range summary.callable {
  864. if !g.isSigSupported(m.Type()) {
  865. g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name())
  866. continue
  867. }
  868. s := g.funcSummary(nil, m)
  869. g.Printf("- %s {\n", s.asMethod(g))
  870. g.Indent()
  871. g.genFunc(s, obj.Name())
  872. g.Outdent()
  873. g.Printf("}\n\n")
  874. }
  875. g.Printf("@end\n")
  876. g.Printf("\n")
  877. return summary.implementable
  878. }
  879. func (g *ObjcGen) genInterfaceMethodProxy(obj *types.TypeName, m *types.Func) {
  880. oName := obj.Name()
  881. s := g.funcSummary(nil, m)
  882. g.genInterfaceMethodSignature(m, oName, false, g.paramName)
  883. g.Indent()
  884. g.Printf("@autoreleasepool {\n")
  885. g.Indent()
  886. g.Printf("%s* o = go_seq_objc_from_refnum(refnum);\n", g.refTypeBase(obj.Type()))
  887. for _, p := range s.params {
  888. g.genRead("_"+p.name, p.name, p.typ, modeTransient)
  889. }
  890. // call method
  891. for _, p := range s.retParams {
  892. if isErrorType(p.typ) {
  893. g.Printf("NSError* %s = nil;\n", p.name)
  894. } else {
  895. g.Printf("%s %s;\n", g.objcType(p.typ), p.name)
  896. }
  897. }
  898. if isErrorType(obj.Type()) && m.Name() == "Error" {
  899. // As a special case, ObjC NSErrors are passed to Go pretending to implement the Go error interface.
  900. // They don't actually have an Error method, so calls to to it needs to be rerouted.
  901. g.Printf("%s = [o localizedDescription];\n", s.retParams[0].name)
  902. } else {
  903. if s.ret == "void" {
  904. g.Printf("[o %s];\n", s.callMethod(g))
  905. } else if !s.returnsVal() {
  906. g.Printf("%s returnVal = [o %s];\n", s.ret, s.callMethod(g))
  907. } else {
  908. g.Printf("%s = [o %s];\n", s.retParams[0].name, s.callMethod(g))
  909. }
  910. }
  911. if len(s.retParams) > 0 {
  912. if len(s.retParams) == 1 && !isErrorType(s.retParams[0].typ) {
  913. p := s.retParams[0]
  914. g.genWrite(p.name, p.typ, modeRetained)
  915. g.Printf("return _%s;\n", p.name)
  916. } else {
  917. var rets []string
  918. for _, p := range s.retParams {
  919. if isErrorType(p.typ) {
  920. g.Printf("NSError *_%s = nil;\n", p.name)
  921. if !s.returnsVal() {
  922. g.Printf("if (!returnVal) {\n")
  923. } else {
  924. g.Printf("if (%s != nil) {\n", p.name)
  925. }
  926. g.Indent()
  927. g.Printf("_%[1]s = %[1]s;\n", p.name)
  928. g.Outdent()
  929. g.Printf("}\n")
  930. g.genWrite("_"+p.name, p.typ, modeRetained)
  931. rets = append(rets, "__"+p.name)
  932. } else {
  933. g.genWrite(p.name, p.typ, modeRetained)
  934. rets = append(rets, "_"+p.name)
  935. }
  936. }
  937. if len(rets) > 1 {
  938. g.Printf("cproxy%s_%s_%s_return _sres = {\n", g.pkgPrefix, oName, m.Name())
  939. g.Printf(" %s\n", strings.Join(rets, ", "))
  940. g.Printf("};\n")
  941. g.Printf("return _sres;\n")
  942. } else {
  943. g.Printf("return %s;\n", rets[0])
  944. }
  945. }
  946. }
  947. g.Outdent()
  948. g.Printf("}\n")
  949. g.Outdent()
  950. g.Printf("}\n\n")
  951. }
  952. // genRelease cleans up arguments that weren't copied in genWrite.
  953. func (g *ObjcGen) genRelease(varName string, t types.Type, mode varMode) {
  954. switch t := t.(type) {
  955. case *types.Slice:
  956. switch e := t.Elem().(type) {
  957. case *types.Basic:
  958. switch e.Kind() {
  959. case types.Uint8: // Byte.
  960. if mode == modeTransient {
  961. // If the argument was not mutable, go_seq_from_objc_bytearray created a copy.
  962. // Free it here.
  963. g.Printf("if (![%s isKindOfClass:[NSMutableData class]]) {\n", varName)
  964. g.Printf(" free(_%s.ptr);\n", varName)
  965. g.Printf("}\n")
  966. }
  967. }
  968. }
  969. }
  970. }
  971. func (g *ObjcGen) genStructH(obj *types.TypeName, t *types.Struct) {
  972. doc := g.docs[obj.Name()]
  973. g.objcdoc(doc.Doc())
  974. g.Printf("@interface %s%s : ", g.namePrefix, obj.Name())
  975. oinf := g.ostructs[obj]
  976. var prots []string
  977. if oinf != nil {
  978. for _, sup := range oinf.supers {
  979. if !sup.Protocol {
  980. g.Printf(sup.Name)
  981. } else {
  982. prots = append(prots, sup.Name)
  983. }
  984. }
  985. } else {
  986. g.Printf("NSObject")
  987. prots = append(prots, "goSeqRefInterface")
  988. }
  989. pT := types.NewPointer(obj.Type())
  990. for _, iface := range g.allIntf {
  991. p := iface.obj.Pkg()
  992. if g.Pkg != nil && g.Pkg != p {
  993. // To avoid header include cycles, only declare implementation of interfaces
  994. // from imported packages. TODO(elias.naur): Include every interface that
  995. // doesn't introduce an include cycle.
  996. found := false
  997. for _, imp := range g.Pkg.Imports() {
  998. if imp == p {
  999. found = true
  1000. break
  1001. }
  1002. }
  1003. if !found {
  1004. continue
  1005. }
  1006. }
  1007. obj := iface.obj
  1008. if types.AssignableTo(pT, obj.Type()) {
  1009. n := fmt.Sprintf("%s%s", g.namePrefixOf(obj.Pkg()), obj.Name())
  1010. prots = append(prots, n)
  1011. }
  1012. }
  1013. if len(prots) > 0 {
  1014. g.Printf(" <%s>", strings.Join(prots, ", "))
  1015. }
  1016. g.Printf(" {\n")
  1017. g.Printf("}\n")
  1018. g.Printf("@property(strong, readonly) _Nonnull id _ref;\n")
  1019. g.Printf("\n")
  1020. g.Printf("- (nonnull instancetype)initWithRef:(_Nonnull id)ref;\n")
  1021. cons := g.constructors[obj]
  1022. if oinf == nil {
  1023. for _, f := range cons {
  1024. if !g.isSigSupported(f.Type()) {
  1025. g.Printf("// skipped constructor %s.%s with unsupported parameter or return types\n\n", obj.Name(), f.Name())
  1026. continue
  1027. }
  1028. g.genInitH(obj, f)
  1029. }
  1030. }
  1031. if oinf != nil || len(cons) == 0 {
  1032. // default constructor won't return nil
  1033. g.Printf("- (nonnull instancetype)init;\n")
  1034. }
  1035. // accessors to exported fields.
  1036. for _, f := range exportedFields(t) {
  1037. if t := f.Type(); !g.isSupported(t) {
  1038. g.Printf("// skipped field %s.%s with unsupported type: %s\n\n", obj.Name(), f.Name(), t)
  1039. continue
  1040. }
  1041. name, typ := f.Name(), g.objcType(f.Type())
  1042. g.objcdoc(doc.Member(f.Name()))
  1043. // properties are atomic by default so explicitly say otherwise
  1044. g.Printf("@property (nonatomic) %s %s;\n", typ, objcNameReplacer(lowerFirst(name)))
  1045. }
  1046. // exported methods
  1047. for _, m := range exportedMethodSet(types.NewPointer(obj.Type())) {
  1048. if !g.isSigSupported(m.Type()) {
  1049. g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name())
  1050. continue
  1051. }
  1052. s := g.funcSummary(obj, m)
  1053. g.objcdoc(doc.Member(m.Name()))
  1054. g.Printf("- %s;\n", s.asMethod(g))
  1055. }
  1056. g.Printf("@end\n")
  1057. }
  1058. func (g *ObjcGen) objcdoc(doc string) {
  1059. if doc == "" {
  1060. return
  1061. }
  1062. g.Printf("/**\n * %s */\n", doc)
  1063. }
  1064. func (g *ObjcGen) genStructM(obj *types.TypeName, t *types.Struct) {
  1065. fields := exportedFields(t)
  1066. methods := exportedMethodSet(types.NewPointer(obj.Type()))
  1067. g.Printf("\n")
  1068. oinf := g.ostructs[obj]
  1069. g.Printf("@implementation %s%s {\n", g.namePrefix, obj.Name())
  1070. g.Printf("}\n\n")
  1071. g.Printf("- (nonnull instancetype)initWithRef:(_Nonnull id)ref {\n")
  1072. g.Indent()
  1073. g.Printf("self = [super init];\n")
  1074. g.Printf("if (self) { __ref = ref; }\n")
  1075. g.Printf("return self;\n")
  1076. g.Outdent()
  1077. g.Printf("}\n\n")
  1078. cons := g.constructors[obj]
  1079. if oinf == nil {
  1080. for _, f := range cons {
  1081. if !g.isSigSupported(f.Type()) {
  1082. g.Printf("// skipped constructor %s.%s with unsupported parameter or return types\n\n", obj, f.Name())
  1083. continue
  1084. }
  1085. g.genInitM(obj, f)
  1086. }
  1087. }
  1088. if oinf != nil || len(cons) == 0 {
  1089. g.Printf("- (nonnull instancetype)init {\n")
  1090. g.Indent()
  1091. g.Printf("self = [super init];\n")
  1092. g.Printf("if (self) {\n")
  1093. g.Indent()
  1094. g.Printf("__ref = go_seq_from_refnum(new_%s_%s());\n", g.pkgPrefix, obj.Name())
  1095. g.Outdent()
  1096. g.Printf("}\n")
  1097. g.Printf("return self;\n")
  1098. g.Outdent()
  1099. g.Printf("}\n\n")
  1100. }
  1101. for _, f := range fields {
  1102. if !g.isSupported(f.Type()) {
  1103. g.Printf("// skipped unsupported field %s with type %s\n\n", f.Name(), f.Type())
  1104. continue
  1105. }
  1106. g.genGetter(obj.Name(), f)
  1107. g.genSetter(obj.Name(), f)
  1108. }
  1109. for _, m := range methods {
  1110. if !g.isSigSupported(m.Type()) {
  1111. g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name())
  1112. continue
  1113. }
  1114. s := g.funcSummary(obj, m)
  1115. g.Printf("- %s {\n", s.asMethod(g))
  1116. g.Indent()
  1117. g.genFunc(s, obj.Name())
  1118. g.Outdent()
  1119. g.Printf("}\n\n")
  1120. }
  1121. g.Printf("@end\n\n")
  1122. }
  1123. func (g *ObjcGen) genInitH(obj *types.TypeName, f *types.Func) {
  1124. s := g.funcSummary(obj, f)
  1125. doc := g.docs[f.Name()]
  1126. g.objcdoc(doc.Doc())
  1127. // custom inits can return nil in Go so make them nullable
  1128. g.Printf("- (nullable instancetype)%s%s;\n", s.initName, s.asInitSignature(g))
  1129. }
  1130. func (g *ObjcGen) genInitM(obj *types.TypeName, f *types.Func) {
  1131. s := g.funcSummary(obj, f)
  1132. g.Printf("- (instancetype)%s%s {\n", s.initName, s.asInitSignature(g))
  1133. g.Indent()
  1134. g.Printf("self = [super init];\n")
  1135. g.Printf("if (!self) return nil;\n")
  1136. for _, p := range s.params {
  1137. g.genWrite(p.name, p.typ, modeTransient)
  1138. }
  1139. // Constructors always return a mandatory *T and an optional error
  1140. if len(s.retParams) == 1 {
  1141. g.Printf("%s refnum = ", g.cgoType(s.retParams[0].typ))
  1142. } else {
  1143. g.Printf("struct proxy%s__%s_return res = ", g.pkgPrefix, s.goname)
  1144. }
  1145. g.Printf("proxy%s__%s(", g.pkgPrefix, s.goname)
  1146. for i, p := range s.params {
  1147. if i > 0 {
  1148. g.Printf(", ")
  1149. }
  1150. g.Printf("_%s", p.name)
  1151. }
  1152. g.Printf(");\n")
  1153. for _, p := range s.params {
  1154. g.genRelease(p.name, p.typ, modeTransient)
  1155. }
  1156. if len(s.retParams) == 2 {
  1157. g.Printf("int32_t refnum = res.r0;\n")
  1158. g.Printf("GoSeqRef *_err = go_seq_from_refnum(res.r1);\n")
  1159. }
  1160. g.Printf("__ref = go_seq_from_refnum(refnum);\n")
  1161. if len(s.retParams) == 2 {
  1162. g.Printf("if (_err != NULL)\n")
  1163. g.Printf(" return nil;\n")
  1164. }
  1165. g.Printf("return self;\n")
  1166. g.Outdent()
  1167. g.Printf("}\n\n")
  1168. }
  1169. func (g *ObjcGen) errorf(format string, args ...interface{}) {
  1170. g.err = append(g.err, fmt.Errorf(format, args...))
  1171. }
  1172. func (g *ObjcGen) refTypeBase(typ types.Type) string {
  1173. switch typ := typ.(type) {
  1174. case *types.Pointer:
  1175. if _, ok := typ.Elem().(*types.Named); ok {
  1176. return g.objcType(typ.Elem())
  1177. }
  1178. case *types.Named:
  1179. n := typ.Obj()
  1180. if isObjcType(typ) {
  1181. return g.wrapMap[n.Name()].Name
  1182. }
  1183. if isErrorType(typ) || g.validPkg(n.Pkg()) {
  1184. switch typ.Underlying().(type) {
  1185. case *types.Interface, *types.Struct:
  1186. return g.namePrefixOf(n.Pkg()) + n.Name()
  1187. }
  1188. }
  1189. }
  1190. // fallback to whatever objcType returns. This must not happen.
  1191. return g.objcType(typ)
  1192. }
  1193. func (g *ObjcGen) objcParamType(t types.Type) string {
  1194. switch typ := t.(type) {
  1195. case *types.Basic:
  1196. switch typ.Kind() {
  1197. case types.String, types.UntypedString:
  1198. return "NSString* _Nullable"
  1199. }
  1200. }
  1201. return g.objcType(t)
  1202. }
  1203. func (g *ObjcGen) objcType(typ types.Type) string {
  1204. if isErrorType(typ) {
  1205. return "NSError* _Nullable"
  1206. }
  1207. switch typ := typ.(type) {
  1208. case *types.Basic:
  1209. switch typ.Kind() {
  1210. case types.Bool, types.UntypedBool:
  1211. return "BOOL"
  1212. case types.Int:
  1213. return "long"
  1214. case types.Int8:
  1215. return "int8_t"
  1216. case types.Int16:
  1217. return "int16_t"
  1218. case types.Int32, types.UntypedRune: // types.Rune
  1219. return "int32_t"
  1220. case types.Int64, types.UntypedInt:
  1221. return "int64_t"
  1222. case types.Uint8:
  1223. // byte is an alias of uint8, and the alias is lost.
  1224. return "byte"
  1225. case types.Uint16:
  1226. return "uint16_t"
  1227. case types.Uint32:
  1228. return "uint32_t"
  1229. case types.Uint64:
  1230. return "uint64_t"
  1231. case types.Float32:
  1232. return "float"
  1233. case types.Float64, types.UntypedFloat:
  1234. return "double"
  1235. case types.String, types.UntypedString:
  1236. return "NSString* _Nonnull"
  1237. default:
  1238. g.errorf("unsupported type: %s", typ)
  1239. return "TODO"
  1240. }
  1241. case *types.Slice:
  1242. elem := g.objcType(typ.Elem())
  1243. // Special case: NSData seems to be a better option for byte slice.
  1244. if elem == "byte" {
  1245. return "NSData* _Nullable"
  1246. }
  1247. // TODO(hyangah): support other slice types: NSArray or CFArrayRef.
  1248. // Investigate the performance implication.
  1249. g.errorf("unsupported type: %s", typ)
  1250. return "TODO"
  1251. case *types.Pointer:
  1252. if _, ok := typ.Elem().(*types.Named); ok {
  1253. return g.objcType(typ.Elem()) + "* _Nullable"
  1254. }
  1255. g.errorf("unsupported pointer to type: %s", typ)
  1256. return "TODO"
  1257. case *types.Named:
  1258. n := typ.Obj()
  1259. if isObjcType(typ) {
  1260. w := g.wrapMap[n.Name()]
  1261. return w.ObjcType()
  1262. }
  1263. if !isErrorType(typ) && !g.validPkg(n.Pkg()) {
  1264. g.errorf("type %s is in package %s, which is not bound", n.Name(), n.Pkg().Name())
  1265. return "TODO"
  1266. }
  1267. switch t := typ.Underlying().(type) {
  1268. case *types.Interface:
  1269. if makeIfaceSummary(t).implementable {
  1270. return "id<" + g.namePrefixOf(n.Pkg()) + n.Name() + "> _Nullable"
  1271. } else {
  1272. return g.namePrefixOf(n.Pkg()) + n.Name() + "* _Nullable"
  1273. }
  1274. case *types.Struct:
  1275. return g.namePrefixOf(n.Pkg()) + n.Name()
  1276. }
  1277. g.errorf("unsupported, named type %s", typ)
  1278. return "TODO"
  1279. default:
  1280. g.errorf("unsupported type: %#+v, %s", typ, typ)
  1281. return "TODO"
  1282. }
  1283. }
  1284. // embeddedObjcTypes returns the possible empty list of Objc types embedded
  1285. // in the given struct type.
  1286. func embeddedObjcTypes(t *types.Struct) []string {
  1287. typeSet := make(map[string]struct{})
  1288. var typs []string
  1289. for i := 0; i < t.NumFields(); i++ {
  1290. f := t.Field(i)
  1291. if !f.Exported() {
  1292. continue
  1293. }
  1294. if ft := f.Type(); isObjcType(ft) {
  1295. name := ft.(*types.Named).Obj().Name()
  1296. if _, exists := typeSet[name]; !exists {
  1297. typeSet[name] = struct{}{}
  1298. typs = append(typs, name)
  1299. }
  1300. }
  1301. }
  1302. return typs
  1303. }
  1304. func isObjcType(t types.Type) bool {
  1305. return typePkgFirstElem(t) == "ObjC"
  1306. }
  1307. var objcNameReplacer = newNameSanitizer([]string{
  1308. "bool", "bycopy", "byref", "char", "const", "double", "float",
  1309. "id", "in", "init", "inout", "int", "long", "nil", "oneway",
  1310. "out", "self", "short", "signed", "super", "unsigned", "void",
  1311. "volatile"})
  1312. const (
  1313. objcPreamble = `// Objective-C API for talking to %[1]s Go package.
  1314. // gobind %[2]s %[3]s
  1315. //
  1316. // File is generated by gobind. Do not edit.
  1317. `
  1318. )