Beispiel #1
0
type pkgObject struct {
	types.Object
	name                        string // the final path element; display name
	srcDir, importPath, pkgName string
}

func (p pkgObject) fullPath() string {
	return filepath.Join(p.srcDir, p.importPath)
}

func (p pkgObject) GetName() string        { return p.name }
func (p pkgObject) GetPkg() *types.Package { return nil }

var (
	protoPointer   = types.NewTypeName(0, nil, "pointer", nil)
	protoArray     = types.NewTypeName(0, nil, "array", nil)
	protoSlice     = types.NewTypeName(0, nil, "slice", nil)
	protoMap       = types.NewTypeName(0, nil, "map", nil)
	protoChan      = types.NewTypeName(0, nil, "chan", nil)
	protoFunc      = types.NewTypeName(0, nil, "func", nil)
	protoInterface = types.NewTypeName(0, nil, "interface", nil)
	protoStruct    = types.NewTypeName(0, nil, "struct", nil)
)

func newProtoType(t *types.TypeName) types.Type {
	switch t {
	case protoPointer:
		return &types.Pointer{}
	case protoArray:
		return &types.Array{}
Beispiel #2
0
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)
		}
	}
}
Beispiel #3
0
func (r *reader) typ(x ast.Expr) types.Type {
	switch x := x.(type) {
	case *ast.Ident:
		if t, ok := r.scope.LookupParent(x.Name).(*types.TypeName); ok {
			return t.Type
		}
		return types.NewNamed(types.NewTypeName(0, r.pkg, x.Name, nil), types.Typ[types.Invalid], nil) //unknown(t.Obj) == true
	case *ast.SelectorExpr:
		pkg := r.scope.LookupParent(name(x.X)).(*types.PkgName).Pkg
		if t, ok := pkg.Scope().Lookup(x.Sel.Name).(*types.TypeName); ok {
			return t.Type
		}
		return types.NewNamed(types.NewTypeName(0, r.pkg, x.Sel.Name, nil), types.Typ[types.Invalid], nil) //unknown(t.Obj) == true
	case *ast.StarExpr:
		return types.NewPointer(r.typ(x.X))
	case *ast.ArrayType:
		elem := r.typ(x.Elt)
		if x.Len != nil {
			// TODO: x.Len
			return types.NewArray(elem, 0)
		}
		return types.NewSlice(elem)
	case *ast.Ellipsis:
		return types.NewSlice(r.typ(x.Elt))
	case *ast.MapType:
		return types.NewMap(r.typ(x.Key), r.typ(x.Value))
	case *ast.ChanType:
		dir := types.SendRecv
		if x.Dir&ast.SEND == 0 {
			dir = types.RecvOnly
		}
		if x.Dir&ast.RECV == 0 {
			dir = types.SendOnly
		}
		return types.NewChan(dir, r.typ(x.Value))
	case *ast.FuncType:
		var params, results []*types.Var
		for _, f := range x.Params.List {
			t := r.typ(f.Type)
			if f.Names == nil {
				params = append(params, types.NewParam(0, r.pkg, "", t))
			}
			for _, n := range f.Names {
				params = append(params, types.NewParam(0, r.pkg, n.Name, t))
			}
		}
		variadic := false
		if x.Results != nil {
			for _, f := range x.Results.List {
				t := r.typ(f.Type)
				if f.Names == nil {
					results = append(results, types.NewParam(0, r.pkg, "", t))
				}
				for _, n := range f.Names {
					results = append(results, types.NewParam(0, r.pkg, n.Name, t))
				}
				_, variadic = f.Type.(*ast.Ellipsis)
			}
		}
		return types.NewSignature(nil, nil, params, results, variadic)
	case *ast.StructType:
		var fields []*types.Var
		if x.Fields != nil {
			for _, f := range x.Fields.List {
				t := r.typ(f.Type)
				if f.Names == nil {
					fields = append(fields, types.NewField(0, r.pkg, "", t, true))
				}
				for _, n := range f.Names {
					fields = append(fields, types.NewField(0, r.pkg, n.Name, t, false))
				}
			}
		}
		return types.NewStruct(fields, nil)
	case *ast.InterfaceType:
		var methods []*types.Func
		var embeddeds []*types.Named
		if x.Methods != nil {
			for _, f := range x.Methods.List {
				switch t := r.typ(f.Type).(type) {
				case *types.Signature:
					methods = append(methods, types.NewFunc(0, r.pkg, f.Names[0].Name, t))
				case *types.Named:
					embeddeds = append(embeddeds, t)
				}
			}
		}
		return types.NewInterface(methods, embeddeds)
	}
	panic("unreachable")
}