Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
gr.uom.java.xmi.decomposition.ReplacementAlgorithm Maven / Gradle / Ivy
package gr.uom.java.xmi.decomposition;
import static gr.uom.java.xmi.Constants.JAVA;
import static gr.uom.java.xmi.decomposition.OperationInvocation.PRIMITIVE_WRAPPER_CLASS_MAP;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.argumentsWithIdenticalMethodCalls;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.classInstanceCreationWithEverythingReplaced;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.commonConcat;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.commonConditional;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.containsMethodSignatureOfAnonymousClass;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.containsValidOperatorReplacements;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.declarationWithArrayInitializer;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.differOnlyInCastExpressionOrPrefixOperatorOrInfixOperand;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.differOnlyInDefaultInitializer;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.differOnlyInFinalModifier;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.differOnlyInThis;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.differOnlyInThrow;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.equalAfterArgumentMerge;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.equalAfterInfixExpressionExpansion;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.equalAfterNewArgumentAdditions;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.equalAfterParenthesisElimination;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.extractedToVariable;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.hasElseIfBranch;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.identicalAfterVariableAndTypeReplacements;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.identicalVariableDeclarationsWithDifferentNames;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.invocationWithEverythingReplaced;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.isElseBranch;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.isElseIfBranch;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.isIfBranch;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.oneIsVariableDeclarationTheOtherIsReturnStatement;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.oneIsVariableDeclarationTheOtherIsVariableAssignment;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.onlyDifferentInvoker;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.operatorExpressionWithEverythingReplaced;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.statementWithoutAnonymous;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.thisConstructorCallWithEverythingReplaced;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.validStatementForConcatComparison;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.variableAssignmentWithEverythingReplaced;
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.variableDeclarationsWithEverythingReplaced;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
import org.refactoringminer.api.Refactoring;
import org.refactoringminer.api.RefactoringMinerTimedOutException;
import gr.uom.java.xmi.LeafType;
import gr.uom.java.xmi.UMLAnonymousClass;
import gr.uom.java.xmi.UMLAttribute;
import gr.uom.java.xmi.UMLClass;
import gr.uom.java.xmi.UMLOperation;
import gr.uom.java.xmi.UMLParameter;
import gr.uom.java.xmi.UMLType;
import gr.uom.java.xmi.VariableDeclarationContainer;
import gr.uom.java.xmi.LocationInfo.CodeElementType;
import gr.uom.java.xmi.decomposition.AbstractCall.StatementCoverageType;
import gr.uom.java.xmi.decomposition.UMLOperationBodyMapper.ReplacementInfo;
import gr.uom.java.xmi.decomposition.replacement.ClassInstanceCreationWithMethodInvocationReplacement;
import gr.uom.java.xmi.decomposition.replacement.CompositeReplacement;
import gr.uom.java.xmi.decomposition.replacement.InitializerReplacement;
import gr.uom.java.xmi.decomposition.replacement.MethodInvocationReplacement;
import gr.uom.java.xmi.decomposition.replacement.MethodInvocationWithClassInstanceCreationReplacement;
import gr.uom.java.xmi.decomposition.replacement.ObjectCreationReplacement;
import gr.uom.java.xmi.decomposition.replacement.Replacement;
import gr.uom.java.xmi.decomposition.replacement.VariableReplacementWithMethodInvocation;
import gr.uom.java.xmi.decomposition.replacement.Replacement.ReplacementType;
import gr.uom.java.xmi.decomposition.replacement.VariableReplacementWithMethodInvocation.Direction;
import gr.uom.java.xmi.diff.ExtractOperationRefactoring;
import gr.uom.java.xmi.diff.ExtractVariableRefactoring;
import gr.uom.java.xmi.diff.ReplaceAnonymousWithLambdaRefactoring;
import gr.uom.java.xmi.diff.StringDistance;
import gr.uom.java.xmi.diff.UMLAbstractClassDiff;
import gr.uom.java.xmi.diff.UMLAnonymousClassDiff;
import gr.uom.java.xmi.diff.UMLClassBaseDiff;
import gr.uom.java.xmi.diff.UMLModelDiff;
import gr.uom.java.xmi.diff.UMLOperationDiff;
public class ReplacementAlgorithm {
private static final int MAXIMUM_NUMBER_OF_COMPARED_STRINGS = 100;
protected static Set findReplacementsWithExactMatching(AbstractCodeFragment statement1, AbstractCodeFragment statement2,
Map parameterToArgumentMap, ReplacementInfo replacementInfo, boolean equalNumberOfAssertions, UMLOperationBodyMapper operationBodyMapper) throws RefactoringMinerTimedOutException {
VariableDeclarationContainer container1 = operationBodyMapper.getContainer1();
VariableDeclarationContainer container2 = operationBodyMapper.getContainer2();
UMLOperationBodyMapper parentMapper = operationBodyMapper.getParentMapper();
Set mappings = operationBodyMapper.getMappings();
UMLAbstractClassDiff classDiff = operationBodyMapper.getClassDiff();
UMLModelDiff modelDiff = operationBodyMapper.getModelDiff();
Optional operationSignatureDiff = operationBodyMapper.getOperationSignatureDiff();
List variableDeclarations1 = new ArrayList(statement1.getVariableDeclarations());
List variableDeclarations2 = new ArrayList(statement2.getVariableDeclarations());
VariableDeclaration variableDeclarationWithArrayInitializer1 = declarationWithArrayInitializer(variableDeclarations1);
VariableDeclaration variableDeclarationWithArrayInitializer2 = declarationWithArrayInitializer(variableDeclarations2);
AbstractCall invocationCoveringTheEntireStatement1 = statement1.invocationCoveringEntireFragment();
AbstractCall invocationCoveringTheEntireStatement2 = statement2.invocationCoveringEntireFragment();
ObjectCreation creationCoveringTheEntireStatement1 = statement1.creationCoveringEntireFragment();
ObjectCreation creationCoveringTheEntireStatement2 = statement2.creationCoveringEntireFragment();
Map> methodInvocationMap1 = convertToMap(statement1.getMethodInvocations());
Map> methodInvocationMap2 = convertToMap(statement2.getMethodInvocations());
Set variables1 = convertToStringSet(statement1.getVariables());
Set variables2 = convertToStringSet(statement2.getVariables());
Set variableIntersection = new LinkedHashSet(variables1);
variableIntersection.retainAll(variables2);
// ignore the variables in the intersection that also appear with "this." prefix in the sets of variables
// ignore the variables in the intersection that are static fields
// ignore the variables in the intersection that one of them is a variable declaration and the other is not
// ignore the variables in the intersection that one of them is part of a method invocation, but the same method invocation does not appear on the other side
Set variablesToBeRemovedFromTheIntersection = new LinkedHashSet();
for(String variable : variableIntersection) {
if(!variable.startsWith(JAVA.THIS_DOT) && !variableIntersection.contains(JAVA.THIS_DOT+variable) &&
(variables1.contains(JAVA.THIS_DOT+variable) || variables2.contains(JAVA.THIS_DOT+variable))) {
variablesToBeRemovedFromTheIntersection.add(variable);
}
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
invocationCoveringTheEntireStatement1.identicalName(invocationCoveringTheEntireStatement2)) {
if(!invocationCoveringTheEntireStatement1.arguments().contains(variable) &&
invocationCoveringTheEntireStatement2.arguments().contains(variable)) {
for(String argument : invocationCoveringTheEntireStatement1.arguments()) {
String argumentNoWhiteSpace = argument.replaceAll("\\s","");
if(argument.contains(variable) && !argument.equals(variable) && !argumentNoWhiteSpace.contains("+" + variable + "+") &&
!argumentNoWhiteSpace.contains(variable + "+") && !argumentNoWhiteSpace.contains("+" + variable) &&
!nonMatchedStatementUsesVariableInArgument(replacementInfo.getStatements1(), variable, argument)) {
variablesToBeRemovedFromTheIntersection.add(variable);
}
}
}
else if(invocationCoveringTheEntireStatement1.arguments().contains(variable) &&
!invocationCoveringTheEntireStatement2.arguments().contains(variable)) {
for(String argument : invocationCoveringTheEntireStatement2.arguments()) {
String argumentNoWhiteSpace = argument.replaceAll("\\s","");
if(argument.contains(variable) && !argument.equals(variable) && !argumentNoWhiteSpace.contains("+" + variable + "+") &&
!argumentNoWhiteSpace.contains(variable + "+") && !argumentNoWhiteSpace.contains("+" + variable) &&
!nonMatchedStatementUsesVariableInArgument(replacementInfo.getStatements2(), variable, argument)) {
variablesToBeRemovedFromTheIntersection.add(variable);
}
}
}
}
if(variable.toUpperCase().equals(variable) && !ReplacementUtil.sameCharsBeforeAfter(statement1.getString(), statement2.getString(), variable)) {
variablesToBeRemovedFromTheIntersection.add(variable);
}
boolean foundInDeclaration1 = false;
boolean foundInInitializer1 = false;
for(VariableDeclaration declaration : variableDeclarations1) {
if(declaration.getVariableName().equals(variable)) {
foundInDeclaration1 = true;
AbstractExpression initializer = declaration.getInitializer();
if(initializer != null && initializer.getString().endsWith("." + declaration.getVariableName())) {
variablesToBeRemovedFromTheIntersection.add(variable);
}
break;
}
AbstractExpression initializer = declaration.getInitializer();
if(initializer != null && initializer.getString().endsWith("." + variable)) {
foundInInitializer1 = true;
}
}
boolean foundInDeclaration2 = false;
boolean foundInInitializer2 = false;
for(VariableDeclaration declaration : variableDeclarations2) {
if(declaration.getVariableName().equals(variable)) {
foundInDeclaration2 = true;
AbstractExpression initializer = declaration.getInitializer();
if(initializer != null && initializer.getString().endsWith("." + declaration.getVariableName())) {
variablesToBeRemovedFromTheIntersection.add(variable);
}
break;
}
AbstractExpression initializer = declaration.getInitializer();
if(initializer != null && initializer.getString().endsWith("." + variable)) {
foundInInitializer2 = true;
}
}
if(foundInDeclaration1 != foundInDeclaration2 || foundInInitializer1 != foundInInitializer2) {
variablesToBeRemovedFromTheIntersection.add(variable);
}
else if(!variable.contains(".")) {
boolean foundInInvocation1 = false;
for(String key : methodInvocationMap1.keySet()) {
if(key.startsWith(variable + ".")) {
foundInInvocation1 = true;
break;
}
}
boolean foundInInvocation2 = false;
for(String key : methodInvocationMap2.keySet()) {
if(key.startsWith(variable + ".")) {
foundInInvocation2 = true;
break;
}
}
boolean sameCoverageInvocations = invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
invocationCoveringTheEntireStatement1.getCoverage().equals(invocationCoveringTheEntireStatement2.getCoverage());
boolean sameCoverageCreations = creationCoveringTheEntireStatement1 != null && creationCoveringTheEntireStatement2 != null &&
creationCoveringTheEntireStatement1.getCoverage().equals(creationCoveringTheEntireStatement2.getCoverage());
if((sameCoverageInvocations || sameCoverageCreations) && foundInInvocation1 != foundInInvocation2) {
variablesToBeRemovedFromTheIntersection.add(variable);
}
else if(methodInvocationMap1.isEmpty() && !methodInvocationMap2.isEmpty() && foundInInvocation1 != foundInInvocation2) {
variablesToBeRemovedFromTheIntersection.add(variable);
}
else if(!methodInvocationMap1.isEmpty() && methodInvocationMap2.isEmpty() && foundInInvocation1 != foundInInvocation2) {
variablesToBeRemovedFromTheIntersection.add(variable);
}
}
}
variableIntersection.removeAll(variablesToBeRemovedFromTheIntersection);
// remove common variables from the two sets
variables1.removeAll(variableIntersection);
variables2.removeAll(variableIntersection);
// replace variables with the corresponding arguments
replaceVariablesWithArguments(variables1, parameterToArgumentMap);
replaceVariablesWithArguments(variables2, parameterToArgumentMap);
Set methodInvocations1 = new LinkedHashSet(methodInvocationMap1.keySet());
Set methodInvocations2 = new LinkedHashSet(methodInvocationMap2.keySet());
Map> creationMap1 = convertToMap(statement1.getCreations());
Map> creationMap2 = convertToMap(statement2.getCreations());
Set creations1 = new LinkedHashSet(creationMap1.keySet());
Set creations2 = new LinkedHashSet(creationMap2.keySet());
Set arguments1 = convertToStringSet(statement1.getArguments());
Set arguments2 = convertToStringSet(statement2.getArguments());
removeCommonElements(arguments1, arguments2);
if(!argumentsWithIdenticalMethodCalls(arguments1, arguments2, variables1, variables2)) {
boolean argsAreMethodCalls = false;
if(arguments1.size() == arguments2.size()) {
Iterator it1 = arguments1.iterator();
Iterator it2 = arguments2.iterator();
for(int i=0; i calls1 = methodInvocationMap1.get(arg1);
List extends AbstractCall> calls2 = methodInvocationMap2.get(arg2);
if(calls1.get(0).getName().equals(calls2.get(0).getName())) {
argsAreMethodCalls = true;
break;
}
}
else {
String matchingKey1 = null;
for(String key1 : methodInvocationMap1.keySet()) {
if(arg1.contains(key1)) {
matchingKey1 = key1;
break;
}
}
String matchingKey2 = null;
for(String key2 : methodInvocationMap2.keySet()) {
if(arg2.contains(key2)) {
matchingKey2 = key2;
break;
}
}
if(matchingKey1 != null && matchingKey2 != null) {
List extends AbstractCall> calls1 = methodInvocationMap1.get(matchingKey1);
List extends AbstractCall> calls2 = methodInvocationMap2.get(matchingKey2);
if(calls1.get(0).getName().equals(calls2.get(0).getName())) {
argsAreMethodCalls = true;
break;
}
}
}
}
}
if(!argsAreMethodCalls) {
findReplacements(arguments1, variables2, replacementInfo, ReplacementType.ARGUMENT_REPLACED_WITH_VARIABLE, container1, container2, classDiff);
}
}
Map map = new LinkedHashMap();
Set replacementsToBeRemoved = new LinkedHashSet();
Set replacementsToBeAdded = new LinkedHashSet();
for(Replacement r : replacementInfo.getReplacements()) {
map.put(r.getBefore(), r.getAfter());
if(methodInvocationMap1.containsKey(r.getBefore())) {
Replacement replacement = new VariableReplacementWithMethodInvocation(r.getBefore(), r.getAfter(), methodInvocationMap1.get(r.getBefore()).get(0), Direction.INVOCATION_TO_VARIABLE);
replacementsToBeAdded.add(replacement);
replacementsToBeRemoved.add(r);
}
}
replacementInfo.getReplacements().removeAll(replacementsToBeRemoved);
replacementInfo.getReplacements().addAll(replacementsToBeAdded);
// replace variables with the corresponding arguments in method invocations
replaceVariablesWithArguments(methodInvocationMap1, methodInvocations1, parameterToArgumentMap);
replaceVariablesWithArguments(methodInvocationMap2, methodInvocations2, parameterToArgumentMap);
replaceVariablesWithArguments(methodInvocationMap1, methodInvocations1, map);
//remove methodInvocation covering the entire statement
if(invocationCoveringTheEntireStatement1 != null) {
for(String methodInvocation1 : methodInvocationMap1.keySet()) {
for(AbstractCall call : methodInvocationMap1.get(methodInvocation1)) {
if(invocationCoveringTheEntireStatement1.getLocationInfo().equals(call.getLocationInfo())) {
methodInvocations1.remove(methodInvocation1);
}
}
}
}
if(invocationCoveringTheEntireStatement2 != null) {
for(String methodInvocation2 : methodInvocationMap2.keySet()) {
for(AbstractCall call : methodInvocationMap2.get(methodInvocation2)) {
if(invocationCoveringTheEntireStatement2.getLocationInfo().equals(call.getLocationInfo())) {
methodInvocations2.remove(methodInvocation2);
}
}
}
}
Set methodInvocationIntersection = new LinkedHashSet(methodInvocations1);
methodInvocationIntersection.retainAll(methodInvocations2);
Set methodInvocationsToBeRemovedFromTheIntersection = new LinkedHashSet();
for(String methodInvocation : methodInvocationIntersection) {
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
invocationCoveringTheEntireStatement1.identicalName(invocationCoveringTheEntireStatement2)) {
if(!invocationCoveringTheEntireStatement1.arguments().contains(methodInvocation) &&
invocationCoveringTheEntireStatement2.arguments().contains(methodInvocation)) {
methodInvocationsToBeRemovedFromTheIntersection.add(methodInvocation);
}
else if(invocationCoveringTheEntireStatement1.arguments().contains(methodInvocation) &&
!invocationCoveringTheEntireStatement2.arguments().contains(methodInvocation)) {
methodInvocationsToBeRemovedFromTheIntersection.add(methodInvocation);
}
}
for(String key : methodInvocationMap1.keySet()) {
if(key.startsWith(methodInvocation + ".") && !methodInvocationMap2.containsKey(key)) {
methodInvocationsToBeRemovedFromTheIntersection.add(methodInvocation);
}
}
for(String key : methodInvocationMap2.keySet()) {
if(key.startsWith(methodInvocation + ".") && !methodInvocationMap1.containsKey(key)) {
methodInvocationsToBeRemovedFromTheIntersection.add(methodInvocation);
}
}
}
methodInvocationIntersection.removeAll(methodInvocationsToBeRemovedFromTheIntersection);
// remove common methodInvocations from the two sets
methodInvocations1.removeAll(methodInvocationIntersection);
methodInvocations2.removeAll(methodInvocationIntersection);
Set variablesAndMethodInvocations1 = new LinkedHashSet();
//variablesAndMethodInvocations1.addAll(methodInvocations1);
//variablesAndMethodInvocations1.addAll(variables1);
Set variablesAndMethodInvocations2 = new LinkedHashSet();
variablesAndMethodInvocations2.addAll(methodInvocations2);
variablesAndMethodInvocations2.addAll(variables2);
Set types1 = new LinkedHashSet(statement1.getTypes());
for(AnonymousClassDeclarationObject anonymous1 : statement1.getAnonymousClassDeclarations()) {
types1.addAll(anonymous1.getTypes());
}
Set types2 = new LinkedHashSet(statement2.getTypes());
for(AnonymousClassDeclarationObject anonymous2 : statement2.getAnonymousClassDeclarations()) {
types2.addAll(anonymous2.getTypes());
}
removeCommonTypes(types1, types2, statement1.getTypes(), statement2.getTypes());
// replace variables with the corresponding arguments in object creations
replaceVariablesWithArguments(creationMap1, creations1, parameterToArgumentMap);
replaceVariablesWithArguments(creationMap2, creations2, parameterToArgumentMap);
replaceVariablesWithArguments(creationMap1, creations1, map);
//remove objectCreation covering the entire statement
for(String objectCreation1 : creationMap1.keySet()) {
for(AbstractCall creation1 : creationMap1.get(objectCreation1)) {
if(creationCoveringTheEntireStatement1 != null &&
creationCoveringTheEntireStatement1.getLocationInfo().equals(creation1.getLocationInfo())) {
creations1.remove(objectCreation1);
}
if(((ObjectCreation)creation1).getAnonymousClassDeclaration() != null) {
creations1.remove(objectCreation1);
}
}
}
for(String objectCreation2 : creationMap2.keySet()) {
for(AbstractCall creation2 : creationMap2.get(objectCreation2)) {
if(creationCoveringTheEntireStatement2 != null &&
creationCoveringTheEntireStatement2.getLocationInfo().equals(creation2.getLocationInfo())) {
creations2.remove(objectCreation2);
}
if(((ObjectCreation)creation2).getAnonymousClassDeclaration() != null) {
creations2.remove(objectCreation2);
}
}
}
Set creationIntersection = new LinkedHashSet(creations1);
creationIntersection.retainAll(creations2);
// remove common creations from the two sets
creations1.removeAll(creationIntersection);
creations2.removeAll(creationIntersection);
Set stringLiterals1 = convertToStringSet(statement1.getStringLiterals());
Set stringLiterals2 = convertToStringSet(statement2.getStringLiterals());
removeCommonElements(stringLiterals1, stringLiterals2);
Set charLiterals1 = convertToStringSet(statement1.getCharLiterals());
Set charLiterals2 = convertToStringSet(statement2.getCharLiterals());
removeCommonElements(charLiterals1, charLiterals2);
Set typeLiterals1 = convertToStringSet(statement1.getTypeLiterals());
Set typeLiterals2 = convertToStringSet(statement2.getTypeLiterals());
removeCommonElements(typeLiterals1, typeLiterals2);
Set numberLiterals1 = convertToStringSet(statement1.getNumberLiterals());
Set numberLiterals2 = convertToStringSet(statement2.getNumberLiterals());
removeCommonElements(numberLiterals1, numberLiterals2);
Set booleanLiterals1 = convertToStringSet(statement1.getBooleanLiterals());
Set booleanLiterals2 = convertToStringSet(statement2.getBooleanLiterals());
removeCommonElements(booleanLiterals1, booleanLiterals2);
Set infixOperators1 = new LinkedHashSet(statement1.getInfixOperators());
Set infixOperators2 = new LinkedHashSet(statement2.getInfixOperators());
removeCommonElements(infixOperators1, infixOperators2);
Set arrayAccesses1 = convertToStringSet(statement1.getArrayAccesses());
Set arrayAccesses2 = convertToStringSet(statement2.getArrayAccesses());
removeCommonElements(arrayAccesses1, arrayAccesses2);
Set prefixExpressions1 = convertToStringSet(statement1.getPrefixExpressions());
Set prefixExpressions2 = convertToStringSet(statement2.getPrefixExpressions());
removeCommonElements(prefixExpressions1, prefixExpressions2);
Set parenthesizedExpressions1 = convertToStringSet(statement1.getParenthesizedExpressions());
Set parenthesizedExpressions2 = convertToStringSet(statement2.getParenthesizedExpressions());
removeCommonElements(parenthesizedExpressions1, parenthesizedExpressions2);
Set castExpressions1 = convertToStringSet(statement1.getCastExpressions());
Set castExpressions2 = convertToStringSet(statement2.getCastExpressions());
removeCommonElements(castExpressions1, castExpressions2);
//perform type replacements
findReplacements(types1, types2, replacementInfo, ReplacementType.TYPE, container1, container2, classDiff);
if(statement1.getLocationInfo().getCodeElementType().equals(statement2.getLocationInfo().getCodeElementType())) {
Set infixExpressions1 = convertToStringSet(statement1.getInfixExpressions());
String infixExpressionCoveringTheEntireFragment = statement1.infixExpressionCoveringTheEntireFragment();
if(infixExpressionCoveringTheEntireFragment != null) {
boolean skip = false;
if(statement1.getLocationInfo().getCodeElementType().equals(CodeElementType.IF_STATEMENT) || statement1.getLocationInfo().getCodeElementType().equals(CodeElementType.WHILE_STATEMENT)) {
if(infixExpressionCoveringTheEntireFragment.contains(" || ") || infixExpressionCoveringTheEntireFragment.contains(" && ")) {
skip = true;
}
}
if(!skip) {
infixExpressions1.remove(infixExpressionCoveringTheEntireFragment);
}
}
Set infixExpressions2 = convertToStringSet(statement2.getInfixExpressions());
Set tmpVariables2 = new LinkedHashSet<>(variables2);
Set variablesToBeRemoved = new LinkedHashSet();
for(String infix : infixExpressions2) {
for(String variable : tmpVariables2) {
if(ReplacementUtil.contains(infix, variable) &&
(infix.contains(variable + " > ") || infix.contains(variable + " < ") ||
infix.contains(variable + " >= ") || infix.contains(variable + " <= ") ||
infix.contains(variable + " != ") || infix.contains(variable + " == "))) {
variablesToBeRemoved.add(variable);
}
}
}
tmpVariables2.removeAll(variablesToBeRemoved);
infixExpressions2.remove(statement2.infixExpressionCoveringTheEntireFragment());
removeCommonElements(infixExpressions1, infixExpressions2);
if(infixExpressions1.size() != infixExpressions2.size()) {
List infixExpressions1AsList = new ArrayList<>(infixExpressions1);
Collections.reverse(infixExpressions1AsList);
Set reverseInfixExpressions1 = new LinkedHashSet(infixExpressions1AsList);
findReplacements(reverseInfixExpressions1, tmpVariables2, replacementInfo, ReplacementType.INFIX_EXPRESSION, container1, container2, classDiff);
}
}
//perform operator replacements
findReplacements(infixOperators1, infixOperators2, replacementInfo, ReplacementType.INFIX_OPERATOR, container1, container2, classDiff);
//apply existing replacements on method invocations
for(String methodInvocation1 : methodInvocations1) {
String temp = new String(methodInvocation1);
for(Replacement replacement : replacementInfo.getReplacements()) {
temp = ReplacementUtil.performReplacement(temp, replacement.getBefore(), replacement.getAfter());
}
if(!temp.equals(methodInvocation1)) {
variablesAndMethodInvocations1.add(temp);
methodInvocationMap1.put(temp, methodInvocationMap1.get(methodInvocation1));
}
}
//add updated method invocation to the original list of invocations
methodInvocations1.addAll(variablesAndMethodInvocations1);
variablesAndMethodInvocations1.addAll(methodInvocations1);
variablesAndMethodInvocations1.addAll(variables1);
findReplacements(variables1, creations2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_CLASS_INSTANCE_CREATION, container1, container2, classDiff);
if(statement1.getString().startsWith(JAVA.THROW_SPACE) && statement2.getString().startsWith(JAVA.THROW_SPACE) && creationCoveringTheEntireStatement2 != null && creations2.isEmpty()) {
findReplacements(variables1, Set.of(creationCoveringTheEntireStatement2.actualString()), replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_CLASS_INSTANCE_CREATION, container1, container2, classDiff);
}
if(charLiterals1.size() > 0 && charLiterals2.isEmpty() && stringLiterals2.size() > 0) {
findReplacements(charLiterals1, stringLiterals2, replacementInfo, ReplacementType.STRING_LITERAL_REPLACED_WITH_CHAR_LITERAL, container1, container2, classDiff);
}
if(charLiterals2.size() > 0 && charLiterals1.isEmpty() && stringLiterals1.size() > 0) {
findReplacements(stringLiterals1, charLiterals2, replacementInfo, ReplacementType.STRING_LITERAL_REPLACED_WITH_CHAR_LITERAL, container1, container2, classDiff);
}
if(variablesAndMethodInvocations1.size() > MAXIMUM_NUMBER_OF_COMPARED_STRINGS || variablesAndMethodInvocations2.size() > MAXIMUM_NUMBER_OF_COMPARED_STRINGS) {
return null;
}
if (replacementInfo.getRawDistance() > 0) {
for(String s1 : variablesAndMethodInvocations1) {
TreeMap replacementMap = new TreeMap();
int minDistance = replacementInfo.getRawDistance();
for(String s2 : variablesAndMethodInvocations2) {
if(Thread.interrupted()) {
throw new RefactoringMinerTimedOutException();
}
String temp = ReplacementUtil.performReplacement(replacementInfo.getArgumentizedString1(), replacementInfo.getArgumentizedString2(), s1, s2);
int distanceRaw = StringDistance.editDistance(temp, replacementInfo.getArgumentizedString2(), minDistance);
boolean multipleInstances = ReplacementUtil.countInstances(temp, s2) > 1;
boolean typeContainsVariableName = false;
if(variableDeclarations1.size() > 0 && !s1.equals(s2)) {
VariableDeclaration variableDeclaration = variableDeclarations1.get(0);
UMLType variableType = variableDeclaration.getType();
if(variableType != null) {
String typeTolowerCase = variableType.toString().toLowerCase();
if(typeTolowerCase.contains(variableDeclaration.getVariableName().toLowerCase()) && typeTolowerCase.contains(s2.toLowerCase())) {
typeContainsVariableName = true;
}
if(!typeContainsVariableName && statement1.getString().contains(s1 + JAVA.ASSIGNMENT) && statement2.getString().contains(s2 + JAVA.ASSIGNMENT)) {
String[] tokens1 = LeafType.CAMEL_CASE_SPLIT_PATTERN.split(variableType.toString());
String[] tokens2 = LeafType.CAMEL_CASE_SPLIT_PATTERN.split(s2);
int commonTokens = 0;
for(String token1 : tokens1) {
for(String token2 : tokens2) {
if(token1.toLowerCase().equals(token2.toLowerCase()) ||
token1.toLowerCase().startsWith(token2.toLowerCase()) ||
token2.toLowerCase().startsWith(token1.toLowerCase())) {
commonTokens++;
}
}
}
if(commonTokens > 1) {
typeContainsVariableName = true;
}
}
}
}
if(distanceRaw == -1 && (multipleInstances || typeContainsVariableName)) {
distanceRaw = StringDistance.editDistance(temp, replacementInfo.getArgumentizedString2());
}
boolean allowReplacementIncreasingDistance = (multipleInstances && Math.abs(s1.length() - s2.length()) == Math.abs(distanceRaw - minDistance) && !s1.equals(s2)) || typeContainsVariableName;
if(distanceRaw >= 0 && (distanceRaw < replacementInfo.getRawDistance() || allowReplacementIncreasingDistance)) {
minDistance = distanceRaw;
Replacement replacement = null;
if(variables1.contains(s1) && variables2.contains(s2) && variablesStartWithSameCase(s1, s2, replacementInfo)) {
replacement = new Replacement(s1, s2, ReplacementType.VARIABLE_NAME);
if(s1.startsWith("(") && s2.startsWith("(") && s1.contains(")") && s2.contains(")")) {
String prefix1 = s1.substring(0, s1.indexOf(")")+1);
String prefix2 = s2.substring(0, s2.indexOf(")")+1);
if(prefix1.equals(prefix2)) {
String suffix1 = s1.substring(prefix1.length(), s1.length());
String suffix2 = s2.substring(prefix2.length(), s2.length());
replacement = new Replacement(suffix1, suffix2, ReplacementType.VARIABLE_NAME);
}
}
VariableDeclaration v1 = statement1.searchVariableDeclaration(s1);
if(v1 == null && container1 != null) {
for(VariableDeclaration declaration : container1.getParameterDeclarationList()) {
if(declaration.getVariableName().equals(s1)) {
v1 = declaration;
break;
}
}
}
VariableDeclaration v2 = statement2.searchVariableDeclaration(s2);
if(v2 == null && container2 != null) {
for(VariableDeclaration declaration : container2.getParameterDeclarationList()) {
if(declaration.getVariableName().equals(s2)) {
v2 = declaration;
break;
}
}
}
if((inconsistentVariableMappingCount(statement1, statement2, v1, v2, mappings) > 1 || mappingsForStatementsInScope(statement1, statement2, v1, v2, mappings) == 0) &&
!existsVariableDeclarationForV2InitializedWithV1(v1, v2, replacementInfo) && !existsVariableDeclarationForV1InitializedWithV2(v1, v2, replacementInfo) &&
!isExtractedVariable(v2, mappings) && !containsRightHandSideReplacementWithAppendChange(statement1, statement2, replacementInfo, replacement) &&
container2 != null && container2.loopWithVariables(v1.getVariableName(), v2.getVariableName()) == null) {
replacement = null;
}
}
else if(variables1.contains(s1) && methodInvocations2.contains(s2)) {
AbstractCall invokedOperationAfter = methodInvocationMap2.get(s2).get(0);
replacement = new VariableReplacementWithMethodInvocation(s1, s2, invokedOperationAfter, Direction.VARIABLE_TO_INVOCATION);
}
else if(methodInvocations1.contains(s1) && methodInvocations2.contains(s2)) {
AbstractCall invokedOperationBefore = methodInvocationMap1.get(s1).get(0);
AbstractCall invokedOperationAfter = methodInvocationMap2.get(s2).get(0);
if(invokedOperationBefore.compatibleExpression(invokedOperationAfter)) {
if(invokedOperationBefore.identicalExpression(invokedOperationAfter) && invokedOperationBefore.equalArguments(invokedOperationAfter)) {
replacement = new MethodInvocationReplacement(s1, s2, invokedOperationBefore, invokedOperationAfter, ReplacementType.METHOD_INVOCATION_NAME);
}
else {
replacement = new MethodInvocationReplacement(s1, s2, invokedOperationBefore, invokedOperationAfter, ReplacementType.METHOD_INVOCATION);
}
}
}
else if(methodInvocations1.contains(s1) && variables2.contains(s2)) {
AbstractCall invokedOperationBefore = methodInvocationMap1.get(s1).get(0);
replacement = new VariableReplacementWithMethodInvocation(s1, s2, invokedOperationBefore, Direction.INVOCATION_TO_VARIABLE);
}
if(replacement != null) {
double distancenormalized = (double)distanceRaw/(double)Math.max(temp.length(), replacementInfo.getArgumentizedString2().length());
replacementMap.put(distancenormalized, replacement);
}
if(distanceRaw == 0 && !replacementInfo.getReplacements().isEmpty()) {
break;
}
}
}
if(!replacementMap.isEmpty()) {
Replacement replacement = replacementMap.firstEntry().getValue();
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
invocationCoveringTheEntireStatement1.methodNameContainsArgumentName() &&
invocationCoveringTheEntireStatement2.methodNameContainsArgumentName() &&
replacement.getType().equals(ReplacementType.VARIABLE_NAME)) {
for(Replacement r : replacementMap.values()) {
if(!replacement.equals(r) && r.getType().equals(ReplacementType.VARIABLE_NAME) &&
invocationCoveringTheEntireStatement1.getName().toLowerCase().endsWith(r.getBefore().toLowerCase()) &&
invocationCoveringTheEntireStatement2.getName().toLowerCase().endsWith(r.getAfter().toLowerCase())) {
replacement = r;
break;
}
}
}
replacementInfo.addReplacement(replacement);
replacementInfo.setArgumentizedString1(ReplacementUtil.performReplacement(replacementInfo.getArgumentizedString1(), replacementInfo.getArgumentizedString2(), replacement.getBefore(), replacement.getAfter()));
if(replacementMap.firstEntry().getKey() == 0) {
break;
}
}
}
}
if(replacementInfo.getReplacements().size() > 0 && replacementInfo.getReplacements(ReplacementType.VARIABLE_NAME).size() == 0) {
boolean atLeastOneUpperCaseVariable1 = false;
for(String variable1 : variables1) {
if(Character.isUpperCase(variable1.charAt(0))) {
boolean foundInReplacement = false;
for(Replacement r : replacementInfo.getReplacements()) {
if(r.getBefore().contains(variable1) && !r.getBefore().equals(variable1)) {
foundInReplacement = true;
}
}
if(!foundInReplacement) {
atLeastOneUpperCaseVariable1 = true;
}
}
}
boolean atLeastOneUpperCaseVariable2 = false;
for(String variable2 : variables2) {
if(Character.isUpperCase(variable2.charAt(0))) {
boolean foundInReplacement = false;
for(Replacement r : replacementInfo.getReplacements()) {
if(r.getAfter().contains(variable2) && !r.getAfter().equals(variable2)) {
foundInReplacement = true;
}
}
if(!foundInReplacement) {
atLeastOneUpperCaseVariable2 = true;
}
}
}
if(atLeastOneUpperCaseVariable1 != atLeastOneUpperCaseVariable2) {
findReplacements(variables1, variables2, replacementInfo, ReplacementType.VARIABLE_NAME, container1, container2, classDiff);
}
}
//perform creation replacements
findReplacements(creations1, creations2, replacementInfo, ReplacementType.CLASS_INSTANCE_CREATION, container1, container2, classDiff);
findReplacements(parenthesizedExpressions1, parenthesizedExpressions2, replacementInfo, ReplacementType.PARENTHESIZED_EXPRESSION, container1, container2, classDiff);
//perform literal replacements
findReplacements(stringLiterals1, stringLiterals2, replacementInfo, ReplacementType.STRING_LITERAL, container1, container2, classDiff);
findReplacements(charLiterals1, charLiterals2, replacementInfo, ReplacementType.CHAR_LITERAL, container1, container2, classDiff);
findReplacements(numberLiterals1, numberLiterals2, replacementInfo, ReplacementType.NUMBER_LITERAL, container1, container2, classDiff);
if(!statement1.containsInitializerOfVariableDeclaration(numberLiterals1) && !statement2.containsInitializerOfVariableDeclaration(variables2) &&
(!statement1.getString().endsWith("=0;\n") || (statement1.getString().endsWith("=0;\n") && statement2.getString().endsWith(".length;\n")))) {
findReplacements(numberLiterals1, variables2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_NUMBER_LITERAL, container1, container2, classDiff);
}
findReplacements(variables1, arrayAccesses2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_ARRAY_ACCESS, container1, container2, classDiff);
findReplacements(arrayAccesses1, variables2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_ARRAY_ACCESS, container1, container2, classDiff);
findReplacements(methodInvocations1, arrayAccesses2, replacementInfo, ReplacementType.ARRAY_ACCESS_REPLACED_WITH_METHOD_INVOCATION, container1, container2, classDiff);
findReplacements(arrayAccesses1, methodInvocations2, replacementInfo, ReplacementType.ARRAY_ACCESS_REPLACED_WITH_METHOD_INVOCATION, container1, container2, classDiff);
findReplacements(variables1, prefixExpressions2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_PREFIX_EXPRESSION, container1, container2, classDiff);
findReplacements(prefixExpressions1, variables2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_PREFIX_EXPRESSION, container1, container2, classDiff);
if(prefixExpressions1.size() == 1 && prefixExpressions1.iterator().next().startsWith("!") && booleanLiterals1.isEmpty()) {
findReplacements(prefixExpressions1, booleanLiterals2, replacementInfo, ReplacementType.BOOLEAN_REPLACED_WITH_PREFIX_EXPRESSION, container1, container2, classDiff);
}
if(prefixExpressions2.size() == 1 && prefixExpressions2.iterator().next().startsWith("!") && booleanLiterals2.isEmpty()) {
findReplacements(booleanLiterals1, prefixExpressions2, replacementInfo, ReplacementType.BOOLEAN_REPLACED_WITH_PREFIX_EXPRESSION, container1, container2, classDiff);
}
if(statement2.getThisExpressions().size() > 0 && !statement2.getString().equals(JAVA.RETURN_THIS)) {
findReplacements(variables1, Set.of("this"), replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_THIS_EXPRESSION, container1, container2, classDiff);
}
if(statement1.getThisExpressions().size() > 0 && !statement1.getString().equals(JAVA.RETURN_THIS)) {
findReplacements(Set.of("this"), variables2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_THIS_EXPRESSION, container1, container2, classDiff);
}
if(!container1.isGetter() && !container2.isGetter()) {
findReplacements(stringLiterals1, variables2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_STRING_LITERAL, container1, container2, classDiff);
findReplacements(variables1, stringLiterals2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_STRING_LITERAL, container1, container2, classDiff);
}
findReplacements(parenthesizedExpressions1, variables2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_PARENTHESIZED_EXPRESSION, container1, container2, classDiff);
findReplacements(variables1, parenthesizedExpressions2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_PARENTHESIZED_EXPRESSION, container1, container2, classDiff);
findReplacements(methodInvocations1, stringLiterals2, replacementInfo, ReplacementType.METHOD_INVOCATION_REPLACED_WITH_STRING_LITERAL, container1, container2, classDiff);
if((statement1.getNullLiterals().isEmpty() && !statement2.getNullLiterals().isEmpty()) ||
bothContainNullInDifferentIndexes(invocationCoveringTheEntireStatement1 != null ? invocationCoveringTheEntireStatement1 : creationCoveringTheEntireStatement1,
invocationCoveringTheEntireStatement2 != null ? invocationCoveringTheEntireStatement2 : creationCoveringTheEntireStatement2)) {
Set nullLiterals2 = Set.of("null");
for(String parameter : parameterToArgumentMap.keySet()) {
String argument = parameterToArgumentMap.get(parameter);
if(!parameter.equals(argument) && variables1.contains(parameter)) {
variables1.add(argument);
}
}
findReplacements(variables1, nullLiterals2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_NULL_LITERAL, container1, container2, classDiff);
if(invocationCoveringTheEntireStatement1 != null) {
String expression = invocationCoveringTheEntireStatement1.getExpression();
if(expression != null && expression.equals("Optional") && invocationCoveringTheEntireStatement1.getName().equals("empty") &&
invocationCoveringTheEntireStatement1.arguments().size() == 0) {
Set invocations1 = new LinkedHashSet();
invocations1.add(invocationCoveringTheEntireStatement1.actualString());
findReplacements(invocations1, nullLiterals2, replacementInfo, ReplacementType.NULL_LITERAL_REPLACED_WITH_OPTIONAL_EMPTY, container1, container2, classDiff);
}
}
if(methodInvocations1.contains("Optional.empty()")) {
findReplacements(methodInvocations1, nullLiterals2, replacementInfo, ReplacementType.NULL_LITERAL_REPLACED_WITH_OPTIONAL_EMPTY, container1, container2, classDiff);
}
if(!creations1.isEmpty()) {
findReplacements(creations1, nullLiterals2, replacementInfo, ReplacementType.NULL_LITERAL_REPLACED_WITH_CREATION, container1, container2, classDiff);
}
if(!stringLiterals1.isEmpty()) {
findReplacements(stringLiterals1, nullLiterals2, replacementInfo, ReplacementType.NULL_LITERAL_REPLACED_WITH_STRING_LITERAL, container1, container2, classDiff);
}
if(!typeLiterals1.isEmpty()) {
findReplacements(typeLiterals1, nullLiterals2, replacementInfo, ReplacementType.NULL_LITERAL_REPLACED_WITH_TYPE_LITERAL, container1, container2, classDiff);
}
}
if((!statement1.getNullLiterals().isEmpty() && statement2.getNullLiterals().isEmpty()) ||
bothContainNullInDifferentIndexes(invocationCoveringTheEntireStatement1 != null ? invocationCoveringTheEntireStatement1 : creationCoveringTheEntireStatement1,
invocationCoveringTheEntireStatement2 != null ? invocationCoveringTheEntireStatement2 : creationCoveringTheEntireStatement2)) {
Set nullLiterals1 = Set.of("null");
for(String parameter : parameterToArgumentMap.keySet()) {
String argument = parameterToArgumentMap.get(parameter);
if(!parameter.equals(argument) && variables2.contains(parameter)) {
variables2.add(argument);
}
}
findReplacements(nullLiterals1, variables2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_NULL_LITERAL, container1, container2, classDiff);
if(invocationCoveringTheEntireStatement2 != null) {
String expression = invocationCoveringTheEntireStatement2.getExpression();
if(expression != null && expression.equals("Optional") && invocationCoveringTheEntireStatement2.getName().equals("empty") &&
invocationCoveringTheEntireStatement2.arguments().size() == 0) {
Set invocations2 = new LinkedHashSet();
invocations2.add(invocationCoveringTheEntireStatement2.actualString());
findReplacements(nullLiterals1, invocations2, replacementInfo, ReplacementType.NULL_LITERAL_REPLACED_WITH_OPTIONAL_EMPTY, container1, container2, classDiff);
}
}
if(methodInvocations2.contains("Optional.empty()")) {
findReplacements(nullLiterals1, methodInvocations2, replacementInfo, ReplacementType.NULL_LITERAL_REPLACED_WITH_OPTIONAL_EMPTY, container1, container2, classDiff);
}
if(!creations2.isEmpty()) {
findReplacements(nullLiterals1, creations2, replacementInfo, ReplacementType.NULL_LITERAL_REPLACED_WITH_CREATION, container1, container2, classDiff);
}
if(!stringLiterals2.isEmpty()) {
findReplacements(nullLiterals1, stringLiterals2, replacementInfo, ReplacementType.NULL_LITERAL_REPLACED_WITH_STRING_LITERAL, container1, container2, classDiff);
}
if(!typeLiterals2.isEmpty()) {
findReplacements(nullLiterals1, typeLiterals2, replacementInfo, ReplacementType.NULL_LITERAL_REPLACED_WITH_TYPE_LITERAL, container1, container2, classDiff);
}
if(parentMapper == null && variableDeclarations1.size() > 0 && variableDeclarations2.size() > 0 &&
variableDeclarations1.get(0).getType() != null && variableDeclarations2.get(0).getType() != null &&
variableDeclarations1.get(0).getType().equals(variableDeclarations2.get(0).getType()) &&
statement1.getString().endsWith("=null;\n") && invocationCoveringTheEntireStatement2 != null) {
findReplacements(nullLiterals1, Set.of(invocationCoveringTheEntireStatement2.actualString()), replacementInfo, ReplacementType.METHOD_INVOCATION_REPLACED_WITH_NULL_LITERAL, container1, container2, classDiff);
}
}
if(statement1.getTernaryOperatorExpressions().isEmpty() && !statement2.getTernaryOperatorExpressions().isEmpty()) {
if(!statement1.getNullLiterals().isEmpty()) {
Set nullLiterals1 = new LinkedHashSet();
nullLiterals1.add("null");
Set ternaryExpressions2 = new LinkedHashSet();
for(TernaryOperatorExpression ternary : statement2.getTernaryOperatorExpressions()) {
ternaryExpressions2.add(ternary.getExpression());
}
findReplacements(nullLiterals1, ternaryExpressions2, replacementInfo, ReplacementType.NULL_LITERAL_REPLACED_WITH_CONDITIONAL_EXPRESSION, container1, container2, classDiff);
}
if(methodInvocations1.size() > methodInvocations2.size() && !containsMethodSignatureOfAnonymousClass(statement1.getString())) {
Set ternaryExpressions2 = new LinkedHashSet();
for(TernaryOperatorExpression ternary : statement2.getTernaryOperatorExpressions()) {
ternaryExpressions2.add(ternary.getExpression());
}
findReplacements(methodInvocations1, ternaryExpressions2, replacementInfo, ReplacementType.METHOD_INVOCATION_REPLACED_WITH_CONDITIONAL_EXPRESSION, container1, container2, classDiff);
}
Set ternaryExpressions2 = new LinkedHashSet();
Set tmpVariables1 = new LinkedHashSet();
for(TernaryOperatorExpression ternary : statement2.getTernaryOperatorExpressions()) {
List thenVariables = ternary.getThenExpression().getVariables();
List elseVariables = ternary.getElseExpression().getVariables();
if((thenVariables.size() > 0 && ternary.getThenExpression().getExpression().equals(thenVariables.get(0).getString())) ||
(elseVariables.size() > 0 && ternary.getElseExpression().getExpression().equals(elseVariables.get(0).getString()))) {
ternaryExpressions2.add(ternary.getExpression());
tmpVariables1.addAll(convertToStringSet(ternary.getCondition().getVariables()));
tmpVariables1.addAll(convertToStringSet(ternary.getThenExpression().getVariables()));
tmpVariables1.addAll(convertToStringSet(ternary.getElseExpression().getVariables()));
}
}
findReplacements(tmpVariables1, ternaryExpressions2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_CONDITIONAL_EXPRESSION, container1, container2, classDiff);
if(variableDeclarations1.size() > 0 && variableDeclarations2.size() > 0 && variableDeclarations1.toString().equals(variableDeclarations2.toString()) &&
variableDeclarations2.get(0).getInitializer() != null && variableDeclarations2.get(0).getInitializer().getString().equals(statement2.getTernaryOperatorExpressions().get(0).getString()) &&
variableDeclarations1.get(0).getInitializer() != null && variables1.contains(variableDeclarations1.get(0).getInitializer().getString())) {
findReplacements(variables1, ternaryExpressions2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_CONDITIONAL_EXPRESSION, container1, container2, classDiff);
}
}
else if(!statement1.getTernaryOperatorExpressions().isEmpty() && statement2.getTernaryOperatorExpressions().isEmpty()) {
if(!statement2.getNullLiterals().isEmpty()) {
Set nullLiterals2 = new LinkedHashSet();
nullLiterals2.add("null");
Set ternaryExpressions1 = new LinkedHashSet();
for(TernaryOperatorExpression ternary : statement1.getTernaryOperatorExpressions()) {
ternaryExpressions1.add(ternary.getExpression());
}
findReplacements(ternaryExpressions1, nullLiterals2, replacementInfo, ReplacementType.NULL_LITERAL_REPLACED_WITH_CONDITIONAL_EXPRESSION, container1, container2, classDiff);
}
if(methodInvocations2.size() > methodInvocations1.size() && !containsMethodSignatureOfAnonymousClass(statement2.getString())) {
Set ternaryExpressions1 = new LinkedHashSet();
for(TernaryOperatorExpression ternary : statement1.getTernaryOperatorExpressions()) {
ternaryExpressions1.add(ternary.getExpression());
}
findReplacements(ternaryExpressions1, methodInvocations2, replacementInfo, ReplacementType.METHOD_INVOCATION_REPLACED_WITH_CONDITIONAL_EXPRESSION, container1, container2, classDiff);
}
Set ternaryExpressions1 = new LinkedHashSet();
Set tmpVariables2 = new LinkedHashSet();
for(TernaryOperatorExpression ternary : statement1.getTernaryOperatorExpressions()) {
List thenVariables = ternary.getThenExpression().getVariables();
List elseVariables = ternary.getElseExpression().getVariables();
if((thenVariables.size() > 0 && ternary.getThenExpression().getExpression().equals(thenVariables.get(0).getString())) ||
(elseVariables.size() > 0 && ternary.getElseExpression().getExpression().equals(elseVariables.get(0).getString()))) {
ternaryExpressions1.add(ternary.getExpression());
tmpVariables2.addAll(convertToStringSet(ternary.getCondition().getVariables()));
tmpVariables2.addAll(convertToStringSet(thenVariables));
tmpVariables2.addAll(convertToStringSet(elseVariables));
}
}
findReplacements(ternaryExpressions1, tmpVariables2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_CONDITIONAL_EXPRESSION, container1, container2, classDiff);
if(variableDeclarations1.size() > 0 && variableDeclarations2.size() > 0 && variableDeclarations1.toString().equals(variableDeclarations2.toString()) &&
variableDeclarations1.get(0).getInitializer() != null && variableDeclarations1.get(0).getInitializer().getString().equals(statement1.getTernaryOperatorExpressions().get(0).getString()) &&
variableDeclarations2.get(0).getInitializer() != null && variables2.contains(variableDeclarations2.get(0).getInitializer().getString())) {
findReplacements(ternaryExpressions1, variables2, replacementInfo, ReplacementType.VARIABLE_REPLACED_WITH_CONDITIONAL_EXPRESSION, container1, container2, classDiff);
}
}
if(!statement1.getString().endsWith("=true;\n") && !statement1.getString().endsWith("=false;\n")) {
findReplacements(booleanLiterals1, arguments2, replacementInfo, ReplacementType.BOOLEAN_REPLACED_WITH_ARGUMENT, container1, container2, classDiff);
findReplacements(booleanLiterals1, variables2, replacementInfo, ReplacementType.BOOLEAN_REPLACED_WITH_VARIABLE, container1, container2, classDiff);
if(booleanLiterals1.isEmpty() && statement1.getBooleanLiterals().size() != statement2.getBooleanLiterals().size()) {
Set literals1 = convertToStringSet(statement1.getBooleanLiterals());
Set literals2 = convertToStringSet(statement2.getBooleanLiterals());
if(literals1.equals(literals2) ||
matchingArgument(literals1, arguments2, invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2) ||
matchingArgument(literals1, arguments2, creationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2)) {
findReplacements(literals1, arguments2, replacementInfo, ReplacementType.BOOLEAN_REPLACED_WITH_ARGUMENT, container1, container2, classDiff);
}
if(literals1.equals(literals2) ||
matchingArgument(literals1, variables2, invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2) ||
matchingArgument(literals1, variables2, creationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2)) {
findReplacements(literals1, variables2, replacementInfo, ReplacementType.BOOLEAN_REPLACED_WITH_VARIABLE, container1, container2, classDiff);
}
}
}
if(!statement2.getString().endsWith("=true;\n") && !statement2.getString().endsWith("=false;\n")) {
if(statement1.getBooleanLiterals().size() != statement2.getBooleanLiterals().size()) {
Set literals1 = convertToStringSet(statement1.getBooleanLiterals());
Set literals2 = convertToStringSet(statement2.getBooleanLiterals());
if(literals1.equals(literals2) ||
matchingArgument(arguments1, literals2, invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2) ||
matchingArgument(arguments1, literals2, creationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2)) {
findReplacements(arguments1, literals2, replacementInfo, ReplacementType.BOOLEAN_REPLACED_WITH_ARGUMENT, container1, container2, classDiff);
}
if(literals1.equals(literals2) ||
matchingArgument(variables1, literals2, invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2) ||
matchingArgument(variables1, literals2, creationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2)) {
findReplacements(variables1, literals2, replacementInfo, ReplacementType.BOOLEAN_REPLACED_WITH_VARIABLE, container1, container2, classDiff);
}
}
}
if((statement2.getString().endsWith("true;\n") && statement1.getString().endsWith("Boolean.TRUE;\n")) ||
(statement2.getString().endsWith("false;\n") && statement1.getString().endsWith("Boolean.FALSE;\n"))) {
findReplacements(variables1, booleanLiterals2, replacementInfo, ReplacementType.BOOLEAN_REPLACED_WITH_VARIABLE, container1, container2, classDiff);
}
if((statement1.getString().endsWith("true;\n") && statement2.getString().endsWith("Boolean.TRUE;\n")) ||
(statement1.getString().endsWith("false;\n") && statement2.getString().endsWith("Boolean.FALSE;\n"))) {
findReplacements(booleanLiterals1, variables2, replacementInfo, ReplacementType.BOOLEAN_REPLACED_WITH_VARIABLE, container1, container2, classDiff);
}
if((statement1.getString().endsWith("true;\n") && statement2.getString().endsWith("false;\n")) ||
(statement1.getString().endsWith("false;\n") && statement2.getString().endsWith("true;\n"))) {
findReplacements(booleanLiterals1, booleanLiterals2, replacementInfo, ReplacementType.BOOLEAN_LITERAL, container1, container2, classDiff);
}
if(statement1.getString().contains(" != null") || statement1.getString().contains(" == null")) {
for(String key : methodInvocationMap2.keySet()) {
List extends AbstractCall> calls2 = methodInvocationMap2.get(key);
for(AbstractCall call : calls2) {
if(call.getName().equals("isPresent") && call.getExpression() != null) {
String checkIfNull = call.getExpression() + " == null";
String checkIfNotNull = call.getExpression() + " != null";
if(statement1.getString().contains(checkIfNotNull)) {
Set set1 = Set.of(checkIfNotNull);
Set set2 = Set.of(call.actualString());
findReplacements(set1, set2, replacementInfo, ReplacementType.NULL_LITERAL_CHECK_REPLACED_WITH_OPTIONAL_IS_PRESENT_CHECK, container1, container2, classDiff);
}
else if(statement1.getString().contains(checkIfNull)) {
Set set1 = Set.of(checkIfNull);
Set set2 = Set.of("!" + call.actualString());
findReplacements(set1, set2, replacementInfo, ReplacementType.NULL_LITERAL_CHECK_REPLACED_WITH_OPTIONAL_IS_PRESENT_CHECK, container1, container2, classDiff);
}
}
else if(call.getName().equals("isEmpty") && call.getExpression() != null) {
String checkIfNull = call.getExpression() + " == null";
String checkIfNotNull = call.getExpression() + " != null";
if(statement1.getString().contains(checkIfNotNull)) {
Set set1 = Set.of(checkIfNotNull);
Set set2 = Set.of("!" + call.actualString());
findReplacements(set1, set2, replacementInfo, ReplacementType.NULL_LITERAL_CHECK_REPLACED_WITH_OPTIONAL_IS_EMPTY_CHECK, container1, container2, classDiff);
}
else if(statement1.getString().contains(checkIfNull)) {
Set set1 = Set.of(checkIfNull);
Set set2 = Set.of(call.actualString());
findReplacements(set1, set2, replacementInfo, ReplacementType.NULL_LITERAL_CHECK_REPLACED_WITH_OPTIONAL_IS_EMPTY_CHECK, container1, container2, classDiff);
}
}
}
}
}
if(variableDeclarations1.toString().equals(variableDeclarations2.toString()) && castExpressions1.size() == castExpressions2.size() && castExpressions1.size() > 0) {
findReplacements(castExpressions1, castExpressions2, replacementInfo, ReplacementType.CAST_EXPRESSION, container1, container2, classDiff);
}
if(!argumentsWithIdenticalMethodCalls(arguments1, arguments2, methodInvocations1, methodInvocations2)) {
findReplacements(arguments1, methodInvocations2, replacementInfo, ReplacementType.ARGUMENT_REPLACED_WITH_METHOD_INVOCATION, container1, container2, classDiff);
findReplacements(methodInvocations1, arguments2, replacementInfo, ReplacementType.ARGUMENT_REPLACED_WITH_METHOD_INVOCATION, container1, container2, classDiff);
boolean anonymousArgument1 = false;
if(arguments1.size() == 1 && containsMethodSignatureOfAnonymousClass(arguments1.iterator().next())) {
anonymousArgument1 = true;
}
boolean anonymousArgument2 = false;
if(arguments2.size() == 1 && containsMethodSignatureOfAnonymousClass(arguments2.iterator().next())) {
anonymousArgument2 = true;
}
if(!anonymousArgument1 && !anonymousArgument2) {
findReplacements(arguments1, arguments2, replacementInfo, ReplacementType.ARGUMENT, container1, container2, classDiff);
}
}
if(parentMapper != null && statement1.getParent() != null && statement2.getParent() != null &&
statement1.getParent().getLocationInfo().getCodeElementType().equals(statement2.getParent().getLocationInfo().getCodeElementType())) {
if(statement1.getString().equals(JAVA.RETURN_STATEMENT) && statement2.getString().equals(JAVA.RETURN_NULL)) {
return replacementInfo.getReplacements();
}
else if(statement1.getString().equals(JAVA.RETURN_NULL) && statement2.getString().equals(JAVA.RETURN_STATEMENT)) {
return replacementInfo.getReplacements();
}
if(statement1.getString().equals(JAVA.RETURN_FALSE) && statement2.getString().equals(JAVA.RETURN_NULL)) {
return replacementInfo.getReplacements();
}
else if(statement1.getString().equals(JAVA.RETURN_NULL) && statement2.getString().equals(JAVA.RETURN_FALSE)) {
return replacementInfo.getReplacements();
}
}
else if(parentMapper == null && statement1.getParent() != null && statement2.getParent() != null &&
statement1.getParent().getLocationInfo().getCodeElementType().equals(statement2.getParent().getLocationInfo().getCodeElementType())) {
if(container1 instanceof UMLOperation && container2 instanceof UMLOperation) {
UMLParameter returnParameter1 = ((UMLOperation)container1).getReturnParameter();
UMLParameter returnParameter2 = ((UMLOperation)container2).getReturnParameter();
if(returnParameter1 != null && returnParameter2 != null) {
UMLType returnType1 = returnParameter1.getType();
UMLType returnType2 = returnParameter2.getType();
if(returnType1.getClassType().equals("void") && returnType2.getClassType().equals("boolean")) {
if(statement1.getString().equals(JAVA.RETURN_STATEMENT) && statement2.getString().equals(JAVA.RETURN_FALSE)) {
return replacementInfo.getReplacements();
}
if(statement1.getString().equals(JAVA.RETURN_STATEMENT) && statement2.getString().equals(JAVA.RETURN_TRUE)) {
return replacementInfo.getReplacements();
}
}
else if(returnType1.getClassType().equals("boolean") && returnType2.getClassType().equals("void")) {
if(statement2.getString().equals(JAVA.RETURN_STATEMENT) && statement1.getString().equals(JAVA.RETURN_FALSE)) {
return replacementInfo.getReplacements();
}
if(statement2.getString().equals(JAVA.RETURN_STATEMENT) && statement1.getString().equals(JAVA.RETURN_TRUE)) {
return replacementInfo.getReplacements();
}
}
if(returnType1.getClassType().equals("void") && !returnType2.getClassType().equals("void")) {
if(statement1.getString().equals(JAVA.RETURN_STATEMENT) && statement2.getVariables().size() > 0 && statement2.getString().equals(JAVA.RETURN_SPACE + statement2.getVariables().get(0).getString() + JAVA.STATEMENT_TERMINATION)) {
VariableDeclaration variableDeclaration2 = container2.getVariableDeclaration(statement2.getVariables().get(0).getString());
if(variableDeclaration2 != null && variableDeclaration2.getType() != null && variableDeclaration2.getType().equals(returnType2)) {
return replacementInfo.getReplacements();
}
}
}
else if(!returnType1.getClassType().equals("void") && returnType2.getClassType().equals("void")) {
if(statement2.getString().equals(JAVA.RETURN_STATEMENT) && statement1.getVariables().size() > 0 && statement1.getString().equals(JAVA.RETURN_SPACE + statement1.getVariables().get(0).getString() + JAVA.STATEMENT_TERMINATION)) {
VariableDeclaration variableDeclaration1 = container1.getVariableDeclaration(statement1.getVariables().get(0).getString());
if(variableDeclaration1 != null && variableDeclaration1.getType() != null && variableDeclaration1.getType().equals(returnType1)) {
return replacementInfo.getReplacements();
}
}
}
//match break with already matched return
if(statement1.getString().equals(JAVA.BREAK_STATEMENT)) {
Set mappingsToBeAdded = new LinkedHashSet<>();
for(AbstractCodeMapping mapping : mappings) {
AbstractCodeFragment fragment2 = mapping.getFragment2();
if(fragment2.getParent() != null && fragment2.getString().startsWith(JAVA.RETURN_SPACE)) {
CompositeStatementObject parent1 = statement1.getParent();
CompositeStatementObject parent2 = fragment2.getParent();
String signature1 = parent1.getSignature();
String signature2 = parent2.getSignature();
if(signature1.equals(signature2)) {
LeafMapping leafMapping = operationBodyMapper.createLeafMapping(statement1, fragment2, parameterToArgumentMap, equalNumberOfAssertions);
mappingsToBeAdded.add(leafMapping);
break;
}
}
}
for(AbstractCodeMapping mapping : mappingsToBeAdded) {
operationBodyMapper.addMapping(mapping);
}
}
}
}
}
String s1 = operationBodyMapper.preprocessInput1(statement1, statement2);
String s2 = operationBodyMapper.preprocessInput2(statement1, statement2);
replacementsToBeRemoved = new LinkedHashSet();
replacementsToBeAdded = new LinkedHashSet();
for(Replacement replacement : replacementInfo.getReplacements()) {
s1 = ReplacementUtil.performReplacement(s1, s2, replacement.getBefore(), replacement.getAfter());
//find variable replacements within method invocation replacements, the boolean value indicates if the remaining part of the original replacement is identical or not
Map nestedReplacementMap = replacementsWithinMethodInvocations(replacement.getBefore(), replacement.getAfter(), variables1, methodInvocations2, methodInvocationMap2, Direction.VARIABLE_TO_INVOCATION);
nestedReplacementMap.putAll(replacementsWithinMethodInvocations(replacement.getBefore(), replacement.getAfter(), methodInvocations1, variables2, methodInvocationMap1, Direction.INVOCATION_TO_VARIABLE));
if(!nestedReplacementMap.isEmpty()) {
if(!nestedReplacementMap.values().contains(false)) {
replacementsToBeRemoved.add(replacement);
}
replacementsToBeAdded.addAll(nestedReplacementMap.keySet());
}
boolean methodInvocationReplacementWithDifferentNumberOfArguments = false;
if(replacement instanceof MethodInvocationReplacement) {
MethodInvocationReplacement methodInvocationReplacement = (MethodInvocationReplacement)replacement;
AbstractCall invokedOperationBefore = methodInvocationReplacement.getInvokedOperationBefore();
AbstractCall invokedOperationAfter = methodInvocationReplacement.getInvokedOperationAfter();
if(invokedOperationBefore.arguments().size() != invokedOperationAfter.arguments().size()) {
methodInvocationReplacementWithDifferentNumberOfArguments = true;
}
}
if(!methodInvocationReplacementWithDifferentNumberOfArguments) {
Set r = variableReplacementWithinMethodInvocations(replacement.getBefore(), replacement.getAfter(), variables1, variables2, operationBodyMapper.getParameterToArgumentMap1());
if(!r.isEmpty()) {
replacementsToBeRemoved.add(replacement);
replacementsToBeAdded.addAll(r);
}
Set r2 = variableReplacementWithinMethodInvocations(replacement.getBefore(), replacement.getAfter(), stringLiterals1, variables2, operationBodyMapper.getParameterToArgumentMap1());
if(!r2.isEmpty()) {
replacementsToBeRemoved.add(replacement);
replacementsToBeAdded.addAll(r2);
}
}
}
replacementInfo.removeReplacements(replacementsToBeRemoved);
replacementInfo.addReplacements(replacementsToBeAdded);
boolean isEqualWithReplacement = s1.equals(s2) || (s1 + JAVA.STATEMENT_TERMINATION).equals(s2) || (s2 + JAVA.STATEMENT_TERMINATION).equals(s1) || ("final " + s1 + JAVA.STATEMENT_TERMINATION).equals(s2) || ("final " + s2 + JAVA.STATEMENT_TERMINATION).equals(s1) || replacementInfo.getArgumentizedString1().equals(replacementInfo.getArgumentizedString2()) || equalAfterParenthesisElimination(s1, s2) ||
differOnlyInCastExpressionOrPrefixOperatorOrInfixOperand(s1, s2, methodInvocationMap1, methodInvocationMap2, statement1, statement2, variableDeclarations1, variableDeclarations2, replacementInfo, operationBodyMapper) ||
differOnlyInFinalModifier(s1, s2, variableDeclarations1, variableDeclarations2, replacementInfo) || differOnlyInThis(s1, s2) || differOnlyInThrow(s1, s2) || matchAsLambdaExpressionArgument(s1, s2, parameterToArgumentMap, replacementInfo, statement1, container2, operationBodyMapper) || differOnlyInDefaultInitializer(s1, s2, variableDeclarations1, variableDeclarations2) ||
oneIsVariableDeclarationTheOtherIsVariableAssignment(s1, s2, variableDeclarations1, variableDeclarations2, replacementInfo) || identicalVariableDeclarationsWithDifferentNames(s1, s2, variableDeclarations1, variableDeclarations2, replacementInfo) ||
oneIsVariableDeclarationTheOtherIsReturnStatement(s1, s2, variableDeclarations1, variableDeclarations2) || oneIsVariableDeclarationTheOtherIsReturnStatement(statement1.getString(), statement2.getString(), variableDeclarations1, variableDeclarations2) ||
(invocationCoveringTheEntireStatement1 == null && invocationCoveringTheEntireStatement2 == null && creationCoveringTheEntireStatement1 == null && creationCoveringTheEntireStatement2 == null && wrapInMethodCall(s1, s2, methodInvocationMap1, replacementInfo)) ||
(containsValidOperatorReplacements(replacementInfo) && (equalAfterInfixExpressionExpansion(s1, s2, replacementInfo, statement1.getInfixExpressions()) || commonConditional(s1, s2, parameterToArgumentMap, replacementInfo, statement1, statement2, operationBodyMapper))) ||
equalAfterArgumentMerge(s1, s2, replacementInfo) ||
equalAfterNewArgumentAdditions(s1, s2, replacementInfo, container1, container2, operationSignatureDiff, classDiff) ||
(validStatementForConcatComparison(statement1, statement2) && commonConcat(s1, s2, parameterToArgumentMap, replacementInfo, statement1, statement2, operationBodyMapper));
List anonymousClassDeclarations1 = statement1.getAnonymousClassDeclarations();
List anonymousClassDeclarations2 = statement2.getAnonymousClassDeclarations();
List lambdas1 = statement1.getLambdas();
List lambdas2 = statement2.getLambdas();
List lambdaMappers = new ArrayList();
AbstractCall assignmentInvocationCoveringTheEntireStatement1 = invocationCoveringTheEntireStatement1 == null ? statement1.assignmentInvocationCoveringEntireStatement() : invocationCoveringTheEntireStatement1;
AbstractCall assignmentInvocationCoveringTheEntireStatement2 = invocationCoveringTheEntireStatement2 == null ? statement2.assignmentInvocationCoveringEntireStatement() : invocationCoveringTheEntireStatement2;
AbstractCall assignmentCreationCoveringTheEntireStatement1 = creationCoveringTheEntireStatement1 == null ? statement1.assignmentCreationCoveringEntireStatement() : creationCoveringTheEntireStatement1;
AbstractCall assignmentCreationCoveringTheEntireStatement2 = creationCoveringTheEntireStatement2 == null ? statement2.assignmentCreationCoveringEntireStatement() : creationCoveringTheEntireStatement2;
if(isEqualWithReplacement) {
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null) {
List typeReplacements = replacementInfo.getReplacements(ReplacementType.TYPE);
for(Replacement typeReplacement : typeReplacements) {
if(invocationCoveringTheEntireStatement1.getName().contains(typeReplacement.getBefore()) && invocationCoveringTheEntireStatement2.getName().contains(typeReplacement.getAfter())) {
if(invocationCoveringTheEntireStatement1.identicalExpression(invocationCoveringTheEntireStatement2) && invocationCoveringTheEntireStatement1.equalArguments(invocationCoveringTheEntireStatement2)) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.getName(),
invocationCoveringTheEntireStatement2.getName(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_NAME);
replacementInfo.addReplacement(replacement);
}
else {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
}
break;
}
}
if(invocationCoveringTheEntireStatement1.identicalName(invocationCoveringTheEntireStatement2) &&
invocationCoveringTheEntireStatement1.staticInvokerExpressionReplaced(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements()) &&
invocationCoveringTheEntireStatement1.allArgumentsReplaced(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements())) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
}
for(Replacement r : replacementInfo.getReplacements()) {
if(r instanceof VariableReplacementWithMethodInvocation) {
VariableReplacementWithMethodInvocation replacement = (VariableReplacementWithMethodInvocation)r;
AbstractCall call = replacement.getInvokedOperation();
if(call.getName().equals("of") || call.getName().equals("asList")) {
if(replacement.getDirection().equals(Direction.VARIABLE_TO_INVOCATION)) {
for(String argument2 : call.arguments()) {
for(AbstractCodeFragment fragment1 : replacementInfo.getStatements1()) {
AbstractCall invocation1 = fragment1.invocationCoveringEntireFragment();
if(invocation1 != null && invocation1.getExpression() != null && invocation1.getExpression().equals(replacement.getBefore())) {
boolean argumentMatched = false;
for(String argument1 : invocation1.arguments()) {
if(argument1.equals(argument2)) {
List leafExpressions1 = fragment1.findExpression(argument1);
List leafExpressions2 = statement2.findExpression(argument2);
if(leafExpressions1.size() == 1 && leafExpressions2.size() == 1) {
LeafMapping mapping = operationBodyMapper.createLeafMapping(leafExpressions1.get(0), leafExpressions2.get(0), parameterToArgumentMap, equalNumberOfAssertions);
operationBodyMapper.addMapping(mapping);
}
argumentMatched = true;
break;
}
}
if(argumentMatched) {
break;
}
}
}
}
}
}
}
}
}
if(variableDeclarationsWithEverythingReplaced(variableDeclarations1, variableDeclarations2, replacementInfo) &&
!statement1.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT) &&
!statement2.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT) &&
!statement1.getLocationInfo().getCodeElementType().equals(CodeElementType.CATCH_CLAUSE) &&
!statement2.getLocationInfo().getCodeElementType().equals(CodeElementType.CATCH_CLAUSE)) {
return null;
}
if(variableAssignmentWithEverythingReplaced(statement1, statement2, replacementInfo, operationBodyMapper)) {
return null;
}
if(classInstanceCreationWithEverythingReplaced(statement1, statement2, replacementInfo, parameterToArgumentMap)) {
return null;
}
if(operatorExpressionWithEverythingReplaced(statement1, statement2, replacementInfo, parameterToArgumentMap)) {
return null;
}
if(thisConstructorCallWithEverythingReplaced(invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, replacementInfo)) {
return null;
}
if(invocationWithEverythingReplaced(invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, replacementInfo)) {
return null;
}
if(statement1.getString().startsWith(JAVA.RETURN_SPACE) && statement2.getString().startsWith(JAVA.RETURN_SPACE) && statement1.getParent() != null && statement2.getParent() != null &&
!statement1.getParent().getLocationInfo().getCodeElementType().equals(statement2.getParent().getLocationInfo().getCodeElementType())) {
if(!(statement1.isLastStatementInParentBlock() && statement1.getParent() instanceof TryStatementObject && statement2.isLastStatement()) &&
!(statement2.isLastStatementInParentBlock() && statement2.getParent() instanceof TryStatementObject && statement1.isLastStatement())) {
return null;
}
}
if(!anonymousClassDeclarations1.isEmpty() && !anonymousClassDeclarations2.isEmpty()) {
Set replacementsInsideAnonymous = new LinkedHashSet();
for(Replacement replacement : replacementInfo.getReplacements()) {
if(replacement instanceof MethodInvocationReplacement) {
MethodInvocationReplacement methodInvocationReplacement = (MethodInvocationReplacement)replacement;
for(int i=0; i replacements = processAnonymousAndLambdas(statement1, statement2, parameterToArgumentMap, replacementInfo,
assignmentInvocationCoveringTheEntireStatement1 != null ? assignmentInvocationCoveringTheEntireStatement1 : assignmentCreationCoveringTheEntireStatement1,
assignmentInvocationCoveringTheEntireStatement2 != null ? assignmentInvocationCoveringTheEntireStatement2 : assignmentCreationCoveringTheEntireStatement2,
methodInvocationMap1, methodInvocationMap2, anonymousClassDeclarations1, anonymousClassDeclarations2, lambdas1, lambdas2, lambdaMappers, operationBodyMapper);
if(replacements != null) {
return replacements;
}
//match if with switch
if(statement1.getLocationInfo().getCodeElementType().equals(CodeElementType.IF_STATEMENT) &&
statement2.getLocationInfo().getCodeElementType().equals(CodeElementType.SWITCH_STATEMENT)) {
CompositeStatementObject if1 = (CompositeStatementObject)statement1;
CompositeStatementObject switch2 = (CompositeStatementObject)statement2;
List expressions1 = if1.getExpressions();
List expressions2 = switch2.getExpressions();
if(expressions1.size() == 1 && expressions2.size() == 1 && expressions1.get(0).getString().equals(expressions2.get(0).getString())) {
return replacementInfo.getReplacements();
}
}
//match switch with if
if(statement1.getLocationInfo().getCodeElementType().equals(CodeElementType.SWITCH_STATEMENT) &&
statement2.getLocationInfo().getCodeElementType().equals(CodeElementType.IF_STATEMENT)) {
CompositeStatementObject switch1 = (CompositeStatementObject)statement1;
CompositeStatementObject if2 = (CompositeStatementObject)statement2;
List expressions1 = switch1.getExpressions();
List expressions2 = if2.getExpressions();
if(expressions1.size() == 1 && expressions2.size() == 1 && expressions1.get(0).getString().equals(expressions2.get(0).getString())) {
return replacementInfo.getReplacements();
}
}
//match traditional for with enhanced for
if(statement1.getLocationInfo().getCodeElementType().equals(CodeElementType.FOR_STATEMENT) &&
statement2.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT)) {
CompositeStatementObject for1 = (CompositeStatementObject)statement1;
CompositeStatementObject for2 = (CompositeStatementObject)statement2;
List expressions2 = for2.getExpressions();
AbstractExpression enhancedForExpression = expressions2.get(expressions2.size()-1);
VariableDeclaration inlinedVariableDeclaration = null;
for(AbstractCodeFragment fragment1 : replacementInfo.getStatements1()) {
for(VariableDeclaration variableDeclaration : fragment1.getVariableDeclarations()) {
if(variableDeclaration.getInitializer() != null && variableDeclaration.getInitializer().getString().equals(enhancedForExpression.getString())) {
inlinedVariableDeclaration = variableDeclaration;
break;
}
}
}
//search for previous variable declaration mappings having these for loops in their scope
String renamedVariable = null;
for(AbstractCodeMapping previousMapping : mappings) {
if(previousMapping.getFragment1().getVariableDeclarations().size() > 0 && previousMapping.getFragment2().getVariableDeclarations().size() > 0) {
VariableDeclaration declaration1 = previousMapping.getFragment1().getVariableDeclarations().get(0);
VariableDeclaration declaration2 = previousMapping.getFragment2().getVariableDeclarations().get(0);
if(declaration1.getScope().subsumes(for1.getLocationInfo()) && declaration2.getScope().subsumes(for2.getLocationInfo())) {
if(declaration2.getVariableName().equals(enhancedForExpression.getString())) {
renamedVariable = declaration1.getVariableName();
break;
}
}
}
}
for(AbstractExpression expression1 : for1.getExpressions()) {
if(expression1.getString().contains(enhancedForExpression.getString() + ".length") ||
expression1.getString().contains(enhancedForExpression.getString() + ".size()") ||
expression1.getString().contains(enhancedForExpression.getString() + ".iterator()") ||
expression1.getString().contains(enhancedForExpression.getString() + ".listIterator()") ||
expression1.getString().contains(enhancedForExpression.getString() + ".descendingIterator()")) {
return replacementInfo.getReplacements();
}
if(renamedVariable != null) {
if(expression1.getString().contains(renamedVariable + ".length") ||
expression1.getString().contains(renamedVariable + ".size()") ||
expression1.getString().contains(renamedVariable + ".iterator()") ||
expression1.getString().contains(renamedVariable + ".listIterator()") ||
expression1.getString().contains(renamedVariable + ".descendingIterator()")) {
return replacementInfo.getReplacements();
}
}
if(inlinedVariableDeclaration != null) {
if(expression1.getString().contains(inlinedVariableDeclaration.getVariableName() + ".length") ||
expression1.getString().contains(inlinedVariableDeclaration.getVariableName() + ".size()") ||
expression1.getString().contains(inlinedVariableDeclaration.getVariableName() + ".iterator()") ||
expression1.getString().contains(inlinedVariableDeclaration.getVariableName() + ".listIterator()") ||
expression1.getString().contains(inlinedVariableDeclaration.getVariableName() + ".descendingIterator()")) {
return replacementInfo.getReplacements();
}
}
}
}
if(statement2.getLocationInfo().getCodeElementType().equals(CodeElementType.FOR_STATEMENT) &&
statement1.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT)) {
CompositeStatementObject for1 = (CompositeStatementObject)statement1;
CompositeStatementObject for2 = (CompositeStatementObject)statement2;
List expressions1 = for1.getExpressions();
AbstractExpression enhancedForExpression = expressions1.get(expressions1.size()-1);
//search for previous variable declaration mappings having these for loops in their scope
String renamedVariable = null;
for(AbstractCodeMapping previousMapping : mappings) {
if(previousMapping.getFragment1().getVariableDeclarations().size() > 0 && previousMapping.getFragment2().getVariableDeclarations().size() > 0) {
VariableDeclaration declaration1 = previousMapping.getFragment1().getVariableDeclarations().get(0);
VariableDeclaration declaration2 = previousMapping.getFragment2().getVariableDeclarations().get(0);
if(declaration1.getScope().subsumes(for1.getLocationInfo()) && declaration2.getScope().subsumes(for2.getLocationInfo())) {
if(declaration1.getVariableName().equals(enhancedForExpression.getString())) {
renamedVariable = declaration2.getVariableName();
break;
}
}
}
}
for(AbstractExpression expression2 : for2.getExpressions()) {
if(expression2.getString().contains(enhancedForExpression.getString() + ".length") ||
expression2.getString().contains(enhancedForExpression.getString() + ".size()") ||
expression2.getString().contains(enhancedForExpression.getString() + ".iterator()") ||
expression2.getString().contains(enhancedForExpression.getString() + ".listIterator()") ||
expression2.getString().contains(enhancedForExpression.getString() + ".descendingIterator()")) {
return replacementInfo.getReplacements();
}
if(renamedVariable != null) {
if(expression2.getString().contains(renamedVariable + ".length") ||
expression2.getString().contains(renamedVariable + ".size()") ||
expression2.getString().contains(renamedVariable + ".iterator()") ||
expression2.getString().contains(renamedVariable + ".listIterator()") ||
expression2.getString().contains(renamedVariable + ".descendingIterator()")) {
return replacementInfo.getReplacements();
}
}
}
}
//match while with enhanced for
if(statement1.getLocationInfo().getCodeElementType().equals(CodeElementType.WHILE_STATEMENT) &&
statement2.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT)) {
CompositeStatementObject for2 = (CompositeStatementObject)statement2;
Set additionallyMatchedStatements1 = new LinkedHashSet<>();
List expressions2 = for2.getExpressions();
AbstractExpression enhancedForExpression = expressions2.get(expressions2.size()-1);
VariableDeclaration iteratorDeclaration1 = null;
for(AbstractCodeFragment codeFragment : replacementInfo.getStatements1()) {
AbstractCall invocation = codeFragment.invocationCoveringEntireFragment();
if(invocation != null && invocation.getExpression() != null) {
if(invocation.getExpression().equals(enhancedForExpression.getString())) {
List variableDeclarations = codeFragment.getVariableDeclarations();
if(variableDeclarations.size() == 1 && codeFragment.getLocationInfo().before(statement1.getLocationInfo())) {
boolean iteratorDeclarationFound = false;
for(String key : methodInvocationMap1.keySet()) {
for(AbstractCall call : methodInvocationMap1.get(key)) {
if(call.getExpression() != null && call.getExpression().equals(variableDeclarations.get(0).getVariableName())) {
iteratorDeclarationFound = true;
break;
}
}
}
if(iteratorDeclarationFound) {
iteratorDeclaration1 = variableDeclarations.get(0);
additionallyMatchedStatements1.add(codeFragment);
}
}
}
else if(iteratorDeclaration1 != null && invocation.getExpression().equals(iteratorDeclaration1.getVariableName())) {
List variableDeclarations = codeFragment.getVariableDeclarations();
if(variableDeclarations.size() == 1 && variableDeclarations2.size() == 1 && statement1.getLocationInfo().subsumes(codeFragment.getLocationInfo())) {
//check if variable name and type are the same with the enhanced-for parameter
VariableDeclaration v1 = variableDeclarations.get(0);
VariableDeclaration v2 = variableDeclarations2.get(0);
if(v1.getVariableName().equals(v2.getVariableName()) && v1.getType() != null && v1.getType().equals(v2.getType())) {
additionallyMatchedStatements1.add(codeFragment);
}
}
}
}
}
if(additionallyMatchedStatements1.size() > 0) {
Replacement composite = new CompositeReplacement(statement1.getString(), statement2.getString(), additionallyMatchedStatements1, new LinkedHashSet());
replacementInfo.addReplacement(composite);
return replacementInfo.getReplacements();
}
}
//match try-with-resources with regular try
if(statement1 instanceof TryStatementObject && statement2 instanceof TryStatementObject) {
TryStatementObject try1 = (TryStatementObject)statement1;
TryStatementObject try2 = (TryStatementObject)statement2;
if(!try1.isTryWithResources() && try2.isTryWithResources()) {
List tryStatements1 = try1.getStatements();
List tryStatements2 = try2.getStatements();
List matchedChildStatements1 = new ArrayList<>();
List matchedChildStatements2 = new ArrayList<>();
for(AbstractCodeMapping mapping : mappings) {
if(tryStatements1.contains(mapping.getFragment1()) && tryStatements2.contains(mapping.getFragment2())) {
matchedChildStatements1.add(mapping.getFragment1());
matchedChildStatements2.add(mapping.getFragment2());
}
}
if(matchedChildStatements1.size() > 0 && matchedChildStatements2.size() > 0) {
List unmatchedStatementsTry1 = new ArrayList<>();
for(AbstractStatement tryStatement1 : tryStatements1) {
if(!matchedChildStatements1.contains(tryStatement1)) {
unmatchedStatementsTry1.add(tryStatement1);
}
}
List unmatchedExpressionsTry2 = new ArrayList<>();
for(AbstractExpression tryExpression2 : try2.getExpressions()) {
unmatchedExpressionsTry2.add(tryExpression2);
}
operationBodyMapper.processLeaves(unmatchedStatementsTry1, unmatchedExpressionsTry2, parameterToArgumentMap, false);
Set additionallyMatchedStatements1 = new LinkedHashSet();
for(CompositeStatementObject catchClause1 : try1.getCatchClauses()) {
additionallyMatchedStatements1.add(catchClause1);
}
Replacement composite = new CompositeReplacement(statement1.getString(), statement2.getString(), additionallyMatchedStatements1, new LinkedHashSet());
replacementInfo.addReplacement(composite);
return replacementInfo.getReplacements();
}
}
else if(try1.isTryWithResources() && try2.isTryWithResources()) {
if((creationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null) ||
(invocationCoveringTheEntireStatement1 != null && creationCoveringTheEntireStatement2 != null)) {
List tryStatements1 = try1.getStatements();
List tryStatements2 = try2.getStatements();
List matchedChildStatements1 = new ArrayList<>();
List matchedChildStatements2 = new ArrayList<>();
for(AbstractCodeMapping mapping : mappings) {
if(tryStatements1.contains(mapping.getFragment1()) && tryStatements2.contains(mapping.getFragment2())) {
matchedChildStatements1.add(mapping.getFragment1());
matchedChildStatements2.add(mapping.getFragment2());
}
}
if(matchedChildStatements1.size() > 0 && matchedChildStatements1.size() == matchedChildStatements2.size() &&
(tryStatements1.size() == matchedChildStatements1.size() || tryStatements2.size() == matchedChildStatements2.size())) {
return replacementInfo.getReplacements();
}
}
}
}
//method invocation is identical
if(assignmentInvocationCoveringTheEntireStatement1 != null && assignmentInvocationCoveringTheEntireStatement2 != null) {
for(String key1 : methodInvocationMap1.keySet()) {
for(AbstractCall invocation1 : methodInvocationMap1.get(key1)) {
if(invocation1.identical(assignmentInvocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap, lambdaMappers) &&
!assignmentInvocationCoveringTheEntireStatement1.arguments().contains(key1)) {
if(variableDeclarationsWithEverythingReplaced(variableDeclarations1, variableDeclarations2, replacementInfo) &&
!statement1.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT) &&
!statement2.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT)) {
return null;
}
String expression1 = assignmentInvocationCoveringTheEntireStatement1.getExpression();
if(expression1 == null || !expression1.contains(key1)) {
return replacementInfo.getReplacements();
}
}
else if(invocation1.identicalName(assignmentInvocationCoveringTheEntireStatement2) && invocation1.equalArguments(assignmentInvocationCoveringTheEntireStatement2) &&
!assignmentInvocationCoveringTheEntireStatement1.arguments().contains(key1) && assignmentInvocationCoveringTheEntireStatement2.getExpression() != null) {
boolean expressionMatched = false;
Set additionallyMatchedStatements2 = new LinkedHashSet();
Map variableDeclarationsInUnmatchedStatements2 = new LinkedHashMap();
for(AbstractCodeFragment codeFragment : replacementInfo.getStatements2()) {
for(VariableDeclaration variableDeclaration : codeFragment.getVariableDeclarations()) {
variableDeclarationsInUnmatchedStatements2.put(variableDeclaration, codeFragment);
}
}
for(AbstractCodeFragment codeFragment : replacementInfo.getStatements2()) {
VariableDeclaration variableDeclaration = codeFragment.getVariableDeclaration(assignmentInvocationCoveringTheEntireStatement2.getExpression());
AbstractCall invocationCoveringEntireCodeFragment = codeFragment.invocationCoveringEntireFragment();
if(variableDeclaration != null && variableDeclaration.getInitializer() != null) {
String initializer = variableDeclaration.getInitializer().getString();
if(invocation1.getExpression() != null && invocation1.getExpression().equals(initializer)) {
Replacement r = new Replacement(invocation1.getExpression(), variableDeclaration.getVariableName(), ReplacementType.VARIABLE_REPLACED_WITH_EXPRESSION_OF_METHOD_INVOCATION);
replacementInfo.getReplacements().add(r);
additionallyMatchedStatements2.add(codeFragment);
expressionMatched = true;
}
else if(invocation1.getExpression() != null) {
String temp = initializer;
Set matchingDeclarations = new LinkedHashSet<>();
for(VariableDeclaration decl : variableDeclarationsInUnmatchedStatements2.keySet()) {
if(temp.contains(decl.getVariableName() + ".") && decl.getInitializer() != null) {
temp = ReplacementUtil.performReplacement(temp, decl.getVariableName(), decl.getInitializer().getString());
matchingDeclarations.add(decl);
}
}
if(invocation1.getExpression().equals(temp)) {
expressionMatched = true;
additionallyMatchedStatements2.add(codeFragment);
for(VariableDeclaration decl : matchingDeclarations) {
additionallyMatchedStatements2.add(variableDeclarationsInUnmatchedStatements2.get(decl));
}
}
else if(invocation1.getExpression().startsWith(temp + ".")) {
additionallyMatchedStatements2.add(codeFragment);
for(VariableDeclaration decl : matchingDeclarations) {
additionallyMatchedStatements2.add(variableDeclarationsInUnmatchedStatements2.get(decl));
}
for(AbstractCodeFragment codeFragment2 : replacementInfo.getStatements2()) {
AbstractCall invocationCoveringEntireCodeFragment2 = codeFragment2.invocationCoveringEntireFragment();
if(invocationCoveringEntireCodeFragment2 != null) {
String extendedTemp = temp + "." + invocationCoveringEntireCodeFragment2.actualString().substring(
invocationCoveringEntireCodeFragment2.getExpression() != null ? invocationCoveringEntireCodeFragment2.getExpression().length()+1 : 0);
if(invocation1.getExpression().startsWith(extendedTemp)) {
additionallyMatchedStatements2.add(codeFragment2);
temp = extendedTemp;
}
}
}
if(invocation1.getExpression().equals(temp)) {
expressionMatched = true;
}
}
}
}
if(invocationCoveringEntireCodeFragment != null && assignmentInvocationCoveringTheEntireStatement1.identicalName(invocationCoveringEntireCodeFragment) &&
assignmentInvocationCoveringTheEntireStatement1.equalArguments(invocationCoveringEntireCodeFragment)) {
additionallyMatchedStatements2.add(codeFragment);
}
}
if(classDiff != null) {
boolean removedAttributeMatched = false;
for(UMLAttribute removedAttribute : classDiff.getRemovedAttributes()) {
if(removedAttribute.getName().equals(assignmentInvocationCoveringTheEntireStatement1.getExpression())) {
removedAttributeMatched = true;
break;
}
}
boolean addedAttributeMatched = false;
for(UMLAttribute addedAttribute : classDiff.getAddedAttributes()) {
if(addedAttribute.getName().equals(assignmentInvocationCoveringTheEntireStatement2.getExpression())) {
addedAttributeMatched = true;
break;
}
}
if(removedAttributeMatched && addedAttributeMatched) {
expressionMatched = true;
Replacement r = new Replacement(assignmentInvocationCoveringTheEntireStatement1.getExpression(), assignmentInvocationCoveringTheEntireStatement2.getExpression(), ReplacementType.VARIABLE_NAME);
replacementInfo.addReplacement(r);
}
}
for(AbstractCodeMapping mapping : mappings) {
for(Replacement r : mapping.getReplacements()) {
if(r.getBefore().equals(assignmentInvocationCoveringTheEntireStatement1.getExpression()) &&
r.getAfter().equals(assignmentInvocationCoveringTheEntireStatement2.getExpression())) {
expressionMatched = true;
replacementInfo.addReplacement(r);
break;
}
}
if(expressionMatched) {
break;
}
}
if(expressionMatched) {
if(additionallyMatchedStatements2.size() > 0) {
Replacement r = new CompositeReplacement(statement1.getString(), statement2.getString(), new LinkedHashSet(), additionallyMatchedStatements2);
replacementInfo.getReplacements().add(r);
}
return replacementInfo.getReplacements();
}
}
}
}
}
//method invocation is identical with a difference in the expression call chain
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
invocationCoveringTheEntireStatement1 instanceof OperationInvocation && invocationCoveringTheEntireStatement2 instanceof OperationInvocation) {
if(((OperationInvocation)invocationCoveringTheEntireStatement1).identicalWithExpressionCallChainDifference((OperationInvocation)invocationCoveringTheEntireStatement2)) {
List extends AbstractCall> invokedOperationsBefore = methodInvocationMap1.get(invocationCoveringTheEntireStatement1.getExpression());
List extends AbstractCall> invokedOperationsAfter = methodInvocationMap2.get(invocationCoveringTheEntireStatement2.getExpression());
if(invokedOperationsBefore != null && invokedOperationsBefore.size() > 0 && invokedOperationsAfter != null && invokedOperationsAfter.size() > 0) {
AbstractCall invokedOperationBefore = invokedOperationsBefore.get(0);
AbstractCall invokedOperationAfter = invokedOperationsAfter.get(0);
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.getExpression(), invocationCoveringTheEntireStatement2.getExpression(), invokedOperationBefore, invokedOperationAfter, ReplacementType.METHOD_INVOCATION_EXPRESSION);
replacementInfo.addReplacement(replacement);
boolean skipCompositeReplacementCheck = false;
if(variableDeclarations1.size() > 0 && variableDeclarations1.get(0).getType() != null && invokedOperationBefore.actualString().startsWith(variableDeclarations1.get(0).getType().getClassType()) &&
variableDeclarations2.size() > 0 && variableDeclarations2.get(0).getType() != null && invokedOperationAfter.actualString().startsWith(variableDeclarations2.get(0).getType().getClassType())) {
skipCompositeReplacementCheck = true;
}
if(!skipCompositeReplacementCheck) {
Set additionallyMatchedStatements1 = additionallyMatchedStatements(variableDeclarations2, replacementInfo.getStatements1());
Set additionallyMatchedStatements2 = additionallyMatchedStatements(variableDeclarations1, replacementInfo.getStatements2());
if(additionallyMatchedStatements1.size() > 0 || additionallyMatchedStatements2.size() > 0) {
Replacement r = new CompositeReplacement(statement1.getString(), statement2.getString(), additionallyMatchedStatements1, additionallyMatchedStatements2);
replacementInfo.getReplacements().add(r);
}
}
return replacementInfo.getReplacements();
}
else if(invokedOperationsBefore != null && invokedOperationsBefore.size() > 0) {
AbstractCall invokedOperationBefore = invokedOperationsBefore.get(0);
Replacement replacement = new VariableReplacementWithMethodInvocation(invocationCoveringTheEntireStatement1.getExpression(), invocationCoveringTheEntireStatement2.getExpression(), invokedOperationBefore, Direction.INVOCATION_TO_VARIABLE);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
else if(invokedOperationsAfter != null && invokedOperationsAfter.size() > 0) {
AbstractCall invokedOperationAfter = invokedOperationsAfter.get(0);
Replacement replacement = new VariableReplacementWithMethodInvocation(invocationCoveringTheEntireStatement1.getExpression(), invocationCoveringTheEntireStatement2.getExpression(), invokedOperationAfter, Direction.VARIABLE_TO_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
if(((OperationInvocation)invocationCoveringTheEntireStatement1).numberOfSubExpressions() == ((OperationInvocation)invocationCoveringTheEntireStatement2).numberOfSubExpressions() &&
invocationCoveringTheEntireStatement1.getExpression().contains(".") == invocationCoveringTheEntireStatement2.getExpression().contains(".")) {
return replacementInfo.getReplacements();
}
}
String expression1 = invocationCoveringTheEntireStatement1.getExpression();
String expression2 = invocationCoveringTheEntireStatement2.getExpression();
boolean staticVSNonStatic = (expression1 == null && expression2 != null && container1 != null && container1.getClassName().endsWith("." + expression2)) ||
(expression1 != null && expression2 == null && container2 != null && container2.getClassName().endsWith("." + expression1));
if(!staticVSNonStatic && modelDiff != null) {
for(UMLClass addedClass : modelDiff.getAddedClasses()) {
if((expression1 == null && expression2 != null && container1 != null && addedClass.getName().endsWith("." + expression2)) ||
(expression1 != null && expression2 == null && container2 != null && addedClass.getName().endsWith("." + expression1))) {
staticVSNonStatic = true;
break;
}
}
}
boolean additionalCaller = invocationCoveringTheEntireStatement1.actualString().endsWith("." + invocationCoveringTheEntireStatement2.actualString()) ||
invocationCoveringTheEntireStatement2.actualString().endsWith("." + invocationCoveringTheEntireStatement1.actualString()) ||
s2.endsWith("." + s1) || s1.endsWith("." + s2);
if((invocationCoveringTheEntireStatement1.identicalName(invocationCoveringTheEntireStatement2) || invocationCoveringTheEntireStatement1.compatibleName(invocationCoveringTheEntireStatement2)) &&
(staticVSNonStatic || additionalCaller) && invocationCoveringTheEntireStatement1.identicalOrReplacedArguments(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), lambdaMappers)) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(), invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
//method invocation is identical if arguments are replaced
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
invocationCoveringTheEntireStatement1.identicalExpression(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap) &&
invocationCoveringTheEntireStatement1.identicalName(invocationCoveringTheEntireStatement2) ) {
for(String key : methodInvocationMap2.keySet()) {
for(AbstractCall invocation2 : methodInvocationMap2.get(key)) {
if(invocation2.arguments().size() > 0 && invocationCoveringTheEntireStatement1.identicalOrReplacedArguments(invocation2, replacementInfo.getReplacements(), lambdaMappers)) {
return replacementInfo.getReplacements();
}
}
}
}
//method invocation is identical if expression and one arguments are swapped
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
invocationCoveringTheEntireStatement1.identicalWithExpressionArgumentSwap(invocationCoveringTheEntireStatement2)) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_EXPRESSION_ARGUMENT_SWAPPED);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
//method invocation is identical if arguments are wrapped or concatenated
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
invocationCoveringTheEntireStatement1.identicalExpression(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap) &&
invocationCoveringTheEntireStatement1.identicalName(invocationCoveringTheEntireStatement2) ) {
for(String key : methodInvocationMap2.keySet()) {
for(AbstractCall invocation2 : methodInvocationMap2.get(key)) {
if(invocationCoveringTheEntireStatement1.identicalOrWrappedArguments(invocation2)) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_ARGUMENT_WRAPPED);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
if(invocationCoveringTheEntireStatement1.identicalOrConcatenatedArguments(invocation2)) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_ARGUMENT_CONCATENATED);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
}
//method invocation has been renamed but the expression and arguments are identical
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null && statement1.getClass().equals(statement2.getClass()) &&
invocationCoveringTheEntireStatement1.renamedWithIdenticalExpressionAndArguments(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap, UMLClassBaseDiff.MAX_OPERATION_NAME_DISTANCE, lambdaMappers,
matchPairOfRemovedAddedOperationsWithIdenticalBody(invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, operationBodyMapper), argumentsWithVariableDeclarationMapping(invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, mappings))) {
boolean variableDeclarationMatch = true;
if(variableDeclarations1.size() > 0 && variableDeclarations2.size() > 0 && !variableDeclarations1.toString().equals(variableDeclarations2.toString()) && !invocationCoveringTheEntireStatement1.arguments().equals(invocationCoveringTheEntireStatement2.arguments()) &&
!argumentsWithVariableDeclarationMapping(invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, mappings)) {
variableDeclarationMatch = false;
}
if(variableDeclarationMatch) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.getName(),
invocationCoveringTheEntireStatement2.getName(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_NAME);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
if(invocationCoveringTheEntireStatement1 == null && invocationCoveringTheEntireStatement2 == null && statement1.getLocationInfo().getCodeElementType().equals(statement2.getLocationInfo().getCodeElementType()) && creationMap1.size() == 0 && creationMap2.size() == 0 &&
methodInvocationMap1.size() == methodInvocationMap2.size() && methodInvocationMap1.size() == 1 && methodInvocations1.size() == methodInvocations2.size() && methodInvocations1.size() == 1) {
AbstractCall invocation1 = methodInvocationMap1.get(methodInvocations1.iterator().next()).get(0);
AbstractCall invocation2 = methodInvocationMap2.get(methodInvocations2.iterator().next()).get(0);
if(invocation1.renamedWithIdenticalExpressionAndArguments(invocation2, replacementInfo.getReplacements(), parameterToArgumentMap, UMLClassBaseDiff.MAX_OPERATION_NAME_DISTANCE, lambdaMappers, matchPairOfRemovedAddedOperationsWithIdenticalBody(invocation1, invocation2, operationBodyMapper), argumentsWithVariableDeclarationMapping(invocation1, invocation2, mappings))) {
Replacement replacement = new MethodInvocationReplacement(invocation1.getName(),
invocation2.getName(), invocation1, invocation2, ReplacementType.METHOD_INVOCATION_NAME);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
//method invocation has been renamed and the expression is different but the arguments are identical, and the variable declarations are identical
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
variableDeclarations1.size() > 0 && variableDeclarations1.toString().equals(variableDeclarations2.toString()) &&
invocationCoveringTheEntireStatement1.variableDeclarationInitializersRenamedWithIdenticalArguments(invocationCoveringTheEntireStatement2)) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_NAME_AND_EXPRESSION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
//method invocation has been renamed but the expressions are null and arguments are identical
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
invocationCoveringTheEntireStatement1.renamedWithIdenticalArgumentsAndNoExpression(invocationCoveringTheEntireStatement2, UMLClassBaseDiff.MAX_OPERATION_NAME_DISTANCE, lambdaMappers)) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.getName(),
invocationCoveringTheEntireStatement2.getName(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_NAME);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
//method invocation has been renamed (one name contains the other), one expression is null, but the other is not null, and arguments are identical
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
invocationCoveringTheEntireStatement1.renamedWithDifferentExpressionAndIdenticalArguments(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap)) {
boolean variableDeclarationInitializer1 = invocationCoveringTheEntireStatement1.getCoverage().equals(StatementCoverageType.VARIABLE_DECLARATION_INITIALIZER_CALL);
boolean variableDeclarationInitializer2 = invocationCoveringTheEntireStatement2.getCoverage().equals(StatementCoverageType.VARIABLE_DECLARATION_INITIALIZER_CALL);
boolean logStatement1 = invocationCoveringTheEntireStatement1.isLog();
boolean logStatement2 = invocationCoveringTheEntireStatement2.isLog();
boolean setMatch = (invocationCoveringTheEntireStatement1.getName().equals("set") && !invocationCoveringTheEntireStatement2.getName().equals("set")) ||
(!invocationCoveringTheEntireStatement1.getName().equals("set") && invocationCoveringTheEntireStatement2.getName().equals("set"));
boolean getMatch = (invocationCoveringTheEntireStatement1.getName().equals("get") && !invocationCoveringTheEntireStatement2.getName().equals("get")) ||
(!invocationCoveringTheEntireStatement1.getName().equals("get") && invocationCoveringTheEntireStatement2.getName().equals("get"));
boolean addMatch = (replacementInfo.containsReplacement(ReplacementType.VARIABLE_REPLACED_WITH_METHOD_INVOCATION) || replacementInfo.containsReplacement(ReplacementType.METHOD_INVOCATION)) &&
((invocationCoveringTheEntireStatement1.getName().equals("add") && !invocationCoveringTheEntireStatement2.getName().equals("add")) ||
(!invocationCoveringTheEntireStatement1.getName().equals("add") && invocationCoveringTheEntireStatement2.getName().equals("add")));
boolean callToAddedOperation = false;
boolean callToDeletedOperation = false;
if(classDiff != null) {
callToAddedOperation = classDiff.matchesOperation(invocationCoveringTheEntireStatement2, classDiff.getAddedOperations(), container2) != null;
callToDeletedOperation = classDiff.matchesOperation(invocationCoveringTheEntireStatement1, classDiff.getRemovedOperations(), container1) != null;
}
if(variableDeclarationInitializer1 == variableDeclarationInitializer2 && logStatement1 == logStatement2 && !setMatch && !getMatch && !addMatch && callToAddedOperation == callToDeletedOperation) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_NAME_AND_EXPRESSION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
//method invocation has been renamed (one name contains the other), both expressions are null, and one contains all the arguments of the other
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
invocationCoveringTheEntireStatement1.renamedWithNoExpressionAndArgumentIntersection(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap)) {
boolean callToAddedOperation = false;
boolean callToDeletedOperation = false;
if(classDiff != null && !invocationCoveringTheEntireStatement1.identicalName(invocationCoveringTheEntireStatement2)) {
UMLOperation matchedAddedOperation = classDiff.matchesOperation(invocationCoveringTheEntireStatement2, classDiff.getAddedOperations(), container2);
if(matchedAddedOperation != null) {
callToAddedOperation = true;
for(UMLOperation removedOperation : classDiff.getRemovedOperations()) {
if(removedOperation.getName().equals(matchedAddedOperation.getName())) {
callToAddedOperation = false;
break;
}
}
}
UMLOperation matchedRemovedOperation = classDiff.matchesOperation(invocationCoveringTheEntireStatement1, classDiff.getRemovedOperations(), container1);
if(matchedRemovedOperation != null) {
callToDeletedOperation = true;
for(UMLOperation addedOperation : classDiff.getAddedOperations()) {
if(addedOperation.getName().equals(matchedRemovedOperation.getName())) {
callToDeletedOperation = false;
break;
}
}
}
}
if(callToAddedOperation == callToDeletedOperation) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_NAME_AND_ARGUMENT);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
//method invocation has been renamed and arguments changed, but the expressions are identical
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
invocationCoveringTheEntireStatement1.renamedWithIdenticalExpressionAndDifferentArguments(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap, UMLClassBaseDiff.MAX_OPERATION_NAME_DISTANCE, lambdaMappers)) {
ReplacementType type = invocationCoveringTheEntireStatement1.getName().equals(invocationCoveringTheEntireStatement2.getName()) ? ReplacementType.METHOD_INVOCATION_ARGUMENT : ReplacementType.METHOD_INVOCATION_NAME_AND_ARGUMENT;
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, type);
replacementInfo.addReplacement(replacement);
if(invocationCoveringTheEntireStatement2.arguments().size() > 0) {
for(String argument2 : invocationCoveringTheEntireStatement2.arguments()) {
LeafExpression matchingVariable = null;
for(LeafExpression variable : statement2.getVariables()) {
if(argument2.startsWith(variable.getString())) {
matchingVariable = variable;
break;
}
}
if(matchingVariable != null) {
for(AbstractCodeFragment codeFragment : replacementInfo.getStatements2()) {
if(codeFragment.getString().startsWith(matchingVariable.getString() + "." + "add")) {
for(String argument1 : invocationCoveringTheEntireStatement1.arguments()) {
List leafExpressions2 = codeFragment.findExpression(argument1);
if(leafExpressions2.size() == 1) {
List leafExpressions1 = statement1.findExpression(argument1);
if(leafExpressions1.size() == 1) {
LeafMapping leafMapping = operationBodyMapper.createLeafMapping(leafExpressions1.get(0), leafExpressions2.get(0), parameterToArgumentMap, equalNumberOfAssertions);
operationBodyMapper.addMapping(leafMapping);
}
}
}
}
}
}
}
}
return replacementInfo.getReplacements();
}
if(!methodInvocations1.isEmpty() && invocationCoveringTheEntireStatement2 != null) {
boolean variableDeclarationMatchedWithNonVariableDeclaration = false;
if(invocationCoveringTheEntireStatement2.getCoverage().equals(StatementCoverageType.VARIABLE_DECLARATION_INITIALIZER_CALL)) {
if(invocationCoveringTheEntireStatement1 != null) {
if(!invocationCoveringTheEntireStatement1.getCoverage().equals(StatementCoverageType.VARIABLE_DECLARATION_INITIALIZER_CALL)) {
variableDeclarationMatchedWithNonVariableDeclaration = true;
}
else if(!variableDeclarations1.get(0).getVariableName().equals(variableDeclarations2.get(0).getVariableName()) &&
!variableDeclarations1.get(0).equalType(variableDeclarations2.get(0))) {
variableDeclarationMatchedWithNonVariableDeclaration = true;
}
}
else if(creationCoveringTheEntireStatement1 != null) {
if(!creationCoveringTheEntireStatement1.getCoverage().equals(StatementCoverageType.VARIABLE_DECLARATION_INITIALIZER_CALL)) {
variableDeclarationMatchedWithNonVariableDeclaration = true;
}
else if(!variableDeclarations1.get(0).getVariableName().equals(variableDeclarations2.get(0).getVariableName()) &&
!variableDeclarations1.get(0).equalType(variableDeclarations2.get(0))) {
variableDeclarationMatchedWithNonVariableDeclaration = true;
}
}
}
for(String methodInvocation1 : methodInvocations1) {
for(AbstractCall operationInvocation1 : methodInvocationMap1.get(methodInvocation1)) {
if(operationInvocation1.renamedWithIdenticalExpressionAndDifferentArguments(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap, UMLClassBaseDiff.MAX_OPERATION_NAME_DISTANCE, lambdaMappers) &&
!isExpressionOfAnotherMethodInvocation(operationInvocation1, methodInvocationMap1) &&
!variableDeclarationMatchedWithNonVariableDeclaration) {
ReplacementType type = operationInvocation1.getName().equals(invocationCoveringTheEntireStatement2.getName()) ? ReplacementType.METHOD_INVOCATION_ARGUMENT : ReplacementType.METHOD_INVOCATION_NAME_AND_ARGUMENT;
Replacement replacement = new MethodInvocationReplacement(operationInvocation1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), operationInvocation1, invocationCoveringTheEntireStatement2, type);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
}
//method invocation has only changes in the arguments (different number of arguments)
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null) {
if(invocationCoveringTheEntireStatement1.identicalWithMergedArguments(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap)) {
return replacementInfo.getReplacements();
}
else if(invocationCoveringTheEntireStatement1.identicalWithDifferentNumberOfArguments(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap)) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_ARGUMENT);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
else if(invocationCoveringTheEntireStatement1.inlinedStatementBecomesAdditionalArgument(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), replacementInfo.getStatements1())) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_ARGUMENT);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
if(!methodInvocations1.isEmpty() && invocationCoveringTheEntireStatement2 != null) {
for(String methodInvocation1 : methodInvocations1) {
for(AbstractCall operationInvocation1 : methodInvocationMap1.get(methodInvocation1)) {
if(operationInvocation1.identicalWithMergedArguments(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap)) {
return replacementInfo.getReplacements();
}
else if(operationInvocation1.identicalWithDifferentNumberOfArguments(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap)) {
Replacement replacement = new MethodInvocationReplacement(operationInvocation1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), operationInvocation1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_ARGUMENT);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
else if(operationInvocation1.inlinedStatementBecomesAdditionalArgument(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), replacementInfo.getStatements1())) {
Replacement replacement = new MethodInvocationReplacement(operationInvocation1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), operationInvocation1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_ARGUMENT);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
}
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
invocationCoveringTheEntireStatement1.getName().equals("add") && invocationCoveringTheEntireStatement2.getName().equals("setWidget") &&
invocationCoveringTheEntireStatement1.getExpression() != null && invocationCoveringTheEntireStatement2.getExpression() != null &&
invocationCoveringTheEntireStatement1.argumentIntersection(invocationCoveringTheEntireStatement2).size() > 0) {
if(invocationCoveringTheEntireStatement1.identicalExpression(invocationCoveringTheEntireStatement2)) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_NAME);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
for(Replacement r : replacementInfo.getReplacements()) {
if(invocationCoveringTheEntireStatement1.getExpression().equals(r.getBefore()) && invocationCoveringTheEntireStatement2.getExpression().equals(r.getAfter())) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_NAME_AND_EXPRESSION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null && modelDiff != null &&
invocationCoveringTheEntireStatement1.getExpression() != null && invocationCoveringTheEntireStatement2.getExpression() != null &&
invocationCoveringTheEntireStatement1.getExpression().toLowerCase().contains("log") && invocationCoveringTheEntireStatement2.getExpression().toLowerCase().contains("log")) {
//check for added inner class
UMLClass addedInnerClass = null;
for(UMLClass c : modelDiff.getAddedClasses()) {
if(c.getName().startsWith(container1.getClassName() + ".") && c.getName().startsWith(container2.getClassName() + ".")) {
addedInnerClass = c;
break;
}
}
if(addedInnerClass != null) {
for(UMLOperation operation : addedInnerClass.getOperations()) {
if(invocationCoveringTheEntireStatement2.matchesOperation(operation, container2, classDiff, modelDiff)) {
String[] tokens = LeafType.CAMEL_CASE_SPLIT_PATTERN.split(invocationCoveringTheEntireStatement2.getName());
boolean match = false;
for(String argument1 : invocationCoveringTheEntireStatement1.arguments()) {
String arg = argument1.toLowerCase();
int matchingTokens = 0;
for(String token : tokens) {
if(arg.contains(token.toLowerCase())) {
matchingTokens++;
}
}
int matchingArguments = 0;
for(String arg2 : invocationCoveringTheEntireStatement2.arguments()) {
if(argument1.contains(arg2) || invocationCoveringTheEntireStatement1.arguments().contains(arg2)) {
matchingArguments++;
}
else if(arg2.contains(".")) {
String prefix = arg2.substring(0, arg2.indexOf("."));
if(argument1.contains(prefix) || invocationCoveringTheEntireStatement1.arguments().contains(prefix)) {
matchingArguments++;
}
}
}
if(tokens.length == matchingTokens && matchingArguments == invocationCoveringTheEntireStatement2.arguments().size()) {
match = true;
break;
}
}
if(match) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
}
else {
String[] tokens = LeafType.CAMEL_CASE_SPLIT_PATTERN.split(invocationCoveringTheEntireStatement2.getName());
boolean match = false;
for(String argument1 : invocationCoveringTheEntireStatement1.arguments()) {
String arg = argument1.toLowerCase();
int matchingTokens = 0;
for(String token : tokens) {
if(arg.contains(token.toLowerCase())) {
matchingTokens++;
}
}
int matchingArguments = 0;
for(String arg2 : invocationCoveringTheEntireStatement2.arguments()) {
if(argument1.contains(arg2) || invocationCoveringTheEntireStatement1.arguments().contains(arg2)) {
matchingArguments++;
}
else if(arg2.contains(".")) {
String prefix = arg2.substring(0, arg2.indexOf("."));
if(argument1.contains(prefix) || invocationCoveringTheEntireStatement1.arguments().contains(prefix)) {
matchingArguments++;
}
}
}
if(tokens.length == matchingTokens && matchingArguments == invocationCoveringTheEntireStatement2.arguments().size()) {
match = true;
break;
}
}
if(match) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
//check if the argument of the method call in the first statement is returned in the second statement
Replacement r;
if(invocationCoveringTheEntireStatement1 != null && (r = invocationCoveringTheEntireStatement1.makeReplacementForReturnedArgument(replacementInfo.getArgumentizedString2())) != null) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
else if(invocationCoveringTheEntireStatement1 != null && (r = invocationCoveringTheEntireStatement1.makeReplacementForReturnedArgument(statement2.getString())) != null) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
for(String methodInvocation1 : methodInvocations1) {
for(AbstractCall operationInvocation1 : methodInvocationMap1.get(methodInvocation1)) {
if(statement1.getString().endsWith(methodInvocation1 + JAVA.STATEMENT_TERMINATION) && (r = operationInvocation1.makeReplacementForReturnedArgument(replacementInfo.getArgumentizedString2())) != null) {
if(operationInvocation1.makeReplacementForReturnedArgument(statement2.getString()) != null) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
}
}
}
//check if the argument of the method call in the second statement is returned in the first statement
if(invocationCoveringTheEntireStatement2 != null && (r = invocationCoveringTheEntireStatement2.makeReplacementForWrappedCall(replacementInfo.getArgumentizedString1())) != null) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
if(invocationCoveringTheEntireStatement2 != null && (r = invocationCoveringTheEntireStatement2.makeReplacementForWrappedLambda(replacementInfo.getArgumentizedString1())) != null) {
replacementInfo.addReplacement(r);
return replacementInfo.getReplacements();
}
for(String methodInvocation2 : methodInvocations2) {
for(AbstractCall operationInvocation2 : methodInvocationMap2.get(methodInvocation2)) {
if(statement2.getString().endsWith(methodInvocation2 + JAVA.STATEMENT_TERMINATION) && (r = operationInvocation2.makeReplacementForWrappedCall(replacementInfo.getArgumentizedString1())) != null) {
if(operationInvocation2.makeReplacementForWrappedCall(statement1.getString()) != null) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
}
}
}
//check if the argument of the method call in the second statement is the right hand side of an assignment in the first statement
if(invocationCoveringTheEntireStatement2 != null &&
(r = invocationCoveringTheEntireStatement2.makeReplacementForAssignedArgument(replacementInfo.getArgumentizedString1())) != null &&
(methodInvocationMap1.containsKey(r.getBefore()) || methodInvocationMap1.containsKey(r.getAfter()))) {
replacementInfo.addReplacement(r);
return replacementInfo.getReplacements();
}
//check if the method call in the second statement is the expression (or sub-expression) of the method invocation in the first statement
if(invocationCoveringTheEntireStatement2 != null) {
for(String key1 : methodInvocationMap1.keySet()) {
for(AbstractCall invocation1 : methodInvocationMap1.get(key1)) {
if(statement1.getString().endsWith(key1 + JAVA.STATEMENT_TERMINATION)) {
if(methodInvocationMap2.keySet().contains(invocation1.getExpression())) {
Replacement replacement = new MethodInvocationReplacement(invocation1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocation1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
if(variableDeclarationsWithEverythingReplaced(variableDeclarations1, variableDeclarations2, replacementInfo) &&
invocationCoveringTheEntireStatement2.arguments().contains(invocation1.getExpression()) &&
!statement1.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT) &&
!statement2.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT)) {
return null;
}
return replacementInfo.getReplacements();
}
if(invocation1 instanceof OperationInvocation) {
Set additionallyMatchedStatements2 = new LinkedHashSet();
for(String subExpression1 : ((OperationInvocation)invocation1).getSubExpressions()) {
if(methodInvocationMap2.keySet().contains(subExpression1)) {
AbstractCall subOperationInvocation1 = null;
for(String key : methodInvocationMap1.keySet()) {
if(key.endsWith(subExpression1)) {
subOperationInvocation1 = methodInvocationMap1.get(key).get(0);
break;
}
}
if(additionallyMatchedStatements2.size() > 0) {
CompositeReplacement composite = new CompositeReplacement(subExpression1,
invocationCoveringTheEntireStatement2.actualString(), new LinkedHashSet<>(), additionallyMatchedStatements2);
replacementInfo.addReplacement(composite);
}
Replacement replacement = new MethodInvocationReplacement(subExpression1,
invocationCoveringTheEntireStatement2.actualString(), subOperationInvocation1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
for(AbstractCodeFragment codeFragment : replacementInfo.getStatements2()) {
AbstractCall invocationCoveringEntireCodeFragment = codeFragment.invocationCoveringEntireFragment();
if(invocationCoveringEntireCodeFragment != null && subExpression1.equals(invocationCoveringEntireCodeFragment.actualString())) {
additionallyMatchedStatements2.add(codeFragment);
}
}
}
}
}
}
}
}
//check if the method call in the first statement is the expression (or sub-expression) of the method invocation in the second statement
if(invocationCoveringTheEntireStatement1 != null) {
for(String key2 : methodInvocationMap2.keySet()) {
for(AbstractCall invocation2 : methodInvocationMap2.get(key2)) {
if(statement2.getString().endsWith(key2 + JAVA.STATEMENT_TERMINATION)) {
if(methodInvocationMap1.keySet().contains(invocation2.getExpression())) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocation2.actualString(), invocationCoveringTheEntireStatement1, invocation2, ReplacementType.METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
if(variableDeclarationsWithEverythingReplaced(variableDeclarations1, variableDeclarations2, replacementInfo) &&
invocationCoveringTheEntireStatement1.arguments().contains(invocation2.getExpression()) &&
!statement1.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT) &&
!statement2.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT)) {
return null;
}
return replacementInfo.getReplacements();
}
if(invocation2 instanceof OperationInvocation) {
Set additionallyMatchedStatements1 = new LinkedHashSet();
for(String subExpression2 : ((OperationInvocation)invocation2).getSubExpressions()) {
if(methodInvocationMap1.keySet().contains(subExpression2)) {
AbstractCall subOperationInvocation2 = null;
for(String key : methodInvocationMap2.keySet()) {
if(key.endsWith(subExpression2)) {
subOperationInvocation2 = methodInvocationMap2.get(key).get(0);
break;
}
}
if(additionallyMatchedStatements1.size() > 0) {
CompositeReplacement composite = new CompositeReplacement(invocationCoveringTheEntireStatement1.actualString(),
subExpression2, additionallyMatchedStatements1, new LinkedHashSet<>());
replacementInfo.addReplacement(composite);
}
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
subExpression2, invocationCoveringTheEntireStatement1, subOperationInvocation2, ReplacementType.METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
for(AbstractCodeFragment codeFragment : replacementInfo.getStatements1()) {
AbstractCall invocationCoveringEntireCodeFragment = codeFragment.invocationCoveringEntireFragment();
if(invocationCoveringEntireCodeFragment != null && subExpression2.equals(invocationCoveringEntireCodeFragment.actualString())) {
additionallyMatchedStatements1.add(codeFragment);
}
}
}
}
}
}
}
}
//check if the class instance creation in the first statement is the expression of the method invocation in the second statement
if(creationCoveringTheEntireStatement1 != null) {
for(String key2 : methodInvocationMap2.keySet()) {
for(AbstractCall invocation2 : methodInvocationMap2.get(key2)) {
if(statement2.getString().endsWith(key2 + JAVA.STATEMENT_TERMINATION) && invocation2.getExpression() != null &&
invocation2.getExpression().startsWith(creationCoveringTheEntireStatement1.actualString())) {
Replacement replacement = new ClassInstanceCreationWithMethodInvocationReplacement(creationCoveringTheEntireStatement1.getName(),
invocation2.getName(), creationCoveringTheEntireStatement1, invocation2, ReplacementType.CLASS_INSTANCE_CREATION_REPLACED_WITH_METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
}
//check if the argument of the class instance creation in the second statement is the class instance creation of the first statement
if(creationCoveringTheEntireStatement2 != null) {
for(String key1 : creationMap1.keySet()) {
for(AbstractCall creation1 : creationMap1.get(key1)) {
if(statement1.getString().endsWith(key1 + JAVA.STATEMENT_TERMINATION) &&
creationCoveringTheEntireStatement2.arguments().contains(creation1.actualString())) {
if(variableDeclarations1.size() > 0) {
VariableDeclaration declaration1 = variableDeclarations1.get(0);
for(AbstractCodeFragment fragment1 : replacementInfo.getStatements1()) {
for(AbstractCall fragmentCreation1 : fragment1.getCreations()) {
if(fragmentCreation1.arguments().contains(declaration1.getVariableName()) &&
creationCoveringTheEntireStatement2.identicalName(fragmentCreation1)) {
Set additionallyMatchedStatements1 = new LinkedHashSet();
additionallyMatchedStatements1.add(fragment1);
Replacement replacement = new CompositeReplacement(statement1.getString(), statement2.getString(), additionallyMatchedStatements1, new LinkedHashSet());
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
}
Replacement replacement = new ObjectCreationReplacement(creation1.actualString(),
creationCoveringTheEntireStatement2.actualString(), (ObjectCreation)creation1, creationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION_ARGUMENT);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
}
//builder call chain in the first statement is replaced with class instance creation in the second statement
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement1.getName().equals("build")) {
if(creationCoveringTheEntireStatement2 != null) {
int commonArguments = 0;
for(String key1 : methodInvocationMap1.keySet()) {
if(invocationCoveringTheEntireStatement1.actualString().startsWith(key1)) {
for(AbstractCall invocation1 : methodInvocationMap1.get(key1)) {
Set argumentIntersection = invocation1.argumentIntersection(creationCoveringTheEntireStatement2);
commonArguments += argumentIntersection.size();
}
}
}
if(commonArguments > 0) {
Replacement replacement = new MethodInvocationWithClassInstanceCreationReplacement(invocationCoveringTheEntireStatement1.getName(),
creationCoveringTheEntireStatement2.getName(), invocationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.BUILDER_REPLACED_WITH_CLASS_INSTANCE_CREATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
if(invocationCoveringTheEntireStatement2 != null) {
int commonArguments = 0;
Set additionallyMatchedStatements2 = new LinkedHashSet();
for(String key1 : methodInvocationMap1.keySet()) {
if(invocationCoveringTheEntireStatement1.actualString().startsWith(key1)) {
for(AbstractCall invocation1 : methodInvocationMap1.get(key1)) {
if(invocation1.equalArguments(invocationCoveringTheEntireStatement2)) {
commonArguments += invocation1.arguments().size();
}
else {
Set argumentIntersection = invocation1.argumentIntersection(invocationCoveringTheEntireStatement2);
int threshold = Math.max(invocation1.arguments().size(), invocationCoveringTheEntireStatement2.arguments().size())/2;
if(argumentIntersection.size() > threshold) {
commonArguments += argumentIntersection.size();
}
}
for(AbstractCodeFragment codeFragment : replacementInfo.getStatements2()) {
AbstractCall invocation = codeFragment.invocationCoveringEntireFragment();
if(invocation != null) {
if(invocation.identical(invocation1, replacementInfo.getReplacements(), parameterToArgumentMap, lambdaMappers)) {
additionallyMatchedStatements2.add(codeFragment);
}
if((invocation.getExpression() != null && invocation.getExpression().equals(invocation1.actualString())) ||
invocation.callChainIntersection(invocation1).size() > 0) {
additionallyMatchedStatements2.add(codeFragment);
}
}
}
}
}
}
if(commonArguments > 0) {
if(additionallyMatchedStatements2.size() > 0) {
Replacement composite = new CompositeReplacement(statement1.getString(), statement2.getString(), new LinkedHashSet(), additionallyMatchedStatements2);
replacementInfo.addReplacement(composite);
}
else {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(), invocationCoveringTheEntireStatement2.actualString(),
invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
}
return replacementInfo.getReplacements();
}
}
}
//class instance creation in the first statement is replaced with builder call chain in the second statement
if(invocationCoveringTheEntireStatement2 != null && invocationCoveringTheEntireStatement2.getName().equals("build")) {
if(creationCoveringTheEntireStatement1 != null) {
int commonArguments = 0;
for(String key2 : methodInvocationMap2.keySet()) {
if(invocationCoveringTheEntireStatement2.actualString().startsWith(key2)) {
for(AbstractCall invocation2 : methodInvocationMap2.get(key2)) {
Set argumentIntersection = invocation2.argumentIntersection(creationCoveringTheEntireStatement1);
commonArguments += argumentIntersection.size();
}
}
}
if(commonArguments > 0) {
Replacement replacement = new ClassInstanceCreationWithMethodInvocationReplacement(creationCoveringTheEntireStatement1.getName(),
invocationCoveringTheEntireStatement2.getName(), creationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.BUILDER_REPLACED_WITH_CLASS_INSTANCE_CREATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
if(invocationCoveringTheEntireStatement1 != null) {
int commonArguments = 0;
Set additionallyMatchedStatements1 = new LinkedHashSet();
for(String key2 : methodInvocationMap2.keySet()) {
if(invocationCoveringTheEntireStatement2.actualString().startsWith(key2)) {
for(AbstractCall invocation2 : methodInvocationMap2.get(key2)) {
if(invocation2.equalArguments(invocationCoveringTheEntireStatement1)) {
commonArguments += invocation2.arguments().size();
}
else {
Set argumentIntersection = invocation2.argumentIntersection(invocationCoveringTheEntireStatement1);
int threshold = Math.max(invocation2.arguments().size(), invocationCoveringTheEntireStatement1.arguments().size())/2;
if(argumentIntersection.size() > threshold) {
commonArguments += argumentIntersection.size();
}
}
for(AbstractCodeFragment codeFragment : replacementInfo.getStatements1()) {
AbstractCall invocation = codeFragment.invocationCoveringEntireFragment();
if(invocation != null) {
if(invocation.identical(invocation2, replacementInfo.getReplacements(), parameterToArgumentMap, lambdaMappers)) {
additionallyMatchedStatements1.add(codeFragment);
}
if((invocation.getExpression() != null && invocation.getExpression().equals(invocation2.actualString())) ||
invocation.callChainIntersection(invocation2).size() > 0) {
additionallyMatchedStatements1.add(codeFragment);
}
}
}
}
}
}
if(commonArguments > 0) {
if(additionallyMatchedStatements1.size() > 0) {
Replacement composite = new CompositeReplacement(statement1.getString(), statement2.getString(), additionallyMatchedStatements1, new LinkedHashSet());
replacementInfo.addReplacement(composite);
}
else {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(), invocationCoveringTheEntireStatement2.actualString(),
invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
}
return replacementInfo.getReplacements();
}
}
}
//object creation is identical
if(creationCoveringTheEntireStatement1 != null && creationCoveringTheEntireStatement2 != null &&
creationCoveringTheEntireStatement1.identical(creationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap, lambdaMappers)) {
boolean identicalArrayInitializer = true;
if(creationCoveringTheEntireStatement1.isArray() && creationCoveringTheEntireStatement2.isArray()) {
identicalArrayInitializer = creationCoveringTheEntireStatement1.identicalArrayInitializer(creationCoveringTheEntireStatement2);
}
if(identicalArrayInitializer) {
String anonymousClassDeclaration1 = creationCoveringTheEntireStatement1.getAnonymousClassDeclaration();
String anonymousClassDeclaration2 = creationCoveringTheEntireStatement2.getAnonymousClassDeclaration();
if(anonymousClassDeclaration1 != null && anonymousClassDeclaration2 != null && !anonymousClassDeclaration1.equals(anonymousClassDeclaration2)) {
Replacement replacement = new Replacement(anonymousClassDeclaration1, anonymousClassDeclaration2, ReplacementType.ANONYMOUS_CLASS_DECLARATION);
replacementInfo.addReplacement(replacement);
}
return replacementInfo.getReplacements();
}
}
//object creation has identical arguments, but different type
if(creationCoveringTheEntireStatement1 != null && creationCoveringTheEntireStatement2 != null &&
creationCoveringTheEntireStatement1.arguments().size() > 0 && creationCoveringTheEntireStatement1.equalArguments(creationCoveringTheEntireStatement2)) {
Replacement replacement = new ObjectCreationReplacement(creationCoveringTheEntireStatement1.getName(),
creationCoveringTheEntireStatement2.getName(), creationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
if(creationCoveringTheEntireStatement1 != null && creationCoveringTheEntireStatement2 != null &&
creationCoveringTheEntireStatement1.arguments().size() > 0 && creationCoveringTheEntireStatement1.getType().equalsWithSubType(creationCoveringTheEntireStatement2.getType()) &&
creationCoveringTheEntireStatement1.getType().getClassType().endsWith("Exception") &&
creationCoveringTheEntireStatement2.getType().getClassType().endsWith("Exception")) {
Set argumentIntersection = creationCoveringTheEntireStatement1.argumentIntersection(creationCoveringTheEntireStatement2);
if(argumentIntersection.size() > 0 && argumentIntersection.size() == Math.min(creationCoveringTheEntireStatement1.arguments().size(), creationCoveringTheEntireStatement2.arguments().size())) {
Replacement replacement = new ObjectCreationReplacement(creationCoveringTheEntireStatement1.actualString(),
creationCoveringTheEntireStatement2.actualString(), creationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
if(creationCoveringTheEntireStatement1.getType().equals(creationCoveringTheEntireStatement2.getType())) {
CompositeStatementObject parent1 = statement1.getParent();
CompositeStatementObject parent2 = statement2.getParent();
while(parent1 != null && parent1.getLocationInfo().getCodeElementType().equals(CodeElementType.BLOCK)) {
parent1 = parent1.getParent();
}
while(parent2 != null && parent2.getLocationInfo().getCodeElementType().equals(CodeElementType.BLOCK)) {
parent2 = parent2.getParent();
}
if(parent1 != null && parent2 != null && parent1.getString().equals(parent2.getString())) {
Replacement replacement = new ObjectCreationReplacement(creationCoveringTheEntireStatement1.actualString(),
creationCoveringTheEntireStatement2.actualString(), creationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
//object creation has only changes in the arguments
if(creationCoveringTheEntireStatement1 != null && creationCoveringTheEntireStatement2 != null) {
if(creationCoveringTheEntireStatement1.identicalWithMergedArguments(creationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap)) {
return replacementInfo.getReplacements();
}
else if(creationCoveringTheEntireStatement1.reorderedArguments(creationCoveringTheEntireStatement2)) {
Replacement replacement = new ObjectCreationReplacement(creationCoveringTheEntireStatement1.actualString(),
creationCoveringTheEntireStatement2.actualString(), creationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION_ARGUMENT);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
else if(creationCoveringTheEntireStatement1.identicalWithDifferentNumberOfArguments(creationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap)) {
Replacement replacement = new ObjectCreationReplacement(creationCoveringTheEntireStatement1.actualString(),
creationCoveringTheEntireStatement2.actualString(), creationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION_ARGUMENT);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
else if(creationCoveringTheEntireStatement1.inlinedStatementBecomesAdditionalArgument(creationCoveringTheEntireStatement2, replacementInfo.getReplacements(), replacementInfo.getStatements1())) {
Replacement replacement = new ObjectCreationReplacement(creationCoveringTheEntireStatement1.actualString(),
creationCoveringTheEntireStatement2.actualString(), creationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION_ARGUMENT);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
//check if the argument lists are identical after replacements
if(creationCoveringTheEntireStatement1 != null && creationCoveringTheEntireStatement2 != null &&
creationCoveringTheEntireStatement1.identicalName(creationCoveringTheEntireStatement2) &&
creationCoveringTheEntireStatement1.identicalExpression(creationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap) &&
!creationCoveringTheEntireStatement1.allArgumentsReplaced(creationCoveringTheEntireStatement2, replacementInfo.getReplacements())) {
if(creationCoveringTheEntireStatement1.isArray() && creationCoveringTheEntireStatement2.isArray() && s1.contains("[") && s2.contains("[") &&
s1.substring(s1.indexOf("[")+1, s1.lastIndexOf("]")).equals(s2.substring(s2.indexOf("[")+1, s2.lastIndexOf("]"))) &&
s1.substring(s1.indexOf("[")+1, s1.lastIndexOf("]")).length() > 0) {
return replacementInfo.getReplacements();
}
if(!creationCoveringTheEntireStatement1.isArray() && !creationCoveringTheEntireStatement2.isArray() && s1.contains("(") && s2.contains("(") &&
s1.substring(s1.indexOf("(")+1, s1.lastIndexOf(")")).equals(s2.substring(s2.indexOf("(")+1, s2.lastIndexOf(")"))) &&
s1.substring(s1.indexOf("(")+1, s1.lastIndexOf(")")).length() > 0) {
return replacementInfo.getReplacements();
}
}
//check if array creation is replaced with data structure creation
if(creationCoveringTheEntireStatement1 != null && creationCoveringTheEntireStatement2 != null &&
variableDeclarations1.size() == 1 && variableDeclarations2.size() == 1) {
VariableDeclaration v1 = variableDeclarations1.get(0);
VariableDeclaration v2 = variableDeclarations2.get(0);
String initializer1 = v1.getInitializer() != null ? v1.getInitializer().getString() : null;
String initializer2 = v2.getInitializer() != null ? v2.getInitializer().getString() : null;
UMLType v1Type = v1.getType();
UMLType v2Type = v2.getType();
if(v1Type != null && v2Type != null) {
if(v1Type.getArrayDimension() == 1 && v2Type.containsTypeArgument(v1Type.getClassType()) &&
creationCoveringTheEntireStatement1.isArray() && !creationCoveringTheEntireStatement2.isArray() &&
initializer1 != null && initializer2 != null &&
initializer1.substring(initializer1.indexOf("[")+1, initializer1.lastIndexOf("]")).equals(initializer2.substring(initializer2.indexOf("(")+1, initializer2.lastIndexOf(")")))) {
r = new ObjectCreationReplacement(initializer1, initializer2,
creationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.ARRAY_CREATION_REPLACED_WITH_DATA_STRUCTURE_CREATION);
replacementInfo.addReplacement(r);
return replacementInfo.getReplacements();
}
if(v2Type.getArrayDimension() == 1 && v1Type.containsTypeArgument(v2Type.getClassType()) &&
!creationCoveringTheEntireStatement1.isArray() && creationCoveringTheEntireStatement2.isArray() &&
initializer1 != null && initializer2 != null &&
initializer1.substring(initializer1.indexOf("(")+1, initializer1.lastIndexOf(")")).equals(initializer2.substring(initializer2.indexOf("[")+1, initializer2.lastIndexOf("]")))) {
r = new ObjectCreationReplacement(initializer1, initializer2,
creationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.ARRAY_CREATION_REPLACED_WITH_DATA_STRUCTURE_CREATION);
replacementInfo.addReplacement(r);
return replacementInfo.getReplacements();
}
}
}
if(!creations1.isEmpty() && creationCoveringTheEntireStatement2 != null) {
for(String creation1 : creations1) {
for(AbstractCall objectCreation1 : creationMap1.get(creation1)) {
if(objectCreation1.identicalWithMergedArguments(creationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap)) {
return replacementInfo.getReplacements();
}
else if(objectCreation1.reorderedArguments(creationCoveringTheEntireStatement2)) {
Replacement replacement = new ObjectCreationReplacement(objectCreation1.actualString(),
creationCoveringTheEntireStatement2.actualString(), (ObjectCreation)objectCreation1, creationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION_ARGUMENT);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
else if(objectCreation1.identicalWithDifferentNumberOfArguments(creationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap)) {
Replacement replacement = new ObjectCreationReplacement(objectCreation1.actualString(),
creationCoveringTheEntireStatement2.actualString(), (ObjectCreation)objectCreation1, creationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION_ARGUMENT);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
else if(objectCreation1.inlinedStatementBecomesAdditionalArgument(creationCoveringTheEntireStatement2, replacementInfo.getReplacements(), replacementInfo.getStatements1())) {
Replacement replacement = new ObjectCreationReplacement(objectCreation1.actualString(),
creationCoveringTheEntireStatement2.actualString(), (ObjectCreation)objectCreation1, creationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION_ARGUMENT);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
//check if the argument lists are identical after replacements
if(objectCreation1.identicalName(creationCoveringTheEntireStatement2) &&
objectCreation1.identicalExpression(creationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap)) {
if(((ObjectCreation)objectCreation1).isArray() && creationCoveringTheEntireStatement2.isArray() && s1.contains("[") && s2.contains("[") &&
s1.substring(s1.indexOf("[")+1, s1.lastIndexOf("]")).equals(s2.substring(s2.indexOf("[")+1, s2.lastIndexOf("]"))) &&
s1.substring(s1.indexOf("[")+1, s1.lastIndexOf("]")).length() > 0) {
return replacementInfo.getReplacements();
}
if(!((ObjectCreation)objectCreation1).isArray() && !creationCoveringTheEntireStatement2.isArray() && s1.contains("(") && s2.contains("(") &&
s1.substring(s1.indexOf("(")+1, s1.lastIndexOf(")")).equals(s2.substring(s2.indexOf("(")+1, s2.lastIndexOf(")"))) &&
s1.substring(s1.indexOf("(")+1, s1.lastIndexOf(")")).length() > 0) {
return replacementInfo.getReplacements();
}
}
}
}
}
if(creationCoveringTheEntireStatement1 != null && (r = creationCoveringTheEntireStatement1.makeReplacementForReturnedArgument(replacementInfo.getArgumentizedString2())) != null) {
replacementInfo.addReplacement(r);
return replacementInfo.getReplacements();
}
for(String creation1 : creations1) {
for(AbstractCall objectCreation1 : creationMap1.get(creation1)) {
if(statement1.getString().endsWith(creation1 + JAVA.STATEMENT_TERMINATION) && (r = objectCreation1.makeReplacementForReturnedArgument(replacementInfo.getArgumentizedString2())) != null) {
replacementInfo.addReplacement(r);
return replacementInfo.getReplacements();
}
}
}
if(variableDeclarationWithArrayInitializer1 != null && invocationCoveringTheEntireStatement2 != null && !(invocationCoveringTheEntireStatement2 instanceof MethodReference) && variableDeclarations2.isEmpty() &&
!containsMethodSignatureOfAnonymousClass(statement1.getString()) && !containsMethodSignatureOfAnonymousClass(statement2.getString())) {
String args1 = s1.substring(s1.indexOf(JAVA.OPEN_ARRAY_INITIALIZER)+1, s1.lastIndexOf(JAVA.CLOSE_ARRAY_INITIALIZER));
String args2 = s2.substring(s2.indexOf("(")+1, s2.lastIndexOf(")"));
if(args1.equals(args2)) {
r = new Replacement(args1, args2, ReplacementType.ARRAY_INITIALIZER_REPLACED_WITH_METHOD_INVOCATION_ARGUMENTS);
replacementInfo.addReplacement(r);
return replacementInfo.getReplacements();
}
}
if(variableDeclarationWithArrayInitializer2 != null && invocationCoveringTheEntireStatement1 != null && !(invocationCoveringTheEntireStatement1 instanceof MethodReference) && variableDeclarations1.isEmpty() &&
!containsMethodSignatureOfAnonymousClass(statement1.getString()) && !containsMethodSignatureOfAnonymousClass(statement2.getString())) {
String args1 = s1.substring(s1.indexOf("(")+1, s1.lastIndexOf(")"));
String args2 = s2.substring(s2.indexOf(JAVA.OPEN_ARRAY_INITIALIZER)+1, s2.lastIndexOf(JAVA.CLOSE_ARRAY_INITIALIZER));
if(args1.equals(args2)) {
r = new Replacement(args1, args2, ReplacementType.ARRAY_INITIALIZER_REPLACED_WITH_METHOD_INVOCATION_ARGUMENTS);
replacementInfo.addReplacement(r);
return replacementInfo.getReplacements();
}
}
List ternaryOperatorExpressions1 = statement1.getTernaryOperatorExpressions();
List ternaryOperatorExpressions2 = statement2.getTernaryOperatorExpressions();
if(ternaryOperatorExpressions1.isEmpty() && ternaryOperatorExpressions2.size() == 1) {
TernaryOperatorExpression ternary = ternaryOperatorExpressions2.get(0);
for(String creation : creationIntersection) {
if((r = ternary.makeReplacementWithTernaryOnTheRight(creation, parameterToArgumentMap)) != null) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
}
for(String methodInvocation : methodInvocationIntersection) {
if((r = ternary.makeReplacementWithTernaryOnTheRight(methodInvocation, parameterToArgumentMap)) != null) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
}
if(invocationCoveringTheEntireStatement1 != null && (r = ternary.makeReplacementWithTernaryOnTheRight(invocationCoveringTheEntireStatement1.actualString(), parameterToArgumentMap)) != null) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
if(creationCoveringTheEntireStatement1 != null && (r = ternary.makeReplacementWithTernaryOnTheRight(creationCoveringTheEntireStatement1.actualString(), parameterToArgumentMap)) != null) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
for(String creation2 : creations2) {
if((r = ternary.makeReplacementWithTernaryOnTheRight(creation2, parameterToArgumentMap)) != null) {
for(AbstractCall c2 : creationMap2.get(creation2)) {
for(String creation1 : creations1) {
for(AbstractCall c1 : creationMap1.get(creation1)) {
if(((ObjectCreation)c1).getType().compatibleTypes(((ObjectCreation)c2).getType()) && c1.equalArguments(c2)) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
}
}
}
}
}
}
if(ternaryOperatorExpressions1.size() == 1 && ternaryOperatorExpressions2.isEmpty()) {
TernaryOperatorExpression ternary = ternaryOperatorExpressions1.get(0);
for(String creation : creationIntersection) {
if((r = ternary.makeReplacementWithTernaryOnTheLeft(creation, parameterToArgumentMap)) != null) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
}
for(String methodInvocation : methodInvocationIntersection) {
if((r = ternary.makeReplacementWithTernaryOnTheLeft(methodInvocation, parameterToArgumentMap)) != null) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
}
if(invocationCoveringTheEntireStatement2 != null && (r = ternary.makeReplacementWithTernaryOnTheLeft(invocationCoveringTheEntireStatement2.actualString(), parameterToArgumentMap)) != null) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
if(creationCoveringTheEntireStatement2 != null && (r = ternary.makeReplacementWithTernaryOnTheLeft(creationCoveringTheEntireStatement2.actualString(), parameterToArgumentMap)) != null) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
for(String creation1 : creations1) {
if((r = ternary.makeReplacementWithTernaryOnTheLeft(creation1, parameterToArgumentMap)) != null) {
for(AbstractCall c1 : creationMap1.get(creation1)) {
for(String creation2 : creations2) {
for(AbstractCall c2 : creationMap2.get(creation2)) {
if(((ObjectCreation)c1).getType().compatibleTypes(((ObjectCreation)c2).getType()) && c1.equalArguments(c2)) {
replacementInfo.addReplacement(r);
addLeafMappings(statement1, statement2, r, replacementInfo, container1, container2);
return replacementInfo.getReplacements();
}
}
}
}
}
}
}
if(invocationCoveringTheEntireStatement2 != null && statement2.getString().equals(invocationCoveringTheEntireStatement2.actualString() + JAVA.STATEMENT_TERMINATION) &&
invocationCoveringTheEntireStatement2.arguments().size() == 1 && statement1.getString().endsWith(JAVA.ASSIGNMENT + invocationCoveringTheEntireStatement2.arguments().get(0) + JAVA.STATEMENT_TERMINATION) &&
invocationCoveringTheEntireStatement2.expressionIsNullOrThis() && invocationCoveringTheEntireStatement2.getName().startsWith("set")) {
String prefix1 = statement1.getString().substring(0, statement1.getString().lastIndexOf(JAVA.ASSIGNMENT));
if(variables1.contains(prefix1)) {
String before = prefix1 + JAVA.ASSIGNMENT + invocationCoveringTheEntireStatement2.arguments().get(0);
String after = invocationCoveringTheEntireStatement2.actualString();
r = new Replacement(before, after, ReplacementType.FIELD_ASSIGNMENT_REPLACED_WITH_SETTER_METHOD_INVOCATION);
replacementInfo.addReplacement(r);
return replacementInfo.getReplacements();
}
}
if(creationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null &&
(variableDeclarations1.size() == variableDeclarations2.size() || (variableDeclarations1.size() > 0 && statement2.getString().startsWith(JAVA.RETURN_SPACE)))) {
if(invocationCoveringTheEntireStatement2.getName().equals("of") && variableDeclarations1.size() > 0) {
Set additionallyMatchedStatements1 = new LinkedHashSet<>();
for(String argument2 : invocationCoveringTheEntireStatement2.arguments()) {
for(AbstractCodeFragment fragment1 : replacementInfo.getStatements1()) {
AbstractCall invocation1 = fragment1.invocationCoveringEntireFragment();
if(invocation1 != null && invocation1.getExpression() != null && invocation1.getExpression().equals(variableDeclarations1.get(0).getVariableName())) {
boolean argumentMatched = false;
for(String argument1 : invocation1.arguments()) {
if(argument1.equals(argument2)) {
List leafExpressions1 = fragment1.findExpression(argument1);
List leafExpressions2 = statement2.findExpression(argument2);
if(leafExpressions1.size() == 1 && leafExpressions2.size() == 1) {
LeafMapping mapping = operationBodyMapper.createLeafMapping(leafExpressions1.get(0), leafExpressions2.get(0), parameterToArgumentMap, equalNumberOfAssertions);
operationBodyMapper.addMapping(mapping);
additionallyMatchedStatements1.add(fragment1);
}
argumentMatched = true;
break;
}
}
if(argumentMatched) {
break;
}
}
}
}
if(additionallyMatchedStatements1.size() > 0) {
return replacementInfo.getReplacements();
}
}
if(creationCoveringTheEntireStatement1.equalArguments(invocationCoveringTheEntireStatement2) && creationCoveringTheEntireStatement1.arguments().size() > 0) {
Replacement replacement = new ClassInstanceCreationWithMethodInvocationReplacement(creationCoveringTheEntireStatement1.getName(),
invocationCoveringTheEntireStatement2.getName(), creationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION_REPLACED_WITH_METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
else if(invocationCoveringTheEntireStatement2.arguments().size() == 1 && invocationCoveringTheEntireStatement2.arguments().contains(creationCoveringTheEntireStatement1.actualString())) {
Replacement replacement = new ClassInstanceCreationWithMethodInvocationReplacement(creationCoveringTheEntireStatement1.getName(),
invocationCoveringTheEntireStatement2.getName(), creationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION_WRAPPED_IN_METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
else if(creationCoveringTheEntireStatement1 == null && invocationCoveringTheEntireStatement2 == null) {
for(String key1 : creationMap1.keySet()) {
for(AbstractCall creation1 : creationMap1.get(key1)) {
if(statement1.getString().endsWith(key1 + JAVA.STATEMENT_TERMINATION)) {
for(String key2 : methodInvocationMap2.keySet()) {
for(AbstractCall invocation2 : methodInvocationMap2.get(key2)) {
if(statement2.getString().endsWith(key2 + JAVA.STATEMENT_TERMINATION)) {
if(invocation2.getName().equals("of")) {
String assignedVariable = null;
if(assignmentCreationCoveringTheEntireStatement1 != null) {
assignedVariable = statement1.getString().substring(0, statement1.getString().indexOf(JAVA.ASSIGNMENT));
}
Set additionallyMatchedStatements1 = new LinkedHashSet<>();
for(String argument2 : invocation2.arguments()) {
for(AbstractCodeFragment fragment1 : replacementInfo.getStatements1()) {
AbstractCall invocation1 = fragment1.invocationCoveringEntireFragment();
if(invocation1 != null && invocation1.getExpression() != null && invocation1.getExpression().equals(assignedVariable)) {
boolean argumentMatched = false;
for(String argument1 : invocation1.arguments()) {
if(argument1.equals(argument2)) {
List leafExpressions1 = fragment1.findExpression(argument1);
List leafExpressions2 = statement2.findExpression(argument2);
if(leafExpressions1.size() == 1 && leafExpressions2.size() == 1) {
LeafMapping mapping = operationBodyMapper.createLeafMapping(leafExpressions1.get(0), leafExpressions2.get(0), parameterToArgumentMap, equalNumberOfAssertions);
operationBodyMapper.addMapping(mapping);
additionallyMatchedStatements1.add(fragment1);
}
argumentMatched = true;
break;
}
}
if(argumentMatched) {
break;
}
}
}
}
if(additionallyMatchedStatements1.size() > 0) {
return replacementInfo.getReplacements();
}
}
if(creation1.equalArguments(invocation2) && creation1.arguments().size() > 0) {
Replacement replacement = new ClassInstanceCreationWithMethodInvocationReplacement(creation1.getName(),
invocation2.getName(), (ObjectCreation)creation1, invocation2, ReplacementType.CLASS_INSTANCE_CREATION_REPLACED_WITH_METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
else if(invocation2.arguments().size() == 1 && invocation2.arguments().contains(creation1.actualString())) {
Replacement replacement = new ClassInstanceCreationWithMethodInvocationReplacement(creation1.getName(),
invocation2.getName(), (ObjectCreation)creation1, invocation2, ReplacementType.CLASS_INSTANCE_CREATION_WRAPPED_IN_METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
}
}
}
}
}
if(invocationCoveringTheEntireStatement1 != null && creationCoveringTheEntireStatement2 != null &&
variableDeclarations1.size() == variableDeclarations2.size()) {
if(invocationCoveringTheEntireStatement1.equalArguments(creationCoveringTheEntireStatement2) && invocationCoveringTheEntireStatement1.arguments().size() > 0) {
Replacement replacement = new MethodInvocationWithClassInstanceCreationReplacement(invocationCoveringTheEntireStatement1.getName(),
creationCoveringTheEntireStatement2.getName(), invocationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_REPLACED_WITH_CLASS_INSTANCE_CREATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
else if(creationCoveringTheEntireStatement2.arguments().size() == 1 && creationCoveringTheEntireStatement2.arguments().contains(invocationCoveringTheEntireStatement1.actualString())) {
Replacement replacement = new MethodInvocationWithClassInstanceCreationReplacement(invocationCoveringTheEntireStatement1.getName(),
creationCoveringTheEntireStatement2.getName(), invocationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_WRAPPED_IN_CLASS_INSTANCE_CREATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
else if(invocationCoveringTheEntireStatement1 == null && creationCoveringTheEntireStatement2 == null) {
for(String key1 : methodInvocationMap1.keySet()) {
for(AbstractCall invocation1 : methodInvocationMap1.get(key1)) {
if(statement1.getString().endsWith(key1 + JAVA.STATEMENT_TERMINATION)) {
for(String key2 : creationMap2.keySet()) {
for(AbstractCall creation2 : creationMap2.get(key2)) {
if(statement2.getString().endsWith(key2 + JAVA.STATEMENT_TERMINATION)) {
if(invocation1.equalArguments(creation2) && invocation1.arguments().size() > 0) {
Replacement replacement = new MethodInvocationWithClassInstanceCreationReplacement(invocation1.getName(),
creation2.getName(), invocation1, (ObjectCreation)creation2, ReplacementType.METHOD_INVOCATION_REPLACED_WITH_CLASS_INSTANCE_CREATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
else if(creation2.arguments().size() == 1 && creation2.arguments().contains(invocation1.actualString())) {
Replacement replacement = new MethodInvocationWithClassInstanceCreationReplacement(invocation1.getName(),
creation2.getName(), invocation1, (ObjectCreation)creation2, ReplacementType.METHOD_INVOCATION_WRAPPED_IN_CLASS_INSTANCE_CREATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
}
}
}
}
}
if(creationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null) {
if(creationCoveringTheEntireStatement1.arguments().size() > 1 && creationCoveringTheEntireStatement1.argumentIntersection(invocationCoveringTheEntireStatement2).size() > 0 &&
creationCoveringTheEntireStatement1.getCoverage().equals(invocationCoveringTheEntireStatement2.getCoverage()) &&
creationCoveringTheEntireStatement1.identicalOrReplacedArguments(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), lambdaMappers)) {
Replacement replacement = new ClassInstanceCreationWithMethodInvocationReplacement(creationCoveringTheEntireStatement1.getName(),
invocationCoveringTheEntireStatement2.getName(), creationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION_REPLACED_WITH_METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
if(invocationCoveringTheEntireStatement1 != null && creationCoveringTheEntireStatement2 != null) {
if(invocationCoveringTheEntireStatement1.arguments().size() > 1 && invocationCoveringTheEntireStatement1.argumentIntersection(creationCoveringTheEntireStatement2).size() > 0 &&
invocationCoveringTheEntireStatement1.getCoverage().equals(creationCoveringTheEntireStatement2.getCoverage()) &&
invocationCoveringTheEntireStatement1.identicalOrReplacedArguments(creationCoveringTheEntireStatement2, replacementInfo.getReplacements(), lambdaMappers)) {
Replacement replacement = new MethodInvocationWithClassInstanceCreationReplacement(invocationCoveringTheEntireStatement1.getName(),
creationCoveringTheEntireStatement2.getName(), invocationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_REPLACED_WITH_CLASS_INSTANCE_CREATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
if(invocationCoveringTheEntireStatement1 instanceof OperationInvocation && invocationCoveringTheEntireStatement2 instanceof MethodReference) {
if(invocationCoveringTheEntireStatement1.identicalName(invocationCoveringTheEntireStatement2)) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_REPLACED_WITH_METHOD_REFERENCE);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
else if(invocationCoveringTheEntireStatement1 instanceof MethodReference && invocationCoveringTheEntireStatement2 instanceof OperationInvocation) {
if(invocationCoveringTheEntireStatement1.identicalName(invocationCoveringTheEntireStatement2)) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_REPLACED_WITH_METHOD_REFERENCE);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
if(classDiff != null && statement1.assignmentInvocationCoveringEntireStatement() != null && statement2.assignmentInvocationCoveringEntireStatement() != null) {
String assignedVariable1 = statement1.getString().substring(0, statement1.getString().indexOf(JAVA.ASSIGNMENT));
String assignedVariable2 = statement2.getString().substring(0, statement2.getString().indexOf(JAVA.ASSIGNMENT));
if(assignedVariable1.equals(assignedVariable2)) {
for(UMLOperation removedOperation : classDiff.getRemovedOperations()) {
if(assignmentInvocationCoveringTheEntireStatement1.matchesOperation(removedOperation, container1, classDiff, modelDiff)) {
return replacementInfo.getReplacements();
}
}
}
}
//check if replacement is wrapped in creation within the first statement
if(replacementInfo.getReplacements().size() == 1 && creations1.size() > 0) {
for(String objectCreation1 : creationMap1.keySet()) {
for(AbstractCall creation1 : creationMap1.get(objectCreation1)) {
for(Replacement replacement : replacementInfo.getReplacements()) {
if(creation1.arguments().contains(replacement.getBefore())) {
String creationAfterReplacement = ReplacementUtil.performArgumentReplacement(creation1.actualString(), replacement.getBefore(), replacement.getAfter());
String temp = ReplacementUtil.performReplacement(replacementInfo.getArgumentizedString1(), replacementInfo.getArgumentizedString2(), creationAfterReplacement, replacement.getAfter());
int distanceRaw = StringDistance.editDistance(temp, replacementInfo.getArgumentizedString2(), replacementInfo.getRawDistance());
if(distanceRaw == 0) {
if(replacement instanceof MethodInvocationReplacement) {
MethodInvocationReplacement methodInvocationReplacement = (MethodInvocationReplacement)replacement;
AbstractCall invokedOperationAfter = methodInvocationReplacement.getInvokedOperationAfter();
r = new ClassInstanceCreationWithMethodInvocationReplacement(creation1.actualString(), invokedOperationAfter.actualString(),
(ObjectCreation)creation1, invokedOperationAfter, ReplacementType.CLASS_INSTANCE_CREATION_REPLACED_WITH_METHOD_INVOCATION);
replacementInfo.addReplacement(r);
return replacementInfo.getReplacements();
}
else if(replacement instanceof VariableReplacementWithMethodInvocation) {
VariableReplacementWithMethodInvocation methodInvocationReplacement = (VariableReplacementWithMethodInvocation)replacement;
if(methodInvocationReplacement.getDirection().equals(Direction.VARIABLE_TO_INVOCATION)) {
AbstractCall invokedOperationAfter = methodInvocationReplacement.getInvokedOperation();
r = new ClassInstanceCreationWithMethodInvocationReplacement(creation1.actualString(), invokedOperationAfter.actualString(),
(ObjectCreation)creation1, invokedOperationAfter, ReplacementType.CLASS_INSTANCE_CREATION_REPLACED_WITH_METHOD_INVOCATION);
replacementInfo.addReplacement(r);
return replacementInfo.getReplacements();
}
}
}
}
}
}
}
}
if(variableDeclarations1.size() > 0 && variableDeclarations2.size() > 0 && variableDeclarations1.toString().equals(variableDeclarations2.toString()) &&
invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null && parentMapper == null) {
int variableDeclarationsInOtherStatements1 = 0;
for(AbstractCodeFragment fragment1 : replacementInfo.getStatements1()) {
for(VariableDeclaration variableDeclaration : fragment1.getVariableDeclarations()) {
if(variableDeclarations1.get(0).getScope().overlaps(variableDeclaration.getScope())) {
variableDeclarationsInOtherStatements1++;
}
}
}
int variableDeclarationsInOtherStatements2 = 0;
for(AbstractCodeFragment fragment2 : replacementInfo.getStatements2()) {
for(VariableDeclaration variableDeclaration : fragment2.getVariableDeclarations()) {
if(variableDeclarations2.get(0).getScope().overlaps(variableDeclaration.getScope())) {
variableDeclarationsInOtherStatements2++;
}
}
}
if(variableDeclarationsInOtherStatements1 == 0 && variableDeclarationsInOtherStatements2 == 0) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(), invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null) {
boolean variableDeclarationInitializer1 = invocationCoveringTheEntireStatement1.getCoverage().equals(StatementCoverageType.VARIABLE_DECLARATION_INITIALIZER_CALL);
boolean variableDeclarationInitializer2 = invocationCoveringTheEntireStatement2.getCoverage().equals(StatementCoverageType.VARIABLE_DECLARATION_INITIALIZER_CALL);
if(variableDeclarationInitializer1 && variableDeclarationInitializer2) {
if(variableDeclarations1.toString().equals(variableDeclarations2.toString()) && variableDeclarations1.size() > 0) {
boolean callToAddedOperation = false;
boolean callToDeletedOperation = false;
boolean statementIsExtracted = false;
if(classDiff != null) {
UMLOperation addedOperation = classDiff.matchesOperation(invocationCoveringTheEntireStatement2, classDiff.getAddedOperations(), container2);
statementIsExtracted = checkIfStatementIsExtracted(statement1, statement2, addedOperation, operationBodyMapper);
callToAddedOperation = addedOperation != null;
callToDeletedOperation = classDiff.matchesOperation(invocationCoveringTheEntireStatement1, classDiff.getRemovedOperations(), container1) != null;
}
if(callToAddedOperation != callToDeletedOperation && !statementIsExtracted) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_NAME_AND_EXPRESSION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
else if(variableDeclarations1.get(0).getVariableName().equals(variableDeclarations2.get(0).getVariableName()) && replacementInfo.getReplacements(ReplacementType.TYPE).size() > 0) {
boolean callToAddedOperation = false;
boolean callToDeletedOperation = false;
if(classDiff != null) {
boolean superCall2 = invocationCoveringTheEntireStatement2.getExpression() != null && invocationCoveringTheEntireStatement2.getExpression().equals("super");
if(!superCall2) {
callToAddedOperation = classDiff.matchesOperation(invocationCoveringTheEntireStatement2, classDiff.getNextClass().getOperations(), container2) != null;
}
boolean superCall1 = invocationCoveringTheEntireStatement1.getExpression() != null && invocationCoveringTheEntireStatement1.getExpression().equals("super");
if(!superCall1) {
callToDeletedOperation = classDiff.matchesOperation(invocationCoveringTheEntireStatement1, classDiff.getOriginalClass().getOperations(), container1) != null;
}
}
if(callToAddedOperation != callToDeletedOperation) {
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_NAME_AND_EXPRESSION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
}
else if(creationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null) {
boolean variableDeclarationInitializer1 = creationCoveringTheEntireStatement1.getCoverage().equals(StatementCoverageType.VARIABLE_DECLARATION_INITIALIZER_CALL);
boolean variableDeclarationInitializer2 = invocationCoveringTheEntireStatement2.getCoverage().equals(StatementCoverageType.VARIABLE_DECLARATION_INITIALIZER_CALL);
if(variableDeclarationInitializer1 && variableDeclarationInitializer2) {
if(variableDeclarations1.toString().equals(variableDeclarations2.toString()) && variableDeclarations1.size() > 0) {
boolean callToAddedOperation = false;
boolean callToDeletedOperation = false;
if(classDiff != null) {
boolean superCall2 = invocationCoveringTheEntireStatement2.getExpression() != null && invocationCoveringTheEntireStatement2.getExpression().equals("super");
if(!superCall2) {
callToAddedOperation = classDiff.matchesOperation(invocationCoveringTheEntireStatement2, classDiff.getNextClass().getOperations(), container2) != null;
}
}
if(callToAddedOperation != callToDeletedOperation) {
Replacement replacement = new ClassInstanceCreationWithMethodInvocationReplacement(creationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), creationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION_REPLACED_WITH_METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
}
else if(invocationCoveringTheEntireStatement1 == null && invocationCoveringTheEntireStatement2 == null && methodInvocationMap2.size() > 0) {
if(variableDeclarations1.toString().equals(variableDeclarations2.toString()) && variableDeclarations1.size() > 0 &&
variableDeclarations1.get(0).getInitializer() != null && variableDeclarations2.get(0).getInitializer() != null) {
boolean callToAddedOperation = false;
boolean statementIsExtracted = false;
if(classDiff != null) {
for(String key : methodInvocationMap2.keySet()) {
AbstractCall call = methodInvocationMap2.get(key).get(0);
UMLOperation addedOperation = classDiff.matchesOperation(call, classDiff.getAddedOperations(), container2);
statementIsExtracted = checkIfStatementIsExtracted(statement1, statement2, addedOperation, operationBodyMapper);
callToAddedOperation = addedOperation != null;
if(callToAddedOperation) {
break;
}
}
}
if(callToAddedOperation && !statementIsExtracted) {
Replacement replacement = new InitializerReplacement(variableDeclarations1.get(0).getInitializer(), variableDeclarations2.get(0).getInitializer());
replacementInfo.addReplacement(replacement);
return replacementInfo.getReplacements();
}
}
}
boolean variableReturn1 = statement1.getVariables().size() > 0 && statement1.getString().equals(JAVA.RETURN_SPACE + statement1.getVariables().get(0).getString() + JAVA.STATEMENT_TERMINATION);
boolean variableReturnQualified1 = false;
if(variableReturn1 && statement1.getVariables().get(0).getString().contains(".")) {
variableReturnQualified1 = true;
}
boolean variableReturnAsLastStatement1 = variableReturn1 && statement1.isLastStatement();
boolean variableReturn2 = statement2.getVariables().size() > 0 && statement2.getString().equals(JAVA.RETURN_SPACE + statement2.getVariables().get(0).getString() + JAVA.STATEMENT_TERMINATION);
boolean variableReturnQualified2 = false;
if(variableReturn2 && statement2.getVariables().get(0).getString().contains(".")) {
variableReturnQualified2 = true;
}
boolean variableReturnAsLastStatement2 = variableReturn2 && statement2.isLastStatement();
boolean numberLiteralReturn1 = statement1.getNumberLiterals().size() > 0 && statement1.getString().equals(JAVA.RETURN_SPACE + statement1.getNumberLiterals().get(0).getString() + JAVA.STATEMENT_TERMINATION) && statement1.isLastStatementInParentBlock();
boolean numberLiteralReturn2 = statement2.getNumberLiterals().size() > 0 && statement2.getString().equals(JAVA.RETURN_SPACE + statement2.getNumberLiterals().get(0).getString() + JAVA.STATEMENT_TERMINATION) && statement2.isLastStatementInParentBlock();
boolean lastStatement = (statement1.isLastStatement() && statement2.isLastStatement()) ||
lastStatementInParentBlockWithSameParentType(statement1, statement2);
if(parentMapper == null && !variableReturnAsLastStatement1 && !variableReturnAsLastStatement2 && !numberLiteralReturn1 && !numberLiteralReturn2 && statement1.getString().startsWith(JAVA.RETURN_SPACE) && statement2.getString().startsWith(JAVA.RETURN_SPACE) && lastStatement &&
variableReturnQualified1 == variableReturnQualified2 && container1 instanceof UMLOperation && container2 instanceof UMLOperation && operationBodyMapper.getOperation1().equalSignature(operationBodyMapper.getOperation2()) && statement1.getLambdas().size() == statement2.getLambdas().size()) {
boolean callToAddedOperation = false;
boolean callToDeletedOperation = false;
boolean isMovedMethod = !container1.getClassName().equals(container2.getClassName());
if(classDiff != null) {
if(!container1.getClassName().equals(container2.getClassName()) && modelDiff != null) {
boolean pushDown = false;
UMLClassBaseDiff container2Diff = modelDiff.getUMLClassDiff(container2.getClassName());
if(container2Diff != null && container2Diff.getSuperclass() != null) {
UMLType superclass = container2Diff.getSuperclass();
if(container1.getClassName().endsWith("." + superclass.getClassType())) {
pushDown = true;
}
}
boolean pullUp = false;
UMLClassBaseDiff container1Diff = modelDiff.getUMLClassDiff(container1.getClassName());
if(container1Diff != null && container1Diff.getSuperclass() != null) {
UMLType superclass = container1Diff.getSuperclass();
if(container2.getClassName().endsWith("." + superclass.getClassType())) {
pullUp = true;
}
}
if(pullUp || pushDown) {
isMovedMethod = false;
}
}
if(invocationCoveringTheEntireStatement2 != null) {
boolean superCall2 = invocationCoveringTheEntireStatement2.getExpression() != null && invocationCoveringTheEntireStatement2.getExpression().equals("super");
if(!superCall2) {
UMLOperation addedOperation = classDiff.matchesOperation(invocationCoveringTheEntireStatement2, classDiff.getNextClass().getOperations(), container2);
callToAddedOperation = addedOperation != null && !addedOperation.equals(container2);
if(callToAddedOperation == false) {
if(invocationCoveringTheEntireStatement2.getExpression() != null) {
List methodInvocations = methodInvocationMap2.get(invocationCoveringTheEntireStatement2.getExpression());
if(methodInvocations != null) {
for(AbstractCall invocation : methodInvocations) {
if(classDiff.matchesOperation(invocation, classDiff.getNextClass().getOperations(), container2) != null) {
callToAddedOperation = true;
break;
}
}
}
}
}
}
}
if(invocationCoveringTheEntireStatement1 != null) {
boolean superCall1 = invocationCoveringTheEntireStatement1.getExpression() != null && invocationCoveringTheEntireStatement1.getExpression().equals("super");
if(!superCall1) {
UMLOperation removedOperation = classDiff.matchesOperation(invocationCoveringTheEntireStatement1, classDiff.getOriginalClass().getOperations(), container1);
callToDeletedOperation = removedOperation != null && !removedOperation.equals(container1);
if(callToDeletedOperation == false) {
if(invocationCoveringTheEntireStatement1.getExpression() != null) {
List methodInvocations = methodInvocationMap1.get(invocationCoveringTheEntireStatement1.getExpression());
if(methodInvocations != null) {
for(AbstractCall invocation : methodInvocations) {
if(classDiff.matchesOperation(invocation, classDiff.getOriginalClass().getOperations(), container1) != null) {
callToDeletedOperation = true;
break;
}
}
}
}
}
}
}
}
if(callToAddedOperation == callToDeletedOperation && !isMovedMethod) {
if(invocationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null) {
ReplacementType replacementType = !invocationCoveringTheEntireStatement1.identicalName(invocationCoveringTheEntireStatement2) ? ReplacementType.METHOD_INVOCATION_NAME : ReplacementType.METHOD_INVOCATION;
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, replacementType);
replacementInfo.addReplacement(replacement);
}
else if(invocationCoveringTheEntireStatement1 != null && creationCoveringTheEntireStatement2 != null) {
Replacement replacement = new MethodInvocationWithClassInstanceCreationReplacement(invocationCoveringTheEntireStatement1.actualString(),
creationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.METHOD_INVOCATION_REPLACED_WITH_CLASS_INSTANCE_CREATION);
replacementInfo.addReplacement(replacement);
}
else if(creationCoveringTheEntireStatement1 != null && invocationCoveringTheEntireStatement2 != null) {
Replacement replacement = new ClassInstanceCreationWithMethodInvocationReplacement(creationCoveringTheEntireStatement1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), creationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION_REPLACED_WITH_METHOD_INVOCATION);
replacementInfo.addReplacement(replacement);
}
else if(methodInvocationMap1.size() > 0 && invocationCoveringTheEntireStatement2 != null) {
AbstractCall invocation1 = null;
for(String key : methodInvocationMap1.keySet()) {
List calls = methodInvocationMap1.get(key);
for(AbstractCall call : calls) {
if(statement1.getString().endsWith(call.actualString() + JAVA.STATEMENT_TERMINATION)) {
invocation1 = call;
break;
}
}
if(invocation1 != null) {
break;
}
}
if(invocation1 != null) {
ReplacementType replacementType = !invocation1.identicalName(invocationCoveringTheEntireStatement2) ? ReplacementType.METHOD_INVOCATION_NAME : ReplacementType.METHOD_INVOCATION;
Replacement replacement = new MethodInvocationReplacement(invocation1.actualString(),
invocationCoveringTheEntireStatement2.actualString(), invocation1, invocationCoveringTheEntireStatement2, replacementType);
replacementInfo.addReplacement(replacement);
}
}
else if(methodInvocationMap2.size() > 0 && invocationCoveringTheEntireStatement1 != null) {
AbstractCall invocation2 = null;
for(String key : methodInvocationMap2.keySet()) {
List calls = methodInvocationMap2.get(key);
for(AbstractCall call : calls) {
if(statement2.getString().endsWith(call.actualString() + JAVA.STATEMENT_TERMINATION)) {
invocation2 = call;
break;
}
}
if(invocation2 != null) {
break;
}
}
if(invocation2 != null) {
ReplacementType replacementType = !invocationCoveringTheEntireStatement1.identicalName(invocation2) ? ReplacementType.METHOD_INVOCATION_NAME : ReplacementType.METHOD_INVOCATION;
Replacement replacement = new MethodInvocationReplacement(invocationCoveringTheEntireStatement1.actualString(),
invocation2.actualString(), invocationCoveringTheEntireStatement1, invocation2, replacementType);
replacementInfo.addReplacement(replacement);
}
}
else if(invocationCoveringTheEntireStatement1 != null && variableReturn2) {
VariableReplacementWithMethodInvocation replacement = new VariableReplacementWithMethodInvocation(invocationCoveringTheEntireStatement1.actualString(), statement2.getVariables().get(0).getString(), invocationCoveringTheEntireStatement1, Direction.INVOCATION_TO_VARIABLE);
replacementInfo.addReplacement(replacement);
}
else if(invocationCoveringTheEntireStatement2 != null && variableReturn1) {
VariableReplacementWithMethodInvocation replacement = new VariableReplacementWithMethodInvocation(statement1.getVariables().get(0).getString(), invocationCoveringTheEntireStatement2.actualString(), invocationCoveringTheEntireStatement2, Direction.VARIABLE_TO_INVOCATION);
replacementInfo.addReplacement(replacement);
}
else if(creationCoveringTheEntireStatement1 != null && variableReturn2) {
VariableReplacementWithMethodInvocation replacement = new VariableReplacementWithMethodInvocation(creationCoveringTheEntireStatement1.actualString(), statement2.getVariables().get(0).getString(), creationCoveringTheEntireStatement1, Direction.INVOCATION_TO_VARIABLE);
replacementInfo.addReplacement(replacement);
}
else if(creationCoveringTheEntireStatement2 != null && variableReturn1) {
VariableReplacementWithMethodInvocation replacement = new VariableReplacementWithMethodInvocation(statement1.getVariables().get(0).getString(), creationCoveringTheEntireStatement2.actualString(), creationCoveringTheEntireStatement2, Direction.VARIABLE_TO_INVOCATION);
replacementInfo.addReplacement(replacement);
}
if(lambdas1.size() > 0 && lambdas2.size() > 0) {
boolean lambdaWithBody1 = lambdas1.get(0).getBody() != null;
boolean lambdaWithBody2 = lambdas2.get(0).getBody() != null;
if(lambdaWithBody1 != lambdaWithBody2) {
Replacement replacement = new Replacement(lambdas1.get(0).toString(), lambdas2.get(0).toString(), ReplacementType.LAMBDA_WITH_BODY_REPLACED_LAMBDA_WITH_EXPRESSION);
replacementInfo.addReplacement(replacement);
}
}
return replacementInfo.getReplacements();
}
}
return null;
}
private static boolean wrapInMethodCall(String s1, String s2, Map> methodInvocationMap1, ReplacementInfo info) {
for(String key : methodInvocationMap1.keySet()) {
List calls = methodInvocationMap1.get(key);
AbstractCall call = calls.get(0);
if(call.arguments().size() == 1) {
String argument = new String(call.arguments().get(0));
for(Replacement replacement : info.getReplacements()) {
argument = ReplacementUtil.performReplacement(argument, replacement.getBefore(), replacement.getAfter());
}
if(s2.contains(argument)) {
StringBuilder callBuilder = new StringBuilder();
if(call.getExpression() != null) {
callBuilder.append(call.getExpression()).append(".");
}
callBuilder.append(call.getName());
callBuilder.append("(");
callBuilder.append(argument);
callBuilder.append(")");
String updatedS2 = s2.replace(argument, callBuilder.toString());
if(updatedS2.equals(s1)) {
return true;
}
}
}
}
return false;
}
private static boolean existsVariableDeclarationForV2InitializedWithV1(VariableDeclaration v1, VariableDeclaration v2, ReplacementInfo info) {
for(AbstractCodeFragment fragment2 : info.getStatements2()) {
if(fragment2.getVariableDeclarations().contains(v2)) {
AbstractExpression initializer = v2.getInitializer();
if(initializer != null) {
for(LeafExpression variable : initializer.getVariables()) {
if(variable.getString().equals(v1.getVariableName()) || variable.getString().equals(JAVA.THIS_DOT + v1.getVariableName())) {
return true;
}
}
}
}
if(fragment2.getString().equals(v2.getVariableName() + JAVA.ASSIGNMENT + v1.getVariableName() + JAVA.STATEMENT_TERMINATION)) {
return true;
}
VariableDeclaration v1DeclarationInFragment2 = fragment2.getVariableDeclaration(v1.getVariableName());
if(v1DeclarationInFragment2 != null) {
AbstractExpression initializer = v1DeclarationInFragment2.getInitializer();
if(initializer != null) {
for(LeafExpression variable : initializer.getVariables()) {
if(variable.getString().equals(v2.getVariableName())) {
return true;
}
}
}
}
if(fragment2.getString().equals(v1.getVariableName() + JAVA.ASSIGNMENT + v2.getVariableName() + JAVA.STATEMENT_TERMINATION)) {
return true;
}
}
return false;
}
private static boolean existsVariableDeclarationForV1InitializedWithV2(VariableDeclaration v1, VariableDeclaration v2, ReplacementInfo info) {
for(AbstractCodeFragment fragment1 : info.getStatements1()) {
if(fragment1.getVariableDeclarations().contains(v1)) {
AbstractExpression initializer = v1.getInitializer();
if(initializer != null) {
for(LeafExpression variable : initializer.getVariables()) {
if(variable.getString().equals(v2.getVariableName()) || variable.getString().equals(JAVA.THIS_DOT + v2.getVariableName())) {
return true;
}
}
}
}
if(fragment1.getString().equals(v1.getVariableName() + JAVA.ASSIGNMENT + v2.getVariableName() + JAVA.STATEMENT_TERMINATION)) {
return true;
}
VariableDeclaration v2DeclarationInFragment1 = fragment1.getVariableDeclaration(v2.getVariableName());
if(v2DeclarationInFragment1 != null) {
AbstractExpression initializer = v2DeclarationInFragment1.getInitializer();
if(initializer != null) {
for(LeafExpression variable : initializer.getVariables()) {
if(variable.getString().equals(v1.getVariableName())) {
return true;
}
}
}
}
if(fragment1.getString().equals(v2.getVariableName() + JAVA.ASSIGNMENT + v1.getVariableName() + JAVA.STATEMENT_TERMINATION)) {
return true;
}
}
return false;
}
private static int mappingsForStatementsInScope(AbstractCodeFragment statement1, AbstractCodeFragment statement2, VariableDeclaration v1, VariableDeclaration v2, Set mappings) {
boolean increment = v1 != null && v2 != null && statement1.getString().startsWith(v1.getVariableName() + "+=") && statement2.getString().startsWith(v2.getVariableName() + "+=");
boolean decrement = v1 != null && v2 != null && statement1.getString().startsWith(v1.getVariableName() + "-=") && statement2.getString().startsWith(v2.getVariableName() + "-=");
if(v1 != null && v2 != null && (increment || decrement) && !mappings.isEmpty()) {
int count = 0;
Set statementsInScope1 = v1.getScope().getStatementsInScopeUsingVariable();
Set statementsInScope2 = v2.getScope().getStatementsInScopeUsingVariable();
for(AbstractCodeMapping mapping : mappings) {
if(statementsInScope1.contains(mapping.getFragment1()) && statementsInScope2.contains(mapping.getFragment2())) {
count++;
}
if(mapping.getFragment1().getVariableDeclarations().contains(v1) && mapping.getFragment2().getVariableDeclarations().contains(v2)) {
count++;
}
}
return count;
}
return -1;
}
private static int inconsistentVariableMappingCount(AbstractCodeFragment statement1, AbstractCodeFragment statement2, VariableDeclaration v1, VariableDeclaration v2, Set mappings) {
int count = 0;
if(v1 != null && v2 != null) {
boolean variableDeclarationMismatch = false;
for(AbstractCodeMapping mapping : mappings) {
List variableDeclarations1 = mapping.getFragment1().getVariableDeclarations();
List variableDeclarations2 = mapping.getFragment2().getVariableDeclarations();
if(variableDeclarations1.contains(v1) &&
variableDeclarations2.size() > 0 &&
!variableDeclarations2.contains(v2)) {
variableDeclarationMismatch = true;
count++;
}
if(variableDeclarations2.contains(v2) &&
variableDeclarations1.size() > 0 &&
!variableDeclarations1.contains(v1)) {
variableDeclarationMismatch = true;
count++;
}
if(mapping.isExact()) {
boolean containsMapping = true;
if(statement1 instanceof CompositeStatementObject && statement2 instanceof CompositeStatementObject &&
statement1.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT)) {
CompositeStatementObject comp1 = (CompositeStatementObject)statement1;
CompositeStatementObject comp2 = (CompositeStatementObject)statement2;
containsMapping = comp1.contains(mapping.getFragment1()) && comp2.contains(mapping.getFragment2());
}
if(containsMapping) {
if(VariableReplacementAnalysis.bothFragmentsUseVariable(v1, mapping)) {
VariableDeclaration otherV1 = mapping.getFragment1().getVariableDeclaration(v1.getVariableName());
if(otherV1 != null) {
VariableScope otherV1Scope = otherV1.getScope();
VariableScope v1Scope = v1.getScope();
if(otherV1Scope.overlaps(v1Scope)) {
count++;
}
}
else {
count++;
}
}
if(VariableReplacementAnalysis.bothFragmentsUseVariable(v2, mapping)) {
VariableDeclaration otherV2 = mapping.getFragment2().getVariableDeclaration(v2.getVariableName());
if(otherV2 != null) {
VariableScope otherV2Scope = otherV2.getScope();
VariableScope v2Scope = v2.getScope();
if(otherV2Scope.overlaps(v2Scope)) {
count++;
}
}
else {
count++;
}
}
}
}
else if(variableDeclarationMismatch && !variableDeclarations1.contains(v1) && !variableDeclarations2.contains(v2)) {
for(Replacement r : mapping.getReplacements()) {
if(r.getBefore().equals(v1.getVariableName()) && !r.getAfter().equals(v2.getVariableName())) {
count++;
}
else if(!r.getBefore().equals(v1.getVariableName()) && r.getAfter().equals(v2.getVariableName())) {
count++;
}
}
}
}
}
return count;
}
private static void removeCommonElements(Set strings1, Set strings2) {
Set intersection = new LinkedHashSet(strings1);
intersection.retainAll(strings2);
strings1.removeAll(intersection);
strings2.removeAll(intersection);
}
private static void removeCommonTypes(Set strings1, Set strings2, List types1, List types2) {
if(types1.size() == types2.size()) {
Set removeFromIntersection = new LinkedHashSet();
for(int i=0; i intersection = new LinkedHashSet(strings1);
intersection.retainAll(strings2);
intersection.removeAll(removeFromIntersection);
strings1.removeAll(intersection);
strings2.removeAll(intersection);
}
else {
removeCommonElements(strings1, strings2);
}
}
private static Map> convertToMap(List calls) {
Map> methodInvocationMap = new LinkedHashMap<>();
for(AbstractCall invocation : calls) {
String methodInvocation = invocation.getString();
if(methodInvocationMap.containsKey(methodInvocation)) {
methodInvocationMap.get(methodInvocation).add(invocation);
}
else {
List list = new ArrayList();
list.add(invocation);
methodInvocationMap.put(methodInvocation, list);
}
}
return methodInvocationMap;
}
private static Set convertToStringSet(List extends LeafExpression> expressions) {
Set set = new LinkedHashSet<>();
for(LeafExpression expression : expressions) {
set.add(expression.getString());
}
return set;
}
private static void replaceVariablesWithArguments(Set variables, Map parameterToArgumentMap) {
for(String parameter : parameterToArgumentMap.keySet()) {
String argument = parameterToArgumentMap.get(parameter);
if(variables.contains(parameter)) {
if(!StringDistance.isNumeric(argument)) {
variables.add(argument);
}
if(argument.contains("(") && argument.contains(")")) {
int indexOfOpeningParenthesis = argument.indexOf("(");
int indexOfClosingParenthesis = argument.lastIndexOf(")");
boolean openingParenthesisInsideSingleQuotes = ReplacementUtil.isInsideSingleQuotes(argument, indexOfOpeningParenthesis);
boolean closingParenthesisInsideSingleQuotes = ReplacementUtil.isInsideSingleQuotes(argument, indexOfClosingParenthesis);
boolean openingParenthesisInsideDoubleQuotes = ReplacementUtil.isInsideDoubleQuotes(argument, indexOfOpeningParenthesis);
boolean closingParenthesisIndideDoubleQuotes = ReplacementUtil.isInsideDoubleQuotes(argument, indexOfClosingParenthesis);
if(indexOfOpeningParenthesis < indexOfClosingParenthesis &&
!openingParenthesisInsideSingleQuotes && !closingParenthesisInsideSingleQuotes &&
!openingParenthesisInsideDoubleQuotes && !closingParenthesisIndideDoubleQuotes) {
String arguments = argument.substring(indexOfOpeningParenthesis+1, indexOfClosingParenthesis);
if(!arguments.isEmpty() && !arguments.contains(",") && !arguments.contains("(") && !arguments.contains(")") && !StringDistance.isNumeric(arguments)) {
variables.add(arguments);
}
}
}
}
}
}
private static void replaceVariablesWithArguments(Map> callMap,
Set calls, Map parameterToArgumentMap) {
if(isCallChain(callMap.values())) {
for(String parameter : parameterToArgumentMap.keySet()) {
String argument = parameterToArgumentMap.get(parameter);
if(!parameter.equals(argument)) {
Set toBeAdded = new LinkedHashSet();
for(String call : calls) {
String afterReplacement = ReplacementUtil.performArgumentReplacement(call, parameter, argument);
if(!call.equals(afterReplacement)) {
toBeAdded.add(afterReplacement);
List extends AbstractCall> oldCalls = callMap.get(call);
List newCalls = new ArrayList();
for(AbstractCall oldCall : oldCalls) {
AbstractCall newCall = oldCall.update(parameter, argument);
newCalls.add(newCall);
}
callMap.put(afterReplacement, newCalls);
}
}
calls.addAll(toBeAdded);
}
}
}
else {
Set finalNewCalls = new LinkedHashSet();
for(String parameter : parameterToArgumentMap.keySet()) {
String argument = parameterToArgumentMap.get(parameter);
if(!parameter.equals(argument)) {
Set toBeAdded = new LinkedHashSet();
for(String call : calls) {
String afterReplacement = ReplacementUtil.performArgumentReplacement(call, parameter, argument);
if(!call.equals(afterReplacement)) {
toBeAdded.add(afterReplacement);
List extends AbstractCall> oldCalls = callMap.get(call);
List newCalls = new ArrayList();
for(AbstractCall oldCall : oldCalls) {
AbstractCall newCall = oldCall.update(parameter, argument);
newCalls.add(newCall);
}
callMap.put(afterReplacement, newCalls);
}
}
finalNewCalls.addAll(toBeAdded);
}
}
calls.addAll(finalNewCalls);
}
}
private static boolean isCallChain(Collection> calls) {
if(calls.size() > 1) {
AbstractCall previous = null;
AbstractCall current = null;
int chainLength = 0;
for(List extends AbstractCall> list : calls) {
previous = current;
current = list.get(0);
if(current != null && previous != null) {
if(previous.getExpression() != null && previous.getExpression().equals(current.actualString())) {
chainLength++;
}
else {
return false;
}
}
}
if(chainLength == calls.size()-1) {
return true;
}
}
return false;
}
private static void findReplacements(Set strings1, Set