func()

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
}