Beispiel #1
0
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")
}
Beispiel #2
0
//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)
	}
}