X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=case-study%2Frefaktor-after%2Fsrc%2Fno%2Fuio%2Fifi%2Frefaktor%2Fchange%2Fexecutors%2FMoveMethodRefactoringTargetFinder.java;fp=case-study%2Frefaktor-after%2Fsrc%2Fno%2Fuio%2Fifi%2Frefaktor%2Fchange%2Fexecutors%2FMoveMethodRefactoringTargetFinder.java;h=a94efab101d626ee357c9a5e2ebad1443057d9b5;hb=1b2798f607d741df30e5197f427381cbff326adc;hp=0000000000000000000000000000000000000000;hpb=246231e4bd9b24345490f369747c0549ca308c4d;p=ifi-stolz-refaktor.git diff --git a/case-study/refaktor-after/src/no/uio/ifi/refaktor/change/executors/MoveMethodRefactoringTargetFinder.java b/case-study/refaktor-after/src/no/uio/ifi/refaktor/change/executors/MoveMethodRefactoringTargetFinder.java new file mode 100644 index 00000000..a94efab1 --- /dev/null +++ b/case-study/refaktor-after/src/no/uio/ifi/refaktor/change/executors/MoveMethodRefactoringTargetFinder.java @@ -0,0 +1,99 @@ +package no.uio.ifi.refaktor.change.executors; + +import java.util.List; + +import no.uio.ifi.refaktor.change.exceptions.RefaktorChangerException; +import no.uio.ifi.refaktor.change.exceptions.VariableBindingNullException; +import no.uio.ifi.refaktor.utils.ParseUtils; +import no.uio.ifi.refaktor.utils.RefaktorASTNodeSearchUtil; + +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.IVariableBinding; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.SingleVariableDeclaration; +import org.eclipse.jdt.internal.corext.refactoring.ParameterInfo; + +/** + * A class responsible for finding the actual target to move the given method. + * + * It does so with the help of the original target found before a + * method got extracted. If the original target is a field, then it + * is used a the new target. If it is not, then this class must search + * through the method parameters for the new method to find a parameter + * that corresponds to the binding for the original target. + * + * If no target is found after this, the there probably is an error in + * the analysis, and an exception is thrown. + */ +@SuppressWarnings("restriction") +class MoveMethodRefactoringTargetFinder { + + private final IMethod method; + private final IVariableBinding originalTarget; + private final List parameterInfos; + + public MoveMethodRefactoringTargetFinder(IMethod method, IVariableBinding originalTarget, List parameterInfos) { + this.method = method; + this.originalTarget = originalTarget; + this.parameterInfos = parameterInfos; + } + + public IVariableBinding findTarget() throws JavaModelException, RefaktorChangerException { + if (originalTarget.isField()) + return originalTarget; + + return searchMethodParametersForTarget(); + } + + private IVariableBinding searchMethodParametersForTarget() throws JavaModelException { + if (methodHasParameters()) { + ParameterInfo parameterInfo = getParameterInfoWithOldBinding(); + MethodDeclaration node = RefaktorASTNodeSearchUtil.getMethodDeclarationNode(method, ParseUtils.parse(method.getCompilationUnit())); + for (Object declaration: node.parameters()) { + assert declaration instanceof SingleVariableDeclaration; + IVariableBinding declarationBinding = ((SingleVariableDeclaration)declaration).resolveBinding(); + if (declarationBinding == null) + throw new VariableBindingNullException(this.getClass()); + + if (declarationMatchesParameterInfo(declarationBinding, parameterInfo)) + return declarationBinding; + } + } + throw new GenericChangerException(this.getClass() + ": Could not find target for Move Method refactoring. Analysis probably wrong."); + } + + private boolean methodHasParameters() throws JavaModelException { + return method.getParameters().length != 0; + } + + private ParameterInfo getParameterInfoWithOldBinding() { + String originalTargetKey = originalTarget.getKey(); + + for (ParameterInfo parameterInfo: parameterInfos) { + IVariableBinding parameterInfoOldBinding = parameterInfo.getOldBinding(); + assert parameterInfoOldBinding != null; + if (parameterInfoOldBinding.getKey().equals(originalTargetKey)) + return parameterInfo; + } + assert false: "The algorithm for finding the target may be wrong. Or some part of the analysis."; + return null; + } + + private boolean declarationMatchesParameterInfo(IVariableBinding declarationBinding, ParameterInfo parameterInfo) { + return hasMatchingTypes(declarationBinding, parameterInfo) && hasMatchingNames(declarationBinding, parameterInfo); + } + + private boolean hasMatchingTypes(IVariableBinding declarationBinding, ParameterInfo parameterInfo) { + ITypeBinding declarationBindingType = declarationBinding.getType(); + assert declarationBindingType != null; + ITypeBinding parameterInfoOldBindingType = parameterInfo.getOldBinding().getType(); + assert parameterInfoOldBindingType != null; + return declarationBindingType.isEqualTo(parameterInfoOldBindingType); + } + + private boolean hasMatchingNames(IVariableBinding declarationBinding, ParameterInfo parameterInfo) { + return declarationBinding.getName().equals(parameterInfo.getNewName()); + } +} \ No newline at end of file