diff --git a/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtVisitor.java b/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtVisitor.java
index 775079c7..46e86acb 100644
--- a/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtVisitor.java
+++ b/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtVisitor.java
@@ -46,7 +46,7 @@ public class JdtVisitor extends AbstractJdtVisitor {
private static final Type ARRAY_INITIALIZER = nodeAsSymbol(ASTNode.ARRAY_INITIALIZER);
private static final Type SIMPLE_NAME = nodeAsSymbol(ASTNode.SIMPLE_NAME);
- private IScanner scanner;
+ protected IScanner scanner;
public JdtVisitor(IScanner scanner) {
super();
diff --git a/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtWithCommentsTreeGenerator.java b/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtWithCommentsTreeGenerator.java
new file mode 100644
index 00000000..91af0336
--- /dev/null
+++ b/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtWithCommentsTreeGenerator.java
@@ -0,0 +1,37 @@
+/*
+ * 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.gen.Register;
+import com.github.gumtreediff.utils.Registry;
+import org.eclipse.jdt.core.compiler.IScanner;
+
+
+/* Created by pourya on 2024-09-05*/
+@Register(id = "java-jdtc", accept = "\\.java$", priority = Registry.Priority.HIGH)
+public class JdtWithCommentsTreeGenerator extends AbstractJdtTreeGenerator {
+ @Override
+ protected AbstractJdtVisitor createVisitor(IScanner scanner) {
+ return new JdtWithCommentsVisitor(scanner);
+ }
+}
+
+
diff --git a/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtWithCommentsVisitor.java b/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtWithCommentsVisitor.java
new file mode 100644
index 00000000..c1b9a6e0
--- /dev/null
+++ b/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtWithCommentsVisitor.java
@@ -0,0 +1,103 @@
+/*
+ * 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*/
+public class JdtWithCommentsVisitor extends JdtVisitor {
+
+ public JdtWithCommentsVisitor(IScanner scanner) {
+ super(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 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..d113721c 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,65 @@ 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 JdtWithCommentsTreeGenerator().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());
+ }
+
+ @Test
+ public void testComments2() throws IOException {
+ String input = "/**\n"
+ + " * test\n"
+ + " */\n"
+ + "public class X {\n"
+ + " void A(boolean b\n"
+ + " ) {\n"
+ + " /**\n"
+ + " * test2 \n"
+ + " */\n"
+ + " sleep();\n"
+ + " }\n"
+ + "}\n";
+ String expected = "CompilationUnit [0,145]\n"
+ + " TypeDeclaration [0,144]\n"
+ + " Javadoc [0,31]\n"
+ + " TagElement [15,19]\n"
+ + " TextElement: test [15,19]\n"
+ + " Modifier: public [32,38]\n"
+ + " TYPE_DECLARATION_KIND: class [39,44]\n"
+ + " SimpleName: X [45,46]\n"
+ + " MethodDeclaration [53,142]\n"
+ + " PrimitiveType: void [53,57]\n"
+ + " SimpleName: A [58,59]\n"
+ + " SingleVariableDeclaration [60,69]\n"
+ + " PrimitiveType: boolean [60,67]\n"
+ + " SimpleName: b [68,69]\n"
+ + " Block [76,142]\n"
+ + " Javadoc: /**\n"
+ + " * test2 \n"
+ + " */ [86,119]\n"
+ + " ExpressionStatement [128,136]\n"
+ + " MethodInvocation [128,135]\n"
+ + " SimpleName: sleep [128,133]";
+ TreeContext ct = new JdtWithCommentsTreeGenerator().generateFrom().string(input);
+ assertEquals(expected, ct.getRoot().toTreeString());
+ }
}