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()); + } }