Please wait. This can take some minutes ...
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.
org.refactoringminer.astDiff.matchers.ProjectASTDiffer Maven / Gradle / Ivy
package org.refactoringminer.astDiff.matchers;
import com.github.gumtreediff.tree.Tree;
import com.github.gumtreediff.tree.TreeContext;
import com.github.gumtreediff.utils.Pair;
import gr.uom.java.xmi.*;
import gr.uom.java.xmi.LocationInfo.CodeElementType;
import gr.uom.java.xmi.decomposition.*;
import gr.uom.java.xmi.decomposition.replacement.CompositeReplacement;
import gr.uom.java.xmi.decomposition.replacement.Replacement;
import gr.uom.java.xmi.diff.*;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.refactoringminer.api.Refactoring;
import org.refactoringminer.api.RefactoringMinerTimedOutException;
import org.refactoringminer.api.RefactoringType;
import org.refactoringminer.astDiff.actions.ASTDiff;
import org.refactoringminer.astDiff.actions.ProjectASTDiff;
import org.refactoringminer.astDiff.utils.TreeUtilFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Pourya Alikhani Fard [email protected]
*/
public class ProjectASTDiffer
{
private final static Logger logger = LoggerFactory.getLogger(ProjectASTDiffer.class);
private final UMLModelDiff modelDiff;
private List lastStepMappings;
private ExtendedMultiMappingStore optimizationMappingStore;
private List modelDiffRefactorings;
private final ProjectASTDiff projectASTDiff;
public ProjectASTDiffer(UMLModelDiff modelDiff, Map fileContentsBefore, Map fileContentsAfter) throws RefactoringMinerTimedOutException {
this.modelDiff = modelDiff;
this.projectASTDiff = new ProjectASTDiff(fileContentsBefore, fileContentsAfter);
diff();
}
public ProjectASTDiff getProjectASTDiff() {
return projectASTDiff;
}
//kept for backward compatibility, but getProjectASTDiff() should be used instead
public Set getDiffSet() {
return projectASTDiff.getDiffSet();
}
private void diff() throws RefactoringMinerTimedOutException {
long start = System.currentTimeMillis();
this.modelDiffRefactorings = modelDiff.getRefactorings();
long finish = System.currentTimeMillis();
logger.info("ModelDiff.getRefactorings() execution time: " + (finish - start)/ 1000 + " seconds");
projectASTDiff.setRefactorings(this.modelDiffRefactorings);
long diff_execution_started = System.currentTimeMillis();
makeASTDiff(modelDiff.getCommonClassDiffList(),false);
makeASTDiff(modelDiff.getClassRenameDiffList(),false);
makeASTDiff(modelDiff.getClassMoveDiffList(),false);
makeASTDiff(modelDiff.getInnerClassMoveDiffList(),true);
makeASTDiff(getExtraDiffs(),true);
long diff_execution_finished = System.currentTimeMillis();
logger.info("Diff execution: " + (diff_execution_finished - diff_execution_started)/ 1000 + " seconds");
for (ASTDiff diff : projectASTDiff.getDiffSet()) {
processOptimization(diff, optimizationDataMap.get(diff.getSrcPath()));
}
for (ASTDiff diff : projectASTDiff.getDiffSet()) {
new MissingIdenticalSubtree().match(diff.src.getRoot(), diff.dst.getRoot(), diff.getAllMappings());
}
computeAllEditScripts();
}
private List extends UMLAbstractClassDiff> getExtraDiffs() {
List extraDiffs = new ArrayList<>();
for (Refactoring modelDiffRefactoring : modelDiffRefactorings) {
if ((modelDiffRefactoring.getRefactoringType() == RefactoringType.REPLACE_ANONYMOUS_WITH_CLASS))
{
ReplaceAnonymousWithClassRefactoring replaceAnonymousWithClassRefactoring = (ReplaceAnonymousWithClassRefactoring) modelDiffRefactoring;
extraDiffs.add(replaceAnonymousWithClassRefactoring.getDiff());
}
}
return extraDiffs;
}
private void computeAllEditScripts() {
long editScript_start = System.currentTimeMillis();
for (ASTDiff diff : projectASTDiff.getDiffSet()) {
diff.computeEditScript(modelDiff.getParentModel().getTreeContextMap(), modelDiff.getChildModel().getTreeContextMap());
}
long editScript_end = System.currentTimeMillis();
logger.info("EditScript execution: " + (editScript_end - editScript_start)/ 1000 + " seconds");
}
private void makeASTDiff(List extends UMLAbstractClassDiff> umlClassBaseDiffList, boolean mergeFlag){
for (UMLAbstractClassDiff classDiff : umlClassBaseDiffList) {
ASTDiff append = findAppend(classDiff);
boolean decision = (append != null) || mergeFlag;
ASTDiff classASTDiff = process(classDiff, findTreeContexts(classDiff), decision);
if (append != null)
append.getAllMappings().mergeMappings(classASTDiff.getAllMappings());
else {
projectASTDiff.addASTDiff(classASTDiff);
}
}
}
private ASTDiff findAppend(UMLAbstractClassDiff classBaseDiff) {
for (ASTDiff existing : projectASTDiff.getDiffSet()) {
if (existing.getSrcPath().equals(classBaseDiff.getOriginalClass().getSourceFile()))
return existing;
else if (existing.getDstPath().equals(classBaseDiff.getNextClass().getSourceFile()))
return existing;
}
return null;
}
private Pair findTreeContexts(UMLAbstractClassDiff classDiff) {
return new Pair<>(modelDiff.getParentModel().getTreeContextMap().get(classDiff.getOriginalClass().getSourceFile()),
modelDiff.getChildModel().getTreeContextMap().get(classDiff.getNextClass().getSourceFile()));
}
private ASTDiff process(UMLAbstractClassDiff classDiff, Pair treeContextPair,boolean mergeFlag){
TreeContext srcTreeContext = treeContextPair.first;
TreeContext dstTreeContext = treeContextPair.second;
Tree srcTree = srcTreeContext.getRoot();
Tree dstTree = dstTreeContext.getRoot();
ExtendedMultiMappingStore mappingStore = new ExtendedMultiMappingStore(srcTree,dstTree);
String key = classDiff.getOriginalClass().getLocationInfo().getFilePath();
if (optimizationDataMap.containsKey(key)) {
this.lastStepMappings = optimizationDataMap.get(key).lastStepMappings;
this.optimizationMappingStore = optimizationDataMap.get(key).optimizationMappingStore;
}
else {
this.lastStepMappings = new ArrayList<>();
this.optimizationMappingStore = new ExtendedMultiMappingStore(srcTree,dstTree);
}
if (!mergeFlag) {
mappingStore.addMapping(srcTree, dstTree);
processPackageDeclaration(srcTree,dstTree,mappingStore);
}
boolean isBaseDiff = classDiff instanceof UMLClassBaseDiff;
if (isBaseDiff) {
UMLClassBaseDiff baseClassDiff = (UMLClassBaseDiff) classDiff;
processImports(srcTree, dstTree, (baseClassDiff).getImportDiffList(), mappingStore);
processClassDeclarationMapping(srcTree,dstTree, baseClassDiff,mappingStore);
}
processClassAttributes(srcTree,dstTree,classDiff,mappingStore);
processEnumConstants(srcTree,dstTree,classDiff.getCommonEnumConstants(),mappingStore);
processAllMethods(srcTree,dstTree,classDiff.getOperationBodyMapperList(),mappingStore);
processModelDiffRefactorings(classDiff,mappingStore);
processMovedAttributes(classDiff,mappingStore);
if (isBaseDiff){
UMLClassBaseDiff baseClassDiff = (UMLClassBaseDiff) classDiff;
processRefactorings(srcTree,dstTree,getClassDiffRefactorings(baseClassDiff),mappingStore);
}
optimizationDataMap.put(key, new OptimizationData(lastStepMappings, optimizationMappingStore));
return new ASTDiff(classDiff.getOriginalClass().getLocationInfo().getFilePath(),
classDiff.getNextClass().getLocationInfo().getFilePath(), treeContextPair.first, treeContextPair.second, mappingStore);
}
private List getClassDiffRefactorings(UMLClassBaseDiff classDiff) {
List classDiffRefactorings = new ArrayList<>();
for (Refactoring modelDiffRefactoring : modelDiffRefactorings) {
Set> involvedClassesBeforeRefactoring = modelDiffRefactoring.getInvolvedClassesBeforeRefactoring();
Set> involvedClassesAfterRefactoring = modelDiffRefactoring.getInvolvedClassesAfterRefactoring();
if (involvedClassesBeforeRefactoring.size() > 1 || involvedClassesAfterRefactoring.size() > 1) continue; //Must extend the logic to work for cases with more than one involving classes such as ExtractAndMoveMethodRefactoring
UMLClass umlClassBefore = classDiff.getOriginalClass();
UMLClass umlClassAfter = classDiff.getNextClass();
ImmutablePair refactoringClassBefore = involvedClassesBeforeRefactoring.iterator().next();
ImmutablePair refactoringClassAfter = involvedClassesAfterRefactoring.iterator().next();
if (umlClassBefore.getLocationInfo().getFilePath().equals(refactoringClassBefore.getLeft())
&& umlClassAfter.getLocationInfo().getFilePath().equals(refactoringClassAfter.getLeft())) {
String refactoringClassNameBefore = refactoringClassBefore.getRight();
String refactoringClassNameAfter = refactoringClassAfter.getRight();
// Relied on || in order to ascertain at least one class involves (handling move to anonymous and vice versa)
boolean isNameMatching = refactoringClassNameBefore.equals(umlClassBefore.getName()) || refactoringClassNameAfter.equals(umlClassAfter.getName());
boolean bothInAnonymous = refactoringClassNameBefore.contains(umlClassBefore.getName()) && refactoringClassNameAfter.contains(umlClassAfter.getName());
if (isNameMatching || bothInAnonymous)
classDiffRefactorings.add(modelDiffRefactoring);
}
}
return classDiffRefactorings;
}
private void processMovedAttributes(UMLAbstractClassDiff classDiff, ExtendedMultiMappingStore mappingStore) {
List movedAttributeDiffList = modelDiff.getMovedAttributeDiffList();
for (UMLAttributeDiff umlAttributeDiff : movedAttributeDiffList) {
UMLAttribute srcAttr = umlAttributeDiff.getRemovedAttribute();
UMLAttribute dstAttr = umlAttributeDiff.getAddedAttribute();
String srcAttrPath = srcAttr.getLocationInfo().getFilePath();
String dstAttrPath = dstAttr.getLocationInfo().getFilePath();
if (classDiff.getOriginalClass().getLocationInfo().getFilePath().equals(srcAttrPath) &&
classDiff.getNextClass().getLocationInfo().getFilePath().equals(dstAttrPath)) {
Tree srcTotalTree = modelDiff.getParentModel().getTreeContextMap().get(srcAttrPath).getRoot();
Tree dstTotalTree = modelDiff.getChildModel().getTreeContextMap().get(dstAttrPath).getRoot();
processFieldDeclarationByAttrDiff(srcTotalTree,dstTotalTree,umlAttributeDiff,mappingStore);
}
}
}
private static void processOptimization(ASTDiff input, OptimizationData optimizationData) {
Tree srcTree = input.src.getRoot();
Tree dstTree = input.dst.getRoot();
ExtendedMultiMappingStore lastStepMappingStore = new ExtendedMultiMappingStore(srcTree,dstTree);
for (AbstractCodeMapping lastStepMapping : optimizationData.lastStepMappings) {
// if (lastStepMapping.getFragment1().getLocationInfo().getFilePath().equals(lastStepMapping.getFragment2().getLocationInfo().getFilePath())) {
if (lastStepMapping.getFragment1().getLocationInfo().getFilePath().equals(input.getSrcPath()) && lastStepMapping.getFragment2().getLocationInfo().getFilePath().equals(input.getDstPath())) {
Tree srcExp = TreeUtilFunctions.findByLocationInfo(srcTree, lastStepMapping.getFragment1().getLocationInfo());
Tree dstExp = TreeUtilFunctions.findByLocationInfo(dstTree, lastStepMapping.getFragment2().getLocationInfo());
if (srcExp == null || dstExp == null) continue;
if (needToOverride(input, srcExp, dstExp))
new LeafMatcher().match(srcExp, dstExp, lastStepMappingStore);
else
new LeafMatcher().match(srcExp,dstExp,input.getAllMappings());
}
}
ExtendedMultiMappingStore allMappings = input.getAllMappings();
allMappings.replaceWithOptimizedMappings(lastStepMappingStore);
allMappings.replaceWithOptimizedMappings(optimizationData.optimizationMappingStore);
}
private static boolean needToOverride(ASTDiff input, Tree srcExp, Tree dstExp) {
if (!srcExp.isIsomorphicTo(dstExp)) return true;
ExtendedMultiMappingStore allMappings = input.getAllMappings();
Set dsts = allMappings.getDsts(srcExp);
if (dsts != null)
{
for (Tree dst : dsts)
if (!srcExp.isIsomorphicTo(dst))
return true;
return false;
}
Set srcs = allMappings.getSrcs(dstExp);
if (srcs != null) {
for (Tree src : srcs) {
if (!src.isIsomorphicTo(dstExp)) {
return true;
}
return false;
}
}
return true;
}
private static boolean isTestRelated(Tree srcTree) {
Tree p1 = TreeUtilFunctions.getParentUntilType(srcTree, Constants.METHOD_DECLARATION);
if (p1 == null) return false;
for (Tree child : p1.getChildren()) {
if (child.getType().name.equals(Constants.MARKER_ANNOTATION))
{
if (!child.getChildren().isEmpty())
{
Tree c0 = child.getChild(0);
if (c0.getLabel().equals("Test") || c0.getLabel().equals("ParameterizedTest")) return true;
}
}
}
return false;
}
private void processEnumConstants(Tree srcTree, Tree dstTree, Set> commonEnumConstants, ExtendedMultiMappingStore mappingStore) {
for (org.apache.commons.lang3.tuple.Pair commonEnumConstant : commonEnumConstants) {
LocationInfo locationInfo1 = commonEnumConstant.getLeft().getLocationInfo();
LocationInfo locationInfo2 = commonEnumConstant.getRight().getLocationInfo();
Tree srcEnumConstant = TreeUtilFunctions.findByLocationInfo(srcTree,locationInfo1);
Tree dstEnumConstant = TreeUtilFunctions.findByLocationInfo(dstTree,locationInfo2);
new LeafMatcher().match(srcEnumConstant,dstEnumConstant,mappingStore);
}
}
private void processModelDiffRefactorings(UMLAbstractClassDiff classDiff, ExtendedMultiMappingStore mappingStore) {
for(Refactoring refactoring : modelDiffRefactorings) {
List beforeRefactoringClasses = refactoring.getInvolvedClassesBeforeRefactoring().stream().map(ImmutablePair::getRight).collect(Collectors.toList());
List afterRefactoringClasses = refactoring.getInvolvedClassesAfterRefactoring().stream().map(ImmutablePair::getRight).collect(Collectors.toList());
if (refactoring instanceof MoveOperationRefactoring) {
if (afterRefactoringClasses.contains(classDiff.getNextClass().getName()) ||
beforeRefactoringClasses.contains(classDiff.getOriginalClass().getName())) {
MoveOperationRefactoring moveOperationRefactoring = (MoveOperationRefactoring) refactoring;
if (isExtractedMethodRef(moveOperationRefactoring.getBodyMapper().getOperation2())) return;
String srcPath = moveOperationRefactoring.getOriginalOperation().getLocationInfo().getFilePath();
String dstPath = moveOperationRefactoring.getMovedOperation().getLocationInfo().getFilePath();
Tree srcTotalTree = modelDiff.getParentModel().getTreeContextMap().get(srcPath).getRoot();
Tree dstTotalTree = modelDiff.getChildModel().getTreeContextMap().get(dstPath).getRoot();
processMethod(srcTotalTree, dstTotalTree, moveOperationRefactoring.getBodyMapper(), mappingStore);
}
} else if (refactoring instanceof MoveAttributeRefactoring) {
if (afterRefactoringClasses.contains(classDiff.getNextClass().getName()) ||
beforeRefactoringClasses.contains(classDiff.getOriginalClass().getName())) {
MoveAttributeRefactoring moveAttributeRefactoring = (MoveAttributeRefactoring) refactoring;
String srcPath = moveAttributeRefactoring.getOriginalAttribute().getLocationInfo().getFilePath();
String dstPath = moveAttributeRefactoring.getMovedAttribute().getLocationInfo().getFilePath();
Tree srcTotalTree = modelDiff.getParentModel().getTreeContextMap().get(srcPath).getRoot();
Tree dstTotalTree = modelDiff.getChildModel().getTreeContextMap().get(dstPath).getRoot();
processFieldDeclaration(srcTotalTree, dstTotalTree, moveAttributeRefactoring.getOriginalAttribute(), moveAttributeRefactoring.getMovedAttribute(), mappingStore);
}
} else if (refactoring.getRefactoringType().equals(RefactoringType.EXTRACT_AND_MOVE_OPERATION)) {
if (afterRefactoringClasses.contains(classDiff.getNextClass().getName()) ||
beforeRefactoringClasses.contains(classDiff.getOriginalClass().getName())) {
ExtractOperationRefactoring extractOperationRefactoring = (ExtractOperationRefactoring) refactoring;
findTreeFromMapperAndProcessBodyMapper(extractOperationRefactoring.getBodyMapper(), mappingStore);
}
}
else if (refactoring.getRefactoringType().equals(RefactoringType.MOVE_AND_INLINE_OPERATION)) {
if (afterRefactoringClasses.contains(classDiff.getNextClass().getName()) ||
beforeRefactoringClasses.contains(classDiff.getOriginalClass().getName())) {
InlineOperationRefactoring inlineOperationRefactoring = (InlineOperationRefactoring) refactoring;
findTreeFromMapperAndProcessBodyMapper(inlineOperationRefactoring.getBodyMapper(), mappingStore);
}
}
}
}
private void findTreeFromMapperAndProcessBodyMapper(UMLOperationBodyMapper bodyMapper, ExtendedMultiMappingStore mappingStore) {
String srcPath = bodyMapper.getOperation1().getLocationInfo().getFilePath();
String dstPath = bodyMapper.getOperation2().getLocationInfo().getFilePath();
Tree srcTotalTree = modelDiff.getParentModel().getTreeContextMap().get(srcPath).getRoot();
Tree dstTotalTree = modelDiff.getChildModel().getTreeContextMap().get(dstPath).getRoot();
processBodyMapper(srcTotalTree, dstTotalTree, bodyMapper, mappingStore, true);
}
private boolean isExtractedMethodRef(UMLOperation operation2) {
for (Refactoring modelDiffRefactoring : modelDiffRefactorings) {
if (modelDiffRefactoring.getRefactoringType().equals(RefactoringType.EXTRACT_OPERATION))
{
if (((ExtractOperationRefactoring) modelDiffRefactoring).getExtractedOperation().equals(operation2)) return true;
}
}
return false;
}
private void processAllMethods(Tree srcTree, Tree dstTree, List operationBodyMapperList, ExtendedMultiMappingStore mappingStore) {
for(UMLOperationBodyMapper umlOperationBodyMapper : new ArrayList<>(operationBodyMapperList))
processMethod(srcTree,dstTree,umlOperationBodyMapper,mappingStore);
}
private void processMethod(Tree srcTree, Tree dstTree, UMLOperationBodyMapper umlOperationBodyMapper, ExtendedMultiMappingStore mappingStore) {
Tree srcOperationNode;
Tree dstOperationNode;
if (umlOperationBodyMapper.getOperation1() != null & umlOperationBodyMapper.getOperation2() != null) {
srcOperationNode = TreeUtilFunctions.findByLocationInfo(srcTree, umlOperationBodyMapper.getOperation1().getLocationInfo());
dstOperationNode = TreeUtilFunctions.findByLocationInfo(dstTree, umlOperationBodyMapper.getOperation2().getLocationInfo());
if (srcOperationNode == null || !(srcOperationNode.getType().name.equals(Constants.METHOD_DECLARATION) || srcOperationNode.getType().name.equals(Constants.ANNOTATION_TYPE_MEMBER_DECLARATION))) return;
if (dstOperationNode == null || !(dstOperationNode.getType().name.equals(Constants.METHOD_DECLARATION) || dstOperationNode.getType().name.equals(Constants.ANNOTATION_TYPE_MEMBER_DECLARATION))) return;
processJavaDocs(srcOperationNode, dstOperationNode, umlOperationBodyMapper.getOperation1().getJavadoc(), umlOperationBodyMapper.getOperation2().getJavadoc(), mappingStore);
mappingStore.addMapping(srcOperationNode, dstOperationNode);
} else {
//Static Initializers
srcOperationNode = TreeUtilFunctions.findByLocationInfo(srcTree, umlOperationBodyMapper.getContainer1().getLocationInfo());
dstOperationNode = TreeUtilFunctions.findByLocationInfo(dstTree, umlOperationBodyMapper.getContainer2().getLocationInfo());
if (srcOperationNode != null & dstOperationNode != null) {
if (srcOperationNode.getType().name.equals(Constants.INITIALIZER) && dstOperationNode.getType().name.equals(Constants.INITIALIZER)) {
mappingStore.addMapping(srcOperationNode, dstOperationNode);
//static keyword
if (umlOperationBodyMapper.getContainer1() instanceof UMLInitializer && umlOperationBodyMapper.getContainer2() instanceof UMLInitializer)
if (((UMLInitializer) umlOperationBodyMapper.getContainer1()).isStatic() && ((UMLInitializer) umlOperationBodyMapper.getContainer2()).isStatic()) {
Tree srcModifier = TreeUtilFunctions.findChildByType(srcOperationNode, Constants.MODIFIER);
Tree dstModifier = TreeUtilFunctions.findChildByType(dstOperationNode, Constants.MODIFIER);
if (srcModifier != null && dstModifier != null)
mappingStore.addMapping(srcModifier, dstModifier);
}
//Javadoc
Tree srcJavadoc = TreeUtilFunctions.findChildByType(srcOperationNode, Constants.JAVA_DOC);
Tree dstJavadoc = TreeUtilFunctions.findChildByType(dstOperationNode, Constants.JAVA_DOC);
if (srcJavadoc != null && dstJavadoc != null)
new BasicTreeMatcher().match(srcJavadoc, dstJavadoc, mappingStore);
}
}
}
if (srcOperationNode != null && dstOperationNode != null) {
processMethodSignature(srcOperationNode, dstOperationNode, umlOperationBodyMapper, mappingStore);
processBodyMapper(srcOperationNode, dstOperationNode, umlOperationBodyMapper, mappingStore, false);
processOperationDiff(srcOperationNode, dstOperationNode, umlOperationBodyMapper, mappingStore);
processMethodParameters(srcOperationNode, dstOperationNode, umlOperationBodyMapper.getMatchedVariables(), mappingStore);
}
}
private void processMethodParameters(Tree srcTree, Tree dstTree, Set> matchedVariables, ExtendedMultiMappingStore mappingStore) {
for (org.apache.commons.lang3.tuple.Pair matchedPair: matchedVariables) {
VariableDeclaration leftVarDecl = matchedPair.getLeft();
VariableDeclaration rightVarDecl = matchedPair.getRight();
Tree leftTree = TreeUtilFunctions.findByLocationInfo(srcTree,leftVarDecl.getLocationInfo());
Tree rightTree = TreeUtilFunctions.findByLocationInfo(dstTree,rightVarDecl.getLocationInfo());
if (leftTree == null || rightTree == null) return;
if (leftVarDecl.isParameter() && rightVarDecl.isParameter()) {
if (TreeUtilFunctions.isIsomorphicTo(rightTree, leftTree))
mappingStore.addMappingRecursively(leftTree, rightTree);
else {
new LeafMatcher().match(leftTree,rightTree,mappingStore);
mappingStore.addMapping(leftTree,rightTree);
}
}
}
}
private void processBodyMapper(Tree srcTree, Tree dstTree, UMLOperationBodyMapper bodyMapper, ExtendedMultiMappingStore mappingStore, boolean isPartOfExtractedMethod) {
if (bodyMapper.getAnonymousClassDiffs() != null) {
for (UMLAnonymousClassDiff anonymousClassDiff : bodyMapper.getAnonymousClassDiffs()) {
processClassAttributes(srcTree,dstTree,anonymousClassDiff,mappingStore);
for (UMLOperationBodyMapper umlOperationBodyMapper : anonymousClassDiff.getOperationBodyMapperList()) {
processMethod(srcTree,dstTree,umlOperationBodyMapper,mappingStore);
}
}
}
Set mappingSet = bodyMapper.getMappings();
ArrayList mappings = new ArrayList<>(mappingSet);
for (AbstractCodeMapping abstractCodeMapping : mappings) {
if (abstractCodeMapping instanceof LeafMapping)
processLeafMapping(srcTree,dstTree,abstractCodeMapping,mappingStore, isPartOfExtractedMethod);
else if (abstractCodeMapping instanceof CompositeStatementObjectMapping)
processCompositeMapping(srcTree,dstTree,abstractCodeMapping,mappingStore);
}
}
private void processCompositeMapping(Tree srcTree, Tree dstTree, AbstractCodeMapping abstractCodeMapping, ExtendedMultiMappingStore mappingStore) {
CompositeStatementObjectMapping compositeStatementObjectMapping = (CompositeStatementObjectMapping) abstractCodeMapping;
Tree srcStatementNode = TreeUtilFunctions.findByLocationInfo(srcTree,compositeStatementObjectMapping.getFragment1().getLocationInfo());
Tree dstStatementNode = TreeUtilFunctions.findByLocationInfo(dstTree,compositeStatementObjectMapping.getFragment2().getLocationInfo());
//if (srcStatementNode.getMetrics().hash == dstStatementNode.getMetrics().hash)
//{
// mappingStore.addMappingRecursively(srcStatementNode, dstStatementNode);
//}
//else
{
if (srcStatementNode == null || dstStatementNode == null)
return;
if (srcStatementNode.getType().name.equals(dstStatementNode.getType().name))
mappingStore.addMapping(srcStatementNode,dstStatementNode);
if ((srcStatementNode.getType().name.equals(Constants.TRY_STATEMENT) && dstStatementNode.getType().name.equals(Constants.TRY_STATEMENT)) ||
(srcStatementNode.getType().name.equals(Constants.CATCH_CLAUSE) && dstStatementNode.getType().name.equals(Constants.CATCH_CLAUSE))) {
matchBlocks(srcStatementNode, dstStatementNode, mappingStore);
new CompositeMatcher(abstractCodeMapping).match(srcStatementNode,dstStatementNode,mappingStore);
} else if (!srcStatementNode.getType().name.equals(Constants.BLOCK) && !dstStatementNode.getType().name.equals(Constants.BLOCK)) {
new CompositeMatcher(abstractCodeMapping).match(srcStatementNode, dstStatementNode, mappingStore);
}
}
}
private void processLeafMapping(Tree srcTree, Tree dstTree, AbstractCodeMapping abstractCodeMapping, ExtendedMultiMappingStore mappingStore, boolean isPartOfExtractedMethod) {
LeafMapping leafMapping = (LeafMapping) abstractCodeMapping;
Tree srcStatementNode = TreeUtilFunctions.findByLocationInfo(srcTree,leafMapping.getFragment1().getLocationInfo());
Tree dstStatementNode = TreeUtilFunctions.findByLocationInfo(dstTree,leafMapping.getFragment2().getLocationInfo());
if (srcStatementNode == null || dstStatementNode == null) {
System.err.println("Tree not found for " + abstractCodeMapping);
return;
}
if (srcStatementNode.getType().name.equals(dstStatementNode.getType().name))
mappingStore.addMapping(srcStatementNode, dstStatementNode);
boolean _abstractExp = abstractCodeMapping.getFragment1() instanceof AbstractExpression || abstractCodeMapping.getFragment2() instanceof AbstractExpression;
boolean _leafExp = abstractCodeMapping.getFragment1() instanceof LeafExpression || abstractCodeMapping.getFragment2() instanceof LeafExpression;
boolean _abstractExpWithNonCompositeOwner = _abstractExp;
if (_abstractExp){
if (abstractCodeMapping.getFragment1() instanceof AbstractExpression)
if (((AbstractExpression)abstractCodeMapping.getFragment1()).getOwner() != null
&& ((AbstractExpression)abstractCodeMapping.getFragment1()).getOwner().getLocationInfo().getCodeElementType().equals(CodeElementType.FOR_STATEMENT))
_abstractExpWithNonCompositeOwner = false;
if (abstractCodeMapping.getFragment2() instanceof AbstractExpression)
if (((AbstractExpression)abstractCodeMapping.getFragment2()).getOwner() != null
&& ((AbstractExpression)abstractCodeMapping.getFragment2()).getOwner().getLocationInfo().getCodeElementType().equals(CodeElementType.FOR_STATEMENT))
_abstractExpWithNonCompositeOwner = false;
}
if (_abstractExpWithNonCompositeOwner || _leafExp) {
lastStepMappings.add(abstractCodeMapping);
} else {
new LeafMatcher().match(srcStatementNode,dstStatementNode,mappingStore);
additionallyMatchedStatements(srcTree, dstTree, srcStatementNode, dstStatementNode, abstractCodeMapping, mappingStore);
}
optimizeVariableDeclarations(abstractCodeMapping);
if (!isPartOfExtractedMethod && srcStatementNode.getType().name.equals(Constants.RETURN_STATEMENT) && dstStatementNode.getType().name.equals(Constants.RETURN_STATEMENT)) {
optimizationMappingStore.addMapping(srcStatementNode,dstStatementNode);
}
if (abstractCodeMapping.getRefactorings().size() > 0) {
leafMappingRefactoringAwareness(dstTree, abstractCodeMapping, mappingStore);
}
}
private static void leafMappingRefactoringAwareness(Tree dstTree, AbstractCodeMapping abstractCodeMapping, ExtendedMultiMappingStore mappingStore) {
for (Refactoring refactoring : abstractCodeMapping.getRefactorings()) {
if (refactoring instanceof ExtractVariableRefactoring)
{
ExtractVariableRefactoring extractVariableRefactoring = (ExtractVariableRefactoring) refactoring;
for (AbstractCodeMapping reference : extractVariableRefactoring.getReferences()) {
for (LeafExpression variable : reference.getFragment2().getVariables()) {
if (variable.getString().equals(extractVariableRefactoring.getVariableDeclaration().getVariableName())) {
Tree referenceNode = TreeUtilFunctions.findByLocationInfo(dstTree, variable.getLocationInfo());
if (referenceNode != null)
{
if (referenceNode.getChildren().size() > 0){
referenceNode = referenceNode.getChild(0);
}
if (mappingStore.isDstMapped(referenceNode) && !mappingStore.isDstMultiMapped(referenceNode)) {
Tree tempSrc = mappingStore.getSrcs(referenceNode).iterator().next();
mappingStore.removeMapping(tempSrc, referenceNode);
}
}
}
}
}
}
}
}
private void optimizeVariableDeclarations(AbstractCodeMapping abstractCodeMapping) {
List variableDeclarations1 = abstractCodeMapping.getFragment1().getVariableDeclarations();
List variableDeclarations2 = abstractCodeMapping.getFragment2().getVariableDeclarations();
if (variableDeclarations1.size() == 1 && variableDeclarations2.size() == 0){
if (variableDeclarations1.get(0).getInitializer() != null)
if (abstractCodeMapping.getFragment2().toString().contains(variableDeclarations1.get(0).getInitializer().toString()))
lastStepMappings.add(new LeafMapping(variableDeclarations1.get(0).getInitializer(), abstractCodeMapping.getFragment2(),null,null));
}
if (variableDeclarations1.size() == 0 && variableDeclarations2.size() == 1){
if (variableDeclarations2.get(0).getInitializer() != null)
if (abstractCodeMapping.getFragment1().toString().contains(variableDeclarations2.get(0).getInitializer().toString()))
lastStepMappings.add(new LeafMapping(abstractCodeMapping.getFragment1(),variableDeclarations2.get(0).getInitializer(),null,null));
}
}
private static void additionallyMatchedStatements(Tree srcTree, Tree dstTree, Tree srcStatementNode, Tree dstStatementNode, AbstractCodeMapping abstractCodeMapping, ExtendedMultiMappingStore mappingStore) {
if (abstractCodeMapping != null) {
for (Replacement replacement : abstractCodeMapping.getReplacements()) {
if (replacement instanceof CompositeReplacement) {
CompositeReplacement compositeReplacement = (CompositeReplacement) replacement;
if (compositeReplacement.getAdditionallyMatchedStatements1().size() > 0) {
for (AbstractCodeFragment abstractCodeFragment : compositeReplacement.getAdditionallyMatchedStatements1()) {
Tree srcAdditionalTree = TreeUtilFunctions.findByLocationInfo(srcTree, abstractCodeFragment.getLocationInfo());
new LeafMatcher().match(srcAdditionalTree, dstStatementNode, mappingStore);
}
} else if (compositeReplacement.getAdditionallyMatchedStatements2().size() > 0) {
for (AbstractCodeFragment abstractCodeFragment : compositeReplacement.getAdditionallyMatchedStatements2()) {
Tree dstAdditionalTree = TreeUtilFunctions.findByLocationInfo(dstTree, abstractCodeFragment.getLocationInfo());
new LeafMatcher().match(srcStatementNode, dstAdditionalTree, mappingStore);
}
}
}
}
}
}
private void processClassAnnotations(Tree srcTree, Tree dstTree, UMLAnnotationListDiff annotationListDiff, ExtendedMultiMappingStore mappingStore) {
for (org.apache.commons.lang3.tuple.Pair umlAnnotationUMLAnnotationPair : annotationListDiff.getCommonAnnotations()) {
Tree srcClassAnnotationTree = TreeUtilFunctions.findByLocationInfo(srcTree , umlAnnotationUMLAnnotationPair.getLeft().getLocationInfo());
Tree dstClassAnnotationTree = TreeUtilFunctions.findByLocationInfo(dstTree, umlAnnotationUMLAnnotationPair.getRight().getLocationInfo());
if (srcClassAnnotationTree == null || dstClassAnnotationTree == null) return;
if (srcClassAnnotationTree.isIsoStructuralTo(dstClassAnnotationTree))
mappingStore.addMappingRecursively(srcClassAnnotationTree,dstClassAnnotationTree);
}
}
private void matchBlocks(Tree srcStatementNode, Tree dstStatementNode, ExtendedMultiMappingStore mappingStore) {
String searchingType = Constants.BLOCK;
Pair matched = matchBasedOnType(srcStatementNode,dstStatementNode, searchingType);
if (matched != null)
mappingStore.addMapping(matched.first,matched.second);
}
private void processJavaDocs(Tree srcTree, Tree dstTree, UMLJavadoc srcUMLJavaDoc, UMLJavadoc dstUMLJavaDoc, ExtendedMultiMappingStore mappingStore) {
if (srcUMLJavaDoc != null && dstUMLJavaDoc != null) {
Tree srcJavaDocNode = TreeUtilFunctions.findByLocationInfo(srcTree,srcUMLJavaDoc.getLocationInfo());
Tree dstJavaDocNode = TreeUtilFunctions.findByLocationInfo(dstTree,dstUMLJavaDoc.getLocationInfo());
if (srcJavaDocNode == null || dstJavaDocNode == null) return;
if (srcUMLJavaDoc.equalText(dstUMLJavaDoc) && srcJavaDocNode.isIsoStructuralTo(dstJavaDocNode)) {
mappingStore.addMappingRecursively(srcJavaDocNode,dstJavaDocNode);
} else {
new BasicTreeMatcher().match(srcJavaDocNode,dstJavaDocNode,mappingStore);
mappingStore.addMapping(srcJavaDocNode,dstJavaDocNode);
}
}
}
private void processOperationDiff(Tree srcTree, Tree dstTree, UMLOperationBodyMapper umlOperationBodyMapper, ExtendedMultiMappingStore mappingStore) {
UMLOperationDiff umlOperationDiff = umlOperationBodyMapper.getOperationSignatureDiff().isPresent() ? umlOperationBodyMapper.getOperationSignatureDiff().get() : null;
if (umlOperationDiff == null) return;
UMLTypeParameterListDiff umlTypeParameterListDiff = umlOperationDiff.getTypeParameterListDiff();
for (org.apache.commons.lang3.tuple.Pair commonTypeParamSet : umlTypeParameterListDiff.getCommonTypeParameters()) {
Tree srcTypeParam = TreeUtilFunctions.findByLocationInfo(srcTree, commonTypeParamSet.getLeft().getLocationInfo());
Tree dstTypeParam = TreeUtilFunctions.findByLocationInfo(dstTree, commonTypeParamSet.getRight().getLocationInfo());
mappingStore.addMappingRecursively(srcTypeParam,dstTypeParam);
}
for (org.apache.commons.lang3.tuple.Pair umlAnnotationUMLAnnotationPair : umlOperationDiff.getAnnotationListDiff().getCommonAnnotations()) {
Tree srcClassAnnotationTree = TreeUtilFunctions.findByLocationInfo(srcTree , umlAnnotationUMLAnnotationPair.getLeft().getLocationInfo());
Tree dstClassAnnotationTree = TreeUtilFunctions.findByLocationInfo(dstTree, umlAnnotationUMLAnnotationPair.getRight().getLocationInfo());
mappingStore.addMappingRecursively(srcClassAnnotationTree,dstClassAnnotationTree);
}
Set> commonExceptionTypes = umlOperationDiff.getCommonExceptionTypes();
if (commonExceptionTypes != null) {
for (org.apache.commons.lang3.tuple.Pair matchedException : commonExceptionTypes) {
Tree srcExceptionNode =TreeUtilFunctions.findByLocationInfo(srcTree, matchedException.getLeft().getLocationInfo());
Tree dstExceptionNode =TreeUtilFunctions.findByLocationInfo(dstTree, matchedException.getRight().getLocationInfo());
mappingStore.addMappingRecursively(srcExceptionNode,dstExceptionNode);
}
}
AbstractMap.SimpleEntry, Set> changedExceptionTypes = umlOperationDiff.getChangedExceptionTypes();
if (changedExceptionTypes != null){
Iterator keys = changedExceptionTypes.getKey().iterator();
Iterator values = changedExceptionTypes.getValue().iterator();
if (keys.hasNext() && values.hasNext())
{
Tree srcExceptionNode =TreeUtilFunctions.findByLocationInfo(srcTree, keys.next().getLocationInfo());
Tree dstExceptionNode =TreeUtilFunctions.findByLocationInfo(dstTree, values.next().getLocationInfo());
mappingStore.addMappingRecursively(srcExceptionNode,dstExceptionNode);
}
}
if (umlOperationDiff.getRemovedOperation().getReturnParameter() != null && umlOperationDiff.getAddedOperation().getReturnParameter() != null ) {
LocationInfo srcLocationInfo = umlOperationDiff.getRemovedOperation().getReturnParameter().getType().getLocationInfo();
LocationInfo dstLocationInfo = umlOperationDiff.getAddedOperation().getReturnParameter().getType().getLocationInfo();
Tree srcNode =TreeUtilFunctions.findByLocationInfo(srcTree, srcLocationInfo);
Tree dstNode =TreeUtilFunctions.findByLocationInfo(dstTree, dstLocationInfo);
if (srcNode == null || dstNode == null) return;
if (srcNode.isIsoStructuralTo(dstNode))
mappingStore.addMappingRecursively(srcNode,dstNode);
else {
new LeafMatcher().match(srcNode,dstNode,mappingStore);
}
}
}
private static boolean multipleInstancesWithSameDescription(List refactoringList, Refactoring refactoring) {
int count = 0;
for (Refactoring r : refactoringList) {
if(r.toString().equals(refactoring.toString()))
count++;
}
return count > 1;
}
private void processRefactorings(Tree srcTree, Tree dstTree, List refactoringList, ExtendedMultiMappingStore mappingStore){
for (Refactoring refactoring : refactoringList) {
if (refactoring instanceof ReplaceLoopWithPipelineRefactoring) {
ReplaceLoopWithPipelineRefactoring replaceLoopWithPipelineRefactoring = (ReplaceLoopWithPipelineRefactoring) refactoring;
if (replaceLoopWithPipelineRefactoring.getCodeFragmentsAfter().size() != 1) continue;
AbstractCodeFragment next = replaceLoopWithPipelineRefactoring.getCodeFragmentsAfter().iterator().next();
List lambdas = next.getLambdas();
AbstractCodeFragment enhancedFor = null;
for (AbstractCodeFragment abstractCodeFragment : replaceLoopWithPipelineRefactoring.getCodeFragmentsBefore()) {
if (abstractCodeFragment instanceof CompositeStatementObject && ((CompositeStatementObject)abstractCodeFragment).isLoop()) {
enhancedFor = abstractCodeFragment;
break;
}
}
if (enhancedFor == null) continue;
for (LambdaExpressionObject lambda : lambdas) {
for (VariableDeclaration parameter : lambda.getParameters()) {
String variableName = parameter.getVariableName();
VariableDeclaration variableDeclaration = enhancedFor.getVariableDeclaration(variableName);
if (variableDeclaration != null) {
Tree srcNode = TreeUtilFunctions.findByLocationInfo(srcTree,variableDeclaration.getLocationInfo());
Tree dstNode = TreeUtilFunctions.findByLocationInfo(dstTree,parameter.getLocationInfo());
new LeafMatcher().match(srcNode,dstNode,mappingStore);
}
}
}
Tree srcSt = TreeUtilFunctions.findByLocationInfo(srcTree,enhancedFor.getLocationInfo());
Tree dstSt = TreeUtilFunctions.findByLocationInfo(dstTree,next.getLocationInfo());
if (srcSt != null && dstSt != null)
if (srcSt.getType().name.equals(dstSt.getType().name))
mappingStore.addMapping(srcSt,dstSt);
} else if (refactoring instanceof ReplacePipelineWithLoopRefactoring) {
ReplacePipelineWithLoopRefactoring replaceLoopWithPipelineRefactoring = (ReplacePipelineWithLoopRefactoring) refactoring;
if (replaceLoopWithPipelineRefactoring.getCodeFragmentsBefore().size() != 1) continue;
AbstractCodeFragment next = replaceLoopWithPipelineRefactoring.getCodeFragmentsBefore().iterator().next();
List lambdas = next.getLambdas();
AbstractCodeFragment enhancedFor = null;
for (AbstractCodeFragment abstractCodeFragment : replaceLoopWithPipelineRefactoring.getCodeFragmentsAfter()) {
if (abstractCodeFragment.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT)) {
enhancedFor = abstractCodeFragment;
break;
}
}
if( enhancedFor == null) continue;
for (LambdaExpressionObject lambda : lambdas) {
for (VariableDeclaration parameter : lambda.getParameters()) {
String variableName = parameter.getVariableName();
VariableDeclaration variableDeclaration = enhancedFor.getVariableDeclaration(variableName);
if (variableDeclaration == null)
continue;
Tree srcNode = TreeUtilFunctions.findByLocationInfo(srcTree,parameter.getLocationInfo());
Tree dstNode = TreeUtilFunctions.findByLocationInfo(dstTree,variableDeclaration.getLocationInfo());
new LeafMatcher().match(srcNode,dstNode,mappingStore);
}
}
Tree srcSt = TreeUtilFunctions.findByLocationInfo(srcTree,next.getLocationInfo());
Tree dstSt = TreeUtilFunctions.findByLocationInfo(dstTree,enhancedFor.getLocationInfo());
if (dstSt != null && srcSt != null && srcSt.getType().name.equals(dstSt.getType().name))
mappingStore.addMapping(srcSt, dstSt);
} else if (refactoring instanceof MergeOperationRefactoring) {
MergeOperationRefactoring mergeOperationRefactoring = (MergeOperationRefactoring) refactoring;
for(UMLOperationBodyMapper bodyMapper : mergeOperationRefactoring.getMappers()) {
processMethod(srcTree,dstTree,bodyMapper,mappingStore);
}
} else if (refactoring instanceof SplitOperationRefactoring) {
SplitOperationRefactoring splitOperationRefactoring = (SplitOperationRefactoring) refactoring;
for(UMLOperationBodyMapper bodyMapper : splitOperationRefactoring.getMappers()) {
processMethod(srcTree,dstTree,bodyMapper,mappingStore);
}
} else if (refactoring instanceof ExtractOperationRefactoring) {
ExtractOperationRefactoring extractOperationRefactoring = (ExtractOperationRefactoring) refactoring;
UMLOperationBodyMapper bodyMapper = extractOperationRefactoring.getBodyMapper();
processBodyMapper(srcTree,dstTree,bodyMapper,mappingStore, true);
processArgumentMappings(srcTree, dstTree, refactoringList, refactoring, extractOperationRefactoring.getArgumentMappings());
} else if (refactoring instanceof InlineOperationRefactoring) {
InlineOperationRefactoring inlineOperationRefactoring = (InlineOperationRefactoring) refactoring;
UMLOperationBodyMapper bodyMapper = inlineOperationRefactoring.getBodyMapper();
processBodyMapper(srcTree,dstTree,bodyMapper,mappingStore, false);
processArgumentMappings(srcTree, dstTree, refactoringList, refactoring, inlineOperationRefactoring.getArgumentMappings());
} else if (refactoring instanceof MoveCodeRefactoring) {
MoveCodeRefactoring moveCodeRefactoring = (MoveCodeRefactoring) refactoring;
UMLOperationBodyMapper bodyMapper = moveCodeRefactoring.getBodyMapper();
processBodyMapper(srcTree,dstTree,bodyMapper,mappingStore, false);
} else if (refactoring instanceof ParameterizeTestRefactoring) {
ParameterizeTestRefactoring parameterizeTestRefactoring = (ParameterizeTestRefactoring) refactoring;
UMLOperationBodyMapper bodyMapper = parameterizeTestRefactoring.getBodyMapper();
processBodyMapper(srcTree,dstTree,bodyMapper,mappingStore, false);
} else if (refactoring instanceof ExtractVariableRefactoring) {
ExtractVariableRefactoring extractVariableRefactoring = (ExtractVariableRefactoring) refactoring;
lastStepMappings.addAll(extractVariableRefactoring.getSubExpressionMappings());
} else if (refactoring instanceof InlineVariableRefactoring) {
InlineVariableRefactoring inlineVariableRefactoring = (InlineVariableRefactoring) refactoring;
lastStepMappings.addAll(inlineVariableRefactoring.getSubExpressionMappings());
} else if (refactoring instanceof AssertThrowsRefactoring) {
AssertThrowsRefactoring assertThrowsRefactoring = (AssertThrowsRefactoring) refactoring;
lastStepMappings.addAll(assertThrowsRefactoring.getSubExpressionMappings());
} else if (refactoring instanceof InlineAttributeRefactoring) {
InlineAttributeRefactoring inlineAttributeRefactoring = (InlineAttributeRefactoring) refactoring;
//Tree srcAttrDeclaration = TreeUtilFunctions.findByLocationInfo(srcTree, inlineAttributeRefactoring.getVariableDeclaration().getLocationInfo());
//for (AbstractCodeMapping reference : inlineAttributeRefactoring.getReferences()) {
// Tree dstStatementTree = TreeUtilFunctions.findByLocationInfo(dstTree,reference.getFragment2().getLocationInfo());
// new LeafMatcher().match(srcAttrDeclaration,dstStatementTree,mappingStore);
//}
lastStepMappings.addAll(inlineAttributeRefactoring.getSubExpressionMappings());
} else if (refactoring instanceof ExtractAttributeRefactoring) {
ExtractAttributeRefactoring extractAttributeRefactoring = (ExtractAttributeRefactoring) refactoring;
//Tree dstAttrDeclaration = TreeUtilFunctions.findByLocationInfo(dstTree, extractAttributeRefactoring.getVariableDeclaration().getLocationInfo());
//for (AbstractCodeMapping reference : extractAttributeRefactoring.getReferences()) {
// Tree srcStatementTree = TreeUtilFunctions.findByLocationInfo(srcTree,reference.getFragment1().getLocationInfo());
// new LeafMatcher().match(srcStatementTree,dstAttrDeclaration,mappingStore);
//}
lastStepMappings.addAll(extractAttributeRefactoring.getSubExpressionMappings());
for (UMLAnonymousClassDiff umlAnonymousClassDiff : extractAttributeRefactoring.getAnonymousClassDiffList()) {
processAnonymousClassDiff(srcTree,dstTree,umlAnonymousClassDiff,mappingStore);
}
} else if (refactoring instanceof MergeVariableRefactoring) {
MergeVariableRefactoring mergeVariableRefactoring = (MergeVariableRefactoring) refactoring;
Set mergedVariables = mergeVariableRefactoring.getMergedVariables();
VariableDeclaration newVariable = mergeVariableRefactoring.getNewVariable();
Tree dstVariableDeclaration =TreeUtilFunctions.findByLocationInfo(dstTree,newVariable.getLocationInfo());
if (dstVariableDeclaration != null) {
List dstChildrenList = dstVariableDeclaration.getChildren();
Tree dstVarName = dstChildrenList.get(dstChildrenList.size() - 1);
for (VariableDeclaration variableDeclaration : mergedVariables) {
Tree srcVariableDeclaration = TreeUtilFunctions.findByLocationInfo(srcTree, variableDeclaration.getLocationInfo());
if (srcVariableDeclaration != null) {
List srcChildrenList = srcVariableDeclaration.getChildren();
Tree srcVarName = srcChildrenList.get(srcChildrenList.size() - 1);
mappingStore.addMapping(srcVarName, dstVarName);
}
}
}
} else if (refactoring instanceof SplitConditionalRefactoring) {
SplitConditionalRefactoring splitConditionalRefactoring = (SplitConditionalRefactoring) refactoring;
lastStepMappings.addAll(splitConditionalRefactoring.getSubExpressionMappings());
} else if (refactoring instanceof MergeConditionalRefactoring) {
MergeConditionalRefactoring mergeConditionalRefactoring = (MergeConditionalRefactoring) refactoring;
lastStepMappings.addAll(mergeConditionalRefactoring.getSubExpressionMappings());
} else if (refactoring instanceof MergeCatchRefactoring) {
MergeCatchRefactoring mergeCatchRefactoring = (MergeCatchRefactoring) refactoring;
Tree dstSubTree = TreeUtilFunctions.findByLocationInfo(dstTree,mergeCatchRefactoring.getNewCatchBlock().getLocationInfo());
for (AbstractCodeFragment eachMerged : mergeCatchRefactoring.getMergedCatchBlocks()) {
Tree srcSubTree = TreeUtilFunctions.findByLocationInfo(srcTree,eachMerged.getLocationInfo());
new GeneralMatcher(eachMerged, mergeCatchRefactoring.getNewCatchBlock())
.match(srcSubTree,dstSubTree,mappingStore);
}
} else if (refactoring instanceof RenameVariableRefactoring) {
RenameVariableRefactoring renameVariableRefactoring = (RenameVariableRefactoring) refactoring;
VariableDeclaration originalVariable = renameVariableRefactoring.getOriginalVariable();
VariableDeclaration renamedVariable = renameVariableRefactoring.getRenamedVariable();
Tree srcInput = TreeUtilFunctions.findByLocationInfo(srcTree,originalVariable.getLocationInfo());
Tree dstInput = TreeUtilFunctions.findByLocationInfo(dstTree, renamedVariable.getLocationInfo());
if (srcInput == null || dstInput == null) continue;
boolean eligible = true;
switch (renameVariableRefactoring.getRefactoringType()) {
case REPLACE_VARIABLE_WITH_ATTRIBUTE:
srcInput = TreeUtilFunctions.getParentUntilType(srcInput,Constants.VARIABLE_DECLARATION_STATEMENT);
dstInput = TreeUtilFunctions.getParentUntilType(dstInput,Constants.FIELD_DECLARATION);
if (mappingStore.isSrcMapped(srcInput) || mappingStore.isDstMapped(dstInput))
continue;
break;
case REPLACE_ATTRIBUTE_WITH_VARIABLE:
srcInput = TreeUtilFunctions.getParentUntilType(srcInput,Constants.FIELD_DECLARATION);
dstInput = TreeUtilFunctions.getParentUntilType(dstInput,Constants.VARIABLE_DECLARATION_STATEMENT);
if (mappingStore.isSrcMapped(srcInput) || mappingStore.isDstMapped(dstInput))
continue;
break;
case RENAME_PARAMETER:
eligible = !renameVariableRefactoring.isInsideExtractedOrInlinedMethod();
break;
case RENAME_VARIABLE:
Set references = renameVariableRefactoring.getReferences();
for (AbstractCodeMapping abstractCodeMapping : references) {
if (((RenameVariableRefactoring) refactoring).isInsideExtractedOrInlinedMethod() &&
multipleInstancesWithSameDescription(refactoringList,((RenameVariableRefactoring) refactoring).getOperationBefore(),((RenameVariableRefactoring) refactoring).getOperationAfter())) {
eligible = false;
}
if (eligible) {
if (abstractCodeMapping instanceof LeafMapping) {
findVariablesAndMatch(srcTree, dstTree, abstractCodeMapping, renameVariableRefactoring.getOriginalVariable().getVariableName(), renameVariableRefactoring.getRenamedVariable().getVariableName());
}
}
}
eligible = false;
break;
case PARAMETERIZE_VARIABLE:
eligible = !renameVariableRefactoring.isInsideExtractedOrInlinedMethod();
if (!eligible)
break;
while (!TreeUtilFunctions.isStatement(srcInput.getType().name)) {
if (srcInput.getType() == null) break;
srcInput = srcInput.getParent();
}
if (TreeUtilFunctions.isStatement(srcInput.getType().name)){
new LeafMatcher().match(srcInput,dstInput,mappingStore);
}
eligible = false;
break;
case LOCALIZE_PARAMETER:
eligible = !renameVariableRefactoring.isInsideExtractedOrInlinedMethod();
if (!eligible)
break;
while (!TreeUtilFunctions.isStatement(dstInput.getType().name)) {
if (dstInput.getType() == null) break;
dstInput = dstInput.getParent();
}
if (TreeUtilFunctions.isStatement(dstInput.getType().name)){
new LeafMatcher().match(srcInput,dstInput,mappingStore);
}
eligible = false;
break;
default:
eligible = false;
}
if (eligible) new LeafMatcher().match(
srcInput,
dstInput,
mappingStore);
}
else if (refactoring instanceof ModifyClassAnnotationRefactoring)
{
ModifyClassAnnotationRefactoring modifiedAnnotationRefactoring = (ModifyClassAnnotationRefactoring) refactoring;
if (modifiedAnnotationRefactoring.getAnnotationBefore().getTypeName().equals(modifiedAnnotationRefactoring.getAnnotationAfter().getTypeName()))
processModifiedAnnotation(srcTree, dstTree, mappingStore, modifiedAnnotationRefactoring.getAnnotationBefore(), modifiedAnnotationRefactoring.getAnnotationAfter());
}
else if (refactoring instanceof ModifyMethodAnnotationRefactoring)
{
ModifyMethodAnnotationRefactoring modifiedAnnotationRefactoring = (ModifyMethodAnnotationRefactoring) refactoring;
if (modifiedAnnotationRefactoring.getAnnotationBefore().getTypeName().equals(modifiedAnnotationRefactoring.getAnnotationAfter().getTypeName()))
processModifiedAnnotation(srcTree, dstTree, mappingStore, modifiedAnnotationRefactoring.getAnnotationBefore(), modifiedAnnotationRefactoring.getAnnotationAfter());
}
else if (refactoring instanceof ModifyAttributeAnnotationRefactoring)
{
ModifyAttributeAnnotationRefactoring modifiedAnnotationRefactoring = (ModifyAttributeAnnotationRefactoring) refactoring;
if (modifiedAnnotationRefactoring.getAnnotationBefore().getTypeName().equals(modifiedAnnotationRefactoring.getAnnotationAfter().getTypeName()))
processModifiedAnnotation(srcTree, dstTree, mappingStore, modifiedAnnotationRefactoring.getAnnotationBefore(), modifiedAnnotationRefactoring.getAnnotationAfter());
}
else if (refactoring instanceof ModifyVariableAnnotationRefactoring)
{
ModifyVariableAnnotationRefactoring modifiedAnnotationRefactoring = (ModifyVariableAnnotationRefactoring) refactoring;
if (modifiedAnnotationRefactoring.getAnnotationBefore().getTypeName().equals(modifiedAnnotationRefactoring.getAnnotationAfter().getTypeName()))
processModifiedAnnotation(srcTree, dstTree, mappingStore, modifiedAnnotationRefactoring.getAnnotationBefore(), modifiedAnnotationRefactoring.getAnnotationAfter());
}
else if (refactoring instanceof RenameAttributeRefactoring) {
RenameAttributeRefactoring renameAttributeRefactoring = (RenameAttributeRefactoring) refactoring;
for (AbstractCodeMapping reference : renameAttributeRefactoring.getReferences()) {
List subExpressionMappings = reference.getSubExpressionMappings();
for (LeafMapping subExpressionMapping : subExpressionMappings) {
Tree srcSimpleName = TreeUtilFunctions.findByLocationInfo(srcTree, subExpressionMapping.getFragment1().getLocationInfo(), Constants.SIMPLE_NAME);
Tree dstSimpleName = TreeUtilFunctions.findByLocationInfo(dstTree, subExpressionMapping.getFragment2().getLocationInfo(), Constants.SIMPLE_NAME);
if (srcSimpleName != null && dstSimpleName != null)
optimizationMappingStore.addMapping(srcSimpleName,dstSimpleName);
}
}
}
}
}
private void processArgumentMappings(Tree srcTree, Tree dstTree, List refactoringList, Refactoring refactoring, List argumentMappings) {
//skip argument mappings, if the same method is extracted more than once from the original method.
if(!multipleInstancesWithSameDescription(refactoringList, refactoring)) {
for(AbstractCodeMapping expressionMapping : argumentMappings) {
Tree t1 = TreeUtilFunctions.findByLocationInfo(srcTree,expressionMapping.getFragment1().getLocationInfo());
Tree t2 = TreeUtilFunctions.findByLocationInfo(dstTree,expressionMapping.getFragment2().getLocationInfo());
new LeafMatcher().match(t1,t2,optimizationMappingStore);
}
}
}
private boolean multipleInstancesWithSameDescription(List refactoringList, VariableDeclarationContainer operationBefore, VariableDeclarationContainer operationAfter) {
int counter1 = 0;
int counter2 = 0;
for (Refactoring r : refactoringList) {
if (r.getRefactoringType().equals(RefactoringType.EXTRACT_OPERATION))
{
if (((ExtractOperationRefactoring)r).getExtractedOperation().equals(operationAfter))
counter1++;
}
else if (r.getRefactoringType().equals(RefactoringType.INLINE_OPERATION))
{
if (((InlineOperationRefactoring)r).getInlinedOperation().equals(operationBefore))
counter2++;
}
}
return (counter1 > 1 || counter2 > 1);
}
private static void processModifiedAnnotation(Tree srcTree, Tree dstTree, ExtendedMultiMappingStore mappingStore, UMLAnnotation annotationBefore, UMLAnnotation annotationAfter) {
Tree srcAnnotationTree = TreeUtilFunctions.findByLocationInfo(srcTree, annotationBefore.getLocationInfo());
Tree dstAnnotationTree = TreeUtilFunctions.findByLocationInfo(dstTree, annotationAfter.getLocationInfo());
if (srcAnnotationTree != null & dstAnnotationTree != null)
new BasicTreeMatcher().match(srcAnnotationTree,dstAnnotationTree, mappingStore);
mappingStore.addMapping(srcAnnotationTree,dstAnnotationTree);
}
private void findVariablesAndMatch(Tree srcTree, Tree dstTree, AbstractCodeMapping abstractCodeMapping, String originalVariableName, String renamedVariableName) {
Tree srcStatement = TreeUtilFunctions.findByLocationInfo(srcTree, abstractCodeMapping.getFragment1().getLocationInfo());
Tree dstStatement = TreeUtilFunctions.findByLocationInfo(dstTree, abstractCodeMapping.getFragment2().getLocationInfo());
List srcRefs = TreeUtilFunctions.findVariable(srcStatement ,originalVariableName);
List dstRefs = TreeUtilFunctions.findVariable(dstStatement ,renamedVariableName);
if (srcRefs == null || dstRefs == null) return;
if (srcRefs.size() == 1 && dstRefs.size() == 1)
optimizationMappingStore.addMapping(srcRefs.get(0),dstRefs.get(0));
else{
if (srcRefs.size() == dstRefs.size())
{
for (int i = 0; i < srcRefs.size(); i++) {
optimizationMappingStore.addMapping(srcRefs.get(i),dstRefs.get(i));
}
}
}
}
private void processClassImplementedInterfaces(Tree srcTree, Tree dstTree, UMLClassBaseDiff classDiff, ExtendedMultiMappingStore mappingStore) {
List srcImplementedInterfaces = classDiff.getOriginalClass().getImplementedInterfaces();
List dstImplementedInterfaces = classDiff.getNextClass().getImplementedInterfaces();
List removedOnes = classDiff.getRemovedImplementedInterfaces();
for (UMLType srcUmlType : srcImplementedInterfaces) {
if (!removedOnes.contains(srcUmlType)) {
Tree srcInterfaceTree =TreeUtilFunctions.findByLocationInfo(srcTree,srcUmlType.getLocationInfo());
for (UMLType dstUmlType : dstImplementedInterfaces) {
if (dstUmlType.getClassType().equals(srcUmlType.getClassType())) {
Tree dstInterfaceTree =TreeUtilFunctions.findByLocationInfo(dstTree,dstUmlType.getLocationInfo());
mappingStore.addMappingRecursively(srcInterfaceTree, dstInterfaceTree);
break;
}
}
}
}
}
private void processClassAttributes(Tree srcTree, Tree dstTree, UMLAbstractClassDiff classDiff, ExtendedMultiMappingStore mappingStore) {
Set> pairs = classDiff.getCommonAtrributes();
for (org.apache.commons.lang3.tuple.Pair pair : pairs) {
processFieldDeclaration(srcTree,dstTree,pair.getLeft(),pair.getRight(),mappingStore);
}
List attributeDiffList = classDiff.getAttributeDiffList();
for (UMLAttributeDiff umlAttributeDiff : attributeDiffList) {
processFieldDeclarationByAttrDiff(srcTree,dstTree,umlAttributeDiff,mappingStore);
}
List enumConstantDiffList = classDiff.getEnumConstantDiffList();
for (UMLEnumConstantDiff enumConstantDiff : enumConstantDiffList) {
processFieldDeclarationByEnumConstantDiff(srcTree,dstTree,enumConstantDiff,mappingStore);
}
}
private void processFieldDeclarationByAttrDiff(Tree srcTree, Tree dstTree, UMLAttributeDiff umlAttributeDiff, ExtendedMultiMappingStore mappingStore) {
processFieldDeclaration(srcTree,dstTree,umlAttributeDiff.getRemovedAttribute(),umlAttributeDiff.getAddedAttribute(),mappingStore);
if (umlAttributeDiff.getInitializerMapper().isPresent()) {
UMLOperationBodyMapper umlOperationBodyMapper = umlAttributeDiff.getInitializerMapper().get();
processMethod(srcTree, dstTree, umlOperationBodyMapper, mappingStore);
}
}
private void processFieldDeclarationByEnumConstantDiff(Tree srcTree, Tree dstTree, UMLEnumConstantDiff umlEnumConstantDiff, ExtendedMultiMappingStore mappingStore) {
processFieldDeclaration(srcTree,dstTree,umlEnumConstantDiff.getRemovedEnumConstant(),umlEnumConstantDiff.getAddedEnumConstant(),mappingStore);
if(umlEnumConstantDiff.getAnonymousClassDiff().isPresent()) {
UMLAnonymousClassDiff anonymousClassDiff = umlEnumConstantDiff.getAnonymousClassDiff().get();
processAnonymousClassDiff(srcTree, dstTree, anonymousClassDiff, mappingStore);
}
}
private void processAnonymousClassDiff(Tree srcTree, Tree dstTree, UMLAnonymousClassDiff anonymousClassDiff, ExtendedMultiMappingStore mappingStore) {
List operationBodyMapperList = anonymousClassDiff.getOperationBodyMapperList();
for (UMLOperationBodyMapper umlOperationBodyMapper : operationBodyMapperList) {
processMethod(srcTree, dstTree,umlOperationBodyMapper, mappingStore);
}
}
private void processFieldDeclaration(Tree srcTree, Tree dstTree, UMLAttribute srcUMLAttribute,UMLAttribute dstUMLAttribute, ExtendedMultiMappingStore mappingStore) {
Tree srcAttr = TreeUtilFunctions.findByLocationInfo(srcTree, srcUMLAttribute.getLocationInfo());
Tree dstAttr = TreeUtilFunctions.findByLocationInfo(dstTree, dstUMLAttribute.getLocationInfo());
if (srcAttr == null || dstAttr == null) return;
Tree srcFieldDeclaration = TreeUtilFunctions.getParentUntilType(srcAttr, Constants.FIELD_DECLARATION);
Tree dstFieldDeclaration = TreeUtilFunctions.getParentUntilType(dstAttr, Constants.FIELD_DECLARATION);
if (srcFieldDeclaration == null) {
srcFieldDeclaration = TreeUtilFunctions.getParentUntilType(srcAttr, Constants.ENUM_CONSTANT_DECLARATION);
}
if (dstFieldDeclaration == null) {
dstFieldDeclaration = TreeUtilFunctions.getParentUntilType(dstAttr, Constants.ENUM_CONSTANT_DECLARATION);
}
//handle Record Components (SingleVariableDeclaration)
if (srcFieldDeclaration == null) {
srcFieldDeclaration = TreeUtilFunctions.getParentUntilType(srcAttr, Constants.RECORD_COMPONENT);
}
if (dstFieldDeclaration == null) {
dstFieldDeclaration = TreeUtilFunctions.getParentUntilType(dstAttr, Constants.RECORD_COMPONENT);
}
// || srcFieldDeclaration.isIsoStructuralTo(dstFieldDeclaration))
if (srcFieldDeclaration != null && dstFieldDeclaration != null && srcFieldDeclaration.getMetrics().hash == dstFieldDeclaration.getMetrics().hash) {
//IsoStructural can't be a good idea here, i.e. anonymous class
mappingStore.addMappingRecursively(srcFieldDeclaration, dstFieldDeclaration);
return;
}
if (srcAttr.getMetrics().hash == dstAttr.getMetrics().hash) {
mappingStore.addMappingRecursively(srcAttr,dstAttr);
}
mappingStore.addMapping(srcFieldDeclaration,dstFieldDeclaration);
matchFieldAllModifiers(srcFieldDeclaration,dstFieldDeclaration,srcUMLAttribute,dstUMLAttribute,mappingStore);
if (srcUMLAttribute.getType().getLocationInfo() == null || dstUMLAttribute.getType().getLocationInfo() == null) {
if (srcUMLAttribute instanceof UMLEnumConstant && dstUMLAttribute instanceof UMLEnumConstant) {
//JavaDocs are mapped as well.
new LeafMatcher().match(srcAttr,dstAttr,mappingStore);
return;
}
}
Tree srcType = TreeUtilFunctions.findByLocationInfo(srcTree,srcUMLAttribute.getType().getLocationInfo());
Tree dstType = TreeUtilFunctions.findByLocationInfo(dstTree,dstUMLAttribute.getType().getLocationInfo());
if (srcType != null && dstType != null && srcType.isIsoStructuralTo(dstType)) mappingStore.addMappingRecursively(srcType,dstType);
else {
new LeafMatcher().match(srcType,dstType,mappingStore);
}
Tree srcVarDeclaration = TreeUtilFunctions.findByLocationInfo(srcTree,srcUMLAttribute.getVariableDeclaration().getLocationInfo());
Tree dstVarDeclaration = TreeUtilFunctions.findByLocationInfo(dstTree,dstUMLAttribute.getVariableDeclaration().getLocationInfo());
mappingStore.addMapping(srcVarDeclaration,dstVarDeclaration);
new LeafMatcher().match(srcVarDeclaration,dstVarDeclaration,mappingStore);
processJavaDocs(srcTree,dstTree,srcUMLAttribute.getJavadoc(),dstUMLAttribute.getJavadoc(),mappingStore);
if (srcVarDeclaration != null && dstVarDeclaration != null)
mappingStore.addMapping(srcVarDeclaration.getChild(0),dstVarDeclaration.getChild(0));
}
private void matchFieldAllModifiers(Tree srcFieldDeclaration, Tree dstFieldDeclaration, UMLAttribute srcUMLAttribute, UMLAttribute dstUMLAttribute, ExtendedMultiMappingStore mappingStore) {
//Pair attributeAccessModifierPair = findAttributeAccessModifierPair(srcFieldDeclaration, dstFieldDeclaration, srcUMLAttribute, dstUMLAttribute);
//if (attributeAccessModifierPair.first != null && attributeAccessModifierPair.second != null)
// mappingStore.addMapping(attributeAccessModifierPair.first, attributeAccessModifierPair.second);
// if (srcUMLAttribute.getVisibility().equals(dstUMLAttribute.getVisibility()))
matchModifiersForField(srcFieldDeclaration,dstFieldDeclaration,srcUMLAttribute.getVisibility().toString(),dstUMLAttribute.getVisibility().toString(),mappingStore);
if (srcUMLAttribute.isFinal() && dstUMLAttribute.isFinal())
matchModifierForField(srcFieldDeclaration,dstFieldDeclaration,Constants.FINAL,mappingStore);
if (srcUMLAttribute.isVolatile() && dstUMLAttribute.isVolatile())
matchModifierForField(srcFieldDeclaration,dstFieldDeclaration,Constants.VOLATILE,mappingStore);
if (srcUMLAttribute.isStatic() && dstUMLAttribute.isStatic())
matchModifierForField(srcFieldDeclaration,dstFieldDeclaration,Constants.STATIC,mappingStore);
if (srcUMLAttribute.isTransient() && dstUMLAttribute.isTransient())
matchModifierForField(srcFieldDeclaration,dstFieldDeclaration,Constants.TRANSIENT,mappingStore);
}
private void matchModifiersForField(Tree srcFieldDeclaration, Tree dstFieldDeclaration, String srcModifier, String dstModifier, ExtendedMultiMappingStore mappingStore) {
Tree srcModifierTree = findAttributeModifierByLabel(srcFieldDeclaration, srcModifier);
Tree dstModifierTree = findAttributeModifierByLabel(dstFieldDeclaration, dstModifier);
if (srcModifierTree != null && dstModifierTree != null)
mappingStore.addMapping(srcModifierTree,dstModifierTree);
}
private void matchModifierForField(Tree srcFieldDeclaration, Tree dstFieldDeclaration, String modifier, ExtendedMultiMappingStore mappingStore) {
Tree srcModifierTree = findAttributeModifierByLabel(srcFieldDeclaration, modifier);
Tree dstModifierTree = findAttributeModifierByLabel(dstFieldDeclaration, modifier);
if (srcModifierTree != null && dstModifierTree != null)
mappingStore.addMapping(srcModifierTree,dstModifierTree);
}
private Tree findAttributeModifierByLabel(Tree anyFieldDeclaration,String label) {
if (anyFieldDeclaration.getChildren().size() > 0) {
for (Tree child : anyFieldDeclaration.getChildren()) {
if (child.getLabel().equals(label))
return child;
if (child.getType().name.equals(Constants.VARIABLE_DECLARATION_FRAGMENT))
break;
}
}
return null;
}
private void processSuperClass(Tree srcTree, Tree dstTree, UMLClassBaseDiff classDiff, ExtendedMultiMappingStore mappingStore) {
UMLType srcParentUML = classDiff.getOldSuperclass();
UMLType dstParentUML = classDiff.getNewSuperclass();
if (srcParentUML != null && dstParentUML != null) {
Tree srcParentClassTree =TreeUtilFunctions.findByLocationInfo(srcTree, srcParentUML.getLocationInfo());
Tree dstParentClassTree =TreeUtilFunctions.findByLocationInfo(dstTree, dstParentUML.getLocationInfo());
if (srcParentClassTree != null && dstParentClassTree != null)
if (srcParentClassTree.isIsoStructuralTo(dstParentClassTree))
mappingStore.addMappingRecursively(srcParentClassTree,dstParentClassTree);
}
}
private void processPackageDeclaration(Tree srcTree, Tree dstTree, ExtendedMultiMappingStore mappingStore) {
Tree srcPackageDeclaration = findPackageDeclaration(srcTree);
Tree dstPackageDeclaration = findPackageDeclaration(dstTree);
if (srcPackageDeclaration != null && dstPackageDeclaration != null)
mappingStore.addMappingRecursively(srcPackageDeclaration,dstPackageDeclaration);
}
private Tree findPackageDeclaration(Tree inputTree) {
String searchingType = Constants.PACKAGE_DECLARATION;
if (!inputTree.getChildren().isEmpty()) {
List children = inputTree.getChildren();
for(Tree child: children) {
if (child.getType().name.equals(searchingType))
return child;
}
}
return null;
}
private void processImports(Tree srcTree, Tree dstTree, UMLImportListDiff importDiffList, ExtendedMultiMappingStore mappingStore) {
if (importDiffList == null) return;
Set> commonImports = importDiffList.getCommonImports();
String searchingType = Constants.IMPORT_DECLARATION;
if (!commonImports.isEmpty()) {
for (org.apache.commons.lang3.tuple.Pair pair : commonImports) {
Tree srcImportStatement = findImportByTypeAndLabel(srcTree, searchingType, pair.getLeft());
Tree dstImportStatement = findImportByTypeAndLabel(dstTree, searchingType, pair.getRight());
if (srcImportStatement != null && dstImportStatement != null)
mappingStore.addMappingRecursively(srcImportStatement, dstImportStatement);
}
}
//Grouped Imports
for (Map.Entry, UMLImport> setUMLImportEntry : importDiffList.getGroupedImports().entrySet()) {
Set srcImportSet = setUMLImportEntry.getKey();
UMLImport dstImport = setUMLImportEntry.getValue();
Tree dstImportStatement = findImportByTypeAndLabel(dstTree,searchingType,dstImport);
for (UMLImport srcUMLImport : srcImportSet) {
Tree srcImportStatement = findImportByTypeAndLabel(srcTree,searchingType,srcUMLImport);
mappingStore.addMappingRecursively(srcImportStatement,dstImportStatement);
}
}
//UnGrouped Imports
for (Map.Entry> umlImportSetEntry : importDiffList.getUnGroupedImports().entrySet()) {
UMLImport srcImport = umlImportSetEntry.getKey();
Set dstImportSet = umlImportSetEntry.getValue();
Tree srcImportStatement = findImportByTypeAndLabel(srcTree,searchingType,srcImport);
for (UMLImport dstUMLImport : dstImportSet) {
Tree dstImportStatement = findImportByTypeAndLabel(dstTree,searchingType,dstUMLImport);
mappingStore.addMappingRecursively(srcImportStatement,dstImportStatement);
}
}
//Changed Imports
for(org.apache.commons.lang3.tuple.Pair pair : importDiffList.getChangedImports()) {
Tree srcImportStatement = findImportByTypeAndLabel(srcTree,searchingType,pair.getLeft());
Tree dstImportStatement = findImportByTypeAndLabel(dstTree,searchingType,pair.getRight());
mappingStore.addMappingRecursively(srcImportStatement,dstImportStatement);
}
}
private Tree findImportByTypeAndLabel(Tree inputTree, String searchingType, UMLImport label) {
for (Tree treeNode: inputTree.getChildren()) {
if (treeNode.getType().name.equals(searchingType)) {
if (treeNode.getChild(0).getLabel().equals(label.getName()) && treeNode.getPos() == label.getLocationInfo().getStartOffset()) //getChild 0 might be problematic
if (label.isOnDemand()) {
if (treeNode.getChild(0).getEndPos() + 3 == treeNode.getEndPos()) {
return treeNode;
}
} else {
return treeNode;
}
}
}
return null;
}
private void processMethodSignature(Tree srcOperationNode, Tree dstOperationNode, UMLOperationBodyMapper umlOperationBodyMapper, ExtendedMultiMappingStore mappingStore) {
if (srcOperationNode == null || dstOperationNode == null) return;
List searchingTypes = new ArrayList<>();
//searchingTypes.add(Constants.ACCESS_MODIFIER);
searchingTypes.add(Constants.SIMPLE_NAME);
searchingTypes.add(Constants.PRIMITIVE_TYPE);
searchingTypes.add(Constants.BLOCK);
for (String type : searchingTypes) {
Pair matched = matchBasedOnType(srcOperationNode,dstOperationNode,type);
if (matched != null)
mappingStore.addMapping(matched.first,matched.second);
}
if (umlOperationBodyMapper.getOperation1() != null && umlOperationBodyMapper.getOperation2() != null) {
if (umlOperationBodyMapper.getOperation1().isStatic() && umlOperationBodyMapper.getOperation2().isStatic())
matchModifier(srcOperationNode, dstOperationNode, Constants.STATIC, mappingStore);
if (umlOperationBodyMapper.getOperation1().isFinal() && umlOperationBodyMapper.getOperation2().isFinal())
matchModifier(srcOperationNode, dstOperationNode, Constants.FINAL, mappingStore);
if (umlOperationBodyMapper.getOperation1().isAbstract() && umlOperationBodyMapper.getOperation2().isAbstract())
matchModifier(srcOperationNode, dstOperationNode, Constants.ABSTRACT, mappingStore);
if (umlOperationBodyMapper.getOperation1().isSynchronized() && umlOperationBodyMapper.getOperation2().isSynchronized())
matchModifier(srcOperationNode, dstOperationNode, Constants.SYNCHRONIZED, mappingStore);
if (umlOperationBodyMapper.getOperation1().isNative() && umlOperationBodyMapper.getOperation2().isNative())
matchModifier(srcOperationNode, dstOperationNode, Constants.NATIVE, mappingStore);
String v1 = umlOperationBodyMapper.getOperation1().getVisibility().toString();
String v2 = umlOperationBodyMapper.getOperation2().getVisibility().toString();
Tree tree1 = TreeUtilFunctions.findChildByTypeAndLabel(srcOperationNode, Constants.MODIFIER, v1);
Tree tree2 = TreeUtilFunctions.findChildByTypeAndLabel(dstOperationNode, Constants.MODIFIER, v2);
if (tree1 != null && tree2 != null)
mappingStore.addMappingRecursively(tree1,tree2);
}
}
private Pair matchBasedOnType(Tree srcOperationNode, Tree dstOperationNode, String searchingType) {
if (srcOperationNode == null || dstOperationNode == null) return null;
Tree srcModifier = TreeUtilFunctions.findChildByType(srcOperationNode,searchingType);
Tree dstModifier = TreeUtilFunctions.findChildByType(dstOperationNode,searchingType);
if (srcModifier != null && dstModifier != null)
return new Pair<>(srcModifier, dstModifier);
return null;
}
private void processClassDeclarationMapping(Tree srcTree, Tree dstTree, UMLClassBaseDiff classDiff, ExtendedMultiMappingStore mappingStore) {
String AST_type = Constants.TYPE_DECLARATION;
if (classDiff.getOriginalClass().isEnum())
AST_type = Constants.ENUM_DECLARATION;
else if (classDiff.getOriginalClass().isAnnotation())
AST_type = Constants.ANNOTATION_TYPE_DECLARATION;
else if (classDiff.getOriginalClass().isRecord())
AST_type = Constants.RECORD_DECLARATION;
Tree srcTypeDeclaration = TreeUtilFunctions.findByLocationInfo(srcTree,classDiff.getOriginalClass().getLocationInfo(),AST_type);
Tree dstTypeDeclaration = TreeUtilFunctions.findByLocationInfo(dstTree,classDiff.getNextClass().getLocationInfo(),AST_type);
if (srcTypeDeclaration == null || dstTypeDeclaration == null) return;
if (srcTypeDeclaration.getParent() != null && dstTypeDeclaration.getParent() != null) {
if (
srcTypeDeclaration.getParent().getType().name.equals(Constants.TYPE_DECLARATION_STATEMENT)
&&
dstTypeDeclaration.getParent().getType().name.equals(Constants.TYPE_DECLARATION_STATEMENT)
)
mappingStore.addMapping(srcTypeDeclaration.getParent(),dstTypeDeclaration.getParent());
}
mappingStore.addMapping(srcTypeDeclaration,dstTypeDeclaration);
String v1 = classDiff.getOriginalClass().getVisibility().toString();
String v2 = classDiff.getNextClass().getVisibility().toString();
Tree tree1 = TreeUtilFunctions.findChildByTypeAndLabel(srcTypeDeclaration, Constants.MODIFIER, v1);
Tree tree2 = TreeUtilFunctions.findChildByTypeAndLabel(dstTypeDeclaration, Constants.MODIFIER, v2);
if (tree1 != null && tree2 != null)
mappingStore.addMappingRecursively(tree1,tree2);
List searchingTypes = new ArrayList<>();
searchingTypes.add(Constants.SIMPLE_NAME);
searchingTypes.add(Constants.TYPE_DECLARATION_KIND);
for (String type : searchingTypes) {
Pair matched = matchBasedOnType(srcTypeDeclaration,dstTypeDeclaration,type);
if (matched != null)
mappingStore.addMapping(matched.first,matched.second);
}
if (classDiff.getOriginalClass().isStatic() && classDiff.getNextClass().isStatic())
matchModifier(srcTypeDeclaration,dstTypeDeclaration,Constants.STATIC,mappingStore);
if (classDiff.getOriginalClass().isFinal() && classDiff.getNextClass().isFinal())
matchModifier(srcTypeDeclaration,dstTypeDeclaration,Constants.FINAL,mappingStore);
if (classDiff.getOriginalClass().isAbstract() && classDiff.getNextClass().isAbstract())
matchModifier(srcTypeDeclaration,dstTypeDeclaration,Constants.ABSTRACT,mappingStore);
for (org.apache.commons.lang3.tuple.Pair commonTypeParamSet : classDiff.getTypeParameterDiffList().getCommonTypeParameters()) {
Tree srcTypeParam = TreeUtilFunctions.findByLocationInfo(srcTypeDeclaration, commonTypeParamSet.getLeft().getLocationInfo());
Tree dstTypeParam = TreeUtilFunctions.findByLocationInfo(dstTypeDeclaration, commonTypeParamSet.getRight().getLocationInfo());
mappingStore.addMappingRecursively(srcTypeParam,dstTypeParam);
}
processSuperClass(srcTypeDeclaration,dstTypeDeclaration,classDiff,mappingStore);
processClassImplementedInterfaces(srcTypeDeclaration,dstTypeDeclaration,classDiff,mappingStore);
processJavaDocs(srcTypeDeclaration,dstTypeDeclaration,classDiff.getOriginalClass().getJavadoc(),classDiff.getNextClass().getJavadoc(),mappingStore);
processClassAnnotations(srcTypeDeclaration,dstTypeDeclaration,classDiff.getAnnotationListDiff(),mappingStore);
}
private void matchModifier(Tree srcTypeDeclaration, Tree dstTypeDeclaration, String modifier, ExtendedMultiMappingStore mappingStore) {
String type = Constants.MODIFIER;
Tree srcTree = TreeUtilFunctions.findChildByTypeAndLabel(srcTypeDeclaration,type,modifier);
Tree dstTree = TreeUtilFunctions.findChildByTypeAndLabel(dstTypeDeclaration,type,modifier);
if (srcTree != null && dstTree != null){
mappingStore.addMapping(srcTree,dstTree);
}
}
private final Map optimizationDataMap = new HashMap<>();
private static class OptimizationData{
List lastStepMappings;
ExtendedMultiMappingStore optimizationMappingStore;
public OptimizationData(List lastStepMappings, ExtendedMultiMappingStore optimizationMappingStore) {
this.lastStepMappings = lastStepMappings;
this.optimizationMappingStore = optimizationMappingStore;
}
}
}