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 (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) } } }