/******************************************************************************* * Copyright (c) 2010 György Orosz. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * György Orosz - initial API and implementation ******************************************************************************/ package org.erlide.wrangler.refactoring.core.internal; import java.util.HashMap; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.swt.widgets.Shell; import org.erlide.util.ErlLogger; import org.erlide.wrangler.refactoring.backend.IRefactoringRpcMessage; import org.erlide.wrangler.refactoring.backend.internal.GenFunRefactoringMessage; import org.erlide.wrangler.refactoring.backend.internal.GenFunRefactoringMessage.GenFunReturnParameterName; import org.erlide.wrangler.refactoring.backend.internal.WranglerBackendManager; import org.erlide.wrangler.refactoring.core.CostumWorkflowRefactoringWithPositionsSelection; import org.erlide.wrangler.refactoring.core.RefactoringWorkflowController; import org.erlide.wrangler.refactoring.selection.IErlMemberSelection; import org.erlide.wrangler.refactoring.selection.IErlSelection; import org.erlide.wrangler.refactoring.util.ErlRange; import org.erlide.wrangler.refactoring.util.GlobalParameters; import org.erlide.wrangler.refactoring.util.IErlRange; import org.erlide.wrangler.refactoring.util.Range; import com.ericsson.otp.erlang.OtpErlangBoolean; import com.ericsson.otp.erlang.OtpErlangException; import com.ericsson.otp.erlang.OtpErlangList; import com.ericsson.otp.erlang.OtpErlangObject; import com.ericsson.otp.erlang.OtpErlangTuple; /** * Integration class of the generalise function refactoring * * @author Gyorgy Orosz * @version %I%, %G% */ public class GeneraliseFunctionRefactoring extends CostumWorkflowRefactoringWithPositionsSelection { /** * The state of the generalise function refactoring, after calling the first * RPC * * @author Gyorgy Orosz * @version %I%, %G% */ public enum State { ok, error, multi_instance, unknown_side_effect, more_than_one_clause; } private final State state; private String errorMessage; private GenFunRefactoringMessage message; private boolean onlyInClause; private boolean sideEffect; /** * Constructor * * @param state * state of the refactoring * @param text * error message in case of wrong input */ public GeneraliseFunctionRefactoring(final State state, final String text) { this.state = state; errorMessage = text; } /** * Constructor * * @param state * state of the refactoring * @param message * RPC message from Wrangler */ public GeneraliseFunctionRefactoring(final State state, final GenFunRefactoringMessage message) { this.state = state; this.message = message; } /** * Constructor * * @param state * state of the refactoring * @param message * RPC message from Wrangler * @param onlyInClause * user input */ public GeneraliseFunctionRefactoring(final State state, final GenFunRefactoringMessage message, final boolean onlyInClause) { this(state, message); this.onlyInClause = onlyInClause; } /** * Constructor * * @param state * state of the refactoring * @param message * RPC message from Wrangler * @param onlyInClause * user input * @param sideEffect * user input */ public GeneraliseFunctionRefactoring(final State state, final GenFunRefactoringMessage message, final boolean onlyInClause, final boolean sideEffect) { this(state, message, onlyInClause); this.sideEffect = sideEffect; } /* * public GeneraliseFunctionRefactoring(State state) { } */ @Override public RefactoringStatus checkInitialConditions(final IProgressMonitor pm) throws CoreException, OperationCanceledException { if (state == State.error) { return RefactoringStatus.createFatalErrorStatus(errorMessage); } else if (state == State.multi_instance) { positions = createPositionList((OtpErlangList) message.getParameters() .get(GenFunReturnParameterName.dupsInFun)); } else if (state == State.more_than_one_clause) { if (onlyInClause) { positions = createPositionList((OtpErlangList) message.getParameters() .get(GenFunReturnParameterName.dupsInClause)); } else { positions = createPositionList((OtpErlangList) message.getParameters() .get(GenFunReturnParameterName.dupsInFun)); } } else if (state == State.unknown_side_effect) { if (onlyInClause) { positions = createPositionList((OtpErlangList) message.getParameters() .get(GenFunReturnParameterName.dupsInClause)); } else { positions = createPositionList((OtpErlangList) message.getParameters() .get(GenFunReturnParameterName.dupsInFun)); } } return new RefactoringStatus(); } /** * Returns IErlRange, OtpErlangTuple pairs, which are represents the same * position in a module * * @param thePositions * @return */ protected HashMap<IErlRange, OtpErlangTuple> createPositionList( final OtpErlangList thePositions) { try { final HashMap<IErlRange, OtpErlangTuple> ret = new HashMap<>(); final IErlMemberSelection sel = (IErlMemberSelection) GlobalParameters .getWranglerSelection(); for (final OtpErlangObject o : thePositions) { // {{sl, sc}, {el,ec}} final OtpErlangTuple pos = (OtpErlangTuple) o; ret.put(new ErlRange(new Range(pos), sel.getDocument()), pos); } return ret; } catch (final OtpErlangException e) { ErlLogger.error(e); return null; } } @Override public String getName() { return "Generalise function definition"; } @Override public IRefactoringRpcMessage run(final IErlSelection sel) { if (state == State.ok) { return message; } else if (state == State.error) { return null; } else { final HashMap<GenFunReturnParameterName, OtpErlangObject> p = message .getParameters(); OtpErlangObject sideEffectPar, parName, funName, arity, funDefPos, exp, logCmd; sideEffectPar = p.get(GenFunReturnParameterName.sideEffect); parName = p.get(GenFunReturnParameterName.parName); funName = p.get(GenFunReturnParameterName.funName); arity = p.get(GenFunReturnParameterName.arity); funDefPos = p.get(GenFunReturnParameterName.funDefPos); exp = p.get(GenFunReturnParameterName.exp); logCmd = p.get(GenFunReturnParameterName.logCmd); if (state == State.multi_instance) { return WranglerBackendManager.getRefactoringBackend().call( "gen_fun_1_eclipse", "xsxxxxxxxix", sideEffectPar, sel.getFilePath(), parName, funName, arity, funDefPos, exp, getSelectedPos(), sel.getSearchPath(), GlobalParameters.getTabWidth(), logCmd); } else if (state == State.unknown_side_effect) { if (onlyInClause) { return WranglerBackendManager.getRefactoringBackend().call( "gen_fun_clause_eclipse", "sxxxxxixxx", sel.getFilePath(), parName, funName, arity, funDefPos, exp, GlobalParameters.getTabWidth(), new OtpErlangBoolean(sideEffect), getSelectedPos(), logCmd); } return WranglerBackendManager.getRefactoringBackend().call( "gen_fun_1_eclipse", "xsxxxxxxxix", new OtpErlangBoolean(sideEffect), sel.getFilePath(), parName, funName, arity, funDefPos, exp, getSelectedPos(), sel.getSearchPath(), GlobalParameters.getTabWidth(), logCmd); } else if (state == State.more_than_one_clause) { if (onlyInClause) { return WranglerBackendManager.getRefactoringBackend().call( "gen_fun_clause_eclipse", "sxxxxxixxx", sel.getFilePath(), parName, funName, arity, funDefPos, exp, GlobalParameters.getTabWidth(), sideEffectPar, getSelectedPos(), logCmd); } return WranglerBackendManager.getRefactoringBackend().call( "gen_fun_1_eclipse", "xsxxxxxxxix", sideEffectPar, sel.getFilePath(), parName, funName, arity, funDefPos, exp, getSelectedPos(), sel.getSearchPath(), GlobalParameters.getTabWidth(), logCmd); } } return null; } @Override public RefactoringStatus checkFinalConditions(final IProgressMonitor pm) throws CoreException, OperationCanceledException { final IErlSelection sel = GlobalParameters.getWranglerSelection(); final IRefactoringRpcMessage theMessage = run(sel); if (theMessage.isSuccessful()) { changedFiles = theMessage.getRefactoringChangeset(); return new RefactoringStatus(); } return RefactoringStatus.createFatalErrorStatus(theMessage.getMessageString()); } @Override public RefactoringWorkflowController getWorkflowController(final Shell shell) { return new RefactoringWorkflowController(shell) { @Override public void doRefactoring() { } }; } @Override public IRefactoringRpcMessage runAlternative(final IErlSelection selection) { return null; } }