in bind/genobjc.go [431:536]
func (g *ObjcGen) funcSummary(obj *types.TypeName, f *types.Func) *funcSummary {
sig := f.Type().(*types.Signature)
s := &funcSummary{goname: f.Name(), sig: sig}
var om *objc.Func
var sigElems []string
oinf := g.ostructs[obj]
if oinf != nil {
om = oinf.methods[f.Name()]
}
if om != nil {
sigElems = strings.Split(om.Sig, ":")
s.name = sigElems[0]
} else {
s.name = f.Name()
}
params := sig.Params()
first := 0
if oinf != nil {
if params.Len() > 0 {
v := params.At(0)
if v.Name() == "self" {
t := v.Type()
if t, ok := t.(*types.Named); ok {
if pkg := t.Obj().Pkg(); pkgFirstElem(pkg) == "ObjC" {
s.hasself = true
module := pkg.Path()[len("ObjC/"):]
typName := module + "." + t.Obj().Name()
exp := g.namePrefix + "." + obj.Name()
if typName != exp {
g.errorf("the type %s of the `this` argument to method %s is not %s", typName, f.Name(), exp)
}
}
}
}
}
}
for i := first; i < params.Len(); i++ {
p := params.At(i)
v := paramInfo{
typ: p.Type(),
}
if om != nil {
v.name = sigElems[i-first]
} else {
v.name = g.paramName(params, i)
}
s.params = append(s.params, v)
}
if obj != nil {
if pref := "New" + obj.Name(); strings.Index(f.Name(), pref) != -1 {
s.initName = "init" + f.Name()[len(pref):]
}
}
res := sig.Results()
switch res.Len() {
case 0:
s.ret = "void"
case 1:
p := res.At(0)
if isErrorType(p.Type()) {
s.retParams = append(s.retParams, paramInfo{
typ: p.Type(),
name: "error",
})
s.ret = "BOOL"
} else {
name := p.Name()
if name == "" || paramRE.MatchString(name) {
name = "ret0_"
}
typ := p.Type()
s.retParams = append(s.retParams, paramInfo{typ: typ, name: name})
s.ret = g.objcType(typ)
}
case 2:
name := res.At(0).Name()
if name == "" || paramRE.MatchString(name) {
name = "ret0_"
}
typ := res.At(0).Type()
s.retParams = append(s.retParams, paramInfo{
typ: typ,
name: name,
})
if isNullableType(typ) {
s.ret = g.objcType(typ) // Return is nullable, so satisfies the ObjC/Swift error protocol
} else {
s.ret = "BOOL" // Return is not nullable, must use an output parameter and return bool
}
if !isErrorType(res.At(1).Type()) {
g.errorf("second result value must be of type error: %s", f)
return nil
}
s.retParams = append(s.retParams, paramInfo{
typ: res.At(1).Type(),
name: "error", // TODO(hyangah): name collision check.
})
default:
// TODO(hyangah): relax the constraint on multiple return params.
g.errorf("too many result values: %s", f)
return nil
}
return s
}