org.refactoringminer.astDiff.moved.MovedDeclarationGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refactoring-miner Show documentation
Show all versions of refactoring-miner Show documentation
RefactoringMiner is a library/API written in Java that can detect refactorings applied in the history of a Java project.
package org.refactoringminer.astDiff.moved;
import com.github.gumtreediff.actions.model.Action;
import com.github.gumtreediff.matchers.Mapping;
import com.github.gumtreediff.tree.Tree;
import com.github.gumtreediff.utils.Pair;
import gr.uom.java.xmi.diff.UMLModelDiff;
import org.refactoringminer.astDiff.models.ASTDiff;
import org.refactoringminer.astDiff.actions.classifier.ExtendedOnlyRootsClassifier;
import org.refactoringminer.astDiff.models.ProjectASTDiff;
import org.refactoringminer.astDiff.actions.model.MoveOut;
import org.refactoringminer.astDiff.actions.model.MultiMove;
import org.refactoringminer.astDiff.utils.Constants;
import org.refactoringminer.astDiff.utils.TreeUtilFunctions;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static org.refactoringminer.astDiff.utils.Helpers.findNameByTree;
/* Created by pourya on 2024-05-16*/
public class MovedDeclarationGenerator extends MovedASTDiffGenerator {
public MovedDeclarationGenerator(UMLModelDiff modelDiff, ProjectASTDiff projectASTDiff) {
super(modelDiff, projectASTDiff);
}
@Override
public Map, List> makeFilePairMappings() {
Map, List> filePairMappings = new LinkedHashMap<>();
for(ASTDiff diff : projectASTDiff.getDiffSet()) {
Map> methodDeclarationMappings = new LinkedHashMap>();
Map> fieldDeclarationMappings = new LinkedHashMap>();
Map> typeDeclarationMappings = new LinkedHashMap>();
Map actionMap = new LinkedHashMap();
ExtendedOnlyRootsClassifier classifier = (ExtendedOnlyRootsClassifier) diff.createRootNodesClassifier();
populateMoveMappings(diff, methodDeclarationMappings, fieldDeclarationMappings, typeDeclarationMappings, actionMap, classifier.getSrcMoveOutTreeMap());
populateMoveMappings(diff, methodDeclarationMappings, fieldDeclarationMappings, typeDeclarationMappings, actionMap, classifier.getMultiMapSrc());
//group the mappings based on the pair of src and dst files.
String srcPath = diff.getSrcPath();
for(Tree key : methodDeclarationMappings.keySet()) {
if(actionMap.containsKey(key)) {
Action action = actionMap.get(key);
if(action instanceof MoveOut) {
MoveOut moveOut = (MoveOut)action;
String dstPath = moveOut.getDstFile();
Pair pair = new Pair(srcPath, dstPath);
if(filePairMappings.containsKey(pair)) {
filePairMappings.get(pair).addAll(methodDeclarationMappings.get(key));
}
else {
List mappings = new ArrayList();
mappings.addAll(methodDeclarationMappings.get(key));
filePairMappings.put(pair, mappings);
}
}
else if(action instanceof MultiMove) {
MultiMove moveOut = (MultiMove)action;
String dstPath = findNameByTree(modelDiff.getChildModel().getTreeContextMap(), moveOut.getParent());
Pair pair = new Pair(srcPath, dstPath);
if(filePairMappings.containsKey(pair)) {
filePairMappings.get(pair).addAll(methodDeclarationMappings.get(key));
}
else {
List mappings = new ArrayList();
mappings.addAll(methodDeclarationMappings.get(key));
filePairMappings.put(pair, mappings);
}
}
}
}
for(Tree key : fieldDeclarationMappings.keySet()) {
if(actionMap.containsKey(key)) {
Action action = actionMap.get(key);
if(action instanceof MoveOut) {
MoveOut moveOut = (MoveOut)action;
String dstPath = moveOut.getDstFile();
Pair pair = new Pair(srcPath, dstPath);
if(filePairMappings.containsKey(pair)) {
filePairMappings.get(pair).addAll(fieldDeclarationMappings.get(key));
}
else {
List mappings = new ArrayList();
mappings.addAll(fieldDeclarationMappings.get(key));
filePairMappings.put(pair, mappings);
}
}
else if(action instanceof MultiMove) {
MultiMove moveOut = (MultiMove)action;
String dstPath = findNameByTree(modelDiff.getChildModel().getTreeContextMap(), moveOut.getParent());
Pair pair = new Pair(srcPath, dstPath);
if(filePairMappings.containsKey(pair)) {
filePairMappings.get(pair).addAll(fieldDeclarationMappings.get(key));
}
else {
List mappings = new ArrayList();
mappings.addAll(fieldDeclarationMappings.get(key));
filePairMappings.put(pair, mappings);
}
}
}
}
for(Tree key : typeDeclarationMappings.keySet()) {
if(actionMap.containsKey(key)) {
Action action = actionMap.get(key);
if(action instanceof MoveOut) {
MoveOut moveOut = (MoveOut)action;
String dstPath = moveOut.getDstFile();
Pair pair = new Pair(srcPath, dstPath);
if(filePairMappings.containsKey(pair)) {
filePairMappings.get(pair).addAll(typeDeclarationMappings.get(key));
}
else {
List mappings = new ArrayList();
mappings.addAll(typeDeclarationMappings.get(key));
filePairMappings.put(pair, mappings);
}
}
else if(action instanceof MultiMove) {
MultiMove moveOut = (MultiMove)action;
String dstPath = findNameByTree(modelDiff.getChildModel().getTreeContextMap(), moveOut.getParent());
Pair pair = new Pair(srcPath, dstPath);
if(filePairMappings.containsKey(pair)) {
filePairMappings.get(pair).addAll(typeDeclarationMappings.get(key));
}
else {
List mappings = new ArrayList();
mappings.addAll(typeDeclarationMappings.get(key));
filePairMappings.put(pair, mappings);
}
}
}
}
}
return filePairMappings;
}
private void populateMoveMappings(ASTDiff diff, Map> methodDeclarationMappings,
Map> fieldDeclarationMappings, Map> typeDeclarationMappings,
Map actionMap, Map map) {
for(Tree src : map.keySet()) {
Tree methodRoot = TreeUtilFunctions.getParentUntilType(src, Constants.METHOD_DECLARATION);
populateMappingsRoot(diff, methodDeclarationMappings, actionMap, map, src, methodRoot);
Tree fieldRoot = TreeUtilFunctions.getParentUntilType(src, Constants.FIELD_DECLARATION);
populateMappingsRoot(diff, fieldDeclarationMappings, actionMap, map, src, fieldRoot);
if(src.getType().name.equals(Constants.TYPE_DECLARATION) ||
src.getType().name.equals(Constants.ENUM_DECLARATION) ||
src.getType().name.equals(Constants.RECORD_DECLARATION)) {
actionMap.put(src, map.get(src));
List mappings = new ArrayList();
mappings.addAll(getMappingForLeft(diff, src));
typeDeclarationMappings.put(src, mappings);
}
}
}
private void populateMappingsRoot(ASTDiff diff, Map> elementDeclMappings, Map actionMap, Map map, Tree src, Tree elementRoot) {
if(elementRoot != null) {
if(elementDeclMappings.containsKey(elementRoot)) {
elementDeclMappings.get(elementRoot).addAll(getMappingForLeft(diff, src));
}
else {
List mappings = new ArrayList();
mappings.addAll(getMappingForLeft(diff, src));
elementDeclMappings.put(elementRoot, mappings);
}
if(map.containsKey(elementRoot)) {
actionMap.put(elementRoot, map.get(elementRoot));
}
}
}
private List getMappingForLeft(ASTDiff diff, Tree left) {
List matchingMappings = new ArrayList();
for(Mapping mapping : diff.getAllMappings()) {
if(mapping.first.equals(left)) {
matchingMappings.add(mapping);
}
}
return matchingMappings;
}
}