Commit d376935a authored by Robert Griesemer's avatar Robert Griesemer

go/ast: consider anonymous fields and set Incomplete bit when filtering ASTs

Also:
- fieldListExports: don't require internal pointer to StructType/InterfaceType node
- filterFieldLists: make structure match fieldListExports

R=rsc
CC=golang-dev
https://golang.org/cl/4527050
parent 26bbb2b2
...@@ -21,24 +21,26 @@ func identListExports(list []*Ident) []*Ident { ...@@ -21,24 +21,26 @@ func identListExports(list []*Ident) []*Ident {
} }
// isExportedType assumes that typ is a correct type. // fieldName assumes that x is the type of an anonymous field and
func isExportedType(typ Expr) bool { // returns the corresponding field name. If x is not an acceptable
switch t := typ.(type) { // anonymous field, the result is nil.
//
func fieldName(x Expr) *Ident {
switch t := x.(type) {
case *Ident: case *Ident:
return t.IsExported() return t
case *ParenExpr:
return isExportedType(t.X)
case *SelectorExpr: case *SelectorExpr:
// assume t.X is a typename if _, ok := t.X.(*Ident); ok {
return t.Sel.IsExported() return t.Sel
}
case *StarExpr: case *StarExpr:
return isExportedType(t.X) return fieldName(t.X)
} }
return false return nil
} }
func fieldListExports(fields *FieldList, incomplete *bool) { func fieldListExports(fields *FieldList) (removedFields bool) {
if fields == nil { if fields == nil {
return return
} }
...@@ -53,12 +55,13 @@ func fieldListExports(fields *FieldList, incomplete *bool) { ...@@ -53,12 +55,13 @@ func fieldListExports(fields *FieldList, incomplete *bool) {
// fields, so this is not absolutely correct. // fields, so this is not absolutely correct.
// However, this cannot be done w/o complete // However, this cannot be done w/o complete
// type information.) // type information.)
exported = isExportedType(f.Type) name := fieldName(f.Type)
exported = name != nil && name.IsExported()
} else { } else {
n := len(f.Names) n := len(f.Names)
f.Names = identListExports(f.Names) f.Names = identListExports(f.Names)
if len(f.Names) < n { if len(f.Names) < n {
*incomplete = true removedFields = true
} }
exported = len(f.Names) > 0 exported = len(f.Names) > 0
} }
...@@ -69,9 +72,10 @@ func fieldListExports(fields *FieldList, incomplete *bool) { ...@@ -69,9 +72,10 @@ func fieldListExports(fields *FieldList, incomplete *bool) {
} }
} }
if j < len(list) { if j < len(list) {
*incomplete = true removedFields = true
} }
fields.List = list[0:j] fields.List = list[0:j]
return
} }
...@@ -90,12 +94,16 @@ func typeExports(typ Expr) { ...@@ -90,12 +94,16 @@ func typeExports(typ Expr) {
case *ArrayType: case *ArrayType:
typeExports(t.Elt) typeExports(t.Elt)
case *StructType: case *StructType:
fieldListExports(t.Fields, &t.Incomplete) if fieldListExports(t.Fields) {
t.Incomplete = true
}
case *FuncType: case *FuncType:
paramListExports(t.Params) paramListExports(t.Params)
paramListExports(t.Results) paramListExports(t.Results)
case *InterfaceType: case *InterfaceType:
fieldListExports(t.Methods, &t.Incomplete) if fieldListExports(t.Methods) {
t.Incomplete = true
}
case *MapType: case *MapType:
typeExports(t.Key) typeExports(t.Key)
typeExports(t.Value) typeExports(t.Value)
...@@ -206,25 +214,36 @@ func filterIdentList(list []*Ident, f Filter) []*Ident { ...@@ -206,25 +214,36 @@ func filterIdentList(list []*Ident, f Filter) []*Ident {
} }
func filterFieldList(list []*Field, f Filter) []*Field { func filterFieldList(fields *FieldList, filter Filter) (removedFields bool) {
if fields == nil {
return false
}
list := fields.List
j := 0 j := 0
for _, field := range list { for _, f := range list {
field.Names = filterIdentList(field.Names, f) keepField := false
if len(field.Names) > 0 { if len(f.Names) == 0 {
list[j] = field // anonymous field
name := fieldName(f.Type)
keepField = name != nil && filter(name.Name)
} else {
n := len(f.Names)
f.Names = filterIdentList(f.Names, filter)
if len(f.Names) < n {
removedFields = true
}
keepField = len(f.Names) > 0
}
if keepField {
list[j] = f
j++ j++
} }
} }
return list[0:j] if j < len(list) {
} removedFields = true
func filterFields(fields *FieldList, f Filter) bool {
if fields == nil {
return false
} }
fields.List = filterFieldList(fields.List, f) fields.List = list[0:j]
return len(fields.List) > 0 return
} }
...@@ -239,9 +258,15 @@ func filterSpec(spec Spec, f Filter) bool { ...@@ -239,9 +258,15 @@ func filterSpec(spec Spec, f Filter) bool {
} }
switch t := s.Type.(type) { switch t := s.Type.(type) {
case *StructType: case *StructType:
return filterFields(t.Fields, f) if filterFieldList(t.Fields, f) {
t.Incomplete = true
}
return len(t.Fields.List) > 0
case *InterfaceType: case *InterfaceType:
return filterFields(t.Methods, f) if filterFieldList(t.Methods, f) {
t.Incomplete = true
}
return len(t.Methods.List) > 0
} }
} }
return false return false
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment