Skip to content

Commit

Permalink
Use statement mappings to improve the accuracy of comment matching
Browse files Browse the repository at this point in the history
  • Loading branch information
tsantalis committed Oct 20, 2024
1 parent f150318 commit 11689c4
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 10 deletions.
10 changes: 10 additions & 0 deletions src/main/java/gr/uom/java/xmi/UMLComment.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import java.util.Scanner;

import gr.uom.java.xmi.LocationInfo.CodeElementType;
import gr.uom.java.xmi.decomposition.CompositeStatementObject;

public class UMLComment extends UMLAbstractDocumentation {

//represents non-attached Javadocs found within method bodies
private Optional<UMLJavadoc> javaDoc;
private CompositeStatementObject parent;

public UMLComment(String text, LocationInfo locationInfo) {
super(text, locationInfo);
Expand All @@ -23,6 +25,14 @@ public Optional<UMLJavadoc> getJavaDoc() {
return javaDoc;
}

public CompositeStatementObject getParent() {
return parent;
}

public void setParent(CompositeStatementObject parent) {
this.parent = parent;
}

@Override
public String getText() {
if(locationInfo.getCodeElementType().equals(CodeElementType.LINE_COMMENT)) {
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/gr/uom/java/xmi/decomposition/OperationBody.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import gr.uom.java.xmi.LocationInfo.CodeElementType;
import gr.uom.java.xmi.UMLAnonymousClass;
import gr.uom.java.xmi.UMLAttribute;
import gr.uom.java.xmi.UMLComment;
import gr.uom.java.xmi.UMLOperation;
import gr.uom.java.xmi.VariableDeclarationContainer;

Expand All @@ -53,10 +54,12 @@ public class OperationBody {
private Set<VariableDeclaration> activeVariableDeclarations;
private VariableDeclarationContainer container;
private int bodyHashCode;
private List<UMLComment> comments;
private final String javaFileContent;

public OperationBody(CompilationUnit cu, String filePath, Block methodBody, VariableDeclarationContainer container, List<UMLAttribute> attributes, String javaFileContent) {
this.compositeStatement = new CompositeStatementObject(cu, filePath, methodBody, 0, CodeElementType.BLOCK);
this.comments = container.getComments();
this.container = container;
this.javaFileContent = javaFileContent;
this.bodyHashCode = stringify(methodBody).hashCode();
Expand Down Expand Up @@ -168,6 +171,20 @@ public VariableDeclaration getVariableDeclaration(String variableName) {
}

private void processStatement(CompilationUnit cu, String filePath, CompositeStatementObject parent, Statement statement) {
for(UMLComment comment : comments) {
if(comment.getParent() != null && comment.getParent().equals(parent))
continue;
if(parent.getLocationInfo().subsumes(comment.getLocationInfo())) {
if(comment.getParent() != null) {
if(!parent.getLocationInfo().subsumes(comment.getParent().getLocationInfo())) {
comment.setParent(parent);
}
}
else {
comment.setParent(parent);
}
}
}
if(statement instanceof Block) {
Block block = (Block)statement;
List<Statement> blockStatements = block.statements();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ public UMLOperationBodyMapper(UMLOperationBodyMapper mapper1, UMLOperationBodyMa
nonMappedInnerNodesT1.addAll(innerNodes1);
nonMappedInnerNodesT2.addAll(innerNodes2);
if(mapper1.commentListDiff != null && mapper2.commentListDiff != null) {
this.commentListDiff = new UMLCommentListDiff(mapper1.commentListDiff.getDeletedComments(), mapper2.commentListDiff.getAddedComments());
this.commentListDiff = new UMLCommentListDiff(mapper1.commentListDiff.getDeletedComments(), mapper2.commentListDiff.getAddedComments(), this.mappings);
checkUnmatchedStatementsBeingCommented();
}
}
Expand Down Expand Up @@ -227,7 +227,7 @@ public UMLOperationBodyMapper(UMLOperation removedOperation, UMLOperationBodyMap
nonMappedInnerNodesT1.addAll(innerNodes1);
nonMappedInnerNodesT2.addAll(innerNodes2);
if(mapper2.commentListDiff != null) {
this.commentListDiff = new UMLCommentListDiff(container1.getComments(), mapper2.commentListDiff.getAddedComments());
this.commentListDiff = new UMLCommentListDiff(container1.getComments(), mapper2.commentListDiff.getAddedComments(), this.mappings);
checkUnmatchedStatementsBeingCommented();
}
}
Expand Down Expand Up @@ -260,7 +260,7 @@ public UMLOperationBodyMapper(UMLOperationBodyMapper mapper1, UMLOperation added
nonMappedInnerNodesT1.addAll(innerNodes1);
nonMappedInnerNodesT2.addAll(innerNodes2);
if(mapper1.commentListDiff != null) {
this.commentListDiff = new UMLCommentListDiff(mapper1.commentListDiff.getDeletedComments(), container2.getComments());
this.commentListDiff = new UMLCommentListDiff(mapper1.commentListDiff.getDeletedComments(), container2.getComments(), this.mappings);
checkUnmatchedStatementsBeingCommented();
}
}
Expand Down Expand Up @@ -995,7 +995,7 @@ else if(mapping instanceof CompositeStatementObjectMapping) {
UMLJavadocDiff diff = new UMLJavadocDiff(operation1.getJavadoc(), operation2.getJavadoc(), operationSignatureDiff);
this.javadocDiff = Optional.of(diff);
}
this.commentListDiff = new UMLCommentListDiff(container1.getComments(), container2.getComments());
this.commentListDiff = new UMLCommentListDiff(container1.getComments(), container2.getComments(), this.mappings);
checkUnmatchedStatementsBeingCommented();
}

Expand Down Expand Up @@ -1295,7 +1295,7 @@ public UMLOperationBodyMapper(UMLInitializer initializer1, UMLInitializer initia
UMLJavadocDiff diff = new UMLJavadocDiff(initializer1.getJavadoc(), initializer2.getJavadoc());
this.javadocDiff = Optional.of(diff);
}
this.commentListDiff = new UMLCommentListDiff(initializer1.getComments(), initializer2.getComments());
this.commentListDiff = new UMLCommentListDiff(initializer1.getComments(), initializer2.getComments(), this.mappings);
checkUnmatchedStatementsBeingCommented();
}

Expand Down Expand Up @@ -1344,7 +1344,7 @@ else if(lambda1.getBody() != null && lambda2.getExpression() != null) {
this.lambdaBodyMapper = true;
processCompositeStatements(composite1.getLeaves(), leaves2, composite1.getInnerNodes(), Collections.emptyList());
}
this.commentListDiff = new UMLCommentListDiff(lambda1.getComments(), lambda2.getComments());
this.commentListDiff = new UMLCommentListDiff(lambda1.getComments(), lambda2.getComments(), this.mappings);
checkUnmatchedStatementsBeingCommented();
}

Expand Down Expand Up @@ -2093,7 +2093,7 @@ else if(lambda2.getExpression() != null) {
processCompositeStatements(composite1.getLeaves(), leaves2, composite1.getInnerNodes(), new ArrayList<CompositeStatementObject>());
}
}
this.commentListDiff = new UMLCommentListDiff(anonymousClassOperation.getComments(), lambda2.getComments());
this.commentListDiff = new UMLCommentListDiff(anonymousClassOperation.getComments(), lambda2.getComments(), this.mappings);
checkUnmatchedStatementsBeingCommented();
}

Expand Down Expand Up @@ -2696,7 +2696,7 @@ else if(streamAPIStatements1.size() > 0 && streamAPIStatements2.size() == 0) {
if(childMapper.commentListDiff != null)
deletedComments.addAll(childMapper.commentListDiff.getDeletedComments());
}
this.commentListDiff = new UMLCommentListDiff(new ArrayList<>(deletedComments), container2.getComments());
this.commentListDiff = new UMLCommentListDiff(new ArrayList<>(deletedComments), container2.getComments(), this.mappings);
checkUnmatchedStatementsBeingCommented();
}
}
Expand Down Expand Up @@ -3114,7 +3114,7 @@ else if(streamAPIStatements1.size() > 0 && streamAPIStatements2.size() == 0) {
if(childMapper.commentListDiff != null)
addedComments.addAll(childMapper.commentListDiff.getAddedComments());
}
this.commentListDiff = new UMLCommentListDiff(container1.getComments(), new ArrayList<>(addedComments));
this.commentListDiff = new UMLCommentListDiff(container1.getComments(), new ArrayList<>(addedComments), this.mappings);
checkUnmatchedStatementsBeingCommented();
}
}
Expand Down
51 changes: 51 additions & 0 deletions src/main/java/gr/uom/java/xmi/diff/UMLCommentListDiff.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,33 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.tuple.Pair;

import gr.uom.java.xmi.UMLComment;
import gr.uom.java.xmi.UMLCommentGroup;
import gr.uom.java.xmi.decomposition.AbstractCodeMapping;
import gr.uom.java.xmi.LocationInfo.CodeElementType;

public class UMLCommentListDiff {
private List<Pair<UMLComment, UMLComment>> commonComments;
private List<UMLComment> deletedComments;
private List<UMLComment> addedComments;
private boolean manyToManyReformat;
private Set<AbstractCodeMapping> mappings;

public UMLCommentListDiff(List<UMLComment> commentsBefore, List<UMLComment> commentsAfter, Set<AbstractCodeMapping> mappings) {
this.mappings = mappings;
init(commentsBefore, commentsAfter);
}

public UMLCommentListDiff(List<UMLComment> commentsBefore, List<UMLComment> commentsAfter) {
this.mappings = Collections.emptySet();
init(commentsBefore, commentsAfter);
}

private void init(List<UMLComment> commentsBefore, List<UMLComment> commentsAfter) {
this.commonComments = new ArrayList<Pair<UMLComment,UMLComment>>();
this.deletedComments = new ArrayList<UMLComment>();
this.addedComments = new ArrayList<UMLComment>();
Expand Down Expand Up @@ -97,17 +110,44 @@ public UMLCommentListDiff(UMLCommentGroup groupBefore, UMLCommentGroup groupAfte
this.commonComments = new ArrayList<Pair<UMLComment,UMLComment>>();
this.deletedComments = new ArrayList<UMLComment>();
this.addedComments = new ArrayList<UMLComment>();
this.mappings = Collections.emptySet();
processRemainingComments(groupBefore.getGroup(), groupAfter.getGroup());
}

private boolean mappedParent(UMLComment left, UMLComment right) {
if(left.getParent() != null && right.getParent() != null) {
if(left.getParent().getParent() == null && right.getParent().getParent() == null) {
return true;
}
for(AbstractCodeMapping mapping : mappings) {
if(mapping.getFragment1().equals(left.getParent()) &&
mapping.getFragment2().equals(right.getParent())) {
return true;
}
}
}
return false;
}

private void processRemainingComments(List<UMLComment> commentsBefore, List<UMLComment> commentsAfter) {
List<UMLComment> deletedComments = new ArrayList<UMLComment>(commentsBefore);
List<UMLComment> addedComments = new ArrayList<UMLComment>(commentsAfter);
if(commentsBefore.size() <= commentsAfter.size()) {
for(UMLComment comment : commentsBefore) {
List<Integer> matchingIndices = findAllMatchingIndices(commentsAfter, comment);
List<Boolean> mappedParent = new ArrayList<Boolean>();
if(matchingIndices.size() > 1) {
for(Integer index : matchingIndices) {
mappedParent.add(mappedParent(comment, commentsAfter.get(index)));
}
}
int i = -1;
for(Integer index : matchingIndices) {
i++;
if(!alreadyMatchedComment(comment, commentsAfter.get(index))) {
if(mappedParent.contains(true) && mappedParent.get(i) == false) {
continue;
}
Pair<UMLComment, UMLComment> pair = Pair.of(comment, commentsAfter.get(index));
commonComments.add(pair);
deletedComments.remove(comment);
Expand All @@ -120,8 +160,19 @@ private void processRemainingComments(List<UMLComment> commentsBefore, List<UMLC
else {
for(UMLComment comment : commentsAfter) {
List<Integer> matchingIndices = findAllMatchingIndices(commentsBefore, comment);
List<Boolean> mappedParent = new ArrayList<Boolean>();
if(matchingIndices.size() > 1) {
for(Integer index : matchingIndices) {
mappedParent.add(mappedParent(commentsBefore.get(index), comment));
}
}
int i = -1;
for(Integer index : matchingIndices) {
i++;
if(!alreadyMatchedComment(commentsBefore.get(index), comment)) {
if(mappedParent.contains(true) && mappedParent.get(i) == false) {
continue;
}
Pair<UMLComment, UMLComment> pair = Pair.of(commentsBefore.get(index), comment);
commonComments.add(pair);
deletedComments.remove(commentsBefore.get(index));
Expand Down
3 changes: 2 additions & 1 deletion src/test/java/org/refactoringminer/test/TestJavadocDiff.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ public void testClassCommentMappings(String url, String commitId, String contain

@ParameterizedTest
@CsvSource({
"https://github.com/eclipse-jgit/jgit.git, 1b783d037091266b035e1727db6b6ce7a397ef63, org.eclipse.jgit.storage.pack.PackWriter, searchForDeltas, jgit-1b783d037091266b035e1727db6b6ce7a397ef63.txt"
"https://github.com/eclipse-jgit/jgit.git, 1b783d037091266b035e1727db6b6ce7a397ef63, org.eclipse.jgit.storage.pack.PackWriter, searchForDeltas, jgit-1b783d037091266b035e1727db6b6ce7a397ef63.txt",
"https://github.com/hibernate/hibernate-orm.git, 5329bba1ea724eabf5783c71e5127b8f84ad0fcc, org.hibernate.cfg.AnnotationBinder, bindClass, hibernate-orm-5329bba1ea724eabf5783c71e5127b8f84ad0fcc-comments.txt"
})
public void testMethodCommentMappings(String url, String commitId, String className, String containerName, String testResultFileName) throws Exception {
final List<String> actual = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
public bindClass(clazzToProcess XClass, inheritanceStatePerClass Map<XClass,InheritanceState>, mappings Mappings) : void -> public bindClass(clazzToProcess XClass, inheritanceStatePerClass Map<XClass,InheritanceState>, mappings Mappings) : void
line range:576-576==line range:578-578
line range:583-583==line range:585-585
line range:587-587==line range:589-589
line range:623-623==line range:625-625
line range:703-703==line range:726-726
line range:720-720==line range:761-761
line range:729-729==line range:771-771
line range:732-732==line range:774-774
line range:776-776==line range:818-818
line range:779-779==line range:821-821
line range:712-712==line range:733-733
line range:712-712==line range:736-736

0 comments on commit 11689c4

Please sign in to comment.