Example #1
0
func createDef(obj types.Object, ident *ast.Ident, ctx *getDefinitionsContext, isType bool) *Definition {
	fullName := getFullName(obj, ctx, isType)

	if def, ok := ctx.defs[fullName]; ok {
		return def
	}

	def := new(Definition)
	def.Name = fullName
	def.Pkg = obj.Pkg()
	def.IsExported = obj.Exported()
	def.TypeOf = reflect.TypeOf(obj)
	def.SimpleName = obj.Name()
	def.Usages = make([]*Usage, 0)
	def.InterfacesDefs = make([]*Definition, 0)

	if ident != nil {
		position := ctx.fset.Position(ident.Pos())
		def.File = position.Filename
		def.Line = position.Line
		def.Offset = position.Offset
		def.Col = position.Column
	}

	if !types.IsInterface(obj.Type()) {
		fillInterfaces(def, obj, ctx)
	}

	ctx.defs[def.Name] = def
	logDefinition(def, obj, ident, ctx)

	return def
}
Example #2
0
func (b *candidateCollector) asCandidate(obj types.Object) Candidate {
	objClass := classifyObject(obj)
	var typ types.Type
	switch objClass {
	case "const", "func", "var":
		typ = obj.Type()
	case "type":
		typ = obj.Type().Underlying()
	}

	var typStr string
	switch t := typ.(type) {
	case *types.Interface:
		typStr = "interface"
	case *types.Struct:
		typStr = "struct"
	default:
		if _, isBuiltin := obj.(*types.Builtin); isBuiltin {
			typStr = builtinTypes[obj.Name()]
		} else if t != nil {
			typStr = types.TypeString(t, b.qualify)
		}
	}

	return Candidate{
		Class: objClass,
		Name:  obj.Name(),
		Type:  typStr,
	}
}
Example #3
0
func isStringer(obj types.Object) bool {
	switch obj := obj.(type) {
	case *types.Func:
		if obj.Name() != "String" {
			return false
		}
		sig, ok := obj.Type().(*types.Signature)
		if !ok {
			return false
		}
		if sig.Recv() == nil {
			return false
		}
		if sig.Params().Len() != 0 {
			return false
		}
		res := sig.Results()
		if res.Len() != 1 {
			return false
		}
		ret := res.At(0).Type()
		if ret != types.Universe.Lookup("string").Type() {
			return false
		}
		return true
	default:
		return false
	}

	return false
}
Example #4
0
func updateGetDefinitionsContext(ctx *getDefinitionsContext, def *Definition, ident *ast.Ident, obj types.Object) {
	switch obj.(type) {
	case *types.Var:
		//Processing vars later to be sure that all info about structs already filled
		ctx.vars = append(ctx.vars, newObjectWithIdent(obj, ident))
	case *types.Func:
		//Processing funcs later to be sure that all info about interfaces already filled
		ctx.funcs = append(ctx.funcs, newObjectWithIdent(obj, ident))
	case *types.TypeName:
		//If the underlying type is struct, then filling
		//positions of struct's fields (key) and struct name(value)
		//to map. Then we can extract struct name for fields when
		//will be analyze them.
		t := obj.(*types.TypeName)
		underlyingType := t.Type().Underlying()
		switch underlyingType.(type) {
		case *types.Struct:
			s := underlyingType.(*types.Struct)
			for i := 0; i < s.NumFields(); i++ {
				field := s.Field(i)
				ctx.structs[posToStr(ctx.fset, field.Pos())] = obj.Name()
			}
		}
	}

	//Check for interfaces
	underlyingType := obj.Type().Underlying()
	switch underlyingType.(type) {
	case *types.Interface:
		d := new(defWithInterface)
		d.def = def
		d.interfac = underlyingType.(*types.Interface)
		ctx.interfaces = append(ctx.interfaces, d)
	}
}
Example #5
0
// equalObj reports how x and y differ.  They are assumed to belong to
// different universes so cannot be compared directly.
func equalObj(x, y types.Object) error {
	if reflect.TypeOf(x) != reflect.TypeOf(y) {
		return fmt.Errorf("%T vs %T", x, y)
	}
	xt := x.Type()
	yt := y.Type()
	switch x.(type) {
	case *types.Var, *types.Func:
		// ok
	case *types.Const:
		xval := x.(*types.Const).Val()
		yval := y.(*types.Const).Val()
		// Use string comparison for floating-point values since rounding is permitted.
		if constant.Compare(xval, token.NEQ, yval) &&
			!(xval.Kind() == constant.Float && xval.String() == yval.String()) {
			return fmt.Errorf("unequal constants %s vs %s", xval, yval)
		}
	case *types.TypeName:
		xt = xt.Underlying()
		yt = yt.Underlying()
	default:
		return fmt.Errorf("unexpected %T", x)
	}
	return equalType(xt, yt)
}
Example #6
0
//getFullName is returning unique name of obj.
func getFullName(obj types.Object, ctx *getDefinitionsContext, isType bool) string {
	if obj == nil {
		return ""
	}
	if isType {
		return obj.Type().String()
	}

	result := ""

	switch obj.(type) {
	case *types.Func:
		f := obj.(*types.Func)
		r := strings.NewReplacer("(", "", "*", "", ")", "")
		result = r.Replace(f.FullName())
	default:
		if obj.Pkg() != nil {
			result += obj.Pkg().Path()
			result += "."
		}

		if packageName, ok := ctx.structs[posToStr(ctx.fset, obj.Pos())]; ok {
			result += packageName
			result += "."
		}
		result += obj.Name()
	}

	return result
}
Example #7
0
func (f *Function) addParamObj(obj types.Object) *Parameter {
	name := obj.Name()
	if name == "" {
		name = fmt.Sprintf("arg%d", len(f.Params))
	}
	param := f.addParam(name, obj.Type(), obj.Pos())
	param.object = obj
	return param
}
Example #8
0
// addSpilledParam declares a parameter that is pre-spilled to the
// stack; the function body will load/store the spilled location.
// Subsequent lifting will eliminate spills where possible.
//
func (f *Function) addSpilledParam(obj types.Object) {
	param := f.addParamObj(obj)
	spill := &Alloc{Comment: obj.Name()}
	spill.setType(types.NewPointer(obj.Type()))
	spill.setPos(obj.Pos())
	f.objects[obj] = spill
	f.Locals = append(f.Locals, spill)
	f.emit(spill)
	f.emit(&Store{Addr: spill, Val: param})
}
Example #9
0
func formatMember(obj types.Object, maxname int) string {
	qualifier := types.RelativeTo(obj.Pkg())
	var buf bytes.Buffer
	fmt.Fprintf(&buf, "%-5s %-*s", tokenOf(obj), maxname, obj.Name())
	switch obj := obj.(type) {
	case *types.Const:
		fmt.Fprintf(&buf, " %s = %s", types.TypeString(obj.Type(), qualifier), obj.Val().String())

	case *types.Func:
		fmt.Fprintf(&buf, " %s", types.TypeString(obj.Type(), qualifier))

	case *types.TypeName:
		// Abbreviate long aggregate type names.
		var abbrev string
		switch t := obj.Type().Underlying().(type) {
		case *types.Interface:
			if t.NumMethods() > 1 {
				abbrev = "interface{...}"
			}
		case *types.Struct:
			if t.NumFields() > 1 {
				abbrev = "struct{...}"
			}
		}
		if abbrev == "" {
			fmt.Fprintf(&buf, " %s", types.TypeString(obj.Type().Underlying(), qualifier))
		} else {
			fmt.Fprintf(&buf, " %s", abbrev)
		}

	case *types.Var:
		fmt.Fprintf(&buf, " %s", types.TypeString(obj.Type(), qualifier))
	}
	return buf.String()
}
Example #10
0
func (p *exporter) obj(obj types.Object) {
	if trace {
		p.tracef("object %s {\n", obj.Name())
		defer p.tracef("}\n")
	}

	switch obj := obj.(type) {
	case *types.Const:
		p.int(constTag)
		p.string(obj.Name())
		p.typ(obj.Type())
		p.value(obj.Val())
	case *types.TypeName:
		p.int(typeTag)
		// name is written by corresponding named type
		p.typ(obj.Type().(*types.Named))
	case *types.Var:
		p.int(varTag)
		p.string(obj.Name())
		p.typ(obj.Type())
	case *types.Func:
		p.int(funcTag)
		p.string(obj.Name())
		p.typ(obj.Type())
	default:
		panic(fmt.Sprintf("unexpected object type %T", obj))
	}
}
Example #11
0
func (p *exporter) obj(obj types.Object) {
	switch obj := obj.(type) {
	case *types.Const:
		p.tag(constTag)
		p.pos(obj)
		p.qualifiedName(obj)
		p.typ(obj.Type())
		p.value(obj.Val())

	case *types.TypeName:
		p.tag(typeTag)
		p.typ(obj.Type())

	case *types.Var:
		p.tag(varTag)
		p.pos(obj)
		p.qualifiedName(obj)
		p.typ(obj.Type())

	case *types.Func:
		p.tag(funcTag)
		p.pos(obj)
		p.qualifiedName(obj)
		sig := obj.Type().(*types.Signature)
		p.paramList(sig.Params(), sig.Variadic())
		p.paramList(sig.Results(), false)

	default:
		log.Fatalf("gcimporter: unexpected object %v (%T)", obj, obj)
	}
}
Example #12
0
func (w *Walker) emitObj(obj types.Object) {
	switch obj := obj.(type) {
	case *types.Const:
		w.emitf("const %s %s", obj.Name(), w.typeString(obj.Type()))
		w.emitf("const %s = %s", obj.Name(), obj.Val())
	case *types.Var:
		w.emitf("var %s %s", obj.Name(), w.typeString(obj.Type()))
	case *types.TypeName:
		w.emitType(obj)
	case *types.Func:
		w.emitFunc(obj)
	default:
		panic("unknown object: " + obj.String())
	}
}
Example #13
0
func addInterface(obj types.Object, ident *ast.Ident, ctx *getDefinitionsContext) {
	interfac := obj.Type().Underlying().(*types.Interface)

	def := createDef(obj, ident, ctx, true)
	updateGetDefinitionsContext(ctx, def, ident, obj)

	util.Debug("adding interface [%s] [%v] [%v] [%v]", def.Name, def.Pkg, obj.Type().Underlying(), obj.Type())
	//Adding all methods of interface
	for i := 0; i < interfac.NumMethods(); i++ {
		f := interfac.Method(i)
		def := createDef(f, nil, ctx, false)
		util.Debug("\tadding method [%v] [%s]", f, def.Name)
		updateGetDefinitionsContext(ctx, def, ident, f)
	}
}
Example #14
0
func (p *printer) printObj(obj types.Object) {
	p.print(obj.Name())

	typ, basic := obj.Type().Underlying().(*types.Basic)
	if basic && typ.Info()&types.IsUntyped != 0 {
		// don't write untyped types
	} else {
		p.print(" ")
		p.writeType(p.pkg, obj.Type())
	}

	if obj, ok := obj.(*types.Const); ok {
		floatFmt := basic && typ.Info()&(types.IsFloat|types.IsComplex) != 0
		p.print(" = ")
		p.print(valString(obj.Val(), floatFmt))
	}
}
Example #15
0
func newFuncFrom(p *Package, parent string, obj types.Object, sig *types.Signature) (Func, error) {
	haserr := false
	res := sig.Results()
	var ret types.Type

	switch res.Len() {
	case 2:
		if !isErrorType(res.At(1).Type()) {
			return Func{}, fmt.Errorf(
				"bind: second result value must be of type error: %s",
				obj,
			)
		}
		haserr = true
		ret = res.At(0).Type()

	case 1:
		if isErrorType(res.At(0).Type()) {
			haserr = true
			ret = nil
		} else {
			ret = res.At(0).Type()
		}
	case 0:
		ret = nil
	default:
		return Func{}, fmt.Errorf("bind: too many results to return: %v", obj)
	}

	id := obj.Pkg().Name() + "_" + obj.Name()
	if parent != "" {
		id = obj.Pkg().Name() + "_" + parent + "_" + obj.Name()
	}

	return Func{
		pkg:  p,
		sig:  newSignatureFrom(p, sig),
		typ:  obj.Type(),
		name: obj.Name(),
		id:   id,
		doc:  p.getDoc(parent, obj),
		ret:  ret,
		err:  haserr,
	}, nil
}
Example #16
0
func objectKind(obj types.Object) string {
	switch obj := obj.(type) {
	case *types.PkgName:
		return "imported package name"
	case *types.TypeName:
		return "type"
	case *types.Var:
		if obj.IsField() {
			return "field"
		}
	case *types.Func:
		if obj.Type().(*types.Signature).Recv() != nil {
			return "method"
		}
	}
	// label, func, var, const
	return strings.ToLower(strings.TrimPrefix(reflect.TypeOf(obj).String(), "*types."))
}
Example #17
0
func (sym *symtab) addSymbol(obj types.Object) {
	fn := types.ObjectString(obj, nil)
	n := obj.Name()
	pkg := obj.Pkg()
	id := n
	if pkg != nil {
		id = pkg.Name() + "_" + n
	}
	switch obj.(type) {
	case *types.Const:
		sym.syms[fn] = &symbol{
			gopkg:   pkg,
			goobj:   obj,
			kind:    skConst,
			id:      id,
			goname:  n,
			cgoname: "cgo_const_" + id,
			cpyname: "cpy_const_" + id,
		}
		sym.addType(obj, obj.Type())

	case *types.Var:
		sym.syms[fn] = &symbol{
			gopkg:   pkg,
			goobj:   obj,
			kind:    skVar,
			id:      id,
			goname:  n,
			cgoname: "cgo_var_" + id,
			cpyname: "cpy_var_" + id,
		}
		sym.addType(obj, obj.Type())

	case *types.Func:
		sym.syms[fn] = &symbol{
			gopkg:   pkg,
			goobj:   obj,
			kind:    skFunc,
			id:      id,
			goname:  n,
			cgoname: "cgo_func_" + id,
			cpyname: "cpy_func_" + id,
		}
		sig := obj.Type().Underlying().(*types.Signature)
		sym.processTuple(sig.Params())
		sym.processTuple(sig.Results())

	case *types.TypeName:
		sym.addType(obj, obj.Type())

	default:
		panic(fmt.Errorf("gopy: handled object [%#v]", obj))
	}
}
Example #18
0
func (w *Walker) emitObj(obj types.Object) {
	switch obj := obj.(type) {
	case *types.Const:
		w.emitf("const %s %s", obj.Name(), w.typeString(obj.Type()))
		x := obj.Val()
		short := x.String()
		exact := x.ExactString()
		if short == exact {
			w.emitf("const %s = %s", obj.Name(), short)
		} else {
			w.emitf("const %s = %s  // %s", obj.Name(), short, exact)
		}
	case *types.Var:
		w.emitf("var %s %s", obj.Name(), w.typeString(obj.Type()))
	case *types.TypeName:
		w.emitType(obj)
	case *types.Func:
		w.emitFunc(obj)
	default:
		panic("unknown object: " + obj.String())
	}
}
Example #19
0
// memberFromObject populates package pkg with a member for the
// typechecker object obj.
//
// For objects from Go source code, syntax is the associated syntax
// tree (for funcs and vars only); it will be used during the build
// phase.
//
func memberFromObject(pkg *Package, obj types.Object, syntax ast.Node) {
	name := obj.Name()
	switch obj := obj.(type) {
	case *types.TypeName:
		pkg.Members[name] = &Type{
			object: obj,
			pkg:    pkg,
		}

	case *types.Const:
		c := &NamedConst{
			object: obj,
			Value:  NewConst(obj.Val(), obj.Type()),
			pkg:    pkg,
		}
		pkg.values[obj] = c.Value
		pkg.Members[name] = c

	case *types.Var:
		g := &Global{
			Pkg:    pkg,
			name:   name,
			object: obj,
			typ:    types.NewPointer(obj.Type()), // address
			pos:    obj.Pos(),
		}
		pkg.values[obj] = g
		pkg.Members[name] = g

	case *types.Func:
		sig := obj.Type().(*types.Signature)
		if sig.Recv() == nil && name == "init" {
			pkg.ninit++
			name = fmt.Sprintf("init#%d", pkg.ninit)
		}
		fn := &Function{
			name:      name,
			object:    obj,
			Signature: sig,
			syntax:    syntax,
			pos:       obj.Pos(),
			Pkg:       pkg,
			Prog:      pkg.Prog,
		}
		if syntax == nil {
			fn.Synthetic = "loaded from gc object file"
		}

		pkg.values[obj] = fn
		if sig.Recv() == nil {
			pkg.Members[name] = fn // package-level function
		}

	default: // (incl. *types.Package)
		panic("unexpected Object type: " + obj.String())
	}
}
Example #20
0
func (p *exporter) obj(obj types.Object) {
	switch obj := obj.(type) {
	case *types.Const:
		p.tag(constTag)
		p.pos(obj)
		p.qualifiedName(obj)
		p.typ(obj.Type())
		p.value(obj.Val())

	case *types.TypeName:
		p.tag(typeTag)
		p.typ(obj.Type())

	case *types.Var:
		p.tag(varTag)
		p.pos(obj)
		p.qualifiedName(obj)
		p.typ(obj.Type())

	case *types.Func:
		p.tag(funcTag)
		p.pos(obj)
		p.qualifiedName(obj)
		sig := obj.Type().(*types.Signature)
		p.paramList(sig.Params(), sig.Variadic())
		p.paramList(sig.Results(), false)

	// Alias-related code. Keep for now.
	// case *types_Alias:
	// 	// make sure the original is exported before the alias
	// 	// (if the alias declaration was invalid, orig will be nil)
	// 	orig := original(obj)
	// 	if orig != nil && !p.reexported[orig] {
	// 		p.obj(orig)
	// 		p.reexported[orig] = true
	// 	}

	// 	p.tag(aliasTag)
	// 	p.pos(obj)
	// 	p.string(obj.Name())
	// 	p.qualifiedName(orig)

	default:
		log.Fatalf("gcimporter: unexpected object %v (%T)", obj, obj)
	}
}
Example #21
0
// getDoc returns the doc string associated with types.Object
// parent is the name of the containing scope ("" for global scope)
func (p *Package) getDoc(parent string, o types.Object) string {
	n := o.Name()
	switch o.(type) {
	case *types.Const:
		for _, c := range p.doc.Consts {
			for _, cn := range c.Names {
				if n == cn {
					return c.Doc
				}
			}
		}

	case *types.Var:
		for _, v := range p.doc.Vars {
			for _, vn := range v.Names {
				if n == vn {
					return v.Doc
				}
			}
		}

	case *types.Func:
		doc := func() string {
			if o.Parent() == nil || (o.Parent() != nil && parent != "") {
				for _, typ := range p.doc.Types {
					if typ.Name != parent {
						continue
					}
					if o.Parent() == nil {
						for _, m := range typ.Methods {
							if m.Name == n {
								return m.Doc
							}
						}
					} else {
						for _, m := range typ.Funcs {
							if m.Name == n {
								return m.Doc
							}
						}
					}
				}
			} else {
				for _, f := range p.doc.Funcs {
					if n == f.Name {
						return f.Doc
					}
				}
			}
			return ""
		}()

		sig := o.Type().(*types.Signature)

		parseFn := func(tup *types.Tuple) []string {
			params := []string{}
			if tup == nil {
				return params
			}
			for i := 0; i < tup.Len(); i++ {
				paramVar := tup.At(i)
				paramType := p.syms.symtype(paramVar.Type()).pysig
				if paramVar.Name() != "" {
					paramType = fmt.Sprintf("%s %s", paramType, paramVar.Name())
				}
				params = append(params, paramType)
			}
			return params
		}

		params := parseFn(sig.Params())
		results := parseFn(sig.Results())

		paramString := strings.Join(params, ", ")
		resultString := strings.Join(results, ", ")

		//FIXME(sbinet): add receiver for methods?
		docSig := fmt.Sprintf("%s(%s) %s", o.Name(), paramString, resultString)

		if doc != "" {
			doc = fmt.Sprintf("%s\n\n%s", docSig, doc)
		} else {
			doc = docSig
		}
		return doc

	case *types.TypeName:
		for _, t := range p.doc.Types {
			if n == t.Name {
				return t.Doc
			}
		}

	default:
		// TODO(sbinet)
		panic(fmt.Errorf("not yet supported: %v (%T)", o, o))
	}

	return ""
}
Example #22
0
func sameObj(a, b types.Object) bool {
	// Because unnamed types are not canonicalized, we cannot simply compare types for
	// (pointer) identity.
	// Ideally we'd check equality of constant values as well, but this is good enough.
	return objTag(a) == objTag(b) && types.Identical(a.Type(), b.Type())
}
Example #23
0
func (g *cpyGen) genStructMemberSetter(cpy Struct, i int, f types.Object) {
	var (
		pkg          = cpy.Package()
		ft           = f.Type()
		self         = newVar(pkg, cpy.GoType(), cpy.GoName(), "self", "")
		ifield       = newVar(pkg, ft, f.Name(), "ret", "")
		cgo_fsetname = fmt.Sprintf("cgo_func_%[1]s_setter_%[2]d", cpy.sym.id, i+1)
		cpy_fsetname = fmt.Sprintf("cpy_func_%[1]s_setter_%[2]d", cpy.sym.id, i+1)
	)

	g.decl.Printf("\n/* setter for %[1]s.%[2]s.%[3]s */\n",
		pkg.Name(), cpy.sym.goname, f.Name(),
	)

	g.decl.Printf("static int\n")
	g.decl.Printf(
		"%[2]s(%[1]s *self, PyObject *value, void *closure);\n",
		cpy.sym.cpyname,
		cpy_fsetname,
	)

	g.impl.Printf("\n/* setter for %[1]s.%[2]s.%[3]s */\n",
		pkg.Name(), cpy.sym.goname, f.Name(),
	)
	g.impl.Printf("static int\n")
	g.impl.Printf(
		"%[2]s(%[1]s *self, PyObject *value, void *closure) {\n",
		cpy.sym.cpyname,
		cpy_fsetname,
	)
	g.impl.Indent()

	ifield.genDecl(g.impl)
	g.impl.Printf("if (value == NULL) {\n")
	g.impl.Indent()
	g.impl.Printf(
		"PyErr_SetString(PyExc_TypeError, \"cannot delete '%[1]s' attribute\");\n",
		f.Name(),
	)
	g.impl.Printf("return -1;\n")
	g.impl.Outdent()
	g.impl.Printf("}\n\n")

	g.impl.Printf("if (!%s) {\n", fmt.Sprintf(ifield.sym.pychk, "value"))
	g.impl.Indent()
	g.impl.Printf(
		"PyErr_SetString(PyExc_TypeError, \"invalid type for '%[1]s' attribute\");\n",
		f.Name(),
	)
	g.impl.Printf("return -1;\n")
	g.impl.Outdent()
	g.impl.Printf("}\n\n")

	g.impl.Printf("if (!%[1]s(value, &c_ret)) {\n", ifield.sym.py2c)
	g.impl.Indent()
	g.impl.Printf("return -1;\n")
	g.impl.Outdent()
	g.impl.Printf("}\n\n")

	g.impl.Printf("%[1]s((%[2]s)(self->cgopy), c_%[3]s);\n",
		cgo_fsetname,
		self.CGoType(),
		ifield.Name(),
	)

	g.impl.Printf("return 0;\n")
	g.impl.Outdent()
	g.impl.Printf("}\n\n")
}
Example #24
0
func (g *cpyGen) genStructMemberGetter(cpy Struct, i int, f types.Object) {
	pkg := cpy.Package()
	ft := f.Type()
	var (
		cgo_fgetname = fmt.Sprintf("cgo_func_%[1]s_getter_%[2]d", cpy.sym.id, i+1)
		cpy_fgetname = fmt.Sprintf("cpy_func_%[1]s_getter_%[2]d", cpy.sym.id, i+1)
		ifield       = newVar(pkg, ft, f.Name(), "ret", "")
		results      = []*Var{ifield}
	)

	if needWrapType(ft) {
		g.decl.Printf("\n/* wrapper for field %s.%s.%s */\n",
			pkg.Name(),
			cpy.GoName(),
			f.Name(),
		)
		g.decl.Printf("typedef void* %[1]s_field_%d;\n", cpy.sym.cgoname, i+1)
	}

	g.decl.Printf("\n/* getter for %[1]s.%[2]s.%[3]s */\n",
		pkg.Name(), cpy.sym.goname, f.Name(),
	)
	g.decl.Printf("static PyObject*\n")
	g.decl.Printf(
		"%[2]s(%[1]s *self, void *closure); /* %[3]s */\n",
		cpy.sym.cpyname,
		cpy_fgetname,
		f.Name(),
	)

	g.impl.Printf("\n/* getter for %[1]s.%[2]s.%[3]s */\n",
		pkg.Name(), cpy.sym.goname, f.Name(),
	)
	g.impl.Printf("static PyObject*\n")
	g.impl.Printf(
		"%[2]s(%[1]s *self, void *closure) /* %[3]s */ {\n",
		cpy.sym.cpyname,
		cpy_fgetname,
		f.Name(),
	)
	g.impl.Indent()

	g.impl.Printf("PyObject *o = NULL;\n")
	ftname := g.pkg.syms.symtype(ft).cgoname
	if needWrapType(ft) {
		ftname = fmt.Sprintf("%[1]s_field_%d", cpy.sym.cgoname, i+1)
	}
	g.impl.Printf(
		"%[1]s c_ret = %[2]s(self->cgopy); /*wrap*/\n",
		ftname,
		cgo_fgetname,
	)

	{
		format := []string{}
		funcArgs := []string{}
		switch len(results) {
		case 1:
			ret := results[0]
			ret.name = "ret"
			pyfmt, pyaddrs := ret.getArgBuildValue()
			format = append(format, pyfmt)
			funcArgs = append(funcArgs, pyaddrs...)
		default:
			panic("bind: impossible")
		}
		g.impl.Printf("o = Py_BuildValue(%q, %s);\n",
			strings.Join(format, ""),
			strings.Join(funcArgs, ", "),
		)
	}

	g.impl.Printf("return o;\n")
	g.impl.Outdent()
	g.impl.Printf("}\n\n")

}
Example #25
0
// addNamedLocal creates a local variable, adds it to function f and
// returns it.  Its name and type are taken from obj.  Subsequent
// calls to f.lookup(obj) will return the same local.
//
func (f *Function) addNamedLocal(obj types.Object) *Alloc {
	l := f.addLocal(obj.Type(), obj.Pos())
	l.Comment = obj.Name()
	f.objects[obj] = l
	return l
}