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