gr.uom.java.xmi.decomposition.AbstractCall Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refactoring-miner Show documentation
Show all versions of refactoring-miner Show documentation
RefactoringMiner is a library/API written in Java that can detect refactorings applied in the history of a Java project.
package gr.uom.java.xmi.decomposition;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import gr.uom.java.xmi.LocationInfo;
import gr.uom.java.xmi.LocationInfoProvider;
import gr.uom.java.xmi.decomposition.replacement.MergeVariableReplacement;
import gr.uom.java.xmi.decomposition.replacement.Replacement;
import gr.uom.java.xmi.decomposition.replacement.Replacement.ReplacementType;
import gr.uom.java.xmi.diff.CodeRange;
import static gr.uom.java.xmi.diff.UMLClassBaseDiff.allMappingsAreExactMatches;
public abstract class AbstractCall implements LocationInfoProvider {
protected int typeArguments;
protected String expression;
protected List arguments;
protected LocationInfo locationInfo;
protected StatementCoverageType coverage = StatementCoverageType.NONE;
public String getExpression() {
return expression;
}
public List getArguments() {
return arguments;
}
public LocationInfo getLocationInfo() {
return locationInfo;
}
public StatementCoverageType getCoverage() {
return coverage;
}
public abstract boolean identicalName(AbstractCall call);
public abstract String getName();
public abstract double normalizedNameDistance(AbstractCall call);
public abstract AbstractCall update(String oldExpression, String newExpression);
public String actualString() {
StringBuilder sb = new StringBuilder();
if(expression != null) {
sb.append(expression).append(".");
}
sb.append(getName());
sb.append("(");
int size = arguments.size();
if(size > 0) {
for(int i=0; i replacements) {
return identicalExpression(call) ||
identicalExpressionAfterTypeReplacements(call, replacements);
}
public boolean identicalExpression(AbstractCall call) {
return (getExpression() != null && call.getExpression() != null &&
getExpression().equals(call.getExpression())) ||
(getExpression() == null && call.getExpression() == null);
}
private boolean identicalExpressionAfterTypeReplacements(AbstractCall call, Set replacements) {
if(getExpression() != null && call.getExpression() != null) {
String expression1 = getExpression();
String expression2 = call.getExpression();
String expression1AfterReplacements = new String(expression1);
for(Replacement replacement : replacements) {
if(replacement.getType().equals(ReplacementType.TYPE)) {
expression1AfterReplacements = ReplacementUtil.performReplacement(expression1AfterReplacements, expression2, replacement.getBefore(), replacement.getAfter());
}
}
if(expression1AfterReplacements.equals(expression2)) {
return true;
}
}
return false;
}
public boolean equalArguments(AbstractCall call) {
return getArguments().equals(call.getArguments());
}
public boolean identicalOrReplacedArguments(AbstractCall call, Set replacements) {
List arguments1 = getArguments();
List arguments2 = call.getArguments();
if(arguments1.size() != arguments2.size())
return false;
for(int i=0; i arguments1 = getArguments();
List arguments2 = call.getArguments();
if(arguments1.size() != arguments2.size())
return false;
for(int i=0; i tokens1 = new LinkedHashSet(Arrays.asList(argument1.split(UMLOperationBodyMapper.SPLIT_CONCAT_STRING_PATTERN)));
Set tokens2 = new LinkedHashSet(Arrays.asList(argument2.split(UMLOperationBodyMapper.SPLIT_CONCAT_STRING_PATTERN)));
Set intersection = new LinkedHashSet(tokens1);
intersection.retainAll(tokens2);
int size = intersection.size();
int threshold = Math.max(tokens1.size(), tokens2.size()) - size;
if(size > 0 && size >= threshold) {
argumentConcatenated = true;
}
}
if(!argument1.equals(argument2) && !argumentConcatenated)
return false;
}
return true;
}
public boolean identicalOrWrappedArguments(AbstractCall call) {
List arguments1 = getArguments();
List arguments2 = call.getArguments();
if(arguments1.size() != arguments2.size())
return false;
for(int i=0; i replacements) {
int replacedArguments = 0;
List arguments1 = getArguments();
List arguments2 = call.getArguments();
if(arguments1.size() == arguments2.size()) {
for(int i=0; i 0 && replacedArguments == arguments1.size();
}
public boolean allArgumentsReplaced(AbstractCall call, Set replacements, Map parameterToArgumentMap) {
int replacedArguments = 0;
List arguments1 = getArguments();
List arguments2 = call.getArguments();
if(arguments1.size() == arguments2.size()) {
for(int i=0; i 0 && replacedArguments == arguments1.size();
}
public boolean renamedWithIdenticalExpressionAndArguments(AbstractCall call, Set replacements, double distance) {
boolean identicalOrReplacedArguments = identicalOrReplacedArguments(call, replacements);
boolean allArgumentsReplaced = allArgumentsReplaced(call, replacements);
return getExpression() != null && call.getExpression() != null &&
identicalExpression(call, replacements) &&
!identicalName(call) &&
(equalArguments(call) || (allArgumentsReplaced && normalizedNameDistance(call) <= distance) || (identicalOrReplacedArguments && !allArgumentsReplaced));
}
public boolean renamedWithDifferentExpressionAndIdenticalArguments(AbstractCall call) {
return (this.getName().contains(call.getName()) || call.getName().contains(this.getName())) &&
equalArguments(call) && this.arguments.size() > 0 &&
((this.getExpression() == null && call.getExpression() != null) || (call.getExpression() == null && this.getExpression() != null));
}
public boolean renamedWithIdenticalArgumentsAndNoExpression(AbstractCall call, double distance, List lambdaMappers) {
boolean allExactLambdaMappers = lambdaMappers.size() > 0;
for(UMLOperationBodyMapper lambdaMapper : lambdaMappers) {
if(!allMappingsAreExactMatches(lambdaMapper)) {
allExactLambdaMappers = false;
break;
}
}
return getExpression() == null && call.getExpression() == null &&
!identicalName(call) &&
(normalizedNameDistance(call) <= distance || allExactLambdaMappers) &&
equalArguments(call);
}
public boolean renamedWithIdenticalExpressionAndDifferentNumberOfArguments(AbstractCall call, Set replacements, double distance, List lambdaMappers) {
boolean allExactLambdaMappers = lambdaMappers.size() > 0;
for(UMLOperationBodyMapper lambdaMapper : lambdaMappers) {
if(!allMappingsAreExactMatches(lambdaMapper)) {
allExactLambdaMappers = false;
break;
}
}
return getExpression() != null && call.getExpression() != null &&
identicalExpression(call, replacements) &&
(normalizedNameDistance(call) <= distance || allExactLambdaMappers) &&
!equalArguments(call) &&
getArguments().size() != call.getArguments().size();
}
private boolean onlyArgumentsChanged(AbstractCall call, Set replacements) {
return identicalExpression(call, replacements) &&
identicalName(call) &&
!equalArguments(call) &&
getArguments().size() != call.getArguments().size();
}
public boolean identicalWithMergedArguments(AbstractCall call, Set replacements) {
if(onlyArgumentsChanged(call, replacements)) {
List updatedArguments1 = new ArrayList(this.arguments);
Map> commonVariableReplacementMap = new LinkedHashMap>();
for(Replacement replacement : replacements) {
if(replacement.getType().equals(ReplacementType.VARIABLE_NAME)) {
String key = replacement.getAfter();
if(commonVariableReplacementMap.containsKey(key)) {
commonVariableReplacementMap.get(key).add(replacement);
int index = updatedArguments1.indexOf(replacement.getBefore());
if(index != -1) {
updatedArguments1.remove(index);
}
}
else {
Set r = new LinkedHashSet();
r.add(replacement);
commonVariableReplacementMap.put(key, r);
int index = updatedArguments1.indexOf(replacement.getBefore());
if(index != -1) {
updatedArguments1.remove(index);
updatedArguments1.add(index, key);
}
}
}
}
if(updatedArguments1.equals(call.arguments)) {
for(String key : commonVariableReplacementMap.keySet()) {
Set r = commonVariableReplacementMap.get(key);
if(r.size() > 1) {
replacements.removeAll(r);
Set mergedVariables = new LinkedHashSet();
for(Replacement replacement : r) {
mergedVariables.add(replacement.getBefore());
}
MergeVariableReplacement merge = new MergeVariableReplacement(mergedVariables, key);
replacements.add(merge);
}
}
return true;
}
}
return false;
}
public boolean identicalWithDifferentNumberOfArguments(AbstractCall call, Set replacements, Map parameterToArgumentMap) {
if(onlyArgumentsChanged(call, replacements)) {
int argumentIntersectionSize = argumentIntersectionSize(call, parameterToArgumentMap);
if(argumentIntersectionSize > 0 || getArguments().size() == 0 || call.getArguments().size() == 0) {
return true;
}
}
return false;
}
public boolean identical(AbstractCall call, Set replacements) {
return identicalExpression(call, replacements) &&
identicalName(call) &&
equalArguments(call);
}
public Set argumentIntersection(AbstractCall call) {
List args1 = preprocessArguments(getArguments());
List args2 = preprocessArguments(call.getArguments());
Set argumentIntersection = new LinkedHashSet(args1);
argumentIntersection.retainAll(args2);
return argumentIntersection;
}
private List preprocessArguments(List arguments) {
List args = new ArrayList();
for(String arg : arguments) {
if(arg.contains("\n")) {
args.add(arg.substring(0, arg.indexOf("\n")));
}
else {
args.add(arg);
}
}
return args;
}
private int argumentIntersectionSize(AbstractCall call, Map parameterToArgumentMap) {
Set argumentIntersection = argumentIntersection(call);
int argumentIntersectionSize = argumentIntersection.size();
for(String parameter : parameterToArgumentMap.keySet()) {
String argument = parameterToArgumentMap.get(parameter);
if(getArguments().contains(argument) &&
call.getArguments().contains(parameter)) {
argumentIntersectionSize++;
}
}
return argumentIntersectionSize;
}
private boolean argumentIsEqual(String statement) {
return statement.endsWith(";\n") && getArguments().size() == 1 &&
//length()-2 to remove ";\n" from the end of the statement
equalsIgnoringExtraParenthesis(getArguments().get(0), statement.substring(0, statement.length()-2));
}
private boolean argumentIsReturned(String statement) {
return statement.startsWith("return ") && getArguments().size() == 1 &&
//length()-2 to remove ";\n" from the end of the return statement, 7 to remove the prefix "return "
equalsIgnoringExtraParenthesis(getArguments().get(0), statement.substring(7, statement.length()-2));
}
public Replacement makeReplacementForReturnedArgument(String statement) {
if(argumentIsReturned(statement)) {
return new Replacement(getArguments().get(0), statement.substring(7, statement.length()-2),
ReplacementType.ARGUMENT_REPLACED_WITH_RETURN_EXPRESSION);
}
else if(argumentIsEqual(statement)) {
return new Replacement(getArguments().get(0), statement.substring(0, statement.length()-2),
ReplacementType.ARGUMENT_REPLACED_WITH_STATEMENT);
}
return null;
}
public Replacement makeReplacementForWrappedCall(String statement) {
if(argumentIsReturned(statement)) {
return new Replacement(statement.substring(7, statement.length()-2), getArguments().get(0),
ReplacementType.ARGUMENT_REPLACED_WITH_RETURN_EXPRESSION);
}
else if(argumentIsEqual(statement)) {
return new Replacement(statement.substring(0, statement.length()-2), getArguments().get(0),
ReplacementType.ARGUMENT_REPLACED_WITH_STATEMENT);
}
return null;
}
private boolean argumentIsAssigned(String statement) {
return getArguments().size() == 1 && statement.contains("=") && statement.endsWith(";\n") &&
//length()-2 to remove ";\n" from the end of the assignment statement, indexOf("=")+1 to remove the left hand side of the assignment
equalsIgnoringExtraParenthesis(getArguments().get(0), statement.substring(statement.indexOf("=")+1, statement.length()-2));
}
public Replacement makeReplacementForAssignedArgument(String statement) {
if(argumentIsAssigned(statement)) {
return new Replacement(statement.substring(statement.indexOf("=")+1, statement.length()-2),
getArguments().get(0), ReplacementType.ARGUMENT_REPLACED_WITH_RIGHT_HAND_SIDE_OF_ASSIGNMENT_EXPRESSION);
}
return null;
}
private static boolean equalsIgnoringExtraParenthesis(String s1, String s2) {
if(s1.equals(s2))
return true;
String parenthesizedS1 = "("+s1+")";
if(parenthesizedS1.equals(s2))
return true;
String parenthesizedS2 = "("+s2+")";
if(parenthesizedS2.equals(s1))
return true;
return false;
}
protected void update(AbstractCall newCall, String oldExpression, String newExpression) {
newCall.typeArguments = this.typeArguments;
if(this.expression != null && this.expression.equals(oldExpression)) {
newCall.expression = newExpression;
}
else {
newCall.expression = this.expression;
}
newCall.arguments = new ArrayList();
for(String argument : this.arguments) {
newCall.arguments.add(
ReplacementUtil.performReplacement(argument, oldExpression, newExpression));
}
}
public CodeRange codeRange() {
LocationInfo info = getLocationInfo();
return info.codeRange();
}
public enum StatementCoverageType {
NONE, ONLY_CALL, RETURN_CALL, THROW_CALL, CAST_CALL, VARIABLE_DECLARATION_INITIALIZER_CALL;
}
}