Skip to content

Commit

Permalink
Improve the matching of method invocation statements
Browse files Browse the repository at this point in the history
  • Loading branch information
tsantalis committed Apr 21, 2024
1 parent 28da098 commit 66ed3e7
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 38 deletions.
21 changes: 16 additions & 5 deletions src/main/java/gr/uom/java/xmi/decomposition/AbstractCall.java
Original file line number Diff line number Diff line change
Expand Up @@ -526,22 +526,26 @@ else if(this.getExpression() == null && call.getExpression() != null && this.arg
}
}
}
return (this.getName().contains(call.getName()) || call.getName().contains(this.getName()) || (expressionBecomesArgument && commonTokens > 1)) &&
return (oneNameContainsTheOther(call) || (expressionBecomesArgument && commonTokens > 1)) &&
this.arguments.size() > 0 && call.arguments.size() > 0 && (equalArguments(call) || reorderedArguments(call) ||
argumentIntersectionSize(call, replacements, parameterToArgumentMap) == Math.min(this.arguments.size(), call.arguments.size())) &&
((this.getExpression() == null && call.getExpression() != null) || (call.getExpression() == null && this.getExpression() != null));
}

public boolean renamedWithNoExpressionAndArgumentIntersection(AbstractCall call, Set<Replacement> replacements, Map<String, String> parameterToArgumentMap) {
public boolean renamedWithNoExpressionAndArgumentIntersection(AbstractCall call, Set<Replacement> replacements, Map<String, String> parameterToArgumentMap, boolean possiblyRenamedBasedOnClassDiff) {
int argumentIntersectionSize = argumentIntersection(call).size();
return (this.getName().contains(call.getName()) || call.getName().contains(this.getName())) &&
return (oneNameContainsTheOther(call) || (possiblyRenamedBasedOnClassDiff && (equalArguments(call) || commonTokens(call)))) &&
(this.getExpression() == null && call.getExpression() == null) &&
this.arguments.size() > 0 && call.arguments.size() > 0 &&
(argumentIntersectionSize >= Math.floor(Math.min(this.arguments.size(), call.arguments.size())/2) ||
(argumentIntersectionSize > 0 && this.getName().equals("super") && call.getName().equals("super")) ||
argumentIntersectionSize(call, replacements, parameterToArgumentMap) == Math.min(this.arguments.size(), call.arguments.size()));
}

private boolean oneNameContainsTheOther(AbstractCall call) {
return this.getName().contains(call.getName()) || call.getName().contains(this.getName());
}

public boolean renamedWithIdenticalArgumentsAndNoExpression(AbstractCall call, double distance, List<UMLOperationBodyMapper> lambdaMappers) {
boolean allExactLambdaMappers = lambdaMappers.size() > 0;
for(UMLOperationBodyMapper lambdaMapper : lambdaMappers) {
Expand Down Expand Up @@ -578,7 +582,7 @@ private boolean compatibleName(AbstractCall call, double distance) {
return compatibleName(call);
}

public boolean compatibleName(AbstractCall call) {
private boolean commonTokens(AbstractCall call) {
String[] tokens1 = LeafType.CAMEL_CASE_SPLIT_PATTERN.split(this.getName());
String[] tokens2 = LeafType.CAMEL_CASE_SPLIT_PATTERN.split(call.getName());
int commonTokens = 0;
Expand All @@ -592,6 +596,13 @@ public boolean compatibleName(AbstractCall call) {
if(commonTokens == Math.min(tokens1.length, tokens2.length)) {
return true;
}
return false;
}

public boolean compatibleName(AbstractCall call) {
if(commonTokens(call)) {
return true;
}
if(this.loggerExpression() && call.loggerExpression() && this.getExpression().equals(call.getExpression())) {
if(this.matchesLogName() && call.matchesLogName()) {
if(this.arguments().size() == call.arguments().size() && this.arguments().size() == 1) {
Expand Down Expand Up @@ -852,7 +863,7 @@ public boolean identicalWithInlinedStatements(AbstractCall call, Set<Replacement
}

public boolean identicalWithExpressionArgumentSwap(AbstractCall call) {
if(getExpression() != null && call.getExpression() != null && (identicalName(call) || this.getName().contains(call.getName()) || call.getName().contains(this.getName()))) {
if(getExpression() != null && call.getExpression() != null && (identicalName(call) || oneNameContainsTheOther(call))) {
int argumentIndex1 = arguments().indexOf(call.getExpression());
int argumentIndex2 = call.arguments().indexOf(getExpression());
if(argumentIndex1 != -1 && argumentIndex2 != -1 && argumentIndex1 == argumentIndex2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1983,7 +1983,8 @@ else if(invokedOperationsAfter != null && invokedOperationsAfter.size() > 0) {
}
//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)) {
invocationCoveringTheEntireStatement1.renamedWithNoExpressionAndArgumentIntersection(invocationCoveringTheEntireStatement2, replacementInfo.getReplacements(), parameterToArgumentMap,
classDiff != null ? classDiff.matchesPairOfRemovedAddedOperations(invocationCoveringTheEntireStatement1, invocationCoveringTheEntireStatement2, container1, container2) : false)) {
boolean callToAddedOperation = false;
boolean callToDeletedOperation = false;
if(classDiff != null && !invocationCoveringTheEntireStatement1.identicalName(invocationCoveringTheEntireStatement2)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5194,7 +5194,7 @@ else if(pMapping.getFragment1().getLocationInfo().getStartLine() >= first.getFra
for(int i=orderedMappings.size()-1; i>=0; i--) {
AbstractCodeMapping m = orderedMappings.get(i);
if(leaf1.getLocationInfo().subsumes(m.getFragment1().getLocationInfo()) && leaf2.getLocationInfo().subsumes(m.getFragment2().getLocationInfo()) &&
replacementInfo.lambdaMapperContainsMapping(m) && !mappingSet.isEmpty()) {
replacementInfo.lambdaMapperContainsMapping(m)) {
removeMapping(m);
}
else {
Expand Down Expand Up @@ -5617,7 +5617,7 @@ else if(mapping.getFragment1().getLocationInfo().getStartLine() > endMapping.get
for(int i=orderedMappings.size()-1; i>=0; i--) {
AbstractCodeMapping m = orderedMappings.get(i);
if(leaf1.getLocationInfo().subsumes(m.getFragment1().getLocationInfo()) && leaf2.getLocationInfo().subsumes(m.getFragment2().getLocationInfo()) &&
replacementInfo.lambdaMapperContainsMapping(m) && !mappingSet.isEmpty()) {
replacementInfo.lambdaMapperContainsMapping(m)) {
removeMapping(m);
}
else {
Expand Down Expand Up @@ -6003,7 +6003,7 @@ private void checkForOtherPossibleMatchesForFragment2(List<? extends AbstractCod
for(int i=orderedMappings.size()-1; i>=0; i--) {
AbstractCodeMapping m = orderedMappings.get(i);
if(leaf.getLocationInfo().subsumes(m.getFragment1().getLocationInfo()) && leaf2.getLocationInfo().subsumes(m.getFragment2().getLocationInfo()) &&
replacementInfo.lambdaMapperContainsMapping(m) && !mappingSet.isEmpty()) {
replacementInfo.lambdaMapperContainsMapping(m)) {
removeMapping(m);
}
else {
Expand Down Expand Up @@ -6075,7 +6075,7 @@ private void checkForOtherPossibleMatchesForFragment1(List<? extends AbstractCod
for(int i=orderedMappings.size()-1; i>=0; i--) {
AbstractCodeMapping m = orderedMappings.get(i);
if(leaf1.getLocationInfo().subsumes(m.getFragment1().getLocationInfo()) && leaf.getLocationInfo().subsumes(m.getFragment2().getLocationInfo()) &&
replacementInfo.lambdaMapperContainsMapping(m) && !mappingSet.isEmpty()) {
replacementInfo.lambdaMapperContainsMapping(m)) {
removeMapping(m);
}
else {
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/gr/uom/java/xmi/diff/UMLAbstractClassDiff.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import gr.uom.java.xmi.decomposition.AbstractCodeMapping;
import gr.uom.java.xmi.decomposition.CompositeStatementObject;
import gr.uom.java.xmi.decomposition.LeafMapping;
import gr.uom.java.xmi.decomposition.OperationInvocation;
import gr.uom.java.xmi.decomposition.UMLOperationBodyMapper;
import gr.uom.java.xmi.decomposition.VariableDeclaration;
import gr.uom.java.xmi.decomposition.replacement.ConsistentReplacementDetector;
Expand Down Expand Up @@ -1499,4 +1500,28 @@ else if(addedOperation.isSetter()) {
}
return false;
}

public boolean matchesPairOfRemovedAddedOperations(AbstractCall call1, AbstractCall call2, VariableDeclarationContainer container1, VariableDeclarationContainer container2) {
boolean foundInRemoved = false;
if(call1 instanceof OperationInvocation) {
OperationInvocation inv1 = (OperationInvocation)call1;
for(UMLOperation removedOperation : removedOperations) {
if(inv1.matchesOperation(removedOperation, container1, this, modelDiff)) {
foundInRemoved = true;
break;
}
}
}
boolean foundInAdded = false;
if(call2 instanceof OperationInvocation) {
OperationInvocation inv2 = (OperationInvocation)call2;
for(UMLOperation addedOperation : addedOperations) {
if(inv2.matchesOperation(addedOperation, container2, this, modelDiff)) {
foundInAdded = true;
break;
}
}
}
return foundInRemoved && foundInAdded;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,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(12165, 20, 238);
test.assertExpectationsWithGitHubAPI(12172, 20, 238);
}
}
118 changes: 94 additions & 24 deletions src/test/resources/oracle/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -32913,20 +32913,6 @@
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Extract Variable",
"description": "Extract Variable fileSystemAbstraction : FileSystemAbstraction in method public shouldBeAbleToRecoverBrokenStore() : void from class org.neo4j.kernel.impl.recovery.TestStoreRecoverer",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Extract Variable",
"description": "Extract Variable fileSystemAbstraction : FileSystemAbstraction in method public shouldWantToRecoverBrokenStore() : void from class org.neo4j.kernel.impl.recovery.TestStoreRecoverer",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Rename Attribute",
"description": "Rename Attribute legacyindexTransactionOrdering : IdOrderingQueue to legacyIndexTransactionOrdering : IdOrderingQueue in class org.neo4j.kernel.impl.transaction.log.BatchingTransactionAppenderConcurrencyTest",
Expand Down Expand Up @@ -33074,6 +33060,62 @@
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Rename Method",
"description": "Rename Method public createLogFileForNextVersionWithSomeDataInIt(store File, fileSystem FileSystemAbstraction) : void renamed to private createSomeDataAndCrash(store File, fileSystem EphemeralFileSystemAbstraction) : FileSystemAbstraction in class org.neo4j.kernel.impl.recovery.TestStoreRecoverer",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Change Return Type",
"description": "Change Return Type void to FileSystemAbstraction in method private createSomeDataAndCrash(store File, fileSystem EphemeralFileSystemAbstraction) : FileSystemAbstraction from class org.neo4j.kernel.impl.recovery.TestStoreRecoverer",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Change Method Access Modifier",
"description": "Change Method Access Modifier public to private in method private createSomeDataAndCrash(store File, fileSystem EphemeralFileSystemAbstraction) : FileSystemAbstraction from class org.neo4j.kernel.impl.recovery.TestStoreRecoverer",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Remove Method Modifier",
"description": "Remove Method Modifier static in method public createLogFileForNextVersionWithSomeDataInIt(store File, fileSystem FileSystemAbstraction) : void from class org.neo4j.kernel.impl.recovery.TestStoreRecoverer",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Change Parameter Type",
"description": "Change Parameter Type fileSystem : FileSystemAbstraction to fileSystem : EphemeralFileSystemAbstraction in method private createSomeDataAndCrash(store File, fileSystem EphemeralFileSystemAbstraction) : FileSystemAbstraction from class org.neo4j.kernel.impl.recovery.TestStoreRecoverer",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Rename Variable",
"description": "Rename Variable life : LifeSupport to db : GraphDatabaseService in method private createSomeDataAndCrash(store File, fileSystem EphemeralFileSystemAbstraction) : FileSystemAbstraction from class org.neo4j.kernel.impl.recovery.TestStoreRecoverer",
"comment": null,
"validation": "CTP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Change Variable Type",
"description": "Change Variable Type life : LifeSupport to db : GraphDatabaseService in method private createSomeDataAndCrash(store File, fileSystem EphemeralFileSystemAbstraction) : FileSystemAbstraction from class org.neo4j.kernel.impl.recovery.TestStoreRecoverer",
"comment": null,
"validation": "CTP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Add Variable Modifier",
"description": "Add Variable Modifier final in variable db : GraphDatabaseService in method private createSomeDataAndCrash(store File, fileSystem EphemeralFileSystemAbstraction) : FileSystemAbstraction from class org.neo4j.kernel.impl.recovery.TestStoreRecoverer",
"comment": null,
"validation": "CTP",
"detectionTools": "RefactoringMiner",
"validators": null
}],
"refDiffExecutionTime": 11758
}, {
Expand Down Expand Up @@ -50364,16 +50406,16 @@
"type": "Extract Method",
"description": "Extract Method private rescueMembersAndInstantiateSuperInterfaces(type JDeclaredType) : void extracted from public visit(type JInterfaceType, ctx Context) : boolean in class com.google.gwt.dev.jjs.impl.ControlFlowAnalyzer.RescueVisitor",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner, RefDiff, RD-1x, RD-2x, RMiner-1x",
"validators": null
"validation": "FP",
"detectionTools": "RefDiff, RD-1x, RD-2x, RMiner-1x",
"validators": "Nikos"
}, {
"type": "Extract Method",
"description": "Extract Method private rescueMembersAndInstantiateSuperInterfaces(type JDeclaredType) : void extracted from public visit(type JClassType, ctx Context) : boolean in class com.google.gwt.dev.jjs.impl.ControlFlowAnalyzer.RescueVisitor",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner, RefDiff, RD-1x, RD-2x, RMiner-1x",
"validators": null
"validation": "FP",
"detectionTools": "RefDiff, RD-1x, RD-2x, RMiner-1x",
"validators": "Nikos"
}, {
"type": "Rename Method",
"description": "Rename Method public _disabled_testJsType3DimArray_castedFromNativeWithACall() : void renamed to public __disabled__testJsType3DimArray_castedFromNativeWithACall() : void in class com.google.gwt.core.client.interop.JsTypeArrayTest",
Expand All @@ -50384,10 +50426,10 @@
}, {
"type": "Rename Method",
"description": "Rename Method private rescueMembersIfInstantiable(type JDeclaredType) : void renamed to private rescueMembers(type JDeclaredType) : void in class com.google.gwt.dev.jjs.impl.ControlFlowAnalyzer.RescueVisitor",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner, RefDiff, GumTreeDiff, RD-1x, RD-2x, RMiner-1x",
"validators": null
"comment": "<p>Rename Method private rescueMembersIfInstantiable(type JDeclaredType) : void renamed to private rescueMembersAndInstantiateSuperInterfaces(type JDeclaredType) : void in class com.google.gwt.dev.jjs.impl.ControlFlowAnalyzer.RescueVisitor</p>",
"validation": "FP",
"detectionTools": "RefDiff, GumTreeDiff, RD-1x, RD-2x, RMiner-1x",
"validators": "Nikos"
}, {
"type": "Rename Method",
"description": "Rename Method public _disabled_testJsTypeArray_returnFromNativeWithACall() : void renamed to public testJsTypeArray_returnFromNativeWithACall() : void in class com.google.gwt.core.client.interop.JsTypeArrayTest",
Expand Down Expand Up @@ -50507,6 +50549,20 @@
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Rename Method",
"description": "Rename Method private rescueMembersIfInstantiable(type JDeclaredType) : void renamed to private rescueMembersAndInstantiateSuperInterfaces(type JDeclaredType) : void in class com.google.gwt.dev.jjs.impl.ControlFlowAnalyzer.RescueVisitor",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Extract Method",
"description": "Extract Method private rescueMembers(type JDeclaredType) : void extracted from private rescueMembersIfInstantiable(type JDeclaredType) : void in class com.google.gwt.dev.jjs.impl.ControlFlowAnalyzer.RescueVisitor",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}],
"refDiffExecutionTime": 6656
}, {
Expand Down Expand Up @@ -109190,6 +109246,20 @@
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Change Variable Type",
"description": "Change Variable Type size : long to size : int in method public unpackBytes() : byte[] from class org.neo4j.packstream.PackStream.Unpacker",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}, {
"type": "Change Variable Type",
"description": "Change Variable Type size : long to size : int in method public unpackUTF8() : byte[] from class org.neo4j.packstream.PackStream.Unpacker",
"comment": null,
"validation": "TP",
"detectionTools": "RefactoringMiner",
"validators": null
}],
"refDiffExecutionTime": 3709
}, {
Expand Down
6 changes: 3 additions & 3 deletions src/test/resources/oracle/expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ d0e374ce8ecb687b4dc046d1edea9e52da17706f, 11, 0, 0
4aa2e8746b5492bbc1cf2b36af956cf3b01e40f5, 155, 0, 2
e0dda9f61b7c409944c4734edf75b108e0288f59, 4, 0, 0
200f1577d238a6d3fbcf99cb2a2585b2071214a6, 9, 0, 0
22fb2c9c6974bd1fe0f6ff684f52e6cfbed1a387, 17, 0, 0
22fb2c9c6974bd1fe0f6ff684f52e6cfbed1a387, 16, 0, 0
1768840bf1e69892fd2a23776817f620edfed536, 17, 0, 0
a9ca2efae56815dc464189b055ffe9da23766f7f, 3, 0, 0
1bc7905b07821f840068089343e6b77a8686d1ab, 4, 0, 0
Expand All @@ -141,13 +141,13 @@ e19c6874431dc2c3046436c2ac249a0ab2ef3457, 2, 0, 0
5a38d0bca0e48853c3f7c00a0f098bada64797df, 42, 0, 1
a26b61201cd86c9a8773b418d9c84b446e95a601, 70, 0, 4
74d2cc420e5590ba3bc0ffcc15b30b76a9cbef0b, 10, 0, 5
001de307492df8f84ad15f6aaa0bd1e748d4ce27, 154, 3, 8
001de307492df8f84ad15f6aaa0bd1e748d4ce27, 160, 3, 8
4712de476aabe69cd762233c9641dd3cf9f8361b, 53, 0, 2
dc199688d69416da58b370ca2aa728e935fc8e0d, 24, 1, 0
77fab3caea4495798a248035f0e928f745c7c2db, 91, 0, 2
d1a6ae2a16ba1d53b1de02eea8745d67c6a1a005, 8, 0, 0
8d9bedbf96b14beb027ebc1338bc6d5750e1feb5, 223, 0, 4
e0072aac53b3b88de787e7ca653c7e17f9499018, 51, 0, 2
e0072aac53b3b88de787e7ca653c7e17f9499018, 53, 0, 2
03ece4f24163204d8a3948eb53576f1feaa86a61, 11, 0, 2
b83e6a535cbca21d5ea764b0c49bfca8a9ff9db4, 29, 0, 0
03ade425dd5a65d3a713d5e7d85aa7605956fbd2, 46, 3, 0
Expand Down

0 comments on commit 66ed3e7

Please sign in to comment.