func loadExportsGoPath(dir string) map[string]bool { exports := make(map[string]bool) buildPkg, err := build.ImportDir(dir, 0) if err != nil { if strings.Contains(err.Error(), "no buildable Go source files in") { return nil } fmt.Fprintf(os.Stderr, "could not import %q: %v\n", dir, err) return nil } fset := token.NewFileSet() for _, files := range [...][]string{buildPkg.GoFiles, buildPkg.CgoFiles} { for _, file := range files { f, err := parser.ParseFile(fset, filepath.Join(dir, file), nil, 0) if err != nil { fmt.Fprintf(os.Stderr, "could not parse %q: %v\n", file, err) continue } for name := range f.Scope.Objects { if ast.IsExported(name) { exports[name] = true } } } } return exports }
// filterIdentList removes unexported names from list in place // and returns the resulting list. // func filterIdentList(list []*ast.Ident) []*ast.Ident { j := 0 for _, x := range list { if ast.IsExported(x.Name) { list[j] = x j++ } } return list[0:j] }
func (r *reader) filterDecl(decl ast.Decl) bool { switch d := decl.(type) { case *ast.GenDecl: d.Specs = r.filterSpecList(d.Specs, d.Tok) return len(d.Specs) > 0 case *ast.FuncDecl: // ok to filter these methods early because any // conflicting method will be filtered here, too - // thus, removing these methods early will not lead // to the false removal of possible conflicts return ast.IsExported(d.Name.Name) } return false }
// filterFieldList removes unexported fields (field names) from the field list // in place and reports whether fields were removed. Anonymous fields are // recorded with the parent type. filterType is called with the types of // all remaining fields. // func (r *reader) filterFieldList(parent *namedType, fields *ast.FieldList, ityp *ast.InterfaceType) (removedFields bool) { if fields == nil { return } list := fields.List j := 0 for _, field := range list { keepField := false if n := len(field.Names); n == 0 { // anonymous field fname := r.recordAnonymousField(parent, field.Type) if ast.IsExported(fname) { keepField = true } else if ityp != nil && fname == "error" { // possibly the predeclared error interface; keep // it for now but remember this interface so that // it can be fixed if error is also defined locally keepField = true r.remember(ityp) } } else { field.Names = filterIdentList(field.Names) if len(field.Names) < n { removedFields = true } if len(field.Names) > 0 { keepField = true } } if keepField { r.filterType(nil, field.Type) list[j] = field j++ } } if j < len(list) { removedFields = true } fields.List = list[0:j] return }
// Id returns name if it is exported, otherwise it // returns the name qualified with the package path. func Id(pkg *Package, name string) string { if ast.IsExported(name) { return name } // unexported names need the package path for differentiation // (if there's no package, make sure we don't start with '.' // as that may change the order of methods between a setup // inside a package and outside a package - which breaks some // tests) path := "_" // TODO(gri): shouldn't !ast.IsExported(name) => pkg != nil be an precondition? // if pkg == nil { // panic("nil package in lookup of unexported name") // } if pkg != nil { path = pkg.path if path == "" { path = "_" } } return path + "." + name }
func (r *reader) filterSpec(spec ast.Spec, tok token.Token) bool { switch s := spec.(type) { case *ast.ImportSpec: // always keep imports so we can collect them return true case *ast.ValueSpec: s.Names.List = filterIdentList(s.Names.List) if len(s.Names.List) > 0 { r.filterType(nil, s.Type) return true } case *ast.TypeSpec: if name := s.Name.Name; ast.IsExported(name) { r.filterType(r.lookupType(s.Name.Name), s.Type) return true } else if name == "error" { // special case: remember that error is declared locally r.errorDecl = true } } return false }
func sortedFuncs(m methodSet, allMethods bool) []*Func { list := make([]*Func, len(m)) i := 0 for _, m := range m { // determine which methods to include switch { case m.Decl == nil: // exclude conflict entry case allMethods, m.Level == 0, !ast.IsExported(removeStar(m.Orig)): // forced inclusion, method not embedded, or method // embedded but original receiver type not exported list[i] = m i++ } } list = list[0:i] sortBy( func(i, j int) bool { return list[i].Name < list[j].Name }, func(i, j int) { list[i], list[j] = list[j], list[i] }, len(list), ) return list }
func loadExports(dir string) map[string]bool { exports := make(map[string]bool) buildPkg, err := build.ImportDir(dir, 0) if err != nil { if strings.Contains(err.Error(), "no buildable Go source files in") { return nil } log.Printf("could not import %q: %v", dir, err) return nil } for _, file := range buildPkg.GoFiles { f, err := parser.ParseFile(fset, filepath.Join(dir, file), nil, 0) if err != nil { log.Printf("could not parse %q: %v", file, err) continue } for name := range f.Scope.Objects { if ast.IsExported(name) { exports[name] = true } } } return exports }
func (obj *object) Exported() bool { return ast.IsExported(obj.name) }
func (r *reader) isVisible(name string) bool { return r.mode&AllDecls != 0 || ast.IsExported(name) }