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:
parent
fa10d8888b
commit
f5d8ba6777
@ -13,7 +13,22 @@ import (
|
|||||||
|
|
||||||
type goGen struct {
|
type goGen struct {
|
||||||
*Generator
|
*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 (
|
const (
|
||||||
@ -497,15 +512,16 @@ func (g *goGen) genPreamble() {
|
|||||||
g.Printf("import (\n")
|
g.Printf("import (\n")
|
||||||
g.Indent()
|
g.Indent()
|
||||||
g.Printf("_seq \"golang.org/x/mobile/bind/seq\"\n")
|
g.Printf("_seq \"golang.org/x/mobile/bind/seq\"\n")
|
||||||
for path := range g.imports {
|
for _, imp := range g.imports {
|
||||||
g.Printf("%q\n", path)
|
g.Printf("%s\n", imp)
|
||||||
}
|
}
|
||||||
g.Outdent()
|
g.Outdent()
|
||||||
g.Printf(")\n\n")
|
g.Printf(")\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *goGen) gen() error {
|
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
|
// Switch to a temporary buffer so the preamble can be
|
||||||
// written last.
|
// written last.
|
||||||
@ -545,6 +561,28 @@ func (g *goGen) pkgName(pkg *types.Package) string {
|
|||||||
if pkg == nil {
|
if pkg == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
g.imports[pkg.Path()] = struct{}{}
|
if name, exists := g.importMap[pkg]; exists {
|
||||||
return pkg.Name() + "."
|
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 + "."
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,10 @@ import (
|
|||||||
"Java/java/lang/Integer"
|
"Java/java/lang/Integer"
|
||||||
"Java/java/lang/Object"
|
"Java/java/lang/Object"
|
||||||
"Java/java/lang/Runnable"
|
"Java/java/lang/Runnable"
|
||||||
|
"Java/java/net"
|
||||||
"Java/java/util"
|
"Java/java/util"
|
||||||
"Java/java/util/concurrent"
|
"Java/java/util/concurrent"
|
||||||
|
xnet "Java/javax/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -189,3 +191,9 @@ func CastRunnable(o lang.Object) lang.Runnable {
|
|||||||
r.Run()
|
r.Run()
|
||||||
return r
|
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) {
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user