Skip to content

Commit

Permalink
Support extracted class scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
tsantalis committed Oct 4, 2024
1 parent 77e0bac commit 43338b4
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,13 @@ public boolean checkRefactoredAttribute(Version currentVersion, Version parentVe
return false;
}

public void addedClass(Class rightClass, Annotation rightAnnotation, Version parentVersion) {
Annotation leftAnnotation = Annotation.of(rightAnnotation.getAnnotation(), rightClass.getUmlClass(), parentVersion);
annotationChangeHistory.handleAdd(leftAnnotation, rightAnnotation, "added with class");
annotationChangeHistory.connectRelatedNodes();
elements.addFirst(leftAnnotation);
}

public HistoryInfo<Annotation> blameReturn() {
List<HistoryInfo<Annotation>> history = getHistory();
for (History.HistoryInfo<Annotation> historyInfo : history) {
Expand Down
57 changes: 48 additions & 9 deletions src/main/java/org/codetracker/FileTrackerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
import gr.uom.java.xmi.LocationInfo.CodeElementType;
import gr.uom.java.xmi.UMLAttribute;
import gr.uom.java.xmi.decomposition.UMLOperationBodyMapper;
import gr.uom.java.xmi.diff.ExtractClassRefactoring;
import gr.uom.java.xmi.diff.ExtractSuperclassRefactoring;
import gr.uom.java.xmi.diff.MoveOperationRefactoring;
import gr.uom.java.xmi.diff.RenameAttributeRefactoring;
import gr.uom.java.xmi.diff.UMLAbstractClassDiff;
Expand Down Expand Up @@ -315,10 +317,10 @@ else if (leftSuperclass == null && rightSuperclass != null) {
processLocallyRefactoredInnerClasses(notFoundInnerClasses, umlModelDiffLocal, currentVersion, parentVersion, refactorings);
}
UMLClassBaseDiff lightweightClassDiff = lightweightClassDiff(leftClass.getUmlClass(), rightClass.getUmlClass());
processImportsAndClassComments(lightweightClassDiff, rightClass, currentVersion, parentVersion);
processImportsAndClassComments(lightweightClassDiff, rightClass, currentVersion, parentVersion, Collections.emptyList());
for (Pair<Class, Class> pair : foundInnerClasses) {
UMLClassBaseDiff lightweightInnerClassDiff = lightweightClassDiff(pair.getLeft().getUmlClass(), pair.getRight().getUmlClass());
processImportsAndClassComments(lightweightInnerClassDiff, pair.getRight(), currentVersion, parentVersion);
processImportsAndClassComments(lightweightInnerClassDiff, pair.getRight(), currentVersion, parentVersion, Collections.emptyList());
}
continue;
}
Expand Down Expand Up @@ -360,10 +362,10 @@ else if (leftSuperclass == null && rightSuperclass != null) {
processLocallyRefactoredInnerClasses(notFoundInnerClasses, umlModelDiffLocal, currentVersion, parentVersion, refactorings);
}
UMLAbstractClassDiff umlClassDiff = getUMLClassDiff(umlModelDiffLocal, rightClass.getUmlClass().getName());
processImportsAndClassComments(umlClassDiff, rightClass, currentVersion, parentVersion);
processImportsAndClassComments(umlClassDiff, rightClass, currentVersion, parentVersion, refactorings);
for (Pair<Class, Class> pair : foundInnerClasses) {
UMLAbstractClassDiff innerClassDiff = getUMLClassDiff(umlModelDiffLocal, pair.getRight().getUmlClass().getName());
processImportsAndClassComments(innerClassDiff, pair.getRight(), currentVersion, parentVersion);
processImportsAndClassComments(innerClassDiff, pair.getRight(), currentVersion, parentVersion, refactorings);
}
Set<Class> leftSideClasses = new HashSet<>(classRefactored);
leftSideClasses.forEach(startClassChangeHistory::addFirst);
Expand All @@ -390,10 +392,10 @@ else if (leftSuperclass == null && rightSuperclass != null) {
processLocallyRefactoredInnerClasses(notFoundInnerClasses, umlModelDiffPartial, currentVersion, parentVersion, refactoringsPartial);
}
UMLAbstractClassDiff umlClassDiff = getUMLClassDiff(umlModelDiffPartial, rightClass.getUmlClass().getName());
processImportsAndClassComments(umlClassDiff, rightClass, currentVersion, parentVersion);
processImportsAndClassComments(umlClassDiff, rightClass, currentVersion, parentVersion, refactoringsPartial);
for (Pair<Class, Class> pair : foundInnerClasses) {
UMLAbstractClassDiff innerClassDiff = getUMLClassDiff(umlModelDiffPartial, pair.getRight().getUmlClass().getName());
processImportsAndClassComments(innerClassDiff, pair.getRight(), currentVersion, parentVersion);
processImportsAndClassComments(innerClassDiff, pair.getRight(), currentVersion, parentVersion, refactoringsPartial);
}
Set<Class> leftSideClasses = new HashSet<>(classRefactored);
leftSideClasses.forEach(startClassChangeHistory::addFirst);
Expand All @@ -420,10 +422,10 @@ else if (leftSuperclass == null && rightSuperclass != null) {
processLocallyRefactoredInnerClasses(notFoundInnerClasses, umlModelDiffAll, currentVersion, parentVersion, refactorings);
}
UMLAbstractClassDiff umlClassDiff = getUMLClassDiff(umlModelDiffAll, rightClass.getUmlClass().getName());
processImportsAndClassComments(umlClassDiff, rightClass, currentVersion, parentVersion);
processImportsAndClassComments(umlClassDiff, rightClass, currentVersion, parentVersion, refactorings);
for (Pair<Class, Class> pair : foundInnerClasses) {
UMLAbstractClassDiff innerClassDiff = getUMLClassDiff(umlModelDiffAll, pair.getRight().getUmlClass().getName());
processImportsAndClassComments(innerClassDiff, pair.getRight(), currentVersion, parentVersion);
processImportsAndClassComments(innerClassDiff, pair.getRight(), currentVersion, parentVersion, refactorings);
}
Set<Class> leftSideClasses = new HashSet<>(classRefactored);
leftSideClasses.forEach(startClassChangeHistory::addFirst);
Expand Down Expand Up @@ -553,7 +555,8 @@ else if (key instanceof Annotation) {
}
}

private void processImportsAndClassComments(UMLAbstractClassDiff classDiff, Class rightClass, Version currentVersion, Version parentVersion) {
private void processImportsAndClassComments(UMLAbstractClassDiff classDiff, Class rightClass, Version currentVersion, Version parentVersion, List<Refactoring> refactorings) {
boolean extracted = isExtracted(rightClass, refactorings);
for (CodeElement key : programElementMap.keySet()) {
if (key instanceof Import) {
Import startImport = (Import)key;
Expand All @@ -568,6 +571,10 @@ private void processImportsAndClassComments(UMLAbstractClassDiff classDiff, Clas
continue;
}
startImportChangeHistory.poll();
if (extracted) {
startImportChangeHistory.addedClass(rightClass, rightImport, parentVersion);
continue;
}
startImportChangeHistory.checkBodyOfMatchedClasses(currentVersion, parentVersion, rightImport::equalIdentifierIgnoringVersion, classDiff);
}
}
Expand All @@ -585,6 +592,10 @@ else if (key instanceof Comment) {
continue;
}
startCommentChangeHistory.poll();
if (extracted) {
startCommentChangeHistory.addedClass(rightClass, rightComment, parentVersion);
continue;
}
startCommentChangeHistory.checkBodyOfMatchedClasses(currentVersion, parentVersion, rightComment::equalIdentifierIgnoringVersion, classDiff);
}
}
Expand All @@ -602,6 +613,10 @@ else if (key instanceof Annotation) {
continue;
}
startAnnotationChangeHistory.poll();
if (extracted) {
startAnnotationChangeHistory.addedClass(rightClass, rightAnnotation, parentVersion);
continue;
}
startAnnotationChangeHistory.checkBodyOfMatchedClasses(currentVersion, parentVersion, rightAnnotation::equalIdentifierIgnoringVersion, classDiff);
}
}
Expand Down Expand Up @@ -962,6 +977,22 @@ private boolean isMoved(Method rightMethod, List<Refactoring> refactorings) {
return false;
}

private boolean isExtracted(Class rightClass, List<Refactoring> refactorings) {
for (Refactoring r : refactorings) {
if (r instanceof ExtractClassRefactoring) {
ExtractClassRefactoring move = (ExtractClassRefactoring) r;
if (move.getExtractedClass().equals(rightClass.getUmlClass()))
return true;
}
else if (r instanceof ExtractSuperclassRefactoring) {
ExtractSuperclassRefactoring move = (ExtractSuperclassRefactoring) r;
if (move.getExtractedClass().equals(rightClass.getUmlClass()))
return true;
}
}
return false;
}

private void processLocallyRefactoredMethods(Map<Method, MethodTrackerChangeHistory> notFoundMethods, UMLModelDiff umlModelDiff, Version currentVersion, Version parentVersion, List<Refactoring> refactorings) throws RefactoringMinerTimedOutException {
Set<CodeElement> alreadyProcessed = new HashSet<>();
for (Method rightMethod : notFoundMethods.keySet()) {
Expand Down Expand Up @@ -1033,6 +1064,10 @@ else if (key2 instanceof Comment) {
}
startCommentChangeHistory.poll();
alreadyProcessed.add(startComment);
if (moved) {
startCommentChangeHistory.addedMethod(rightMethod, rightComment, parentVersion);
continue;
}
boolean found = startCommentChangeHistory.checkForExtractionOrInline(currentVersion, parentVersion, rightMethod::equalIdentifierIgnoringVersion, rightComment, refactorings);
if (found) {
continue;
Expand Down Expand Up @@ -1062,6 +1097,10 @@ else if (key2 instanceof Annotation) {
}
startAnnotationChangeHistory.poll();
alreadyProcessed.add(startAnnotation);
if (moved) {
startAnnotationChangeHistory.addedMethod(rightMethod, rightAnnotation, parentVersion);
continue;
}
boolean found = startAnnotationChangeHistory.checkForExtractionOrInline(currentVersion, parentVersion, rightMethod::equalIdentifierIgnoringVersion, rightAnnotation, refactorings);
if (found) {
continue;
Expand Down
57 changes: 48 additions & 9 deletions src/main/java/org/codetracker/FileTrackerWithLocalFilesImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
import gr.uom.java.xmi.VariableDeclarationContainer;
import gr.uom.java.xmi.LocationInfo.CodeElementType;
import gr.uom.java.xmi.decomposition.UMLOperationBodyMapper;
import gr.uom.java.xmi.diff.ExtractClassRefactoring;
import gr.uom.java.xmi.diff.ExtractSuperclassRefactoring;
import gr.uom.java.xmi.diff.MoveOperationRefactoring;
import gr.uom.java.xmi.diff.RenameAttributeRefactoring;
import gr.uom.java.xmi.diff.UMLAbstractClassDiff;
Expand Down Expand Up @@ -323,10 +325,10 @@ else if (leftSuperclass == null && rightSuperclass != null) {
processLocallyRefactoredInnerClasses(notFoundInnerClasses, umlModelDiffLocal, currentVersion, parentVersion, refactorings);
}
UMLClassBaseDiff lightweightClassDiff = lightweightClassDiff(leftClass.getUmlClass(), rightClass.getUmlClass());
processImportsAndClassComments(lightweightClassDiff, rightClass, currentVersion, parentVersion);
processImportsAndClassComments(lightweightClassDiff, rightClass, currentVersion, parentVersion, Collections.emptyList());
for (Pair<Class, Class> pair : foundInnerClasses) {
UMLClassBaseDiff lightweightInnerClassDiff = lightweightClassDiff(pair.getLeft().getUmlClass(), pair.getRight().getUmlClass());
processImportsAndClassComments(lightweightInnerClassDiff, pair.getRight(), currentVersion, parentVersion);
processImportsAndClassComments(lightweightInnerClassDiff, pair.getRight(), currentVersion, parentVersion, Collections.emptyList());
}
continue;
}
Expand Down Expand Up @@ -368,10 +370,10 @@ else if (leftSuperclass == null && rightSuperclass != null) {
processLocallyRefactoredInnerClasses(notFoundInnerClasses, umlModelDiffLocal, currentVersion, parentVersion, refactorings);
}
UMLAbstractClassDiff umlClassDiff = getUMLClassDiff(umlModelDiffLocal, rightClass.getUmlClass().getName());
processImportsAndClassComments(umlClassDiff, rightClass, currentVersion, parentVersion);
processImportsAndClassComments(umlClassDiff, rightClass, currentVersion, parentVersion, refactorings);
for (Pair<Class, Class> pair : foundInnerClasses) {
UMLAbstractClassDiff innerClassDiff = getUMLClassDiff(umlModelDiffLocal, pair.getRight().getUmlClass().getName());
processImportsAndClassComments(innerClassDiff, pair.getRight(), currentVersion, parentVersion);
processImportsAndClassComments(innerClassDiff, pair.getRight(), currentVersion, parentVersion, refactorings);
}
Set<Class> leftSideClasses = new HashSet<>(classRefactored);
leftSideClasses.forEach(startClassChangeHistory::addFirst);
Expand All @@ -398,10 +400,10 @@ else if (leftSuperclass == null && rightSuperclass != null) {
processLocallyRefactoredInnerClasses(notFoundInnerClasses, umlModelDiffPartial, currentVersion, parentVersion, refactoringsPartial);
}
UMLAbstractClassDiff umlClassDiff = getUMLClassDiff(umlModelDiffPartial, rightClass.getUmlClass().getName());
processImportsAndClassComments(umlClassDiff, rightClass, currentVersion, parentVersion);
processImportsAndClassComments(umlClassDiff, rightClass, currentVersion, parentVersion, refactoringsPartial);
for (Pair<Class, Class> pair : foundInnerClasses) {
UMLAbstractClassDiff innerClassDiff = getUMLClassDiff(umlModelDiffPartial, pair.getRight().getUmlClass().getName());
processImportsAndClassComments(innerClassDiff, pair.getRight(), currentVersion, parentVersion);
processImportsAndClassComments(innerClassDiff, pair.getRight(), currentVersion, parentVersion, refactoringsPartial);
}
Set<Class> leftSideClasses = new HashSet<>(classRefactored);
leftSideClasses.forEach(startClassChangeHistory::addFirst);
Expand All @@ -428,10 +430,10 @@ else if (leftSuperclass == null && rightSuperclass != null) {
processLocallyRefactoredInnerClasses(notFoundInnerClasses, umlModelDiffAll, currentVersion, parentVersion, refactorings);
}
UMLAbstractClassDiff umlClassDiff = getUMLClassDiff(umlModelDiffAll, rightClass.getUmlClass().getName());
processImportsAndClassComments(umlClassDiff, rightClass, currentVersion, parentVersion);
processImportsAndClassComments(umlClassDiff, rightClass, currentVersion, parentVersion, refactorings);
for (Pair<Class, Class> pair : foundInnerClasses) {
UMLAbstractClassDiff innerClassDiff = getUMLClassDiff(umlModelDiffAll, pair.getRight().getUmlClass().getName());
processImportsAndClassComments(innerClassDiff, pair.getRight(), currentVersion, parentVersion);
processImportsAndClassComments(innerClassDiff, pair.getRight(), currentVersion, parentVersion, refactorings);
}
Set<Class> leftSideClasses = new HashSet<>(classRefactored);
leftSideClasses.forEach(startClassChangeHistory::addFirst);
Expand Down Expand Up @@ -560,7 +562,8 @@ else if (key instanceof Annotation) {
}
}

private void processImportsAndClassComments(UMLAbstractClassDiff classDiff, Class rightClass, Version currentVersion, Version parentVersion) {
private void processImportsAndClassComments(UMLAbstractClassDiff classDiff, Class rightClass, Version currentVersion, Version parentVersion, List<Refactoring> refactorings) {
boolean extracted = isExtracted(rightClass, refactorings);
for (CodeElement key : programElementMap.keySet()) {
if (key instanceof Import) {
Import startImport = (Import)key;
Expand All @@ -575,6 +578,10 @@ private void processImportsAndClassComments(UMLAbstractClassDiff classDiff, Clas
continue;
}
startImportChangeHistory.poll();
if (extracted) {
startImportChangeHistory.addedClass(rightClass, rightImport, parentVersion);
continue;
}
startImportChangeHistory.checkBodyOfMatchedClasses(currentVersion, parentVersion, rightImport::equalIdentifierIgnoringVersion, classDiff);
}
}
Expand All @@ -592,6 +599,10 @@ else if (key instanceof Comment) {
continue;
}
startCommentChangeHistory.poll();
if (extracted) {
startCommentChangeHistory.addedClass(rightClass, rightComment, parentVersion);
continue;
}
startCommentChangeHistory.checkBodyOfMatchedClasses(currentVersion, parentVersion, rightComment::equalIdentifierIgnoringVersion, classDiff);
}
}
Expand All @@ -609,6 +620,10 @@ else if (key instanceof Annotation) {
continue;
}
startAnnotationChangeHistory.poll();
if (extracted) {
startAnnotationChangeHistory.addedClass(rightClass, rightAnnotation, parentVersion);
continue;
}
startAnnotationChangeHistory.checkBodyOfMatchedClasses(currentVersion, parentVersion, rightAnnotation::equalIdentifierIgnoringVersion, classDiff);
}
}
Expand Down Expand Up @@ -969,6 +984,22 @@ private boolean isMoved(Method rightMethod, List<Refactoring> refactorings) {
return false;
}

private boolean isExtracted(Class rightClass, List<Refactoring> refactorings) {
for (Refactoring r : refactorings) {
if (r instanceof ExtractClassRefactoring) {
ExtractClassRefactoring move = (ExtractClassRefactoring) r;
if (move.getExtractedClass().equals(rightClass.getUmlClass()))
return true;
}
else if (r instanceof ExtractSuperclassRefactoring) {
ExtractSuperclassRefactoring move = (ExtractSuperclassRefactoring) r;
if (move.getExtractedClass().equals(rightClass.getUmlClass()))
return true;
}
}
return false;
}

private void processLocallyRefactoredMethods(Map<Method, MethodTrackerChangeHistory> notFoundMethods, UMLModelDiff umlModelDiff, Version currentVersion, Version parentVersion, List<Refactoring> refactorings) throws RefactoringMinerTimedOutException {
Set<CodeElement> alreadyProcessed = new HashSet<>();
for (Method rightMethod : notFoundMethods.keySet()) {
Expand Down Expand Up @@ -1040,6 +1071,10 @@ else if (key2 instanceof Comment) {
}
startCommentChangeHistory.poll();
alreadyProcessed.add(startComment);
if (moved) {
startCommentChangeHistory.addedMethod(rightMethod, rightComment, parentVersion);
continue;
}
boolean found = startCommentChangeHistory.checkForExtractionOrInline(currentVersion, parentVersion, rightMethod::equalIdentifierIgnoringVersion, rightComment, refactorings);
if (found) {
continue;
Expand Down Expand Up @@ -1069,6 +1104,10 @@ else if (key2 instanceof Annotation) {
}
startAnnotationChangeHistory.poll();
alreadyProcessed.add(startAnnotation);
if (moved) {
startAnnotationChangeHistory.addedMethod(rightMethod, rightAnnotation, parentVersion);
continue;
}
boolean found = startAnnotationChangeHistory.checkForExtractionOrInline(currentVersion, parentVersion, rightMethod::equalIdentifierIgnoringVersion, rightAnnotation, refactorings);
if (found) {
continue;
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/org/codetracker/ImportTrackerChangeHistory.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ private boolean isAdded(UMLAbstractClassDiff classDiff, Version currentVersion,
return false;
}

public void addedClass(Class rightClass, Import rightImport, Version parentVersion) {
Import leftImport = Import.of(rightImport.getUmlImport(), rightClass.getUmlClass(), parentVersion);
importChangeHistory.handleAdd(leftImport, rightImport, "added with class");
importChangeHistory.connectRelatedNodes();
elements.addFirst(leftImport);
}

public HistoryInfo<Import> blameReturn() {
List<HistoryInfo<Import>> history = getHistory();
for (History.HistoryInfo<Import> historyInfo : history) {
Expand Down
Loading

0 comments on commit 43338b4

Please sign in to comment.