Example #1
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
}
Example #2
0
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
}
Example #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")
}
Example #4
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
}
Example #5
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
}
Example #6
0
func setObjectName(obj types.Object, name string) {
	switch obj := obj.(type) {
	case *pkgObject:
		obj.name = name
	case *types.TypeName:
		obj.Name = name
	case *types.Func:
		obj.Name = name
	case *types.Var:
		obj.Name = name
	case *types.Const:
		obj.Name = name
	}
}
Example #7
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
}
Example #8
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
}
Example #9
0
func newWriter(obj types.Object) *writer {
	src, err := os.Create(fluxPath(obj))
	if err != nil {
		fmt.Printf("error creating %s: %s\n", fluxPath(obj), err)
		return nil
	}
	w := &writer{src, obj.GetPkg(), map[*types.Package]string{}, map[string]int{}, 0, map[node]int{}, 0}
	fluxObjs[obj] = true

	w.write("// Generated by Flux, not meant for human consumption.  Editing may make it unreadable by Flux.\n\n")
	w.write("package %s\n\n", w.pkg.Name)
	for _, name := range append(types.Universe.Names(), w.pkg.Scope().Names()...) {
		w.name(name)
	}
	return w
}
Example #10
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
}
Example #11
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
}
Example #12
0
func color(obj types.Object, bright, funcAsVal bool) Color {
	alpha := .7
	if bright {
		alpha = 1
	}
	switch obj.(type) {
	case special:
		return Color{1, 1, .6, alpha}
	case *pkgObject:
		return Color{1, 1, 1, alpha}
	case *types.TypeName:
		return Color{.6, 1, .6, alpha}
	case *types.Func, *types.Builtin:
		if funcAsVal && obj.GetPkg() != nil { //Pkg==nil == builtin
			return color(&types.Var{}, bright, funcAsVal)
		}
		return Color{1, .6, .6, alpha}
	case *types.Var, *types.Const, field:
		return Color{.6, .6, 1, alpha}
	}
	panic(fmt.Sprintf("unknown object type %T", obj))
}
Example #13
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")
}
Example #14
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
}
Example #15
0
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
}
Example #16
0
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)
	}
}
Example #17
0
func invisible(obj types.Object, p *types.Package) bool {
	p2 := obj.GetPkg()
	return !(p2 == nil || p == nil || p2 == p || obj.IsExported())
}
Example #18
0
func isOperator(obj types.Object) bool {
	name := obj.GetName()
	return len(name) > 0 && !unicode.IsLetter([]rune(name)[0])
}