package ast
-import "go/ast"
+import (
+ "go/ast";
+ "go/token";
+)
func filterIdentList(list []*Ident) []*Ident {
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);