func loadFunc(obj types.Object) *funcNode { f := newFuncNode(obj, nil) fset := token.NewFileSet() file, err := parser.ParseFile(fset, fluxPath(obj), nil, parser.ParseComments) if err == nil { r := &reader{fset, obj.GetPkg(), types.NewScope(obj.GetPkg().Scope()), map[string]*port{}, map[string][]*connection{}, ast.NewCommentMap(fset, file, file.Comments), map[int]node{}} for _, i := range file.Imports { path, _ := strconv.Unquote(i.Path.Value) pkg, err := getPackage(path) if err != nil { fmt.Printf("error importing %s: %s\n", i.Path.Value, err) continue } name := pkg.Name if i.Name != nil { name = i.Name.Name } r.scope.Insert(types.NewPkgName(0, pkg, name)) } decl := file.Decls[len(file.Decls)-1].(*ast.FuncDecl) // get param and result var names from the source, as the obj names might not match if decl.Recv != nil { r.out(decl.Recv.List[0].Names[0], f.inputsNode.newOutput(obj.GetType().(*types.Signature).Recv)) } r.fun(f, decl.Type, decl.Body) } else { // this is a new func; save it if isMethod(obj) { f.inputsNode.newOutput(obj.GetType().(*types.Signature).Recv) } saveFunc(f) } return f }
func (b browser) filteredObjs() (objs objects) { add := func(obj types.Object) { if invisible(obj, b.currentPkg) { return } if _, ok := obj.(*pkgObject); ok || b.options.objFilter == nil || b.options.objFilter(obj) { objs = append(objs, obj) } } addSubPkgs := func(importPath string) { seen := map[string]bool{} for _, srcDir := range build.Default.SrcDirs() { files, err := ioutil.ReadDir(filepath.Join(srcDir, importPath)) if err != nil { continue } for _, f := range files { name := filepath.Base(f.Name()) if !f.IsDir() || !unicode.IsLetter([]rune(name)[0]) || name == "testdata" || seen[name] { continue } if _, ok := b.newObj.(*pkgObject); ok && name == b.oldName { // when editing a package path, it will be added in filteredObjs as newObj, so don't add it here continue } seen[name] = true importPath := path.Join(importPath, name) pkgObj, ok := pkgObjects[importPath] if !ok { if pkg, err := build.Import(importPath, "", build.AllowBinary); err == nil { name = pkg.Name } pkgObj = &pkgObject{nil, path.Base(importPath), srcDir, importPath, name} pkgObjects[importPath] = pkgObj } add(pkgObj) } } } if b.typ != nil { mset := types.NewMethodSet(b.typ) for i := 0; i < mset.Len(); i++ { m := mset.At(i) // m.Type() has the correct receiver for inherited methods (m.Obj does not) add(types.NewFunc(0, m.Obj.GetPkg(), m.Obj.GetName(), m.Type().(*types.Signature))) } fset := types.NewFieldSet(b.typ) for i := 0; i < fset.Len(); i++ { f := fset.At(i) add(field{f.Obj.(*types.Var), f.Recv, f.Indirect}) } } else if len(b.path) > 0 { switch obj := b.path[0].(type) { case *pkgObject: if pkg, err := getPackage(obj.importPath); err == nil { for _, obj := range pkg.Scope().Objects { add(obj) } } else { if _, ok := err.(*build.NoGoError); !ok { fmt.Println(err) } pkgs[obj.importPath] = types.NewPackage(obj.importPath, obj.pkgName, types.NewScope(types.Universe)) } addSubPkgs(obj.importPath) case *types.TypeName: for _, m := range intuitiveMethodSet(obj.Type) { if types.IsIdentical(m.Obj.(*types.Func).Type.(*types.Signature).Recv.Type, m.Recv) { // preserve Object identity for non-inherited methods so that fluxObjs works add(m.Obj) } else { // m.Type() has the correct receiver for inherited methods (m.Obj does not) add(types.NewFunc(0, m.Obj.GetPkg(), m.Obj.GetName(), m.Type().(*types.Signature))) } } } } else { for _, name := range []string{"break", "call", "continue", "convert", "defer", "func", "go", "if", "loop", "return", "select", "typeAssert"} { add(special{newVar(name, nil)}) } for _, name := range []string{"=", "*"} { add(newVar(name, nil)) } pkgs := b.imports if b.currentPkg != nil { pkgs = append(pkgs, b.currentPkg) } for _, p := range pkgs { for _, obj := range p.Scope().Objects { add(obj) } } for _, obj := range types.Universe.Objects { switch obj.GetName() { case "nil", "print", "println": continue } add(obj) } for _, op := range []string{"!", "&&", "||", "+", "-", "*", "/", "%", "&", "|", "^", "&^", "<<", ">>", "==", "!=", "<", "<=", ">", ">=", "[]", "[:]", "<-"} { add(types.NewFunc(0, nil, op, nil)) } for _, t := range []*types.TypeName{protoPointer, protoArray, protoSlice, protoMap, protoChan, protoFunc, protoInterface, protoStruct} { add(t) } addSubPkgs("") } sort.Sort(objs) return }