示例#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
}
示例#2
0
func isMakeableType(obj types.Object) bool {
	switch obj {
	case protoSlice, protoMap, protoChan:
		return true
	}
	if obj, ok := obj.(*types.TypeName); ok {
		switch underlying(obj.GetType()).(type) {
		case *types.Slice, *types.Map, *types.Chan:
			return true
		}
	}
	return false
}
示例#3
0
func isCompositeType(obj types.Object) bool {
	switch obj {
	case protoArray, protoSlice, protoMap, protoStruct:
		return true
	}
	if obj, ok := obj.(*types.TypeName); ok {
		switch underlying(obj.GetType()).(type) {
		case *types.Array, *types.Slice, *types.Map, *types.Struct:
			return true
		}
	}
	return false
}
示例#4
0
func isGoDeferrable(obj types.Object) bool {
	switch obj := obj.(type) {
	case special:
		return obj.Name == "call"
	case *types.Builtin:
		switch obj.Name {
		case "close", "copy", "delete", "panic", "recover":
			return true
		}
	case *types.Func:
		return !isOperator(obj)
	case *types.TypeName:
		_, ok := obj.GetType().(*types.Named)
		return ok
	}
	return false
}
示例#5
0
func fluxPath(obj types.Object) string {
	pkg, err := build.Import(obj.GetPkg().Path, "", build.FindOnly)
	if err != nil {
		fmt.Println("error importing \"%s\": %s\n", obj.GetPkg().Path, err)
		return ""
	}

	name := obj.GetName()
	if !obj.IsExported() { // unexported names are suffixed with "-" to avoid possible conflicts on case-insensitive systems
		name += "-"
	}
	if isMethod(obj) {
		t, _ := indirect(obj.GetType().(*types.Signature).Recv.Type)
		recv := t.(*types.Named).Obj
		typeName := recv.Name
		if !recv.IsExported() {
			typeName += "-"
		}
		name = typeName + "." + name
	}
	return filepath.Join(pkg.Dir, name+".flux.go")
}
示例#6
0
文件: call.go 项目: gordonklaus/flux
func newCallNode(obj types.Object, currentPkg *types.Package, godefer string) node {
	if obj == nil {
		n := &callNode{}
		n.nodeBase = newGoDeferNodeBase(n, godefer)
		if godefer == "" {
			n.text.SetText("call")
		} else {
			n.text.SetText("") //trigger TextChanged
		}
		n.text.SetTextColor(color(special{}, true, false))
		n.addSeqPorts()
		in := n.newInput(nil)
		in.connsChanged = func() {
			t := inputType(in)
			in.setType(t)
			// TODO: add/remove/modify only the affected ports.  beware: t == in.obj.Type because portsNode mutates the signature in place.
			for _, p := range append(ins(n)[1:], outs(n)...) {
				n.removePortBase(p)
			}
			if t != nil {
				n.addPorts(underlying(t).(*types.Signature))
			}
		}
		return n
	}

	if sig, ok := obj.GetType().(*types.Signature); ok {
		n := &callNode{obj: obj}
		n.nodeBase = newGoDeferNodeBase(n, godefer)
		name := obj.GetName()
		if sig.Recv != nil {
			name = "." + name
		} else if p := obj.GetPkg(); p != currentPkg && p != nil {
			n.pkg.setPkg(obj.GetPkg())
		}
		n.text.SetText(name)
		n.text.SetTextColor(color(&types.Func{}, true, false))
		n.addSeqPorts()
		n.addPorts(sig)
		return n
	}

	switch name := obj.GetName(); name {
	case "append":
		return newAppendNode()
	case "close":
		return newCloseNode(godefer)
	case "complex":
		return newComplexNode()
	case "copy":
		return newCopyNode(godefer)
	case "delete":
		return newDeleteNode(godefer)
	case "len", "cap":
		return newLenCapNode(name)
	case "make":
		return newMakeNode(currentPkg)
	case "new":
		return newNewNode(currentPkg)
	case "panic", "recover":
		return newPanicRecoverNode(name, godefer)
	case "real", "imag":
		return newRealImagNode(name)
	default:
		panic("unknown builtin: " + name)
	}
}