Ejemplo n.º 1
0
func getRecieverSymbol(programTree *program.Program, pack *st.Package, filename string, recieverVarLine int, recieverVarCol int) (*st.VariableSymbol, *errors.GoRefactorError) {
	if recieverVarLine >= 0 && recieverVarLine >= 0 {
		rr, err := programTree.FindSymbolByPosition(filename, recieverVarLine, recieverVarCol)
		if err != nil {
			return nil, &errors.GoRefactorError{ErrorType: "extract method error", Message: "'recieverVarLine' and 'recieverVarCol' arguments don't point on an identifier"}
		}
		recvSym, ok := rr.(*st.VariableSymbol)
		if !ok {
			return nil, &errors.GoRefactorError{ErrorType: "extract method error", Message: "symbol, desired to be reciever, is not a variable symbol"}
		}
		if _, ok := recvSym.VariableType.(*st.BasicTypeSymbol); ok {
			return nil, &errors.GoRefactorError{ErrorType: "extract method error", Message: "can't extract method for basic type " + recvSym.VariableType.Name()}
		}
		if recvSym.VariableType.PackageFrom() != pack {
			return nil, &errors.GoRefactorError{ErrorType: "extract method error", Message: "reciever type is not from the same package as extracted code (not allowed to define methods for a type from imported package)"}
		}
		return recvSym, nil
	}
	return nil, nil
}
Ejemplo n.º 2
0
func implementInterface(programTree *program.Program, filename string, line int, column int, varFile string, varLine int, varColumn int, asPointer bool) (bool, *errors.GoRefactorError) {
	if ok, err := CheckImplementInterfaceParameters(filename, line, column, varFile, varLine, varColumn); !ok {
		return false, err
	}
	packInt, _ := programTree.FindPackageAndFileByFilename(filename)
	if packInt == nil {
		return false, errors.ArgumentError("filename", "Program packages don't contain file '"+filename+"'")
	}
	packType, fileType := programTree.FindPackageAndFileByFilename(varFile)
	if packType == nil {
		return false, errors.ArgumentError("filename", "Program packages don't contain file '"+varFile+"'")
	}
	symInt, err := programTree.FindSymbolByPosition(filename, line, column)
	if err != nil {
		return false, err
	}
	symType, err := programTree.FindSymbolByPosition(varFile, varLine, varColumn)
	if err != nil {
		return false, err
	}

	sI, ok := symInt.(*st.InterfaceTypeSymbol)
	if !ok {
		return false, &errors.GoRefactorError{ErrorType: "implement interface error", Message: "symbol, pointed as interface, is actually not a one"}
	}
	if _, ok := symType.(*st.InterfaceTypeSymbol); ok {
		return false, &errors.GoRefactorError{ErrorType: "implement interface error", Message: "interface can't implement methods"}
	}
	sT, ok := symType.(st.ITypeSymbol)
	if !ok {
		return false, &errors.GoRefactorError{ErrorType: "implement interface error", Message: "interface can be implemented only by a type"}
	}
	if asPointer {
		sT = programTree.GetPointerType(sT)
	}

	errors := make([]*errors.GoRefactorError, 0, 10)
	missedMethods := make(map[*st.FunctionSymbol]bool)
	checker := func(sym st.Symbol) {
		f := sym.(*st.FunctionSymbol)
		ok, err := containsMethod(f, sT)
		if err != nil {
			errors = append(errors, err)
		} else if !ok {
			missedMethods[f] = true
		}
	}
	sI.Methods().ForEachNoLock(checker)
	sI.Methods().ForEachOpenedScope(func(table *st.SymbolTable) {
		table.ForEachNoLock(checker)
	})

	println("missedMethods:")
	for s, _ := range missedMethods {
		list := make([]ast.Stmt, 1)
		list[0] = &ast.ExprStmt{&ast.CallExpr{ast.NewIdent("panic"), token.NoPos, []ast.Expr{&ast.BasicLit{token.NoPos, token.STRING, "\"not implemented yet\""}}, token.NoPos, token.NoPos}}
		fdecl := makeFuncDecl(s.Name(), list, s.FunctionType.(*st.FunctionTypeSymbol).Parameters, nil, s.FunctionType.(*st.FunctionTypeSymbol).Results, st.MakeVariable(st.NO_NAME, sT.Scope(), sT), packType, varFile)
		printer.Fprint(os.Stdout, token.NewFileSet(), fdecl)
		println()
		fileType.Decls = append(fileType.Decls, fdecl)
	}
	println()
	println("errors:")
	for _, err := range errors {
		println(err.String())
	}

	return true, nil
}