Skip to content

Commit

Permalink
Handle better extracted methods with varArgs parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
tsantalis committed Dec 17, 2024
1 parent 2220d7a commit 839aa80
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,13 @@ else if((parentFieldDeclarationMap != null && parentFieldDeclarationMap.contains
}
}
else {
inferredArgumentTypes.add(null);
String numberType = handleNumber(arg);
if(numberType != null) {
inferredArgumentTypes.add(UMLType.extractTypeObject(numberType));
}
else {
inferredArgumentTypes.add(null);
}
}
}
int i=0;
Expand All @@ -378,7 +384,8 @@ else if((parentFieldDeclarationMap != null && parentFieldDeclarationMap.contains
i++;
}
UMLType lastInferredArgumentType = inferredArgumentTypes.size() > 0 ? inferredArgumentTypes.get(inferredArgumentTypes.size()-1) : null;
boolean result = this.numberOfArguments == operation.getParameterTypeList().size() || varArgsMatch(operation, lastInferredArgumentType);
List<UMLType> parameterTypeList = operation.getParameterTypeList();
boolean result = this.numberOfArguments == parameterTypeList.size() || varArgsMatch(operation, lastInferredArgumentType, parameterTypeList);
if(result && classDiff != null) {
for(UMLOperation addedOperation : classDiff.getAddedOperations()) {
if(!addedOperation.equals(operation) && addedOperation.getName().equals(operation.getName()) && addedOperation.getParameterDeclarationList().size() == operation.getParameterDeclarationList().size()) {
Expand Down Expand Up @@ -441,6 +448,26 @@ private static boolean exactlyMatchingArgumentType(UMLType parameterType, UMLTyp
return parameterType.getClassType().equals(argumentType.toString()) || parameterType.toString().equals(argumentType.toString());
}

private static String handleNumber(String argument) {
try {
Integer.parseInt(argument);
return "int";
} catch (NumberFormatException e) {}
try {
Long.parseLong(argument);
return "long";
} catch (NumberFormatException e) {}
try {
Float.parseFloat(argument);
return "float";
} catch (NumberFormatException e) {}
try {
Double.parseDouble(argument);
return "double";
} catch (NumberFormatException e) {}
return null;
}

public static boolean compatibleTypes(UMLParameter parameter, UMLType type, UMLAbstractClassDiff classDiff, UMLModelDiff modelDiff) {
String type1 = parameter.getType().toString();
String type2 = type.toString();
Expand Down Expand Up @@ -500,7 +527,7 @@ else if(isPrimitiveType(type2) && !isPrimitiveType(type1)) {
}
if(!parameter.isVarargs() && type1.endsWith("Object") && !type2.endsWith("Object"))
return true;
if(parameter.isVarargs() && type1.endsWith("Object[]") && (type2.equals("Throwable") || type2.endsWith("Exception")))
if(parameter.isVarargs() && type1.endsWith("Object[]") && (type2.equals("Throwable") || type2.endsWith("Exception") || isPrimitiveType(type2) || type2.equals("String")))
return true;
if(parameter.getType().equalsWithSubType(type))
return true;
Expand Down Expand Up @@ -575,21 +602,24 @@ private static UMLClassBaseDiff getUMLClassDiff(UMLModelDiff modelDiff, UMLType
return classDiff;
}

private boolean varArgsMatch(VariableDeclarationContainer operation, UMLType lastInferredArgumentType) {
private boolean varArgsMatch(VariableDeclarationContainer operation, UMLType lastInferredArgumentType, List<UMLType> parameterTypeList) {
//0 varargs arguments passed
if(this.numberOfArguments == operation.getNumberOfNonVarargsParameters()) {
return true;
}
//>=1 varargs arguments passed
if(operation.hasVarargsParameter() && this.numberOfArguments > operation.getNumberOfNonVarargsParameters()) {
List<UMLType> parameterTypeList = operation.getParameterTypeList();
UMLType lastParameterType = parameterTypeList.get(parameterTypeList.size()-1);
if(lastParameterType.equals(lastInferredArgumentType)) {
return true;
}
if(lastInferredArgumentType != null && lastParameterType.getClassType().equals(lastInferredArgumentType.getClassType())) {
return true;
}
List<UMLParameter> params = operation.getParametersWithoutReturnType();
if(compatibleTypes(params.get(params.size()-1), lastInferredArgumentType, null, null)) {
return true;
}
}
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import static gr.uom.java.xmi.decomposition.StringBasedHeuristics.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
Expand Down Expand Up @@ -2663,6 +2664,28 @@ else if(invocationCoveringTheEntireStatement2.getExpression() != null && invocat
return replacementInfo.getReplacements();
}
}
//check for reordered arguments in argumentized strings
if(creationCoveringTheEntireStatement1 != null && creationCoveringTheEntireStatement2 != null &&
creationCoveringTheEntireStatement1.identicalName(creationCoveringTheEntireStatement2) &&
creationCoveringTheEntireStatement1.identicalExpression(creationCoveringTheEntireStatement2)) {
String string1 = replacementInfo.getArgumentizedString1();
String string2 = replacementInfo.getArgumentizedString2();
String name1 = creationCoveringTheEntireStatement1.getName() + "(";
String name2 = creationCoveringTheEntireStatement2.getName() + "(";
if(string1.contains(name1) && string2.contains(name2) &&
string1.contains(")") && string2.contains(")")) {
String args1 = string1.substring(string1.indexOf(name1) + name1.length(), string1.lastIndexOf(")"));
String args2 = string2.substring(string2.indexOf(name2) + name2.length(), string2.lastIndexOf(")"));
List<String> argumentList1 = Arrays.asList(args1.split(","));
List<String> argumentList2 = Arrays.asList(args2.split(","));
if(argumentList1.containsAll(argumentList2) && argumentList2.containsAll(argumentList1)) {
Replacement replacement = new ObjectCreationReplacement(creationCoveringTheEntireStatement1.getName(),
creationCoveringTheEntireStatement2.getName(), creationCoveringTheEntireStatement1, creationCoveringTheEntireStatement2, ReplacementType.CLASS_INSTANCE_CREATION);
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)) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/refactoringminer/api/PurityChecker.java
Original file line number Diff line number Diff line change
Expand Up @@ -5552,7 +5552,7 @@ private static void relaxCheckForParametrizationOrAddParameterOnTop(List<Refacto
replacementsToCheck.addAll(replacementsToAddSpecific);
replacementsToCheck.removeAll(replacementsToRemoveSpecific);

for (Replacement replacement: replacementsToCheck) {
for (Replacement replacement: new LinkedHashSet<>(replacementsToCheck)) {
if (replacement.getType().equals(Replacement.ReplacementType.CLASS_INSTANCE_CREATION) ||
replacement.getType().equals(Replacement.ReplacementType.CLASS_INSTANCE_CREATION_ARGUMENT)) {
relaxCheckForAddParameterOnTopConstructorVersion(bodyMapper, replacement, refactorings, replacementsToCheck, removedReplacements);
Expand Down

0 comments on commit 839aa80

Please sign in to comment.