From 72f16199dfbb4ce672721f7d538d0acd80999039 Mon Sep 17 00:00:00 2001 From: Mosabbir Khan Shiblu Date: Mon, 5 Jul 2021 18:37:48 -0400 Subject: [PATCH] #113: Parameterize container diff to allow source and class diff to re-use the same diff --- src/io/jsrminer/uml/diff/ClassDiffer.java | 162 +----------------- src/io/jsrminer/uml/diff/ContainerDiffer.java | 10 +- .../jsrminer/uml/diff/SourceFileDiffer.java | 4 +- .../uml/mapping/FunctionBodyMapper.java | 3 +- .../AnonymousFunctionReplacementFinder.java | 3 +- 5 files changed, 20 insertions(+), 162 deletions(-) diff --git a/src/io/jsrminer/uml/diff/ClassDiffer.java b/src/io/jsrminer/uml/diff/ClassDiffer.java index 74fa9c86..f8c080f9 100644 --- a/src/io/jsrminer/uml/diff/ClassDiffer.java +++ b/src/io/jsrminer/uml/diff/ClassDiffer.java @@ -20,20 +20,16 @@ import java.util.List; import java.util.TreeSet; -public class ClassDiffer extends BaseDiffer { - private final IClassDeclaration class1; - private final IClassDeclaration class2; - private final ClassDiff classDiff; - +public class ClassDiffer extends ContainerDiffer { + ClassDiff classDiff; public ClassDiffer(IClassDeclaration class1, IClassDeclaration class2) { - this.class1 = class1; - this.class2 = class2; - this.classDiff = new ClassDiff(class1, class2); + super(new ClassDiff(class1, class2)); + this.classDiff = super.containerDiff; } public ClassDiff diff() { - reportAddedAndRemovedOperations(); - createBodyMapperForCommonNamedFunctions(); + super.reportAddedAndRemovedOperations(); + super.createBodyMapperForCommonFunctions(); // processAnonymousFunctions(sourceDiff); checkForOperationSignatureChanges(); @@ -42,147 +38,7 @@ public ClassDiff diff() { checkForInlinedOperations(); checkForExtractedOperations(); - return this.classDiff; - } - - // Adds the added and removed ops in the model diff - private void reportAddedAndRemovedOperations() { - // region Find uncommon functions between the two files - // For model1 uncommon / not matched functions are the functions that were removed - // For model2 uncommon/ not matched functions are the functions that were added - boolean isEqual; - for (IFunctionDeclaration function1 : this.class1.getFunctionDeclarations()) { - isEqual = false; - for (IFunctionDeclaration function2 : this.class2.getFunctionDeclarations()) { - if (isEqual = FunctionUtil.isEqual(function1, function2)) { - break; - } - } - - // If no match on model2 report as removed - if (!isEqual) - classDiff.reportRemovedOperation((FunctionDeclaration) function1); - } - for (IFunctionDeclaration function2 : classDiff.getContainer2().getFunctionDeclarations()) { - isEqual = false; - for (IFunctionDeclaration function1 : classDiff.getContainer1().getFunctionDeclarations()) { - if (isEqual = FunctionUtil.isEqual(function2, function1)) { - break; - } - } - - // If no match report as added - if (!isEqual) - classDiff.reportAddedOperation((FunctionDeclaration) function2); - } - } - - protected void createBodyMapperForCommonNamedFunctions() { - final List functions1 = classDiff.getContainer1().getFunctionDeclarations(); - final List functions2 = classDiff.getContainer2().getFunctionDeclarations(); - // First match by equalsQualified - // (In RM it's equals signature which checks modifiers, qualified name and parameter types - for (IFunctionDeclaration if1 : functions1) { - FunctionDeclaration function1 = (FunctionDeclaration) if1; - - IFunctionDeclaration function2 = functions2.stream() - .filter(f2 -> FunctionUtil.equalsNameParentQualifiedNameAndParamerNames(f2, function1)) - .findFirst() - .orElse(null); - - if (function2 != null) { -// if (getModelDiff() != null) { -// List mappers -// = getModelDiff().findMappersWithMatchingSignature2(function2); -// if (mappers.size() > 0) { -// var operation1 = mappers.get(0).getOperation1(); -// if (!FunctionUtil.equalNameAndParameterCount(operation1, function1)//operation1.equalSignature(function1) -// && getModelDiff().commonlyImplementedOperations(operation1, function2, this)) { -// if (!containerDiff.getRemovedOperations().contains(function1)) { -// containerDiff.getRemovedOperations().add(function1); -// } -// break; -// } -// } -// } - - // Map and find refactorings between two functions - UMLOperationDiff operationDiff = new UMLOperationDiff(function1, (FunctionDeclaration) function2); - FunctionBodyMapper mapper = new FunctionBodyMapper(operationDiff, classDiff); - operationDiff.setMappings(mapper.getMappings()); - this.classDiff.getRefactoringsBeforePostProcessing().addAll(operationDiff.getRefactorings()); - // save the mapper TODO - this.classDiff.getOperationBodyMapperList().add(mapper); - } - } - - // Second Not qualified but the 2nd file contains the operation - for (IFunctionDeclaration if1 : functions1) { - FunctionDeclaration function1 = (FunctionDeclaration) if1; - IFunctionDeclaration function2 = functions2.stream() - .filter(f2 -> FunctionUtil.isEqual(f2, function1)) - .findFirst() - .orElse(null); - - if (function2 != null - && !containsMapperForOperation(function1) - // && functions2.getOperations().contains(operation) - && !classDiff.getRemovedOperations().contains(function1)) { - -// int index = functions2.indexOf(operation); -// int lastIndex = functions2.lastIndexOf(operation); -// int finalIndex = index; -// if (index != lastIndex) { -// double d1 = operation.getReturnParameter().getType() -// .normalizedNameDistance(nextClass.getOperations().get(index).getReturnParameter().getType()); -// double d2 = operation.getReturnParameter().getType() -// .normalizedNameDistance(nextClass.getOperations().get(lastIndex).getReturnParameter().getType()); -// if (d2 < d1) { -// finalIndex = lastIndex; -// } -// } - - UMLOperationDiff operationDiff = new UMLOperationDiff(function1, (FunctionDeclaration) function2); - FunctionBodyMapper bodyMapper - = new FunctionBodyMapper(operationDiff, classDiff); - operationDiff.setMappings(bodyMapper.getMappings()); - classDiff.getRefactoringsBeforePostProcessing().addAll(operationDiff.getRefactorings()); - classDiff.getOperationBodyMapperList().add(bodyMapper); - } - } - - List removedOperationsToBeRemoved = new ArrayList<>(); - List addedOperationsToBeRemoved = new ArrayList<>(); - for (FunctionDeclaration removedOperation : classDiff.getRemovedOperations()) { - for (FunctionDeclaration addedOperation : classDiff.getAddedOperations()) { - /*if (removedOperation.equalsIgnoringVisibility(addedOperation)) { - UMLOperationBodyMapper operationBodyMapper = new UMLOperationBodyMapper(removedOperation, addedOperation, this); - UMLOperationDiff operationSignatureDiff = new UMLOperationDiff(removedOperation, addedOperation, operationBodyMapper.getMappings()); - refactorings.addAll(operationSignatureDiff.getRefactorings()); - this.addOperationBodyMapper(operationBodyMapper); - removedOperationsToBeRemoved.add(removedOperation); - addedOperationsToBeRemoved.add(addedOperation); - } else*/ - if (FunctionUtil.nameEqualsIgnoreCaseAndEqualParameterCount(removedOperation, addedOperation)) { - UMLOperationDiff operationDiff = new UMLOperationDiff(removedOperation, addedOperation); - FunctionBodyMapper bodyMapper - = new FunctionBodyMapper(operationDiff, classDiff); - operationDiff.setMappings(bodyMapper.getMappings()); - classDiff.getRefactoringsBeforePostProcessing().addAll(operationDiff.getRefactorings()); - - if (!removedOperation.getName().equals(addedOperation.getName()) && - !(removedOperation.isConstructor() && addedOperation.isConstructor())) { - RenameOperationRefactoring rename = new RenameOperationRefactoring(bodyMapper); - classDiff.getRefactoringsBeforePostProcessing().add(rename); - } - classDiff.getOperationBodyMapperList().add(bodyMapper); - removedOperationsToBeRemoved.add(removedOperation); - addedOperationsToBeRemoved.add(addedOperation); - } - } - } - classDiff.getRemovedOperations().removeAll(removedOperationsToBeRemoved); - classDiff.getAddedOperations().removeAll(addedOperationsToBeRemoved); + return this.containerDiff; } private void checkForOperationSignatureChanges() { @@ -332,8 +188,8 @@ private void checkForExtractedOperations() { } protected void processAttributes() { - var originalClass = class1; - var nextClass = class2; + var originalClass = classDiff.getContainer1(); + var nextClass = classDiff.getContainer1(); for (UMLAttribute attribute : originalClass.getAttributes()) { var matchingAttribute = ClassUtil.containsAttribute(nextClass, attribute); diff --git a/src/io/jsrminer/uml/diff/ContainerDiffer.java b/src/io/jsrminer/uml/diff/ContainerDiffer.java index d3f106a6..d3ca8785 100644 --- a/src/io/jsrminer/uml/diff/ContainerDiffer.java +++ b/src/io/jsrminer/uml/diff/ContainerDiffer.java @@ -16,11 +16,11 @@ import java.util.List; import java.util.TreeSet; -public class ContainerDiffer extends BaseDiffer { - protected final ContainerDiff containerDiff; +public class ContainerDiffer> extends BaseDiffer { + protected final D containerDiff; - public ContainerDiffer(T container1, T container2) { - this.containerDiff = new ContainerDiff<>(container1, container2); + public ContainerDiffer(D containerDiff) { + this.containerDiff = containerDiff; } /** @@ -262,7 +262,7 @@ private void checkForExtractedOperations() { } // Adds the added and removed ops in the model diff - private void reportAddedAndRemovedOperations() { + void reportAddedAndRemovedOperations() { // region Find uncommon functions between the two files // For model1 uncommon / not matched functions are the functions that were removed // For model2 uncommon/ not matched functions are the functions that were added diff --git a/src/io/jsrminer/uml/diff/SourceFileDiffer.java b/src/io/jsrminer/uml/diff/SourceFileDiffer.java index c9bc8546..fe225d05 100644 --- a/src/io/jsrminer/uml/diff/SourceFileDiffer.java +++ b/src/io/jsrminer/uml/diff/SourceFileDiffer.java @@ -15,12 +15,12 @@ /** * Diff between two source File? */ -public class SourceFileDiffer extends ContainerDiffer { +public class SourceFileDiffer extends ContainerDiffer> { public final UMLModelDiff modelDiff; public SourceFileDiffer(final ISourceFile container1, final ISourceFile container2, final UMLModelDiff modelDiff) { - super(container1, container2); + super(new ContainerDiff<>(container1, container2)); this.modelDiff = modelDiff; } diff --git a/src/io/jsrminer/uml/mapping/FunctionBodyMapper.java b/src/io/jsrminer/uml/mapping/FunctionBodyMapper.java index cbe07c9e..0186e40d 100644 --- a/src/io/jsrminer/uml/mapping/FunctionBodyMapper.java +++ b/src/io/jsrminer/uml/mapping/FunctionBodyMapper.java @@ -175,7 +175,8 @@ private Set getBlockStatementsRecursiveOrder(List sta private void mapChildFunctionDeclarations(FunctionDeclaration function1, FunctionDeclaration function2) { // Maps the functions that are immediately declared into this mapper if (function1.getFunctionDeclarations().size() > 0 && function2.getFunctionDeclarations().size() > 0) { - var differ = new ContainerDiffer(function1, function2); + var differ = new ContainerDiffer> + (new ContainerDiff<>(function1, function2)); var diff = differ.diffChildFunctions(); this.refactorings.addAll(diff.getAllRefactorings()); } diff --git a/src/io/jsrminer/uml/mapping/replacement/AnonymousFunctionReplacementFinder.java b/src/io/jsrminer/uml/mapping/replacement/AnonymousFunctionReplacementFinder.java index 8a682a66..9c50d109 100644 --- a/src/io/jsrminer/uml/mapping/replacement/AnonymousFunctionReplacementFinder.java +++ b/src/io/jsrminer/uml/mapping/replacement/AnonymousFunctionReplacementFinder.java @@ -81,7 +81,8 @@ void matchAnonymousContainers(List anonymousConta } Replacement diffAnonymousPair(IAnonymousFunctionDeclaration anonymousFunctionDeclaration1, IAnonymousFunctionDeclaration anonymousClassDeclaration2) { - ContainerDiffer differ = new ContainerDiffer<>(anonymousFunctionDeclaration1, anonymousClassDeclaration2); + ContainerDiffer> differ + = new ContainerDiffer<>(new ContainerDiff<>(anonymousFunctionDeclaration1, anonymousClassDeclaration2)); var diff = differ.diff(); // for (IFunctionDeclaration operation1 : anonymousClass1.getFunctionDeclarations()) { // for (IFunctionDeclaration operation2 : anonymousClass2.getFunctionDeclarations()) {