2
0
mirror of synced 2025-02-23 23:08:14 +00:00

bind: support Java packages with the same last component

Before this CL, using the reverse bindings to access two Java packages
with the same last component would fail with a duplicate package import
error. This CL renames generated import statements to use unique
aliases.

Change-Id: I94696281e58f011f45811445cf81aea02af69c4f
Reviewed-on: https://go-review.googlesource.com/34774
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
Elias Naur 2016-12-31 16:33:26 +01:00
parent fa10d8888b
commit f5d8ba6777
2 changed files with 52 additions and 6 deletions

View File

@ -13,7 +13,22 @@ import (
type goGen struct {
*Generator
imports map[string]struct{}
// imports is the list of imports, in the form
// "the/package/path"
//
// or
//
// name "the/package/path"
//
// in case of duplicates.
imports []string
// The set of taken import names.
importNames map[string]struct{}
// importMap is a map from packages to their names. The name of a package is the last
// segment of its path, with duplicates resolved by appending a underscore and a unique
// number.
importMap map[*types.Package]string
}
const (
@ -497,15 +512,16 @@ func (g *goGen) genPreamble() {
g.Printf("import (\n")
g.Indent()
g.Printf("_seq \"golang.org/x/mobile/bind/seq\"\n")
for path := range g.imports {
g.Printf("%q\n", path)
for _, imp := range g.imports {
g.Printf("%s\n", imp)
}
g.Outdent()
g.Printf(")\n\n")
}
func (g *goGen) gen() error {
g.imports = make(map[string]struct{})
g.importNames = make(map[string]struct{})
g.importMap = make(map[*types.Package]string)
// Switch to a temporary buffer so the preamble can be
// written last.
@ -545,6 +561,28 @@ func (g *goGen) pkgName(pkg *types.Package) string {
if pkg == nil {
return ""
}
g.imports[pkg.Path()] = struct{}{}
return pkg.Name() + "."
if name, exists := g.importMap[pkg]; exists {
return name + "."
}
i := 0
pname := pkg.Name()
name := pkg.Name()
for {
if _, exists := g.importNames[name]; !exists {
g.importNames[name] = struct{}{}
g.importMap[pkg] = name
var imp string
if pname != name {
imp = fmt.Sprintf("%s %q", name, pkg.Path())
} else {
imp = fmt.Sprintf("%q", pkg.Path())
}
g.imports = append(g.imports, imp)
break
}
i++
name = fmt.Sprintf("%s_%d", pname, i)
}
g.importMap[pkg] = name
return name + "."
}

View File

@ -15,8 +15,10 @@ import (
"Java/java/lang/Integer"
"Java/java/lang/Object"
"Java/java/lang/Runnable"
"Java/java/net"
"Java/java/util"
"Java/java/util/concurrent"
xnet "Java/javax/net"
)
const (
@ -189,3 +191,9 @@ func CastRunnable(o lang.Object) lang.Runnable {
r.Run()
return r
}
// Test that extending classes from Java packages
// with the same last component (in this case "net")
// works.
func NameClashingPackages(_ net.Socket, _ xnet.SocketFactory) {
}