Exemple #1
0
// pkgPrefix returns a prefix that disambiguates symbol names for binding
// multiple packages.
//
// TODO(elias.naur): Avoid (and test) name clashes from multiple packages
// with the same name. Perhaps use the index from the order the package is
// generated.
func pkgPrefix(pkg *types.Package) string {
	// The error type has no package
	if pkg == nil {
		return ""
	}
	return pkg.Name()
}
Exemple #2
0
func (b *binder) GenGo(pkg *types.Package, allPkg []*types.Package, outdir string) error {
	pkgName := "go_"
	pkgPath := ""
	if pkg != nil {
		pkgName += pkg.Name()
		pkgPath = pkg.Path()
	}
	goFile := filepath.Join(outdir, pkgName+"main.go")

	generate := func(w io.Writer) error {
		if buildX {
			printcmd("gobind -lang=go -outdir=%s %s", outdir, pkgPath)
		}
		if buildN {
			return nil
		}
		conf := &bind.GeneratorConfig{
			Writer: w,
			Fset:   b.fset,
			Pkg:    pkg,
			AllPkg: allPkg,
		}
		return bind.GenGo(conf)
	}
	if err := writeFile(goFile, generate); err != nil {
		return err
	}
	return nil
}
Exemple #3
0
func find(pkg *types.Package, iface string) (*types.Interface, error) {
	scope := pkg.Scope()
	names := scope.Names()
	for _, n := range names {
		obj := scope.Lookup(n)

		tn, ok := obj.(*types.TypeName)
		if !ok {
			continue
		}
		if tn.Name() != iface {
			continue
		}
		if !obj.Exported() {
			return nil, fmt.Errorf("%s should exported", iface)
		}
		t := tn.Type().Underlying()
		i, ok := t.(*types.Interface)
		if !ok {
			return nil, fmt.Errorf("exptected interface, got %s for %s", t, iface)
		}
		return i, nil
	}
	return nil, fmt.Errorf("%s not found in %s", iface, pkg.Name())
}
Exemple #4
0
func (p *Parser) Qualifier(pkg *types.Package) string {
	if pkg.Name() == p.Package {
		return ""
	}

	return pkg.Name()
}
Exemple #5
0
//Collect going through package and collect info
//using conf.Check method. It's using this implementation
//of importer for check all inner packages and go/types/importer.Default()
//to check all built in packages (without sources)
func (_importer *CollectInfoImporter) Collect() (*types.Package, *token.FileSet, error) {
	var conf types.Config
	conf.Importer = _importer
	conf.Error = _importer.errorHandler

	if _importer.packages == nil {
		_importer.packages = make(map[string]*types.Package)
	}

	var pkg *types.Package
	var err error
	var files []string

	if files, err = fs.SourceFiles(_importer.Pkg, false); err != nil {
		return nil, nil, err
	}
	if _importer.fset, _importer.astFiles, err = doParseFiles(files, _importer.fset); err != nil {
		return nil, nil, err
	}

	//XXX: return positive result if check() returns error.
	pkg, _ = conf.Check(_importer.Pkg, _importer.fset, _importer.astFiles, _importer.Info)
	// if pkg, err = conf.Check(_importer.Pkg, _importer.fset, _importer.astFiles, _importer.Info); err != nil {
	// 	return pkg, _importer.fset, err
	// }

	_importer.packages[_importer.Pkg] = pkg
	util.Debug("package [%s] successfully parsed\n", pkg.Name())

	return pkg, _importer.fset, nil
}
Exemple #6
0
func (c *converter) convertPackage(v *gotypes.Package) *types.Package {
	if v == nil {
		return nil
	}
	if v, ok := c.converted[v]; ok {
		return v.(*types.Package)
	}

	ret := types.NewPackage(v.Path(), v.Name())
	if c.ret == nil {
		c.ret = ret
	}
	c.converted[v] = ret

	var imports []*types.Package
	for _, imported := range v.Imports() {
		imports = append(imports, c.convertPackage(imported))
	}
	ret.SetImports(imports)

	c.convertScope(ret.Scope(), v.Scope())

	for _, iface := range c.ifaces {
		iface.Complete()
	}

	return ret
}
Exemple #7
0
func defaultFileName(lang string, pkg *types.Package) string {
	switch lang {
	case "java":
		if pkg == nil {
			return "Universe.java"
		}
		firstRune, size := utf8.DecodeRuneInString(pkg.Name())
		className := string(unicode.ToUpper(firstRune)) + pkg.Name()[size:]
		return className + ".java"
	case "go":
		if pkg == nil {
			return "go_universe.go"
		}
		return "go_" + pkg.Name() + ".go"
	case "objc":
		if pkg == nil {
			return "GoUniverse.m"
		}
		firstRune, size := utf8.DecodeRuneInString(pkg.Name())
		className := string(unicode.ToUpper(firstRune)) + pkg.Name()[size:]
		return "Go" + className + ".m"
	}
	errorf("unknown target language: %q", lang)
	os.Exit(exitStatus)
	return ""
}
Exemple #8
0
func (g *objcGen) namePrefixOf(pkg *types.Package) string {
	p := g.prefix
	if p == "" {
		p = "Go"
	}
	return p + strings.Title(pkg.Name())
}
Exemple #9
0
func (p *exporter) pkg(pkg *types.Package, emptypath bool) {
	if pkg == nil {
		log.Fatalf("gcimporter: unexpected nil pkg")
	}

	// if we saw the package before, write its index (>= 0)
	if i, ok := p.pkgIndex[pkg]; ok {
		p.index('P', i)
		return
	}

	// otherwise, remember the package, write the package tag (< 0) and package data
	if trace {
		p.tracef("P%d = { ", len(p.pkgIndex))
		defer p.tracef("} ")
	}
	p.pkgIndex[pkg] = len(p.pkgIndex)

	p.tag(packageTag)
	p.string(pkg.Name())
	if emptypath {
		p.string("")
	} else {
		p.string(pkg.Path())
	}
}
Exemple #10
0
// pkgName retuns the package name and adds the package to the list of
// imports.
func (g *goGen) pkgName(pkg *types.Package) string {
	// The error type has no package
	if pkg == nil {
		return ""
	}
	g.imports[pkg.Path()] = struct{}{}
	return pkg.Name() + "."
}
Exemple #11
0
func (b *binder) GenObjc(pkg *types.Package, allPkg []*types.Package, outdir string) (string, error) {
	const bindPrefixDefault = "Go"
	if bindPrefix == "" {
		bindPrefix = bindPrefixDefault
	}
	name := strings.Title(pkg.Name())
	bindOption := "-lang=objc"
	if bindPrefix != bindPrefixDefault {
		bindOption += " -prefix=" + bindPrefix
	}

	fileBase := bindPrefix + name
	mfile := filepath.Join(outdir, fileBase+".m")
	hfile := filepath.Join(outdir, fileBase+".h")
	gohfile := filepath.Join(outdir, pkg.Name()+".h")

	conf := &bind.GeneratorConfig{
		Fset:   b.fset,
		Pkg:    pkg,
		AllPkg: allPkg,
	}
	generate := func(w io.Writer) error {
		if buildX {
			printcmd("gobind %s -outdir=%s %s", bindOption, outdir, pkg.Path())
		}
		if buildN {
			return nil
		}
		conf.Writer = w
		return bind.GenObjc(conf, bindPrefix, bind.ObjcM)
	}
	if err := writeFile(mfile, generate); err != nil {
		return "", err
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		conf.Writer = w
		return bind.GenObjc(conf, bindPrefix, bind.ObjcH)
	}
	if err := writeFile(hfile, generate); err != nil {
		return "", err
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		conf.Writer = w
		return bind.GenObjc(conf, bindPrefix, bind.ObjcGoH)
	}
	if err := writeFile(gohfile, generate); err != nil {
		return "", err
	}

	return fileBase, nil
}
Exemple #12
0
func (g *ObjcGen) namePrefixOf(pkg *types.Package) string {
	if pkg == nil {
		return "GoUniverse"
	}
	p := g.Prefix
	if p == "" {
		p = "Go"
	}
	return p + strings.Title(pkg.Name())
}
Exemple #13
0
func joinQuery(pkg *types.Package, parent types.Object, obj types.Object, suffix string) string {
	var args []string
	args = append(args, pkg.Name())
	if parent != nil {
		args = append(args, parent.Name())
	}

	args = append(args, nameExported(obj.Name()))
	return strings.Join(args, ".") + suffix
}
Exemple #14
0
func newBinder(p *types.Package) (*binder, error) {
	if p.Name() == "main" {
		return nil, fmt.Errorf("package %q: can only bind a library package", p.Name())
	}
	b := &binder{
		fset: token.NewFileSet(),
		pkg:  p,
	}
	return b, nil
}
Exemple #15
0
// JavaPkgName returns the Java package name for a Go package
// given a pkg prefix. If the prefix is empty, "go" is used
// instead.
func JavaPkgName(pkgPrefix string, pkg *types.Package) string {
	if pkg == nil {
		return "go"
	}
	s := javaNameReplacer(pkg.Name())
	if pkgPrefix != "" {
		return pkgPrefix + "." + s
	} else {
		return "go." + s
	}
}
Exemple #16
0
func newPackageFrom(bpkg *build.Package, p *types.Package) (*bind.Package, error) {

	var pkgast *ast.Package
	pkgs, err := parser.ParseDir(fset, bpkg.Dir, nil, parser.ParseComments)
	if err != nil {
		return nil, err
	}
	pkgast = pkgs[p.Name()]
	if pkgast == nil {
		return nil, fmt.Errorf("gopy: could not find AST for package %q", p.Name())
	}

	pkgdoc := doc.New(pkgast, bpkg.ImportPath, 0)

	return bind.NewPackage(p, pkgdoc)
}
Exemple #17
0
func (b *binder) GenObjc(pkg *types.Package, outdir string) (string, error) {
	const bindPrefixDefault = "Go"
	if bindPrefix == "" {
		bindPrefix = bindPrefixDefault
	}
	name := strings.Title(pkg.Name())
	bindOption := "-lang=objc"
	if bindPrefix != bindPrefixDefault {
		bindOption += " -prefix=" + bindPrefix
	}

	fileBase := bindPrefix + name
	mfile := filepath.Join(outdir, fileBase+".m")
	hfile := filepath.Join(outdir, fileBase+".h")

	generate := func(w io.Writer) error {
		if buildX {
			printcmd("gobind %s -outdir=%s %s", bindOption, outdir, pkg.Path())
		}
		if buildN {
			return nil
		}
		return bind.GenObjc(w, b.fset, pkg, bindPrefix, false)
	}
	if err := writeFile(mfile, generate); err != nil {
		return "", err
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		return bind.GenObjc(w, b.fset, pkg, bindPrefix, true)
	}
	if err := writeFile(hfile, generate); err != nil {
		return "", err
	}

	objcPkg, err := ctx.Import("golang.org/x/mobile/bind/objc", "", build.FindOnly)
	if err != nil {
		return "", err
	}
	if err := copyFile(filepath.Join(outdir, "seq.h"), filepath.Join(objcPkg.Dir, "seq.h")); err != nil {
		return "", err
	}
	return fileBase, nil
}
Exemple #18
0
// GenCs generates a C# API from a Go package.
func GenCs(w io.Writer, fset *token.FileSet, pkg *types.Package, namespace string) error {
	if namespace == "" {
		namespace = namespaceName(pkg.Name())
	}
	buf := new(bytes.Buffer)
	g := &csGen{
		printer:   &printer{buf: buf, indentEach: []byte("    ")},
		fset:      fset,
		pkg:       pkg,
		namespace: namespace,
	}
	if err := g.gen(); err != nil {
		return err
	}
	_, err := io.Copy(w, buf)
	return err
}
Exemple #19
0
// GenJava generates a Java API from a Go package.
func GenJava(w io.Writer, fset *token.FileSet, pkg *types.Package, javaPkg string) error {
	if javaPkg == "" {
		javaPkg = javaPkgName(pkg.Name())
	}
	buf := new(bytes.Buffer)
	g := &javaGen{
		printer: &printer{buf: buf, indentEach: []byte("    ")},
		fset:    fset,
		pkg:     pkg,
		javaPkg: javaPkg,
	}
	if err := g.gen(); err != nil {
		return err
	}
	_, err := io.Copy(w, buf)
	return err
}
Exemple #20
0
func (b *binder) GenGo(pkg *types.Package, outdir string) error {
	pkgName := "go_" + pkg.Name()
	outdir = filepath.Join(outdir, pkgName)
	goFile := filepath.Join(outdir, pkgName+"main.go")

	generate := func(w io.Writer) error {
		if buildX {
			printcmd("gobind -lang=go -outdir=%s %s", outdir, pkg.Path())
		}
		if buildN {
			return nil
		}
		return bind.GenGo(w, b.fset, pkg)
	}
	if err := writeFile(goFile, generate); err != nil {
		return err
	}
	return nil
}
Exemple #21
0
func defaultFileName(lang string, pkg *types.Package) string {
	if *outdir == "" {
		return ""
	}

	switch lang {
	case "java":
		firstRune, size := utf8.DecodeRuneInString(pkg.Name())
		className := string(unicode.ToUpper(firstRune)) + pkg.Name()[size:]
		return filepath.Join(*outdir, className+".java")
	case "go":
		return filepath.Join(*outdir, "go_"+pkg.Name()+".go")
	case "objc":
		firstRune, size := utf8.DecodeRuneInString(pkg.Name())
		className := string(unicode.ToUpper(firstRune)) + pkg.Name()[size:]
		return filepath.Join(*outdir, "Go"+className+".m")
	}
	errorf("unknown target language: %q", lang)
	os.Exit(exitStatus)
	return ""
}
Exemple #22
0
func (p *exporter) pkg(pkg *types.Package) {
	if trace {
		p.tracef("package { ")
		defer p.tracef("} ")
	}

	if pkg == nil {
		panic("unexpected nil pkg")
	}

	// if the package was seen before, write its index (>= 0)
	if i, ok := p.pkgIndex[pkg]; ok {
		p.int(i)
		return
	}
	p.pkgIndex[pkg] = len(p.pkgIndex)

	// otherwise, write the package tag (< 0) and package data
	p.int(packageTag)
	p.string(pkg.Name())
	p.string(pkg.Path())
}
Exemple #23
0
func (b *binder) GenJava(pkg *types.Package, outdir string) error {
	className := strings.Title(pkg.Name())
	javaFile := filepath.Join(outdir, className+".java")
	bindOption := "-lang=java"
	if bindJavaPkg != "" {
		bindOption += " -javapkg=" + bindJavaPkg
	}

	generate := func(w io.Writer) error {
		if buildX {
			printcmd("gobind %s -outdir=%s %s", bindOption, outdir, pkg.Path())
		}
		if buildN {
			return nil
		}
		return bind.GenJava(w, b.fset, pkg, bindJavaPkg)
	}
	if err := writeFile(javaFile, generate); err != nil {
		return err
	}
	return nil
}
Exemple #24
0
func main() {
	var fset *token.FileSet
	var file *ast.File
	var pkg *types.Package
	var err error

	fset = token.NewFileSet()
	file, err = parser.ParseFile(fset, "greet.go", src, 0)
	if err != nil {
		log.Fatal(err)
	}

	info := types.Info{
		Types:      make(map[ast.Expr]types.TypeAndValue),
		Defs:       make(map[*ast.Ident]types.Object),
		Uses:       make(map[*ast.Ident]types.Object),
		Implicits:  make(map[ast.Node]types.Object),
		Selections: make(map[*ast.SelectorExpr]*types.Selection),
		Scopes:     make(map[ast.Node]*types.Scope),
		InitOrder:  make([]*types.Initializer, 0),
	}

	var conf types.Config
	pkg, err = conf.Check("greet", fset, []*ast.File{file}, &info)

	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Package %s sucsessfully parsed\n", pkg.Name())
	printTypes(info.Types, fset)
	printDefs(info.Defs, fset)
	printUses(info.Uses, fset)
	printImplicits(info.Implicits, fset)
	printSelections(info.Selections, fset)
	printScopes(info.Scopes, fset)
	printInitOrder(info.InitOrder, fset)
}
Exemple #25
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:     append([]byte(magic), format()),
		pkgIndex: make(map[*types.Package]int),
		typIndex: make(map[types.Type]int),
	}

	// populate typIndex with predeclared types
	for _, t := range predeclared {
		p.typIndex[t] = 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
}
Exemple #26
0
func (g *javaGen) javaPkgName(pkg *types.Package) string {
	if g.javaPkg != "" {
		return g.javaPkg
	}
	s := javaNameReplacer.Replace(pkg.Name())
	// Look for Java keywords that are not Go keywords, and avoid using
	// them as a package name.
	//
	// This is not a problem for normal Go identifiers as we only expose
	// exported symbols. The upper case first letter saves everything
	// from accidentally matching except for the package name.
	//
	// Note that basic type names (like int) are not keywords in Go.
	switch s {
	case "abstract", "assert", "boolean", "byte", "catch", "char", "class",
		"do", "double", "enum", "extends", "final", "finally", "float",
		"implements", "instanceof", "int", "long", "native", "private",
		"protected", "public", "short", "static", "strictfp", "super",
		"synchronized", "this", "throw", "throws", "transient", "try",
		"void", "volatile", "while":
		s += "_"
	}
	return "go." + s
}
Exemple #27
0
func genPkg(p *types.Package, allPkg []*types.Package) {
	fname := defaultFileName(*lang, p)
	conf := &bind.GeneratorConfig{
		Fset:   fset,
		Pkg:    p,
		AllPkg: allPkg,
	}
	switch *lang {
	case "java":
		w, closer := writer(fname)
		conf.Writer = w
		processErr(bind.GenJava(conf, *javaPkg, bind.Java))
		closer()
		cname := "java_" + p.Name() + ".c"
		w, closer = writer(cname)
		conf.Writer = w
		processErr(bind.GenJava(conf, *javaPkg, bind.JavaC))
		closer()
		hname := p.Name() + ".h"
		w, closer = writer(hname)
		conf.Writer = w
		processErr(bind.GenJava(conf, *javaPkg, bind.JavaH))
		closer()
	case "go":
		w, closer := writer(fname)
		conf.Writer = w
		processErr(bind.GenGo(conf))
		closer()
	case "objc":
		gohname := p.Name() + ".h"
		w, closer := writer(gohname)
		conf.Writer = w
		processErr(bind.GenObjc(conf, *prefix, bind.ObjcGoH))
		closer()
		hname := fname[:len(fname)-2] + ".h"
		w, closer = writer(hname)
		conf.Writer = w
		processErr(bind.GenObjc(conf, *prefix, bind.ObjcH))
		closer()
		w, closer = writer(fname)
		conf.Writer = w
		processErr(bind.GenObjc(conf, *prefix, bind.ObjcM))
		closer()
	default:
		errorf("unknown target language: %q", *lang)
	}
}
Exemple #28
0
func (b *binder) GenJava(pkg *types.Package, allPkg []*types.Package, outdir, javadir string) error {
	className := strings.Title(pkg.Name())
	javaFile := filepath.Join(javadir, className+".java")
	cFile := filepath.Join(outdir, "java_"+pkg.Name()+".c")
	hFile := filepath.Join(outdir, pkg.Name()+".h")
	bindOption := "-lang=java"
	if bindJavaPkg != "" {
		bindOption += " -javapkg=" + bindJavaPkg
	}

	conf := &bind.GeneratorConfig{
		Fset:   b.fset,
		Pkg:    pkg,
		AllPkg: allPkg,
	}
	generate := func(w io.Writer) error {
		if buildX {
			printcmd("gobind %s -outdir=%s %s", bindOption, javadir, pkg.Path())
		}
		if buildN {
			return nil
		}
		conf.Writer = w
		return bind.GenJava(conf, bindJavaPkg, bind.Java)
	}
	if err := writeFile(javaFile, generate); err != nil {
		return err
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		conf.Writer = w
		return bind.GenJava(conf, bindJavaPkg, bind.JavaC)
	}
	if err := writeFile(cFile, generate); err != nil {
		return err
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		conf.Writer = w
		return bind.GenJava(conf, bindJavaPkg, bind.JavaH)
	}
	return writeFile(hFile, generate)
}
Exemple #29
0
// pkgPrefix returns a prefix that disambiguates symbol names for binding
// multiple packages.
//
// TODO(elias.naur): Avoid (and test) name clashes from multiple packages
// with the same name. Perhaps use the index from the order the package is
// generated.
func pkgPrefix(pkg *types.Package) string {
	return pkg.Name()
}
Exemple #30
0
func (g Generator) qf(pkg *types.Package) string {
	if g.pkg == pkg {
		return ""
	}
	return pkg.Name()
}