func Rename(filename string, line int, column int, newName string) (ok bool, err *errors.GoRefactorError) { if ok, err = CheckRenameParameters(filename, line, column, newName); !ok { return } programTree := parseProgram(filename) var sym st.Symbol if sym, err = programTree.FindSymbolByPosition(filename, line, column); err == nil { if _, ok := sym.(*st.PointerTypeSymbol); ok { panic("find by position returned pointer type!!!") } if st.IsPredeclaredIdentifier(sym.Name()) { return false, errors.UnrenamableIdentifierError(sym.Name(), " It's a basic language symbol") } if sym.PackageFrom().IsGoPackage { return false, errors.UnrenamableIdentifierError(sym.Name(), " It's a symbol,imported from go library") } if unicode.IsUpper(int(sym.Name()[0])) && !unicode.IsUpper(int(newName[0])) || unicode.IsLower(int(sym.Name()[0])) && !unicode.IsLower(int(newName[0])) { return false, &errors.GoRefactorError{ErrorType: "Can't rename identifier", Message: "can't change access modifier. Changing first letter's case can cause errors."} } if _, ok := sym.Scope().LookUp(newName, filename); ok { return false, errors.IdentifierAlreadyExistsError(newName) } if meth, ok := sym.(*st.FunctionSymbol); ok { if meth.IsInterfaceMethod { return false, errors.UnrenamableIdentifierError(sym.Name(), " It's an interface method") } } if ps, ok := sym.(*st.PackageSymbol); ok { pack, file := programTree.FindPackageAndFileByFilename(filename) impDecl := findImportDecl(pack, file, ps) if impDecl == nil { panic("couldn't find import decl") } if impDecl.Name == nil || impDecl.Name.Name == "" { impDecl.Name = ast.NewIdent(newName) } } fnames, fsets, files, err := renameSymbol(sym, newName, programTree) if err == nil { for i, f := range fnames { programTree.SaveFileExplicit(f, fsets[i], files[i]) } } return err == nil, err } else { return false, err } panic("unreachable code") }
//Fixes Type and its' subtypes recursively func (pp *packageParser) fixType(sym st.Symbol) { if sym == nil { panic("error: fixing nil symbol") } if st.IsPredeclaredIdentifier(sym.Name()) { return } if sym.PackageFrom() != pp.Package { return } // fmt.Printf("%s fixing %v %T %p\n", pp.Package.AstPackage.Name, sym.Name(), sym, sym) if pp.checkIsVisited(sym) { return } //fmt.Printf("%s fixing %v %T %p\n", pp.Package.AstPackage.Name, sym.Name(), sym,sym) switch t := sym.(type) { case *st.AliasTypeSymbol: pp.fixAliasTypeSymbol(t) case *st.PointerTypeSymbol: pp.fixPointerTypeSymbol(t) case *st.ArrayTypeSymbol: pp.fixArrayTypeSymbol(t) case *st.StructTypeSymbol: pp.fixStructTypeSymbol(t) case *st.InterfaceTypeSymbol: pp.fixInterfaceTypeSymbol(t) case *st.MapTypeSymbol: pp.fixMapTypeSymbol(t) case *st.ChanTypeSymbol: pp.fixChanTypeSymbol(t) case *st.FunctionTypeSymbol: pp.fixFunctionTypeSymbol(t) case *st.VariableSymbol: pp.fixVariableSymbol(t) case *st.FunctionSymbol: pp.fixFunctionSymbol(t) } }