Protobuf generation should strip empty-imports

The imports are generated because the packages are in the search tree,
but nothing in the generated code needs them. For now, strip them.
This commit is contained in:
Clayton Coleman 2016-04-24 19:11:54 -04:00
parent 3a4f179c75
commit c4b192b67b
No known key found for this signature in database
GPG Key ID: 3D16906B4F1C5CB3

View File

@ -81,9 +81,13 @@ func RewriteGeneratedGogoProtobufFile(name string, extractFn ExtractFunc, header
// remove types that are already declared
decls := []ast.Decl{}
for _, d := range file.Decls {
if !dropExistingTypeDeclarations(d, extractFn) {
decls = append(decls, d)
if dropExistingTypeDeclarations(d, extractFn) {
continue
}
if dropEmptyImportDeclarations(d) {
continue
}
decls = append(decls, d)
}
file.Decls = decls
@ -93,6 +97,8 @@ func RewriteGeneratedGogoProtobufFile(name string, extractFn ExtractFunc, header
})
}
// dropExistingTypeDeclarations removes any type declaration for which extractFn returns true. The function
// returns true if the entire declaration should be dropped.
func dropExistingTypeDeclarations(decl ast.Decl, extractFn ExtractFunc) bool {
switch t := decl.(type) {
case *ast.GenDecl:
@ -117,6 +123,33 @@ func dropExistingTypeDeclarations(decl ast.Decl, extractFn ExtractFunc) bool {
return false
}
// dropEmptyImportDeclarations strips any generated but no-op imports from the generated code
// to prevent generation from being able to define side-effects. The function returns true
// if the entire declaration should be dropped.
func dropEmptyImportDeclarations(decl ast.Decl) bool {
switch t := decl.(type) {
case *ast.GenDecl:
if t.Tok != token.IMPORT {
return false
}
specs := []ast.Spec{}
for _, s := range t.Specs {
switch spec := s.(type) {
case *ast.ImportSpec:
if spec.Name != nil && spec.Name.Name == "_" {
continue
}
specs = append(specs, spec)
}
}
if len(specs) == 0 {
return true
}
t.Specs = specs
}
return false
}
func RewriteTypesWithProtobufStructTags(name string, structTags map[string]map[string]string) error {
return rewriteFile(name, []byte{}, func(fset *token.FileSet, file *ast.File) error {
allErrs := []error{}