Beispiel #1
0
func (x *exporter) export(pkg *types.Package) error {
	x.pkg = pkg
	x.writeFunc = true
	exportsFile := packageExportsFile(x.context, pkg.Path())
	err := os.MkdirAll(filepath.Dir(exportsFile), 0755)
	if err != nil && !os.IsExist(err) {
		return err
	}
	f2, err := os.Create(exportsFile)
	if err != nil {
		return err
	}
	defer f2.Close()
	x.writer = f2
	x.write("package %s\n", pkg.Name())
	for _, imp := range pkg.Imports() {
		x.write("\timport %s \"%s\"\n", imp.Name(), imp.Path())
	}
	for _, n := range pkg.Scope().Names() {
		if obj := pkg.Scope().Lookup(n); obj != nil {
			x.exportObject(obj)
		}
	}
	x.write("$$")
	return nil
}
Beispiel #2
0
func describePackage(o *Oracle, qpos *QueryPos, path []ast.Node) (*describePackageResult, error) {
	var description string
	var pkg *types.Package
	switch n := path[0].(type) {
	case *ast.ImportSpec:
		var pkgname *types.PkgName
		if n.Name != nil {
			pkgname = qpos.info.Defs[n.Name].(*types.PkgName)
		} else if p := qpos.info.Implicits[n]; p != nil {
			pkgname = p.(*types.PkgName)
		}
		description = fmt.Sprintf("import of package %q", pkgname.Pkg().Path())
		pkg = pkgname.Pkg()

	case *ast.Ident:
		if _, isDef := path[1].(*ast.File); isDef {
			// e.g. package id
			pkg = qpos.info.Pkg
			description = fmt.Sprintf("definition of package %q", pkg.Path())
		} else {
			// e.g. import id "..."
			//  or  id.F()
			pkg = qpos.info.ObjectOf(n).Pkg()
			description = fmt.Sprintf("reference to package %q", pkg.Path())
		}

	default:
		// Unreachable?
		return nil, fmt.Errorf("unexpected AST for package: %T", n)
	}

	var members []*describeMember
	// NB: "unsafe" has no types.Package
	if pkg != nil {
		// Enumerate the accessible package members
		// in lexicographic order.
		for _, name := range pkg.Scope().Names() {
			if pkg == qpos.info.Pkg || ast.IsExported(name) {
				mem := pkg.Scope().Lookup(name)
				var methods []*types.Selection
				if mem, ok := mem.(*types.TypeName); ok {
					methods = accessibleMethods(mem.Type(), qpos.info.Pkg)
				}
				members = append(members, &describeMember{
					mem,
					methods,
				})

			}
		}
	}

	return &describePackageResult{o.fset, path[0], description, pkg, members}, nil
}
func declTypeName(pkg *types.Package, name string) *types.TypeName {
	scope := pkg.Scope()
	if obj := scope.Lookup(name); obj != nil {
		return obj.(*types.TypeName)
	}
	obj := types.NewTypeName(token.NoPos, pkg, name, nil)
	// a named type may be referred to before the underlying type
	// is known - set it up
	types.NewNamed(obj, nil, nil)
	scope.Insert(obj)
	return obj
}
Beispiel #4
0
func assocObjectPackages(pkg *types.Package, objectdata map[types.Object]*ObjectData) {
	for _, obj := range pkg.Scope().Entries {
		if data, ok := objectdata[obj]; ok {
			data.Package = pkg
		} else {
			objectdata[obj] = &ObjectData{Package: pkg}
		}
	}
	for _, pkg := range pkg.Imports() {
		assocObjectPackages(pkg, objectdata)
	}
}
Beispiel #5
0
func describePackage(o *Oracle, qpos *QueryPos, path []ast.Node) (*describePackageResult, error) {
	var description string
	var pkg *types.Package
	switch n := path[0].(type) {
	case *ast.ImportSpec:
		// Most ImportSpecs have no .Name Ident so we can't
		// use ObjectOf.
		// We could use the types.Info.Implicits mechanism,
		// but it's easier just to look it up by name.
		description = "import of package " + n.Path.Value
		importPath, _ := strconv.Unquote(n.Path.Value)
		pkg = o.prog.ImportedPackage(importPath).Object

	case *ast.Ident:
		if _, isDef := path[1].(*ast.File); isDef {
			// e.g. package id
			pkg = qpos.info.Pkg
			description = fmt.Sprintf("definition of package %q", pkg.Path())
		} else {
			// e.g. import id
			//  or  id.F()
			pkg = qpos.info.ObjectOf(n).Pkg()
			description = fmt.Sprintf("reference to package %q", pkg.Path())
		}

	default:
		// Unreachable?
		return nil, fmt.Errorf("unexpected AST for package: %T", n)
	}

	var members []*describeMember
	// NB: "unsafe" has no types.Package
	if pkg != nil {
		// Enumerate the accessible package members
		// in lexicographic order.
		for _, name := range pkg.Scope().Names() {
			if pkg == qpos.info.Pkg || ast.IsExported(name) {
				mem := pkg.Scope().Lookup(name)
				var methods []*types.Selection
				if mem, ok := mem.(*types.TypeName); ok {
					methods = accessibleMethods(mem.Type(), qpos.info.Pkg)
				}
				members = append(members, &describeMember{
					mem,
					methods,
				})

			}
		}
	}

	return &describePackageResult{o.prog.Fset, path[0], description, pkg, members}, nil
}
Beispiel #6
0
// pkgString returns a string representation of a package's exported interface.
func pkgString(pkg *types.Package) string {
	var buf bytes.Buffer

	fmt.Fprintf(&buf, "package %s\n", pkg.Name())

	scope := pkg.Scope()
	for _, name := range scope.Names() {
		if exported(name) {
			obj := scope.Lookup(name)
			buf.WriteString(obj.String())

			switch obj := obj.(type) {
			case *types.Const:
				// For now only print constant values if they are not float
				// or complex. This permits comparing go/types results with
				// gc-generated gcimported package interfaces.
				info := obj.Type().Underlying().(*types.Basic).Info()
				if info&types.IsFloat == 0 && info&types.IsComplex == 0 {
					fmt.Fprintf(&buf, " = %s", obj.Val())
				}

			case *types.TypeName:
				// Print associated methods.
				// Basic types (e.g., unsafe.Pointer) have *types.Basic
				// type rather than *types.Named; so we need to check.
				if typ, _ := obj.Type().(*types.Named); typ != nil {
					if n := typ.NumMethods(); n > 0 {
						// Sort methods by name so that we get the
						// same order independent of whether the
						// methods got imported or coming directly
						// for the source.
						// TODO(gri) This should probably be done
						// in go/types.
						list := make([]*types.Func, n)
						for i := 0; i < n; i++ {
							list[i] = typ.Method(i)
						}
						sort.Sort(byName(list))

						buf.WriteString("\nmethods (\n")
						for _, m := range list {
							fmt.Fprintf(&buf, "\t%s\n", m)
						}
						buf.WriteString(")")
					}
				}
			}
			buf.WriteByte('\n')
		}
	}

	return buf.String()
}
Beispiel #7
0
func (ctx *Context) getObjects(paths []string) ([]types.Object, []error) {
	var errors []error
	var objects []types.Object

pathLoop:
	for _, path := range paths {
		buildPkg, err := build.Import(path, ".", 0)
		if err != nil {
			errors = append(errors, fmt.Errorf("Couldn't import %s: %s", path, err))
			continue
		}
		fset := token.NewFileSet()
		var astFiles []*ast.File
		var pkg *types.Package
		if buildPkg.Goroot {
			// TODO what if the compiled package in GoRoot is
			// outdated?
			pkg, err = types.GcImport(ctx.allImports, path)
			if err != nil {
				errors = append(errors, fmt.Errorf("Couldn't import %s: %s", path, err))
				continue
			}
		} else {
			if len(buildPkg.GoFiles) == 0 {
				errors = append(errors, fmt.Errorf("Couldn't parse %s: No (non cgo) Go files", path))
				continue pathLoop
			}
			for _, file := range buildPkg.GoFiles {
				astFile, err := parseFile(fset, filepath.Join(buildPkg.Dir, file))
				if err != nil {
					errors = append(errors, fmt.Errorf("Couldn't parse %s: %s", err))
					continue pathLoop
				}
				astFiles = append(astFiles, astFile)
			}
			pkg, err = check(ctx, path, fset, astFiles)
			if err != nil {
				errors = append(errors, fmt.Errorf("Couldn't parse %s: %s\n", path, err))
				continue pathLoop
			}
		}

		scope := pkg.Scope()
		for i := 0; i < scope.NumEntries(); i++ {
			obj := scope.At(i)
			objects = append(objects, obj)
		}
	}

	return objects, errors
}
Beispiel #8
0
// export emits the exported package features.
func (w *Walker) export(pkg *types.Package) {
	if *verbose {
		log.Println(pkg)
	}
	pop := w.pushScope("pkg " + pkg.Path())
	w.current = pkg
	scope := pkg.Scope()
	for _, name := range scope.Names() {
		if ast.IsExported(name) {
			w.emitObj(scope.Lookup(name))
		}
	}
	pop()
}
Beispiel #9
0
func assocObjectPackages(pkg *types.Package, objectdata map[types.Object]*ObjectData) {
	scope := pkg.Scope()
	for _, name := range scope.Names() {
		obj := scope.Lookup(name)
		if data, ok := objectdata[obj]; ok {
			data.Package = pkg
		} else {
			objectdata[obj] = &ObjectData{Package: pkg}
		}
	}
	for _, pkg := range pkg.Imports() {
		assocObjectPackages(pkg, objectdata)
	}
}
Beispiel #10
0
func FindImplentations(i *types.Interface, pkg *types.Package) []string {
	var names []string

	scope := pkg.Scope()
	allNames := scope.Names()

	for _, name := range allNames {
		obj := scope.Lookup(name)
		if typeName, ok := obj.(*types.TypeName); ok {
			if types.Implements(typeName.Type(), i) {
				names = append(names, typeName.Name())
			} else {
				println(typeName.Name(), "cannot be an ensurer")
				println(types.NewMethodSet(typeName.Type()).String())
			}
		}
	}

	return names
}
Beispiel #11
0
func (p *importer) obj(pkg *types.Package) {
	var obj types.Object
	switch tag := p.int(); tag {
	case constTag:
		obj = types.NewConst(token.NoPos, pkg, p.string(), p.typ(), p.value())
	case typeTag:
		// type object is added to scope via respective named type
		_ = p.typ().(*types.Named)
		return
	case varTag:
		obj = types.NewVar(token.NoPos, pkg, p.string(), p.typ())
	case funcTag:
		obj = types.NewFunc(token.NoPos, pkg, p.string(), p.typ().(*types.Signature))
	default:
		panic(fmt.Sprintf("unexpected object tag %d", tag))
	}

	if alt := pkg.Scope().Insert(obj); alt != nil {
		panic(fmt.Sprintf("%s already declared", alt.Name()))
	}
}
Beispiel #12
0
// ExportData serializes the interface (exported package objects)
// of package pkg and returns the corresponding data. The export
// format is described elsewhere (TODO).
func ExportData(pkg *types.Package) []byte {
	p := exporter{
		data:     []byte(magic),
		pkgIndex: make(map[*types.Package]int),
		typIndex: make(map[types.Type]int),
	}

	// populate typIndex with predeclared types
	for _, t := range types.Typ[1:] {
		p.typIndex[t] = len(p.typIndex)
	}
	p.typIndex[types.Universe.Lookup("error").Type()] = len(p.typIndex)

	if trace {
		p.tracef("export %s\n", pkg.Name())
		defer p.tracef("\n")
	}

	p.string(version)

	p.pkg(pkg)

	// collect exported objects from package scope
	var list []types.Object
	scope := pkg.Scope()
	for _, name := range scope.Names() {
		if exported(name) {
			list = append(list, scope.Lookup(name))
		}
	}

	// write objects
	p.int(len(list))
	for _, obj := range list {
		p.obj(obj)
	}

	return p.data
}
Beispiel #13
0
func (c *exporter) Export(pkg *types.Package) error {
	c.pkg = pkg
	c.writeFunc = true
	f2, err := os.Create(c.compiler.packageExportsFile(pkg.Path()))
	if err != nil {
		return err
	}
	defer f2.Close()
	c.writer = f2
	c.write("package %s\n", pkg.Name())
	for _, imp := range c.pkg.Imports() {
		c.write("\timport %s \"%s\"\n", imp.Name(), imp.Path())
	}

	for _, n := range pkg.Scope().Names() {
		if obj := pkg.Scope().Lookup(n); obj != nil {
			c.exportObject(obj)
		}
	}

	c.write("$$")
	return nil
}
Beispiel #14
0
func newRuntimeInterface(pkg *types.Package, module llvm.Module, tm *llvmTypeMap, fr FuncResolver) (*runtimeInterface, error) {
	var ri runtimeInterface
	runtimeTypes := map[string]*runtimeType{
		"eface":         &ri.eface,
		"rtype":         &ri.rtype,
		"uncommonType":  &ri.uncommonType,
		"arrayType":     &ri.arrayType,
		"chanType":      &ri.chanType,
		"funcType":      &ri.funcType,
		"iface":         &ri.iface,
		"imethod":       &ri.imethod,
		"interfaceType": &ri.interfaceType,
		"itab":          &ri.itab,
		"mapiter":       &ri.mapiter,
		"mapType":       &ri.mapType,
		"method":        &ri.method,
		"ptrType":       &ri.ptrType,
		"sliceType":     &ri.sliceType,
		"structField":   &ri.structField,
		"structType":    &ri.structType,
		"defers":        &ri.defers,
	}
	for name, field := range runtimeTypes {
		obj := pkg.Scope().Lookup(name)
		if obj == nil {
			return nil, fmt.Errorf("no runtime type with name %s", name)
		}
		field.Type = obj.Type()
		field.llvm = tm.ToLLVM(field.Type)
	}

	intrinsics := map[string]**LLVMValue{
		"chanclose":         &ri.chanclose,
		"chanrecv":          &ri.chanrecv,
		"chansend":          &ri.chansend,
		"compareE2E":        &ri.compareE2E,
		"convertE2I":        &ri.convertE2I,
		"convertE2V":        &ri.convertE2V,
		"mustConvertE2I":    &ri.mustConvertE2I,
		"mustConvertE2V":    &ri.mustConvertE2V,
		"convertI2E":        &ri.convertI2E,
		"eqtyp":             &ri.eqtyp,
		"Go":                &ri.Go,
		"initdefers":        &ri.initdefers,
		"llvm_stackrestore": &ri.stackrestore,
		"llvm_stacksave":    &ri.stacksave,
		"llvm_setjmp":       &ri.setjmp,
		"main":              &ri.main,
		"printfloat":        &ri.printfloat,
		"makechan":          &ri.makechan,
		"makemap":           &ri.makemap,
		"malloc":            &ri.malloc,
		"mapaccess":         &ri.mapaccess,
		"mapdelete":         &ri.mapdelete,
		"mapiterinit":       &ri.mapiterinit,
		"mapiternext":       &ri.mapiternext,
		"maplookup":         &ri.maplookup,
		"memcpy":            &ri.memcpy,
		"memequal":          &ri.memequal,
		"memset":            &ri.memset,
		"panic_":            &ri.panic_,
		"pushdefer":         &ri.pushdefer,
		"recover_":          &ri.recover_,
		"rundefers":         &ri.rundefers,
		"chancap":           &ri.chancap,
		"chanlen":           &ri.chanlen,
		"maplen":            &ri.maplen,
		"makeslice":         &ri.makeslice,
		"selectdefault":     &ri.selectdefault,
		"selectgo":          &ri.selectgo,
		"selectinit":        &ri.selectinit,
		"selectrecv":        &ri.selectrecv,
		"selectsend":        &ri.selectsend,
		"selectsize":        &ri.selectsize,
		"sliceappend":       &ri.sliceappend,
		"slicecopy":         &ri.slicecopy,
		"sliceslice":        &ri.sliceslice,
		"stringslice":       &ri.stringslice,
		"strcat":            &ri.strcat,
		"strcmp":            &ri.strcmp,
		"strnext":           &ri.strnext,
		"strrune":           &ri.strrune,
		"strtorunes":        &ri.strtorunes,
		"runestostr":        &ri.runestostr,
		"streqalg":          &ri.streqalg,
		"f32eqalg":          &ri.f32eqalg,
		"f64eqalg":          &ri.f64eqalg,
		"c64eqalg":          &ri.c64eqalg,
		"c128eqalg":         &ri.c128eqalg,
	}
	for name, field := range intrinsics {
		obj := pkg.Scope().Lookup(name)
		if obj == nil {
			return nil, fmt.Errorf("no runtime function with name %s", name)
		}
		*field = fr.ResolveFunc(obj.(*types.Func))
	}
	return &ri, nil
}
Beispiel #15
0
func Write(pkg *types.Package, out io.Writer, sizes types.Sizes) {
	fmt.Fprintf(out, "package %s\n", pkg.Name())

	e := &exporter{pkg: pkg, imports: make(map[*types.Package]bool), out: out}

	for _, imp := range pkg.Imports() {
		e.addImport(imp)
	}

	for _, name := range pkg.Scope().Names() {
		obj := pkg.Scope().Lookup(name)

		_, isTypeName := obj.(*types.TypeName)
		if obj.Exported() || isTypeName {
			e.toExport = append(e.toExport, obj)
		}
	}

	for i := 0; i < len(e.toExport); i++ {
		switch o := e.toExport[i].(type) {
		case *types.TypeName:
			fmt.Fprintf(out, "type %s %s\n", e.makeName(o), e.makeType(o.Type().Underlying()))
			if _, isInterface := o.Type().Underlying().(*types.Interface); !isInterface {
				writeMethods := func(t types.Type) {
					methods := types.NewMethodSet(t)
					for i := 0; i < methods.Len(); i++ {
						m := methods.At(i)
						if len(m.Index()) > 1 {
							continue // method of embedded field
						}
						out.Write([]byte("func (? " + e.makeType(m.Recv()) + ") " + e.makeName(m.Obj()) + e.makeSignature(m.Type()) + "\n"))
					}
				}
				writeMethods(o.Type())
				writeMethods(types.NewPointer(o.Type()))
			}
		case *types.Func:
			out.Write([]byte("func " + e.makeName(o) + e.makeSignature(o.Type()) + "\n"))
		case *types.Const:
			optType := ""
			basic, isBasic := o.Type().(*types.Basic)
			if !isBasic || basic.Info()&types.IsUntyped == 0 {
				optType = " " + e.makeType(o.Type())
			}

			basic = o.Type().Underlying().(*types.Basic)
			var val string
			switch {
			case basic.Info()&types.IsBoolean != 0:
				val = strconv.FormatBool(exact.BoolVal(o.Val()))
			case basic.Info()&types.IsInteger != 0:
				if basic.Kind() == types.Uint64 {
					d, _ := exact.Uint64Val(o.Val())
					val = fmt.Sprintf("%#x", d)
					break
				}
				d, _ := exact.Int64Val(o.Val())
				if basic.Kind() == types.UntypedRune {
					switch {
					case d < 0 || d > unicode.MaxRune:
						val = fmt.Sprintf("('\\x00' + %d)", d)
					case d > 0xffff:
						val = fmt.Sprintf("'\\U%08x'", d)
					default:
						val = fmt.Sprintf("'\\u%04x'", d)
					}
					break
				}
				val = fmt.Sprintf("%#x", d)
			case basic.Info()&types.IsFloat != 0:
				f, _ := exact.Float64Val(o.Val())
				val = strconv.FormatFloat(f, 'b', -1, 64)
			case basic.Info()&types.IsComplex != 0:
				r, _ := exact.Float64Val(exact.Real(o.Val()))
				i, _ := exact.Float64Val(exact.Imag(o.Val()))
				val = fmt.Sprintf("(%s+%si)", strconv.FormatFloat(r, 'b', -1, 64), strconv.FormatFloat(i, 'b', -1, 64))
			case basic.Info()&types.IsString != 0:
				val = fmt.Sprintf("%#v", exact.StringVal(o.Val()))
			default:
				panic("Unhandled constant type: " + basic.String())
			}
			out.Write([]byte("const " + e.makeName(o) + optType + " = " + val + "\n"))
		case *types.Var:
			out.Write([]byte("var " + e.makeName(o) + " " + e.makeType(o.Type()) + "\n"))
		default:
			panic(fmt.Sprintf("Unhandled object: %T\n", o))
		}
	}

	fmt.Fprintf(out, "$$\n")
}
Beispiel #16
0
func (p *printer) printPackage(pkg *types.Package, filter func(types.Object) bool) {
	// collect objects by kind
	var (
		consts   []*types.Const
		typem    []*types.Named    // non-interface types with methods
		typez    []*types.TypeName // interfaces or types without methods
		vars     []*types.Var
		funcs    []*types.Func
		builtins []*types.Builtin
		methods  = make(map[*types.Named][]*types.Selection) // method sets for named types
	)
	scope := pkg.Scope()
	for _, name := range scope.Names() {
		obj := scope.Lookup(name)
		if obj.Exported() {
			// collect top-level exported and possibly filtered objects
			if filter == nil || filter(obj) {
				switch obj := obj.(type) {
				case *types.Const:
					consts = append(consts, obj)
				case *types.TypeName:
					// group into types with methods and types without
					if named, m := methodsFor(obj); named != nil {
						typem = append(typem, named)
						methods[named] = m
					} else {
						typez = append(typez, obj)
					}
				case *types.Var:
					vars = append(vars, obj)
				case *types.Func:
					funcs = append(funcs, obj)
				case *types.Builtin:
					// for unsafe.Sizeof, etc.
					builtins = append(builtins, obj)
				}
			}
		} else if filter == nil {
			// no filtering: collect top-level unexported types with methods
			if obj, _ := obj.(*types.TypeName); obj != nil {
				// see case *types.TypeName above
				if named, m := methodsFor(obj); named != nil {
					typem = append(typem, named)
					methods[named] = m
				}
			}
		}
	}

	p.printf("package %s  // %q\n", pkg.Name(), pkg.Path())

	p.printDecl("const", len(consts), func() {
		for _, obj := range consts {
			p.printObj(obj)
			p.print("\n")
		}
	})

	p.printDecl("var", len(vars), func() {
		for _, obj := range vars {
			p.printObj(obj)
			p.print("\n")
		}
	})

	p.printDecl("type", len(typez), func() {
		for _, obj := range typez {
			p.printf("%s ", obj.Name())
			p.writeType(p.pkg, obj.Type().Underlying())
			p.print("\n")
		}
	})

	// non-interface types with methods
	for _, named := range typem {
		first := true
		if obj := named.Obj(); obj.Exported() {
			if first {
				p.print("\n")
				first = false
			}
			p.printf("type %s ", obj.Name())
			p.writeType(p.pkg, named.Underlying())
			p.print("\n")
		}
		for _, m := range methods[named] {
			if obj := m.Obj(); obj.Exported() {
				if first {
					p.print("\n")
					first = false
				}
				p.printFunc(m.Recv(), obj.(*types.Func))
				p.print("\n")
			}
		}
	}

	if len(funcs) > 0 {
		p.print("\n")
		for _, obj := range funcs {
			p.printFunc(nil, obj)
			p.print("\n")
		}
	}

	// TODO(gri) better handling of builtins (package unsafe only)
	if len(builtins) > 0 {
		p.print("\n")
		for _, obj := range builtins {
			p.printf("func %s() // builtin\n", obj.Name())
		}
	}

	p.print("\n")
}
Beispiel #17
0
func (p *printer) printPackage(pkg *types.Package, filter func(types.Object) bool) {
	// collect objects by kind
	var (
		consts   []*types.Const
		typez    []*types.TypeName // types without methods
		typem    []*types.TypeName // types with methods
		vars     []*types.Var
		funcs    []*types.Func
		builtins []*types.Builtin
	)
	scope := pkg.Scope()
	for _, name := range scope.Names() {
		obj := scope.Lookup(name)
		if !filter(obj) {
			continue
		}
		switch obj := obj.(type) {
		case *types.Const:
			consts = append(consts, obj)
		case *types.TypeName:
			if named, _ := obj.Type().(*types.Named); named != nil && named.NumMethods() > 0 {
				typem = append(typem, obj)
			} else {
				typez = append(typez, obj)
			}
		case *types.Var:
			vars = append(vars, obj)
		case *types.Func:
			funcs = append(funcs, obj)
		case *types.Builtin:
			// for unsafe.Sizeof, etc.
			builtins = append(builtins, obj)
		}
	}

	p.printf("package %s  // %q\n\n", pkg.Name(), pkg.Path())

	if len(consts) > 0 {
		p.print("const (\n")
		p.indent++
		for _, obj := range consts {
			p.printObj(obj)
			p.print("\n")
		}
		p.indent--
		p.print(")\n\n")
	}

	if len(vars) > 0 {
		p.print("var (\n")
		p.indent++
		for _, obj := range vars {
			p.printObj(obj)
			p.print("\n")
		}
		p.indent--
		p.print(")\n\n")
	}

	if len(typez) > 0 {
		p.print("type (\n")
		p.indent++
		for _, obj := range typez {
			p.printf("%s ", obj.Name())
			p.writeType(p.pkg, obj.Type().Underlying())
			p.print("\n")
		}
		p.indent--
		p.print(")\n\n")
	}

	for _, obj := range typem {
		p.printf("type %s ", obj.Name())
		typ := obj.Type().(*types.Named)
		p.writeType(p.pkg, typ.Underlying())
		p.print("\n")
		for i, n := 0, typ.NumMethods(); i < n; i++ {
			p.printFunc(typ.Method(i))
			p.print("\n")
		}
		p.print("\n")
	}

	for _, obj := range funcs {
		p.printFunc(obj)
		p.print("\n")
	}

	// TODO(gri) better handling of builtins (package unsafe only)
	for _, obj := range builtins {
		p.printf("func %s() // builtin\n", obj.Name())
	}

	p.print("\n")
}
Beispiel #18
0
// FunctionType = ParamList ResultList .
func (p *parser) parseFunctionType(pkg *types.Package) *types.Signature {
	params, isVariadic := p.parseParamList(pkg)
	results := p.parseResultList(pkg)
	return types.NewSignature(pkg.Scope(), nil, params, results, isVariadic)
}
Beispiel #19
0
// funcSig returns the signature of the specified package-level function.
func funcSig(pkg *types.Package, name string) *types.Signature {
	if f, ok := pkg.Scope().Lookup(name).(*types.Func); ok {
		return f.Type().(*types.Signature)
	}
	return nil
}