protogen: conflict resolve local package names against predefined idents

Avoid importing packages with a local name that conflicts with a predefined
identifier (e.g., "string").

Change-Id: I51164635351895e8a060355e59d718240e26ef2e
Reviewed-on: https://go-review.googlesource.com/c/140178
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
Damien Neil 2018-10-05 11:23:35 -07:00
parent c6b7561199
commit 872146653d
3 changed files with 52 additions and 6 deletions

View File

@ -50,6 +50,48 @@ func cleanPackageName(name string) GoPackageName {
return GoPackageName(name)
}
var isGoPredeclaredIdentifier = map[string]bool{
"append": true,
"bool": true,
"byte": true,
"cap": true,
"close": true,
"complex": true,
"complex128": true,
"complex64": true,
"copy": true,
"delete": true,
"error": true,
"false": true,
"float32": true,
"float64": true,
"imag": true,
"int": true,
"int16": true,
"int32": true,
"int64": true,
"int8": true,
"iota": true,
"len": true,
"make": true,
"new": true,
"nil": true,
"panic": true,
"print": true,
"println": true,
"real": true,
"recover": true,
"rune": true,
"string": true,
"true": true,
"uint": true,
"uint16": true,
"uint32": true,
"uint64": true,
"uint8": true,
"uintptr": true,
}
// badToUnderscore is the mapping function used to generate Go names from package names,
// which can be dotted in the input .proto file. It replaces non-identifier characters such as
// dot or dash with underscore.

View File

@ -833,7 +833,7 @@ func (g *GeneratedFile) QualifiedGoIdent(ident GoIdent) string {
return string(packageName) + "." + ident.GoName
}
packageName := cleanPackageName(baseName(string(ident.GoImportPath)))
for i, orig := 1, packageName; g.usedPackageNames[packageName]; i++ {
for i, orig := 1, packageName; g.usedPackageNames[packageName] || isGoPredeclaredIdentifier[string(packageName)]; i++ {
packageName = orig + GoPackageName(strconv.Itoa(i))
}
g.packageNames[ident.GoImportPath] = packageName

View File

@ -272,6 +272,8 @@ func TestImports(t *testing.T) {
// Reference to a different package with the same basename.
"golang.org/y/bar",
"golang.org/x/baz",
// Reference to a package conflicting with a predeclared identifier.
"golang.org/z/string",
} {
g.P("var _ = ", GoIdent{GoName: "X", GoImportPath: importPath}, " // ", importPath)
}
@ -281,13 +283,15 @@ import (
bar "golang.org/x/bar"
baz "golang.org/x/baz"
bar1 "golang.org/y/bar"
string1 "golang.org/z/string"
)
var _ = X // "golang.org/x/foo"
var _ = bar.X // "golang.org/x/bar"
var _ = bar.X // "golang.org/x/bar"
var _ = bar1.X // "golang.org/y/bar"
var _ = baz.X // "golang.org/x/baz"
var _ = X // "golang.org/x/foo"
var _ = bar.X // "golang.org/x/bar"
var _ = bar.X // "golang.org/x/bar"
var _ = bar1.X // "golang.org/y/bar"
var _ = baz.X // "golang.org/x/baz"
var _ = string1.X // "golang.org/z/string"
`
got, err := g.Content()
if err != nil {