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