diff --git a/src/pkg/go/ast/filter.go b/src/pkg/go/ast/filter.go index cf65f4ae65..a9dd080152 100644 --- a/src/pkg/go/ast/filter.go +++ b/src/pkg/go/ast/filter.go @@ -4,7 +4,10 @@ package ast -import "go/ast" +import ( + "go/ast"; + "go/token"; +) func filterIdentList(list []*Ident) []*Ident { @@ -39,21 +42,54 @@ func filterFieldList(list []*Field) []*Field { j++; } } + if j > 0 && j < len(list) { + // fields have been stripped but there is at least one left; + // add a '...' anonymous field instead + list[j] = &ast.Field{nil, nil, &ast.Ellipsis{}, nil, nil}; + j++; + } return list[0 : j]; } +func filterParamList(list []*Field) { + for _, f := range list { + filterType(f.Type); + } +} + + +var noPos token.Position; + func filterType(typ Expr) { switch t := typ.(type) { case *ArrayType: filterType(t.Elt); case *StructType: - t.Fields = filterFieldList(t.Fields); + // don't change if empty struct + if len(t.Fields) > 0 { + t.Fields = filterFieldList(t.Fields); + if len(t.Fields) == 0 { + // all fields have been stripped - make look like forward-decl + t.Lbrace = noPos; + t.Fields = nil; + t.Rbrace = noPos; + } + } case *FuncType: - t.Params = filterFieldList(t.Params); - t.Results = filterFieldList(t.Results); + filterParamList(t.Params); + filterParamList(t.Results); case *InterfaceType: - t.Methods = filterFieldList(t.Methods); + // don't change if empty interface + if len(t.Methods) > 0 { + t.Methods = filterFieldList(t.Methods); + if len(t.Methods) == 0 { + // all methods have been stripped - make look like forward-decl + t.Lbrace = noPos; + t.Methods = nil; + t.Rbrace = noPos; + } + } case *MapType: filterType(t.Key); filterType(t.Value);