1// Copyright 2009 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. 4 5// +build go1.16 6 7package doc 8 9import "go/ast" 10 11type Filter func(string) bool 12 13func matchFields(fields *ast.FieldList, f Filter) bool { 14 if fields != nil { 15 for _, field := range fields.List { 16 for _, name := range field.Names { 17 if f(name.Name) { 18 return true 19 } 20 } 21 } 22 } 23 return false 24} 25 26func matchDecl(d *ast.GenDecl, f Filter) bool { 27 for _, d := range d.Specs { 28 switch v := d.(type) { 29 case *ast.ValueSpec: 30 for _, name := range v.Names { 31 if f(name.Name) { 32 return true 33 } 34 } 35 case *ast.TypeSpec: 36 if f(v.Name.Name) { 37 return true 38 } 39 switch t := v.Type.(type) { 40 case *ast.StructType: 41 if matchFields(t.Fields, f) { 42 return true 43 } 44 case *ast.InterfaceType: 45 if matchFields(t.Methods, f) { 46 return true 47 } 48 } 49 } 50 } 51 return false 52} 53 54func filterValues(a []*Value, f Filter) []*Value { 55 w := 0 56 for _, vd := range a { 57 if matchDecl(vd.Decl, f) { 58 a[w] = vd 59 w++ 60 } 61 } 62 return a[0:w] 63} 64 65func filterFuncs(a []*Func, f Filter) []*Func { 66 w := 0 67 for _, fd := range a { 68 if f(fd.Name) { 69 a[w] = fd 70 w++ 71 } 72 } 73 return a[0:w] 74} 75 76func filterTypes(a []*Type, f Filter) []*Type { 77 w := 0 78 for _, td := range a { 79 n := 0 // number of matches 80 if matchDecl(td.Decl, f) { 81 n = 1 82 } else { 83 // type name doesn't match, but we may have matching consts, vars, factories or methods 84 td.Consts = filterValues(td.Consts, f) 85 td.Vars = filterValues(td.Vars, f) 86 td.Funcs = filterFuncs(td.Funcs, f) 87 td.Methods = filterFuncs(td.Methods, f) 88 n += len(td.Consts) + len(td.Vars) + len(td.Funcs) + len(td.Methods) 89 } 90 if n > 0 { 91 a[w] = td 92 w++ 93 } 94 } 95 return a[0:w] 96} 97 98// Filter eliminates documentation for names that don't pass through the filter f. 99// TODO(gri): Recognize "Type.Method" as a name. 100// 101func (p *Package) Filter(f Filter) { 102 p.Consts = filterValues(p.Consts, f) 103 p.Vars = filterValues(p.Vars, f) 104 p.Types = filterTypes(p.Types, f) 105 p.Funcs = filterFuncs(p.Funcs, f) 106 p.Doc = "" // don't show top-level package doc 107} 108