Esempio n. 1
0
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
}
Esempio n. 2
0
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
}