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 }
func WriteArchive(code []byte, pkg *types.Package, w io.Writer) { w.Write(code) w.Write([]byte("$$\n")) for _, impPkg := range pkg.Imports() { w.Write([]byte(impPkg.Path())) w.Write([]byte{'\n'}) } w.Write([]byte("$$\n")) gcexporter.Write(pkg, w, sizes32) }
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) } }
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) } }
// Structure computes the structure of the lexical environment of the // package specified by (pkg, info, files). // // The info.{Types,Defs,Uses,Implicits} maps must have been populated // by the type-checker // // fset is used for logging. // func Structure(fset *token.FileSet, pkg *types.Package, info *types.Info, files []*ast.File) *Info { r := resolver{ fset: fset, imports: make(map[string]*types.Package), result: &Info{ Defs: make(map[types.Object]*Block), Refs: make(map[types.Object][]Reference), Blocks: make(map[ast.Node]*Block), }, pkg: pkg, info: info, } // Build import map for just this package. r.imports["unsafe"] = types.Unsafe for _, imp := range pkg.Imports() { r.imports[imp.Path()] = imp } r.doPackage(pkg, files) return r.result }
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") }