示例#1
0
文件: value.go 项目: gordonklaus/flux
func newValueNode(obj types.Object, currentPkg *types.Package, set bool) *valueNode {
	n := &valueNode{obj: obj, set: set}
	n.nodeBase = newNodeBase(n)
	dot := ""
	switch obj.(type) {
	case field, *types.Func, nil:
		if _, ok := obj.(*types.Func); !ok || isMethod(obj) {
			n.x = n.newInput(nil)
			if obj == nil {
				n.x.connsChanged = n.connsChanged
			}
			dot = "."
		}
	}
	if obj != nil {
		if p := obj.GetPkg(); p != currentPkg && p != nil && dot == "" {
			n.pkg.setPkg(p)
		}
		n.text.SetText(dot + obj.GetName())
	}
	n.text.SetTextColor(color(&types.Var{}, true, false))
	if set {
		n.y = n.newInput(nil)
	} else {
		n.y = n.newOutput(nil)
	}
	n.addSeqPorts()
	n.connsChanged()
	return n
}
示例#2
0
func (w writer) qualifiedName(obj types.Object) string {
	n := obj.GetName()
	if p, ok := w.pkgNames[obj.GetPkg()]; ok {
		return p + "." + n
	}
	return n
}
示例#3
0
func objLess(o1, o2 types.Object) bool {
	n1, n2 := o1.GetName(), o2.GetName()
	switch o1.(type) {
	case special:
		switch o2.(type) {
		case special:
			return n1 < n2
		default:
			return true
		}
	case *types.TypeName:
		switch o2.(type) {
		case special:
			return false
		case *types.TypeName:
			return n1 < n2
		default:
			return true
		}
	case *types.Func, *types.Builtin:
		switch o2.(type) {
		case special, *types.TypeName:
			return false
		case *types.Func, *types.Builtin:
			return n1 < n2
		default:
			return true
		}
	case *types.Var, field:
		switch o2.(type) {
		default:
			return false
		case *types.Var, field:
			return n1 < n2
		case *types.Const, *pkgObject:
			return true
		}
	case *types.Const:
		switch o2.(type) {
		default:
			return false
		case *types.Const:
			return n1 < n2
		case *pkgObject:
			return true
		}
	case *pkgObject:
		switch o2.(type) {
		default:
			return false
		case *pkgObject:
			return n1 < n2
		}
	}
	panic("unreachable")
}
示例#4
0
func newOperatorNode(obj types.Object) *operatorNode {
	n := &operatorNode{op: obj.GetName()}
	n.nodeBase = newNodeBase(n)
	n.text.SetText(n.op)
	n.text.SetTextColor(color(&types.Func{}, true, false))

	n.newInput(nil).connsChanged = n.connsChanged
	if n.op != "!" {
		n.newInput(nil).connsChanged = n.connsChanged
	}
	n.newOutput(nil)

	n.connsChanged()
	return n
}
示例#5
0
func unknown(obj types.Object) bool {
	switch obj := obj.(type) {
	case field:
		fm, _, _ := types.LookupFieldOrMethod(obj.recv, obj.Pkg, obj.Name)
		_, ok := fm.(*types.Var)
		return !ok
	case *types.Func:
		if sig, ok := obj.Type.(*types.Signature); ok && sig.Recv != nil {
			fm, _, _ := types.LookupFieldOrMethod(sig.Recv.Type, obj.Pkg, obj.Name)
			_, ok := fm.(*types.Func)
			return !ok
		}
	}
	pkg := obj.GetPkg()
	return pkg != nil && pkg.Scope().Lookup(obj.GetName()) == nil
}
示例#6
0
func deleteObj(obj types.Object) bool {
	if p, ok := obj.(*pkgObject); ok {
		if p, err := getPackage(p.importPath); err == nil {
			for _, obj := range p.Scope().Objects {
				deleteObj(obj)
			}
		}
		dir := p.fullPath()
		os.Remove(filepath.Join(dir, "package.flux.go"))
		os.Remove(filepath.Join(dir, ".DS_Store"))
		if files, err := ioutil.ReadDir(dir); err != nil || len(files) > 0 || trash.Trash(dir) != nil {
			return false
		}
		delete(pkgObjects, p.importPath)
		delete(pkgs, p.importPath)
		return true
	}
	if !fluxObjs[obj] {
		return false
	}
	if t, ok := obj.(*types.TypeName); ok {
		t := t.Type.(*types.Named)
		for _, m := range t.Methods {
			deleteObj(m)
		}
		if len(t.Methods) > 0 {
			return false
		}
	}
	if trash.Trash(fluxPath(obj)) != nil {
		return false
	}
	if objs := obj.GetPkg().Scope().Objects; objs[obj.GetName()] == obj {
		delete(objs, obj.GetName())
	} else {
		t, _ := indirect(obj.(*types.Func).Type.(*types.Signature).Recv.Type)
		n := t.(*types.Named)
		for i, f2 := range n.Methods {
			if f2 == obj {
				n.Methods = append(n.Methods[:i], n.Methods[i+1:]...)
				break
			}
		}
	}
	delete(fluxObjs, obj)
	return true
}
示例#7
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")
}
示例#8
0
文件: block.go 项目: gordonklaus/flux
func (b *block) newNode(obj types.Object, funcAsVal bool, godefer string) node {
	var n node
	currentPkg := b.func_().pkg()
	switch obj := obj.(type) {
	case special:
		switch obj.Name {
		case "break", "continue", "return":
			n = newBranchNode(obj.Name)
		case "call":
			n = newCallNode(nil, currentPkg, godefer)
		case "convert":
			n = newConvertNode(currentPkg)
		case "func":
			n = newFuncNode(nil, b.childArranged)
		case "go", "defer":
			godefer = obj.Name + " "
			browser := newBrowser(browserOptions{objFilter: isGoDeferrable, enterTypes: true}, b)
			browser.Move(Center(b))
			browser.accepted = func(obj types.Object) {
				browser.Close()
				b.newNode(obj, false, godefer)
			}
			browser.canceled = func() {
				browser.Close()
				SetKeyFocus(b)
			}
			b.Add(browser)
			SetKeyFocus(browser)
			return nil
		case "if":
			i := newIfNode(b.childArranged)
			i.newBlock()
			n = i
		case "loop":
			n = newLoopNode(b.childArranged)
		case "select":
			n = newSelectNode(b.childArranged)
		case "typeAssert":
			n = newTypeAssertNode(currentPkg)
		}
	case *types.Func, *types.Builtin:
		if obj.GetName() == "[]" {
			n = newIndexNode(false)
		} else if obj.GetName() == "[:]" {
			n = newSliceNode()
		} else if obj.GetName() == "<-" {
			n = newChanNode(true)
		} else if isOperator(obj) {
			n = newOperatorNode(obj)
		} else if funcAsVal && obj.GetPkg() != nil { //Pkg==nil == builtin
			n = newValueNode(obj, currentPkg, false)
		} else {
			n = newCallNode(obj, currentPkg, godefer)
		}
	case *types.Var, *types.Const, field:
		switch obj.GetName() {
		default:
			n = newValueNode(obj, currentPkg, false)
		case "=":
			n = newValueNode(nil, nil, true)
		case "*":
			n = newValueNode(nil, nil, false)
		}
	}
	b.addNode(n)
	MoveCenter(n, Center(b))
	if nn, ok := n.(interface {
		editType()
	}); ok {
		nn.editType()
	} else {
		SetKeyFocus(n)
	}
	return n
}
示例#9
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)
	}
}
示例#10
0
func isOperator(obj types.Object) bool {
	name := obj.GetName()
	return len(name) > 0 && !unicode.IsLetter([]rune(name)[0])
}