1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // This file implements export filtering of an AST.
11 func filterIdentList(list []*ast.Ident) []*ast.Ident {
13 for _, x := range list {
14 if ast.IsExported(x.Name) {
22 func baseName(x ast.Expr) *ast.Ident {
23 switch t := x.(type) {
26 case *ast.SelectorExpr:
27 if _, ok := t.X.(*ast.Ident); ok {
36 func (doc *docReader) filterFieldList(fields *ast.FieldList) (removedFields bool) {
42 for _, f := range list {
44 if len(f.Names) == 0 {
46 name := baseName(f.Type)
47 keepField = name != nil && name.IsExported()
50 f.Names = filterIdentList(f.Names)
54 keepField = len(f.Names) > 0
57 doc.filterType(f.Type)
65 fields.List = list[0:j]
69 func (doc *docReader) filterParamList(fields *ast.FieldList) bool {
74 for _, f := range fields.List {
75 if doc.filterType(f.Type) {
82 func (doc *docReader) filterType(typ ast.Expr) bool {
83 switch t := typ.(type) {
85 return ast.IsExported(t.Name)
87 return doc.filterType(t.X)
89 return doc.filterType(t.Elt)
91 if doc.filterFieldList(t.Fields) {
94 return len(t.Fields.List) > 0
96 b1 := doc.filterParamList(t.Params)
97 b2 := doc.filterParamList(t.Results)
99 case *ast.InterfaceType:
100 if doc.filterFieldList(t.Methods) {
103 return len(t.Methods.List) > 0
105 b1 := doc.filterType(t.Key)
106 b2 := doc.filterType(t.Value)
109 return doc.filterType(t.Value)
114 func (doc *docReader) filterSpec(spec ast.Spec) bool {
115 switch s := spec.(type) {
117 s.Names = filterIdentList(s.Names)
118 if len(s.Names) > 0 {
119 doc.filterType(s.Type)
123 if ast.IsExported(s.Name.Name) {
124 doc.filterType(s.Type)
131 func (doc *docReader) filterSpecList(list []ast.Spec) []ast.Spec {
133 for _, s := range list {
134 if doc.filterSpec(s) {
142 func (doc *docReader) filterDecl(decl ast.Decl) bool {
143 switch d := decl.(type) {
145 d.Specs = doc.filterSpecList(d.Specs)
146 return len(d.Specs) > 0
148 return ast.IsExported(d.Name.Name)
153 // fileExports trims the AST for a Go file in place such that
154 // only exported nodes remain. fileExports returns true if
155 // there are exported declarations; otherwise it returns false.
157 func (doc *docReader) fileExports(src *ast.File) bool {
159 for _, d := range src.Decls {
160 if doc.filterDecl(d) {
165 src.Decls = src.Decls[0:j]