From ba604f7de58f2d93d754ac762ff30ff963db3ad9 Mon Sep 17 00:00:00 2001 From: tsantalis Date: Fri, 10 Jan 2025 22:59:42 -0500 Subject: [PATCH] Improved conditions for filtering Move Attribute refactorings --- .../gr/uom/java/xmi/diff/UMLModelDiff.java | 96 ++++++++++++++++++- .../test/TestAllRefactorings.java | 2 +- src/test/resources/oracle/data.json | 12 +-- src/test/resources/oracle/expected.txt | 6 +- 4 files changed, 105 insertions(+), 11 deletions(-) diff --git a/src/main/java/gr/uom/java/xmi/diff/UMLModelDiff.java b/src/main/java/gr/uom/java/xmi/diff/UMLModelDiff.java index 768b6ebac..a798a27ae 100644 --- a/src/main/java/gr/uom/java/xmi/diff/UMLModelDiff.java +++ b/src/main/java/gr/uom/java/xmi/diff/UMLModelDiff.java @@ -1639,7 +1639,7 @@ else if(isSubclassOf(addedAttribute.getClassName(), removedAttribute.getClassNam else if(sourceClassImportsTargetClass(removedAttribute.getClassName(), addedAttribute.getClassName()) || targetClassImportsSourceClass(removedAttribute.getClassName(), addedAttribute.getClassName()) || getRemovedClass(removedAttribute.getClassName()) != null) { - if(!initializerContainsTypeLiteral(addedAttribute, removedAttribute)) { + if(!initializerContainsTypeLiteral(addedAttribute, removedAttribute) && instanceAttributeMovedAlongWithMethod(addedAttribute, removedAttribute)) { UMLAttributeDiff attributeDiff = new UMLAttributeDiff(removedAttribute, addedAttribute, Collections.emptyList()); boolean initializerWithMethodCallReplacement = false; if(attributeDiff.getInitializerMapper().isPresent()) { @@ -1763,6 +1763,100 @@ private boolean initializerContainsTypeLiteral(VariableDeclaration v1, VariableD return false; } + private boolean instanceAttributeMovedAlongWithMethod(UMLAttribute addedAttribute, UMLAttribute removedAttribute) { + if(addedAttribute.isStatic() || removedAttribute.isStatic()) { + return true; + } + if(addedAttribute.getName().equals(addedAttribute.getName().toUpperCase())) { + return true; + } + if(removedAttribute.getName().equals(removedAttribute.getName().toUpperCase())) { + return true; + } + if(addedAttribute.getClassName().startsWith(removedAttribute.getClassName())) { + return true; + } + if(removedAttribute.getClassName().startsWith(addedAttribute.getClassName())) { + return true; + } + //same package + String package1 = removedAttribute.getClassName().contains(".") ? + removedAttribute.getClassName().substring(0, removedAttribute.getClassName().lastIndexOf(".")) : + removedAttribute.getClassName(); + String package2 = addedAttribute.getClassName().contains(".") ? + addedAttribute.getClassName().substring(0, addedAttribute.getClassName().lastIndexOf(".")) : + addedAttribute.getClassName(); + if(package1.equals(package2)) { + return true; + } + UMLClassBaseDiff sourceClassDiff = getUMLClassDiff(removedAttribute.getClassName()); + UMLClassBaseDiff targetClassDiff = getUMLClassDiff(addedAttribute.getClassName()); + if(sourceClassDiff != null) { + for(UMLAttribute attribute : sourceClassDiff.getNextClass().getAttributes()) { + if(attribute.getType() != null && addedAttribute.getClassName().endsWith(attribute.getType().getClassType())) { + return true; + } + if(targetClassDiff != null) { + for(UMLType interfaceType : targetClassDiff.getNextClass().getImplementedInterfaces()) { + if(attribute.getType().equals(interfaceType)) { + return true; + } + } + } + } + } + for(Refactoring r : refactorings) { + if(r instanceof MoveOperationRefactoring) { + MoveOperationRefactoring move = (MoveOperationRefactoring)r; + if(move.getOriginalOperation().getClassName().equals(removedAttribute.getClassName()) && + move.getMovedOperation().getClassName().equals(addedAttribute.getClassName())) { + return true; + } + } + else if(r instanceof ExtractOperationRefactoring) { + ExtractOperationRefactoring extract = (ExtractOperationRefactoring)r; + if(extract.getSourceOperationBeforeExtraction().getClassName().equals(removedAttribute.getClassName()) && + extract.getExtractedOperation().getClassName().equals(addedAttribute.getClassName())) { + return true; + } + } + else if(r instanceof InlineOperationRefactoring) { + InlineOperationRefactoring inline = (InlineOperationRefactoring)r; + if(inline.getInlinedOperation().getClassName().equals(removedAttribute.getClassName()) && + inline.getTargetOperationAfterInline().getClassName().equals(addedAttribute.getClassName())) { + return true; + } + } + else if(r instanceof MoveAttributeRefactoring) { + MoveAttributeRefactoring move = (MoveAttributeRefactoring)r; + if(move.getOriginalAttribute().getClassName().equals(removedAttribute.getClassName()) && + move.getMovedAttribute().getClassName().equals(addedAttribute.getClassName())) { + return true; + } + //allow for attributes moved from many different classes to the same target class + if(move.getMovedAttribute().getClassName().equals(addedAttribute.getClassName()) && + move.getMovedAttribute().getName().equals(addedAttribute.getName())) { + return true; + } + } + else if(r instanceof MoveAndRenameAttributeRefactoring) { + MoveAndRenameAttributeRefactoring move = (MoveAndRenameAttributeRefactoring)r; + if(move.getOriginalAttribute().getClassName().equals(removedAttribute.getClassName()) && + move.getMovedAttribute().getClassName().equals(addedAttribute.getClassName())) { + return true; + } + } + else if(r instanceof AddParameterRefactoring) { + AddParameterRefactoring add = (AddParameterRefactoring)r; + if(add.getParameter().getType().equals(addedAttribute.getType()) && add.getParameter().getName().equals(addedAttribute.getName()) && + add.getOperationAfter().getClassName().equals(addedAttribute.getClassName())) { + return true; + } + } + } + return false; + } + private boolean initializerContainsTypeLiteral(UMLAttribute addedAttribute, UMLAttribute removedAttribute) { VariableDeclaration v1 = addedAttribute.getVariableDeclaration(); VariableDeclaration v2 = removedAttribute.getVariableDeclaration(); diff --git a/src/test/java/org/refactoringminer/test/TestAllRefactorings.java b/src/test/java/org/refactoringminer/test/TestAllRefactorings.java index b945b5a00..4e588344a 100644 --- a/src/test/java/org/refactoringminer/test/TestAllRefactorings.java +++ b/src/test/java/org/refactoringminer/test/TestAllRefactorings.java @@ -17,6 +17,6 @@ public void testAllRefactorings() throws Exception { GitHistoryRefactoringMinerImpl detector = new GitHistoryRefactoringMinerImpl(); TestBuilder test = new TestBuilder(detector, REPOS, Refactorings.All.getValue()); RefactoringPopulator.feedRefactoringsInstances(Refactorings.All.getValue(), Systems.FSE.getValue(), test); - test.assertExpectationsWithGitHubAPI(12401, 20, 226); + test.assertExpectationsWithGitHubAPI(12402, 18, 226); } } diff --git a/src/test/resources/oracle/data.json b/src/test/resources/oracle/data.json index 046c0d243..ddd3d2261 100644 --- a/src/test/resources/oracle/data.json +++ b/src/test/resources/oracle/data.json @@ -32190,7 +32190,7 @@ "description": "Move Attribute private channel : WritableLogChannel from class org.neo4j.kernel.impl.transaction.log.BatchingTransactionAppenderConcurrencyTest to private channel : WritableLogChannel from class org.neo4j.kernel.impl.transaction.log.checkpoint.CheckPointerImpl", "comment": "

new

channel still exists in the source class, but as local variable.CheckPointerImpl does not have any relationship with WritableLogChannel

", "validation": "FP", - "detectionTools": "RefactoringMiner, RMiner-1x", + "detectionTools": "RMiner-1x", "validators": "Matin, Davood" }, { "type": "Extract And Move Method", @@ -64494,8 +64494,8 @@ "type": "Move Attribute", "description": "Move Attribute private booleanFilterNormalizer : BooleanFilterNormalizer from class org.infinispan.objectfilter.impl.BaseMatcher to private booleanFilterNormalizer : BooleanFilterNormalizer from class org.infinispan.objectfilter.impl.FilterRegistry", "comment": null, - "validation": "FP", - "detectionTools": "RMiner-1x", + "validation": "TP", + "detectionTools": "RefactoringMiner, RMiner-1x", "validators": "Nikos" }, { "type": "Pull Up Attribute", @@ -83580,10 +83580,10 @@ }, { "type": "Move Attribute", "description": "Move Attribute public station : DockingStation from class buildcraft.api.robots.StackRequest to public station : DockingStation from class buildcraft.robotics.ai.AIRobotSearchStackRequest", - "comment": "

new

DockingStation still exists, it has been moved apparently. It still has statation

", + "comment": "

new

DockingStation still exists, it has been moved apparently. It still has station

", "validation": "FP", - "detectionTools": "RefactoringMiner, RMiner-1x", - "validators": "Matin, Davood" + "detectionTools": "RMiner-1x", + "validators": "Matin, Davood, Nikos" }, { "type": "Rename Parameter", "description": "Rename Parameter i : int to slot : int in method public offerItem(slot int, stack ItemStack) : ItemStack from class buildcraft.builders.TileBuilder", diff --git a/src/test/resources/oracle/expected.txt b/src/test/resources/oracle/expected.txt index 88360ac91..77c91ed05 100644 --- a/src/test/resources/oracle/expected.txt +++ b/src/test/resources/oracle/expected.txt @@ -55,7 +55,7 @@ cfe88fe3fbcc6b02ca55cee7b1f4ab13e249edea, 5, 0, 0 44dea1f292933192ea5287d9b3e14a7daaef3c0f, 5, 0, 0 15afd616cba5fb3d432d11a6de0d4f7805b202db, 8, 0, 0 da29a040ebae664274b28117b157044af0f525fa, 18, 0, 0 -a5cdd8c4b10a738cb44819d7cc2fee5f5965d4a0, 34, 1, 4 +a5cdd8c4b10a738cb44819d7cc2fee5f5965d4a0, 34, 0, 4 14593c6379445f260baeb5287f618758da6d9952, 75, 0, 0 f61db44ca4a862f1a84450643d92f85449016cfa, 8, 0, 0 e3b84c8753a21b1b15cfc9aa90b5e0c56d290f41, 49, 0, 0 @@ -141,7 +141,7 @@ e19c6874431dc2c3046436c2ac249a0ab2ef3457, 2, 0, 0 5a38d0bca0e48853c3f7c00a0f098bada64797df, 42, 0, 1 a26b61201cd86c9a8773b418d9c84b446e95a601, 70, 0, 4 74d2cc420e5590ba3bc0ffcc15b30b76a9cbef0b, 10, 0, 5 -001de307492df8f84ad15f6aaa0bd1e748d4ce27, 161, 3, 7 +001de307492df8f84ad15f6aaa0bd1e748d4ce27, 161, 2, 7 4712de476aabe69cd762233c9641dd3cf9f8361b, 54, 0, 2 dc199688d69416da58b370ca2aa728e935fc8e0d, 25, 1, 0 77fab3caea4495798a248035f0e928f745c7c2db, 91, 0, 2 @@ -248,7 +248,7 @@ ce4b0e22659c16ae83d421f9621fd3e922750764, 2, 0, 0 59fd9e696cec5f2ed44c27422bbc426b11647321, 3, 0, 0 3b1f4e56fea289860b31ef83ccfe96a3a003cc8b, 24, 0, 1 72dda3404820a82d53f1a16bb2ed9ad95f745d3c, 6, 0, 0 -35b6c869546a7968b6fd2f640add6eea87e03c22, 79, 0, 2 +35b6c869546a7968b6fd2f640add6eea87e03c22, 80, 0, 2 4184c577f4bbc57f3ac13639557cfd99cdaca3e7, 4, 0, 0 30c4ae09745d6062077925a54f27205b7401d8df, 288, 0, 4 03573a655bcbb77f7a76d8e22d851cc22796b4f8, 3, 0, 0