func (r *reader) value(b *block, x, y ast.Expr, set bool, s ast.Stmt) { if x2, ok := x.(*ast.UnaryExpr); ok { x = x2.X } var obj types.Object if _, ok := x.(*ast.StarExpr); !ok { // StarExpr indicates an assignment (*x = y), for which obj must be nil obj = r.obj(x) if u, ok := obj.(unknownObject); ok { if _, ok := s.(*ast.DeclStmt); ok { obj = types.NewConst(0, u.pkg, u.name, nil, nil) } else { var t types.Type if set { t = r.scope.Lookup(name(y)).(*types.Var).Type } addr := false if s, ok := s.(*ast.AssignStmt); ok { if s.Tok == token.DEFINE { _, addr = s.Rhs[0].(*ast.UnaryExpr) } } if u.recv != nil { obj = field{types.NewVar(0, u.pkg, u.name, t), u.recv, addr} // it may be a method val, but a non-addressable field is close enough } else { if addr { obj = types.NewVar(0, u.pkg, u.name, t) } else { obj = types.NewFunc(0, u.pkg, u.name, types.NewSignature(nil, newVar("", u.recv), nil, nil, false)) } } } //unknown(obj) == true } } n := newValueNode(obj, r.pkg, set) b.addNode(n) switch x := x.(type) { case *ast.SelectorExpr: r.in(x.X, n.x) case *ast.StarExpr: r.in(x.X, n.x) } if set { r.in(y, n.y) } else { r.out(y, n.y) } r.seq(n, s) }
func (v *typeView) insertMethod(m *[]*types.Func, elems *[]*typeView, before bool, i int, success, fail func()) { if !before { i++ } sig := &types.Signature{Recv: types.NewVar(0, v.currentPkg, "", *v.typ)} *m = append((*m)[:i], append([]*types.Func{types.NewFunc(0, v.currentPkg, "", sig)}, (*m)[i:]...)...) v.refresh() t := (*elems)[i] t.edit(func() { if *t.typ == nil || len(t.name.Text()) == 0 { *m = append((*m)[:i], (*m)[i+1:]...) v.refresh() if fail != nil { fail() } else { if !before { i-- } SetKeyFocus((*elems)[i]) } } else { if success != nil { success() } else { SetKeyFocus(t) } } }) }
func (v *typeView) insertVar(vs *[]*types.Var, elems *[]*typeView, before bool, i int, success, fail func()) { if !before { i++ } *vs = append((*vs)[:i], append([]*types.Var{types.NewVar(0, v.currentPkg, "", nil)}, (*vs)[i:]...)...) v.refresh() t := (*elems)[i] t.edit(func() { if *t.typ == nil { *vs = append((*vs)[:i], (*vs)[i+1:]...) v.refresh() if fail != nil { fail() } else { if !before { i-- } SetKeyFocus((*elems)[i]) } } else { if success != nil { success() } else { SetKeyFocus(t) } } }) }
func (b *browser) KeyPress(event KeyEvent) { if b.options.canFuncAsVal && event.Shift != b.funcAsVal { b.funcAsVal = event.Shift b.refresh() } switch event.Key { case KeyUp: if b.newObj == nil { b.i-- if b.i < 0 { b.i += len(b.objs) } b.refresh() } case KeyDown: if b.newObj == nil { b.i++ if b.i >= len(b.objs) { b.i -= len(b.objs) } b.refresh() } case KeyLeft: if len(b.path) > 0 && b.newObj == nil { parent := b.path[0] b.path = b.path[1:] i := len(b.pathTexts) - 1 b.pathTexts[i].Close() b.pathTexts = b.pathTexts[:i] b.clearText() b.makeCurrent(parent) } case KeyEnter: obj := b.currentObj() if obj == nil { return } if pkg, ok := obj.(*pkgObject); ok && event.Shift && b.options.mutable && b.newObj == nil { Show(b.pkgName) b.pkgName.Accept = func(name string) { if pkg.pkgName != name { pkg.pkgName = name savePackageName(pkg.importPath, name) } b.refresh() SetKeyFocus(b) } b.pkgName.Reject = func() { b.refresh() SetKeyFocus(b) } SetKeyFocus(b.pkgName) return } if event.Command && b.options.mutable && b.newObj == nil { b.newObj = obj b.oldName = obj.GetName() if p, ok := obj.(*pkgObject); ok { delete(pkgs, p.importPath) delete(pkgObjects, p.importPath) } else { 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 } } } } b.text.SetText(obj.GetName()) return } if obj := b.newObj; obj != nil { if !b.unique(obj.GetName()) { return } b.newObj = nil if p, ok := obj.(*pkgObject); ok { oldImportPath := p.importPath if len(b.path) > 0 { parent := b.path[0].(*pkgObject) p.srcDir = parent.srcDir p.importPath = path.Join(parent.importPath, p.name) } else { dirs := build.Default.SrcDirs() p.srcDir = dirs[len(dirs)-1] p.importPath = p.name } pkgObjects[p.importPath] = p if b.oldName != "" { b.oldName = "" if err := refactor.MovePackage(oldImportPath, p.importPath); err != nil { fmt.Printf("error moving package %s: %s\n", oldImportPath, err) } b.clearText() return } p.pkgName = p.name path := p.fullPath() if err := os.Mkdir(path, 0777); err != nil { fmt.Printf("error creating %s: %s\n", path, err) b.clearText() return } } else { if isMethod(obj) { recv := b.path[0].(*types.TypeName).Type.(*types.Named) recv.Methods = append(recv.Methods, obj.(*types.Func)) } else { pkgs[b.path[0].(*pkgObject).importPath].Scope().Insert(obj) } if b.oldName != "" { newName := obj.GetName() setObjectName(obj, b.oldName) oldPaths := []string{fluxPath(obj)} if t, ok := obj.(*types.TypeName); ok { for _, m := range t.Type.(*types.Named).Methods { oldPaths = append(oldPaths, fluxPath(m)) } } recv := "" if isMethod(obj) { t, _ := indirect(obj.(*types.Func).Type.(*types.Signature).Recv.Type) recv = t.(*types.Named).Obj.Name } if err := refactor.Rename(obj.GetPkg().Path, recv, b.oldName, newName); err != nil { fmt.Printf("error renaming %v to %v: %v\n", b.oldName, newName, err) b.oldName = "" b.clearText() return } setObjectName(obj, newName) newPaths := []string{fluxPath(obj)} if t, ok := obj.(*types.TypeName); ok { for _, m := range t.Type.(*types.Named).Methods { newPaths = append(newPaths, fluxPath(m)) } } for i := range oldPaths { if err := os.Rename(oldPaths[i], newPaths[i]); err != nil { fmt.Println("error renaming files: ", err) } } b.oldName = "" b.clearText() return } } b.makeCurrent(obj) } _, isPkg := obj.(*pkgObject) _, isType := obj.(*types.TypeName) if !(isPkg || isType && !b.options.acceptTypes) { b.finished = true b.accepted(obj) return } fallthrough case KeyRight: if b.newObj == nil { switch obj := b.currentObj().(type) { case *pkgObject, *types.TypeName: if t, ok := obj.(*types.TypeName); ok { if _, ok = t.Type.(*types.Basic); ok || t.Type == nil || !b.options.enterTypes { break } } b.path = append(objects{obj}, b.path...) sep := "." if _, ok := obj.(*pkgObject); ok { sep = "/" } t := NewText(obj.GetName() + sep) t.SetTextColor(color(obj, true, b.funcAsVal)) t.SetBackgroundColor(Color{0, 0, 0, .7}) b.Add(t) x := 0.0 if t, ok := b.lastPathText(); ok { x = Pos(t).X + Width(t) } t.Move(Pt(x, 0)) b.pathTexts = append(b.pathTexts, t) b.clearText() } } case KeyEscape: if b.newObj != nil { if b.oldName != "" { setObjectName(b.newObj, b.oldName) b.oldName = "" if isMethod(b.newObj) { recv := b.path[0].(*types.TypeName).Type.(*types.Named) recv.Methods = append(recv.Methods, b.newObj.(*types.Func)) } else { pkgs[b.path[0].(*pkgObject).importPath].Scope().Insert(b.newObj) } } else if b.i < len(b.objs)-1 { b.i++ } b.newObj = nil b.clearText() } else { b.cancel() } case KeyBackspace: if !event.Command && len(b.text.Text()) > 0 { b.text.KeyPress(event) break } fallthrough case KeyDelete: if event.Command && b.options.mutable && b.newObj == nil { b.clearText() if deleteObj(b.currentObj()) { if b.i > 0 { b.i-- } b.clearText() } } default: if event.Command && (event.Key == KeyN || event.Key == KeyW || event.Key == KeyQ) { b.ViewBase.KeyPress(event) return } if !b.options.mutable { b.text.KeyPress(event) return } makeInPkg := false var pkg *types.Package var recv *types.TypeName if len(b.path) > 0 { switch obj := b.path[0].(type) { case *pkgObject: makeInPkg = true pkg = pkgs[obj.importPath] case *types.TypeName: recv = obj pkg = obj.Pkg } } makePkgInRoot := len(b.path) == 0 && event.Text == "1" makeMethod := recv != nil && event.Text == "3" if b.newObj == nil && event.Command && (makePkgInRoot || makeInPkg || makeMethod) { switch event.Text { case "1": b.newObj = &pkgObject{} case "2": t := types.NewTypeName(0, pkg, "", nil) t.Type = &types.Named{Obj: t} b.newObj = t case "3": sig := &types.Signature{} if recv != nil { sig.Recv = newVar("", &types.Pointer{Elem: recv.Type}) } b.newObj = types.NewFunc(0, pkg, "", sig) case "4": b.newObj = types.NewVar(0, pkg, "", nil) case "5": b.newObj = types.NewConst(0, pkg, "", nil, nil) default: b.text.KeyPress(event) return } b.clearText() } else { b.text.KeyPress(event) } } }
func newVar(name string, typ types.Type) *types.Var { return types.NewVar(0, nil, name, typ) }
func (n *portsNode) KeyPress(event KeyEvent) { if f, ok := n.blk.node.(*funcNode); ok && f.literal && event.Key == KeyDown && n.out { SetKeyFocus(f) } else if l, ok := n.blk.node.(*loopNode); ok && event.Key == KeyUp { SetKeyFocus(l) } else if s, ok := n.blk.node.(*selectNode); ok && event.Key == KeyUp { s.focusFrom(n) } else if n.editable && event.Text == "," { f := n.blk.node.(*funcNode) sig := f.sig() newPort := newOutput ports := &n.outs vars := &sig.Params if n.out { newPort = newInput ports = &n.ins vars = &sig.Results } v := types.NewVar(0, n.blk.func_().pkg(), "", nil) p := newPort(n, v) i := len(*ports) if focus, ok := KeyFocus(n).(*port); ok { for j, p := range *ports { if p == focus { i = j break } } if !event.Shift || i == 0 && p.out && sig.Recv != nil { i++ } } n.Add(p) *ports = append((*ports)[:i], append([]*port{p}, (*ports)[i:]...)...) n.reform() Show(p.valView) p.valView.edit(func() { if v.Type != nil { if p.out && sig.Recv != nil { i-- } *vars = append((*vars)[:i], append([]*types.Var{v}, (*vars)[i:]...)...) if i == len(*vars)-1 { sig.IsVariadic = false } n.blk.func_().addPkgRef(v.Type) SetKeyFocus(p) } else { n.removePortBase(p) } if f.obj == nil { f.output.setType(sig) } }) } else if n.editable && !n.out && event.Key == KeyPeriod && event.Ctrl { f := n.blk.node.(*funcNode) sig := f.sig() len := len(n.outs) if len > 0 && (sig.Recv == nil || len > 1) { p := n.outs[len-1] if KeyFocus(n) != p { return } sig.IsVariadic = !sig.IsVariadic p.valView.ellipsis = sig.IsVariadic if sig.IsVariadic { p.setType(&types.Slice{p.obj.Type}) } else { p.setType(p.obj.Type.(*types.Slice).Elem) } if f.obj == nil { f.output.setType(sig) } } } else { n.nodeBase.KeyPress(event) } }