diff --git a/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/AbstractJdtTreeGenerator.java b/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/AbstractJdtTreeGenerator.java
index d5908f87..81abd3b3 100644
--- a/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/AbstractJdtTreeGenerator.java
+++ b/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/AbstractJdtTreeGenerator.java
@@ -29,13 +29,17 @@
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.CompilationUnit;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
+import java.util.List;
import java.util.Map;
public abstract class AbstractJdtTreeGenerator extends TreeGenerator {
+ protected boolean includeComments = Boolean.parseBoolean(System.getProperty("gumtree.jdt.includeComments", "true"));
+
private static final String JAVA_VERSION = JavaCore.latestSupportedJavaVersion();
private static char[] readerToCharArray(Reader r) throws IOException {
@@ -72,6 +76,15 @@ public TreeContext generate(Reader r) throws IOException {
if ((node.getFlags() & ASTNode.MALFORMED) != 0) // bitwise flag to check if the node has a syntax error
throw new SyntaxException(this, r, null);
node.accept(v);
+ if (includeComments) {
+ if (node instanceof CompilationUnit) {
+ List commentList = ((CompilationUnit) node).getCommentList();
+ for (Object o : commentList) {
+ ASTNode comment = (ASTNode) o;
+ comment.accept(new JdtCommentVisitor(scanner, v.getTreeContext()));
+ }
+ }
+ }
return v.getTreeContext();
}
diff --git a/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtCommentVisitor.java b/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtCommentVisitor.java
new file mode 100644
index 00000000..3b26983a
--- /dev/null
+++ b/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtCommentVisitor.java
@@ -0,0 +1,89 @@
+/*
+ * This file is part of GumTree.
+ *
+ * GumTree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GumTree is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with GumTree. If not, see .
+ *
+ * Copyright 2011-2015 Jean-Rémy Falleri
+ * Copyright 2011-2015 Floréal Morandat
+ */
+
+package com.github.gumtreediff.gen.jdt;
+
+import com.github.gumtreediff.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*/
+class JdtCommentVisitor extends JdtVisitor {
+ final TreeContext context;
+ final char[] source;
+
+ public JdtCommentVisitor(IScanner scanner, TreeContext context) {
+ super(scanner);
+ this.source = scanner.getSource();
+ this.context = context;
+ }
+
+ public boolean visit(BlockComment node) {
+ return visitComment(node);
+ }
+
+ public boolean visit(LineComment node) {
+ return visitComment(node);
+ }
+
+ 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(source, 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 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;
+ }
+
+}
\ No newline at end of file
diff --git a/gen.jdt/src/test/java/com/github/gumtreediff/gen/jdt/TestJdtGenerator.java b/gen.jdt/src/test/java/com/github/gumtreediff/gen/jdt/TestJdtGenerator.java
index 8cf4775d..7c233040 100644
--- a/gen.jdt/src/test/java/com/github/gumtreediff/gen/jdt/TestJdtGenerator.java
+++ b/gen.jdt/src/test/java/com/github/gumtreediff/gen/jdt/TestJdtGenerator.java
@@ -202,4 +202,26 @@ public void testTagElement() throws IOException {
+ " SimpleName: C [26,27]";
assertEquals(expected, ct.getRoot().toTreeString());
}
+
+ @Test
+ public void testComments() throws IOException {
+ String input = "class bar {\n"
+ + " void foo(/*int a*/)\n"
+ + " {\n"
+ + " //run();\n"
+ + " }\n"
+ + "}\n";
+ TreeContext ct = new JdtTreeGenerator().generateFrom().string(input);
+ String expected = "CompilationUnit [0,87]\n"
+ + " TypeDeclaration [0,86]\n"
+ + " TYPE_DECLARATION_KIND: class [0,5]\n"
+ + " SimpleName: bar [6,9]\n"
+ + " MethodDeclaration [20,84]\n"
+ + " PrimitiveType: void [20,24]\n"
+ + " SimpleName: foo [25,28]\n"
+ + " BlockComment: /*int a*/ [29,38]\n"
+ + " Block [48,84]\n"
+ + " LineComment: //run(); [66,74]";
+ assertEquals(expected, ct.getRoot().toTreeString());
+ }
}