Skip to content

Commit

Permalink
ASTDiff: JdtWithCommentsVisitor, configurable via rm.jdt.comments sys…
Browse files Browse the repository at this point in the history
…tem property

Visitor inspired by GumTreeDiff/gumtree#368
  • Loading branch information
pouryafard75 authored and tsantalis committed Oct 2, 2024
1 parent f1137b8 commit dfcbe99
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/main/java/gr/uom/java/xmi/UMLModelASTReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.AbstractTagElement;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
Expand Down Expand Up @@ -69,8 +68,10 @@
import gr.uom.java.xmi.decomposition.AbstractExpression;
import gr.uom.java.xmi.decomposition.OperationBody;
import gr.uom.java.xmi.decomposition.VariableDeclaration;
import org.refactoringminer.astDiff.visitors.JdtWithCommentsVisitor;

public class UMLModelASTReader {
private static final boolean VISIT_JDT_COMMENTS = Boolean.parseBoolean(System.getProperty("rm.jdt.comments", "false"));
private static final String FREE_MARKER_GENERATED = "generated using freemarker";
private static final String FREE_MARKER_GENERATED_2 = "generated using FreeMarker";
private static final String ANTLR_GENERATED = "// $ANTLR";
Expand Down Expand Up @@ -135,7 +136,7 @@ private void processJavaFileContents(Map<String, String> javaFileContents, boole
if(astDiff) {
IScanner scanner = ToolFactory.createScanner(true, false, false, false);
scanner.setSource(charArray);
JdtVisitor visitor = new JdtVisitor(scanner);
JdtVisitor visitor = (VISIT_JDT_COMMENTS) ? new JdtWithCommentsVisitor(scanner) : new JdtVisitor(scanner);
compilationUnit.accept(visitor);
TreeContext treeContext = visitor.getTreeContext();
this.umlModel.getTreeContextMap().put(filePath, treeContext);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package org.refactoringminer.astDiff.visitors;

import com.github.gumtreediff.gen.jdt.JdtVisitor;
import com.github.gumtreediff.tree.Tree;
import org.eclipse.jdt.core.compiler.IScanner;
import org.eclipse.jdt.core.dom.*;

import java.util.List;

/* Created by pourya on 2024-08-28*/
public class JdtWithCommentsVisitor extends JdtVisitor {

private final IScanner scanner;

public JdtWithCommentsVisitor(IScanner scanner) {
super(scanner);
this.scanner = scanner;
}

@Override
public void endVisit(CompilationUnit node) {
super.endVisit(node);
for (Object o : node.getCommentList()) {
ASTNode comment = (ASTNode) o;
comment.accept(new CommentsVisitor());
}
}

class CommentsVisitor extends ASTVisitor {
public boolean visit(BlockComment node) {
return visitComment(node);
}

public boolean visit(LineComment node) {
return visitComment(node);
}

public boolean visit(Javadoc node) {
//We have to check if the java doc is attached to any program element or not
//The attached ones, have been already visited, and we do not want to add them twice.
if (node.getParent() == null)
//Then it is javadoc which is attached to any program element,
//So it will be visited as same as the other comments but with JavaDoc label
return visitComment(node);
return true;
}

public boolean visitComment(Comment node) {
int start = node.getStartPosition();
int end = start + node.getLength();
Tree parent = findMostInnerEnclosingParent(context.getRoot(), start, end);
Tree t = context.createTree(nodeAsSymbol(node), new String(scanner.getSource(), start, end - start));
t.setPos(start);
t.setLength(node.getLength());
insertChildProperly(parent, t);
return true;
}

public void insertChildProperly(Tree parent, Tree newChild) {
int position = 0;
for (Tree child : parent.getChildren()) {
if (child.getPos() < newChild.getPos()) {
position += 1;
} else
break;
}
parent.insertChild(newChild, position);
}

private Tree findMostInnerEnclosingParent(Tree root, int start, int end) {
Tree mostInnerParent = root;
List<Tree> children = root.getChildren();

for (Tree child : children) {
if (child.getPos() <= start && child.getEndPos() >= end) {
Tree candidate = findMostInnerEnclosingParent(child, start, end);
if (candidate.getPos() >= mostInnerParent.getPos()
&& candidate.getEndPos() <= mostInnerParent.getEndPos()) {
mostInnerParent = candidate;
}
}
}

return mostInnerParent;
}
}
}

0 comments on commit dfcbe99

Please sign in to comment.