Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.refactoringminer.astDiff.matchers;
import com.github.gumtreediff.matchers.MappingStore;
import com.github.gumtreediff.matchers.Matcher;
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 org.refactoringminer.astDiff.utils.TreeUtilFunctions;
import java.util.*;
/**
* @author Pourya Alikhani Fard [email protected]
* @since 2022-12-27 8:46 p.m.
*/
public class CustomBottomUpMatcher implements Matcher {
public CustomBottomUpMatcher() {
}
@Override
public MappingStore match(Tree src, Tree dst, MappingStore mappings) {
for (Tree t : src.postOrder()) {
if (t.isRoot()) {
if (t.getType().name.equals(dst.getType().name))
{
if (!mappings.isSrcMapped(t) && !mappings.isDstMapped(dst))
mappings.addMapping(t, dst);
}
lastChanceMatch(mappings, t, dst);
break;
}
else if (!(mappings.isSrcMapped(t) || t.isLeaf())) {
List candidates = getDstCandidates(mappings, t);
Tree best = null;
var max = -1D;
var tSize = t.getDescendants().size();
for (var candidate : candidates) {
var threshold = 1D / (1D + Math.log(candidate.getDescendants().size() + tSize));
var sim = SimilarityMetrics.chawatheSimilarity(t, candidate, mappings);
if (sim > max && sim >= threshold) {
max = sim;
best = candidate;
}
}
if (best != null) {
lastChanceMatch(mappings, t, best);
boolean checkOperatorOfInfixExpression = checkInfixExpression(mappings, t, best);
if (checkOperatorOfInfixExpression)
mappings.addMapping(t, best);
}
}
else if (mappings.isSrcMapped(t) && mappings.hasUnmappedSrcChildren(t)
&& mappings.hasUnmappedDstChildren(mappings.getDstForSrc(t)))
lastChanceMatch(mappings, t, mappings.getDstForSrc(t));
}
return mappings;
}
private static boolean checkInfixExpression(MappingStore mappings, Tree t, Tree best) {
boolean checkOperatorOfInfixExpression = true;
if (t.getType().name.equals(Constants.INFIX_EXPRESSION))
{
checkOperatorOfInfixExpression = false;
Tree a = TreeUtilFunctions.findChildByType(t, Constants.INFIX_EXPRESSION_OPERATOR);
Tree b = TreeUtilFunctions.findChildByType(best, Constants.INFIX_EXPRESSION_OPERATOR);
if (mappings.getDstForSrc(a) == b) checkOperatorOfInfixExpression = true;
}
return checkOperatorOfInfixExpression;
}
protected List getDstCandidates(MappingStore mappings, Tree src) {
List seeds = new ArrayList<>();
for (Tree c : src.getDescendants()) {
Tree m = mappings.getDstForSrc(c);
if (m != null)
seeds.add(m);
}
List candidates = new ArrayList<>();
Set visited = new HashSet<>();
for (var seed : seeds) {
while (seed.getParent() != null) {
var parent = seed.getParent();
if (visited.contains(parent))
break;
visited.add(parent);
if (parent.getType() == src.getType() && !mappings.isDstMapped(parent) && !parent.isRoot())
candidates.add(parent);
seed = parent;
}
}
return candidates;
}
protected void lastChanceMatch(MappingStore mappings, Tree src, Tree dst) {
lcsEqualMatching(mappings, src, dst);
lcsStructureMatching(mappings, src, dst);
histogramMatching(mappings, src, dst);
}
protected void lcsEqualMatching(MappingStore mappings, Tree src, Tree dst) {
List unmappedSrcChildren = new ArrayList<>();
for (Tree c : src.getChildren())
if (!mappings.isSrcMapped(c))
unmappedSrcChildren.add(c);
List unmappedDstChildren = new ArrayList<>();
for (Tree c : dst.getChildren())
if (!mappings.isDstMapped(c))
unmappedDstChildren.add(c);
List lcs = SequenceAlgorithms.longestCommonSubsequenceWithIsomorphism(
unmappedSrcChildren, unmappedDstChildren);
for (int[] x : lcs) {
var t1 = unmappedSrcChildren.get(x[0]);
var t2 = unmappedDstChildren.get(x[1]);
if (mappings.areSrcsUnmapped(TreeUtils.preOrder(t1)) && mappings.areDstsUnmapped(
TreeUtils.preOrder(t2)))
mappings.addMappingRecursively(t1, t2);
}
}
protected void lcsStructureMatching(MappingStore mappings, Tree src, Tree dst) {
List unmappedSrcChildren = new ArrayList<>();
for (Tree c : src.getChildren())
if (!mappings.isSrcMapped(c))
unmappedSrcChildren.add(c);
List unmappedDstChildren = new ArrayList<>();
for (Tree c : dst.getChildren())
if (!mappings.isDstMapped(c))
unmappedDstChildren.add(c);
List lcs = SequenceAlgorithms.longestCommonSubsequenceWithIsostructure(
unmappedSrcChildren, unmappedDstChildren);
for (int[] x : lcs) {
var t1 = unmappedSrcChildren.get(x[0]);
var t2 = unmappedDstChildren.get(x[1]);
if (mappings.areSrcsUnmapped(
TreeUtils.preOrder(t1)) && mappings.areDstsUnmapped(TreeUtils.preOrder(t2)))
mappings.addMappingRecursively(t1, t2);
}
}
protected void histogramMatching(MappingStore mappings, Tree src, Tree dst) {
Map> srcHistogram = new HashMap<>();
for (var c : src.getChildren()) {
if (mappings.isSrcMapped(c))
continue;
srcHistogram.putIfAbsent(c.getType(), new ArrayList<>());
srcHistogram.get(c.getType()).add(c);
}
Map> dstHistogram = new HashMap<>();
for (var c : dst.getChildren()) {
if (mappings.isDstMapped(c))
continue;
dstHistogram.putIfAbsent(c.getType(), new ArrayList<>());
dstHistogram.get(c.getType()).add(c);
}
for (Type t : srcHistogram.keySet()) {
if (dstHistogram.containsKey(t) && srcHistogram.get(t).size() == 1 && dstHistogram.get(t).size() == 1) {
var srcChild = srcHistogram.get(t).get(0);
var dstChild = dstHistogram.get(t).get(0);
mappings.addMapping(srcChild, dstChild);
lastChanceMatch(mappings, srcChild, dstChild);
}
}
}
}