forked from tsantalis/RefactoringMiner
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Modify the TreeMatcher interface and update the subclasses accordingly
- Loading branch information
1 parent
b58854e
commit b4fe6ce
Showing
7 changed files
with
129 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 34 additions & 21 deletions
55
src/org/refactoringminer/astDiff/matchers/BasicTreeMatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,54 @@ | ||
package org.refactoringminer.astDiff.matchers; | ||
|
||
import com.github.gumtreediff.matchers.Mapping; | ||
import com.github.gumtreediff.matchers.MappingStore; | ||
import com.github.gumtreediff.matchers.SimilarityMetrics; | ||
import com.github.gumtreediff.tree.Tree; | ||
import com.github.gumtreediff.tree.TreeUtils; | ||
import com.github.gumtreediff.tree.Type; | ||
import com.github.gumtreediff.utils.SequenceAlgorithms; | ||
import gr.uom.java.xmi.decomposition.AbstractCodeFragment; | ||
import gr.uom.java.xmi.decomposition.AbstractCodeMapping; | ||
import com.github.gumtreediff.utils.Pair; | ||
import org.refactoringminer.astDiff.utils.TreeUtilFunctions; | ||
|
||
import java.util.*; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import static org.refactoringminer.astDiff.matchers.LeafMatcher.extracted; | ||
|
||
/** | ||
* @author Pourya Alikhani Fard [email protected] | ||
*/ | ||
public class BasicTreeMatcher implements TreeMatcher { | ||
|
||
@Override | ||
public void match(Tree src, Tree dst, AbstractCodeMapping abstractCodeMapping, ExtendedMultiMappingStore mappingStore) { | ||
public void match(Tree src, Tree dst, ExtendedMultiMappingStore mappingStore) { | ||
basicMatcher(src, dst, mappingStore); | ||
} | ||
@Override | ||
public void match(Tree src, Tree dst, AbstractCodeFragment abstractCodeFragment1, AbstractCodeFragment abstractCodeFragment2, ExtendedMultiMappingStore mappingStore) { | ||
basicMatcher(src, dst, mappingStore); | ||
private void basicMatcher(Tree src, Tree dst, ExtendedMultiMappingStore mappingStore) { | ||
mappingStore.add(apply(src, dst)); | ||
} | ||
|
||
|
||
private void basicMatcher(Tree src, Tree dst, ExtendedMultiMappingStore mappingStore) { | ||
try { | ||
MappingStore match = extracted(src, dst); | ||
mappingStore.add(match); | ||
public MappingStore apply(Tree src, Tree dst) { | ||
MappingStore match; | ||
match = new CustomGreedy(0, false).match(src, dst); | ||
CustomBottomUpMatcher customBottomUpMatcher = new CustomBottomUpMatcher(); | ||
customBottomUpMatcher.match(src, dst, match); | ||
List<Pair<Tree, Tree>> removeList = new ArrayList<>(); | ||
for (Mapping mapping : match) { | ||
if (mapping.first.getType().name.equals(Constants.METHOD_INVOCATION)) { | ||
Tree srcMethodName = TreeUtilFunctions.findChildByType(mapping.first, Constants.SIMPLE_NAME); | ||
Tree dstMethodName = TreeUtilFunctions.findChildByType(mapping.second, Constants.SIMPLE_NAME); | ||
if (srcMethodName == null || dstMethodName == null) continue; | ||
if (!srcMethodName.getLabel().equals(dstMethodName.getLabel())) { | ||
Tree srcMethodInvocationReceiver = TreeUtilFunctions.findChildByType(mapping.first, Constants.METHOD_INVOCATION_RECEIVER); | ||
Tree dstMethodInvocationReceiver = TreeUtilFunctions.findChildByType(mapping.second, Constants.METHOD_INVOCATION_RECEIVER); | ||
if ((srcMethodInvocationReceiver == null && dstMethodInvocationReceiver != null) | ||
|| | ||
(srcMethodInvocationReceiver != null && dstMethodInvocationReceiver == null)) { | ||
removeList.add(new Pair<>(mapping.first, mapping.second)); | ||
removeList.add(new Pair<>(srcMethodName, dstMethodName)); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
catch (Exception exception) | ||
{ | ||
System.out.println(exception.getMessage()); | ||
for (Pair<Tree, Tree> treeTreePair : removeList) { | ||
match.removeMapping(treeTreePair.first, treeTreePair.second); | ||
} | ||
return match; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,67 +11,48 @@ | |
/** | ||
* @author Pourya Alikhani Fard [email protected] | ||
*/ | ||
public class CompositeMatcher implements TreeMatcher { | ||
public class CompositeMatcher extends BasicTreeMatcher implements TreeMatcher { | ||
|
||
private final CompositeStatementObject fragment1; | ||
private final CompositeStatementObject fragment2; | ||
|
||
public CompositeMatcher(AbstractCodeMapping abstractCodeMapping) { | ||
CompositeStatementObjectMapping compositeStatementObjectMapping = (CompositeStatementObjectMapping) abstractCodeMapping; | ||
fragment1 = (CompositeStatementObject) compositeStatementObjectMapping.getFragment1(); | ||
fragment2 = (CompositeStatementObject) compositeStatementObjectMapping.getFragment2(); | ||
} | ||
|
||
public CompositeMatcher(CompositeStatementObject fragment1, CompositeStatementObject fragment2) { | ||
this.fragment1 = fragment1; | ||
this.fragment2 = fragment2; | ||
} | ||
|
||
@Override | ||
public void match(Tree src, Tree dst, AbstractCodeMapping abstractCodeMapping, ExtendedMultiMappingStore mappingStore) { | ||
public void match(Tree src, Tree dst, ExtendedMultiMappingStore mappingStore) { | ||
String labeled = Constants.LABELED_STATEMENT; | ||
if (src.getType().name.equals(labeled) && dst.getType().name.equals(labeled)) | ||
mappingStore.addMapping(src.getChild(0),dst.getChild(0)); | ||
else | ||
compositeMatcher(src,dst,abstractCodeMapping,mappingStore); | ||
} | ||
|
||
@Override | ||
public void match(Tree src, Tree dst, AbstractCodeFragment st1, AbstractCodeFragment st2, ExtendedMultiMappingStore mappingStore) { | ||
if ((st1 instanceof CompositeStatementObject) && (st2 instanceof CompositeStatementObject)) { | ||
compositeMatcher(src, dst, (CompositeStatementObject) st1, (CompositeStatementObject) st2, mappingStore); | ||
return; | ||
} | ||
//Corner cases; | ||
if (!(st1 instanceof CompositeStatementObject) && | ||
(st2 instanceof CompositeStatementObject)) { | ||
CompositeStatementObject fragment2 = (CompositeStatementObject) st2; | ||
for (AbstractExpression expression : fragment2.getExpressions()) { | ||
Tree dstExpTree = TreeUtilFunctions.findByLocationInfo(dst, expression.getLocationInfo()); | ||
new LeafMatcher(false).match(src,dstExpTree,st1,expression,mappingStore); | ||
} | ||
} else if ((st1 instanceof CompositeStatementObject) && | ||
!(st2 instanceof CompositeStatementObject)) { | ||
CompositeStatementObject fragment1 = (CompositeStatementObject) st1; | ||
for (AbstractExpression expression : fragment1.getExpressions()) { | ||
Tree srcExpTree = TreeUtilFunctions.findByLocationInfo(src, expression.getLocationInfo()); | ||
new LeafMatcher(false).match(srcExpTree,dst,expression,st2,mappingStore); | ||
} | ||
} | ||
|
||
process(src,dst,mappingStore); | ||
} | ||
|
||
private void compositeMatcher(Tree src, Tree dst, AbstractCodeMapping abstractCodeMapping, ExtendedMultiMappingStore mappingStore) { | ||
CompositeStatementObjectMapping compositeStatementObjectMapping = (CompositeStatementObjectMapping) abstractCodeMapping; | ||
CompositeStatementObject fragment1 = (CompositeStatementObject) compositeStatementObjectMapping.getFragment1(); | ||
CompositeStatementObject fragment2 = (CompositeStatementObject) compositeStatementObjectMapping.getFragment2(); | ||
process(src, dst, mappingStore, fragment1, fragment2); | ||
} | ||
|
||
private void process(Tree src, Tree dst, ExtendedMultiMappingStore mappingStore, CompositeStatementObject fragment1, CompositeStatementObject fragment2) { | ||
private void process(Tree src, Tree dst, ExtendedMultiMappingStore mappingStore) { | ||
Map<Tree, Tree> cpyToSrc = new HashMap<>(); | ||
Map<Tree, Tree> cpyToDst = new HashMap<>(); | ||
Tree srcFakeTree = makeFakeTree(src,fragment1, cpyToSrc); | ||
Tree dstFakeTree = makeFakeTree(dst,fragment2, cpyToDst); | ||
ExtendedMultiMappingStore tempMapping = new ExtendedMultiMappingStore(null,null); | ||
new BasicTreeMatcher().match(srcFakeTree,dstFakeTree,null,tempMapping); | ||
super.match(srcFakeTree,dstFakeTree,tempMapping); | ||
for(Mapping mapping : tempMapping) { | ||
if (mapping.first == srcFakeTree) continue; | ||
mappingStore.addMapping(cpyToSrc.get(mapping.first), cpyToDst.get(mapping.second)); | ||
} | ||
} | ||
|
||
private void compositeMatcher(Tree src, Tree dst, CompositeStatementObject fragment1, CompositeStatementObject fragment2, ExtendedMultiMappingStore mappingStore) { | ||
process(src, dst, mappingStore, fragment1, fragment2); | ||
private void compositeMatcher(Tree src, Tree dst, ExtendedMultiMappingStore mappingStore) { | ||
process(src, dst, mappingStore); | ||
} | ||
|
||
private Tree makeFakeTree(Tree tree, CompositeStatementObject fragment, Map<Tree, Tree> cpyMap) { | ||
private static Tree makeFakeTree(Tree tree, CompositeStatementObject fragment, Map<Tree, Tree> cpyMap) { | ||
Tree cpy = TreeUtilFunctions.makeDefaultTree(tree); | ||
cpyMap.put(cpy,tree); | ||
for (AbstractExpression abstractExpression : fragment.getExpressions()) { | ||
|
44 changes: 44 additions & 0 deletions
44
src/org/refactoringminer/astDiff/matchers/GeneralTreeMatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package org.refactoringminer.astDiff.matchers; | ||
|
||
import com.github.gumtreediff.tree.Tree; | ||
import gr.uom.java.xmi.decomposition.AbstractCodeFragment; | ||
import gr.uom.java.xmi.decomposition.AbstractExpression; | ||
import gr.uom.java.xmi.decomposition.CompositeStatementObject; | ||
import org.refactoringminer.astDiff.utils.TreeUtilFunctions; | ||
|
||
/* Created by pourya on 2023-04-25 1:08 p.m. */ | ||
public class GeneralTreeMatcher extends BasicTreeMatcher implements TreeMatcher { | ||
AbstractCodeFragment st1; | ||
AbstractCodeFragment st2; | ||
|
||
public GeneralTreeMatcher(AbstractCodeFragment st1, AbstractCodeFragment st2) { | ||
this.st1 = st1; | ||
this.st2 = st2; | ||
} | ||
@Override | ||
public void match(Tree src, Tree dst, ExtendedMultiMappingStore mappingStore) { | ||
if ((st1 instanceof CompositeStatementObject) && (st2 instanceof CompositeStatementObject)) { | ||
new CompositeMatcher((CompositeStatementObject) st1, (CompositeStatementObject) st2) | ||
.match(src, dst, mappingStore); | ||
return; | ||
} | ||
//Corner cases; | ||
if (!(st1 instanceof CompositeStatementObject) && | ||
(st2 instanceof CompositeStatementObject)) { | ||
CompositeStatementObject fragment2 = (CompositeStatementObject) st2; | ||
for (AbstractExpression expression : fragment2.getExpressions()) { | ||
Tree dstExpTree = TreeUtilFunctions.findByLocationInfo(dst, expression.getLocationInfo()); | ||
new LeafMatcher(false).match(src,dstExpTree,mappingStore); | ||
} | ||
} else if ((st1 instanceof CompositeStatementObject) && | ||
!(st2 instanceof CompositeStatementObject)) { | ||
CompositeStatementObject fragment1 = (CompositeStatementObject) st1; | ||
for (AbstractExpression expression : fragment1.getExpressions()) { | ||
Tree srcExpTree = TreeUtilFunctions.findByLocationInfo(src, expression.getLocationInfo()); | ||
new LeafMatcher(false).match(srcExpTree,dst,mappingStore); | ||
} | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,25 @@ | ||
package org.refactoringminer.astDiff.matchers; | ||
|
||
import com.github.gumtreediff.matchers.Mapping; | ||
import com.github.gumtreediff.matchers.MappingStore; | ||
import com.github.gumtreediff.tree.Tree; | ||
import com.github.gumtreediff.utils.Pair; | ||
import gr.uom.java.xmi.decomposition.AbstractCodeFragment; | ||
import gr.uom.java.xmi.decomposition.AbstractCodeMapping; | ||
import gr.uom.java.xmi.decomposition.LeafMapping; | ||
import org.refactoringminer.astDiff.utils.TreeUtilFunctions; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** | ||
* @author Pourya Alikhani Fard [email protected] | ||
*/ | ||
public class LeafMatcher implements TreeMatcher { | ||
public class LeafMatcher extends BasicTreeMatcher implements TreeMatcher { | ||
private final boolean overwrite; | ||
|
||
public LeafMatcher(boolean overwrite) { | ||
this.overwrite = overwrite; | ||
} | ||
|
||
@Override | ||
public void match(Tree src, Tree dst, AbstractCodeMapping abstractCodeMapping, ExtendedMultiMappingStore mappingStore) { | ||
//if (abstractCodeMapping != null) | ||
// if (abstractCodeMapping.getFragment1() instanceof AbstractExpression || abstractCodeMapping.getFragment2() instanceof AbstractExpression) | ||
// return; | ||
public void match(Tree src, Tree dst, ExtendedMultiMappingStore mappingStore) { | ||
if (src == null || dst == null) return; | ||
Map<Tree,Tree> srcCopy = new HashMap<>(); | ||
Map<Tree,Tree> dstCopy = new HashMap<>(); | ||
|
@@ -41,7 +32,7 @@ public void match(Tree src, Tree dst, AbstractCodeMapping abstractCodeMapping, E | |
match.addMappingRecursively(prunedPair.first, prunedPair.second); | ||
} | ||
else { | ||
match = extracted(prunedPair.first, prunedPair.second); | ||
match = apply(prunedPair.first, prunedPair.second); | ||
} | ||
if (!overwrite) | ||
mappingStore.addWithMaps(match, srcCopy, dstCopy); | ||
|
@@ -53,42 +44,6 @@ public void match(Tree src, Tree dst, AbstractCodeMapping abstractCodeMapping, E | |
System.out.println(exception.getMessage()); | ||
} | ||
} | ||
|
||
public static MappingStore extracted(Tree src, Tree dst) { | ||
MappingStore match; | ||
match = new CustomGreedy(0, false).match(src, dst); | ||
CustomBottomUpMatcher customBottomUpMatcher = new CustomBottomUpMatcher(); | ||
customBottomUpMatcher.match(src, dst, match); | ||
List<Pair<Tree, Tree>> removeList = new ArrayList<>(); | ||
for (Mapping mapping : match) { | ||
if (mapping.first.getType().name.equals(Constants.METHOD_INVOCATION)) { | ||
Tree srcMethodName = TreeUtilFunctions.findChildByType(mapping.first, Constants.SIMPLE_NAME); | ||
Tree dstMethodName = TreeUtilFunctions.findChildByType(mapping.second, Constants.SIMPLE_NAME); | ||
if (srcMethodName == null || dstMethodName == null) continue; | ||
if (!srcMethodName.getLabel().equals(dstMethodName.getLabel())) { | ||
Tree srcMethodInvocationReceiver = TreeUtilFunctions.findChildByType(mapping.first, Constants.METHOD_INVOCATION_RECEIVER); | ||
Tree dstMethodInvocationReceiver = TreeUtilFunctions.findChildByType(mapping.second, Constants.METHOD_INVOCATION_RECEIVER); | ||
if ((srcMethodInvocationReceiver == null && dstMethodInvocationReceiver != null) | ||
|| | ||
(srcMethodInvocationReceiver != null && dstMethodInvocationReceiver == null)) { | ||
removeList.add(new Pair<>(mapping.first, mapping.second)); | ||
removeList.add(new Pair<>(srcMethodName, dstMethodName)); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
for (Pair<Tree, Tree> treeTreePair : removeList) { | ||
match.removeMapping(treeTreePair.first, treeTreePair.second); | ||
} | ||
return match; | ||
} | ||
|
||
@Override | ||
public void match(Tree src, Tree dst, AbstractCodeFragment abstractCodeFragment1, AbstractCodeFragment abstractCodeFragment2, ExtendedMultiMappingStore mappingStore) { | ||
this.match(src,dst, new LeafMapping(abstractCodeFragment1, abstractCodeFragment2, null, null), mappingStore); | ||
} | ||
|
||
public Pair<Tree,Tree> pruneTrees(Tree src, Tree dst, Map<Tree,Tree> srcCopy, Map<Tree,Tree> dstCopy) { | ||
Tree prunedSrc = TreeUtilFunctions.deepCopyWithMapPruning(src,srcCopy); | ||
Tree prunedDst = TreeUtilFunctions.deepCopyWithMapPruning(dst,dstCopy); | ||
|
Oops, something went wrong.