Skip to content

Commit

Permalink
Added ASTRewrite support(Unit test & Rewrite) and ASTConverter unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
subyssurendran666 committed Sep 3, 2024
1 parent 9a5c7a0 commit c44358d
Show file tree
Hide file tree
Showing 8 changed files with 348 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ImplicitTypeDeclaration;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;

import junit.framework.Test;
Expand Down Expand Up @@ -109,4 +113,30 @@ void m() {
assertEquals("Incorrect name", "java.lang.System.out", imp.getName().toString());
}
}

public void test002() throws CoreException {
String contents = """
/** */
void main() {
System.out.println("Eclipse");
}
""";
this.workingCopy = getWorkingCopy("/Converter_23/src/X.java", true/*resolve*/);
ASTNode node = buildAST(contents, this.workingCopy);
assertEquals("Wrong type of statement", ASTNode.COMPILATION_UNIT, node.getNodeType());
CompilationUnit compilationUnit = (CompilationUnit) node;
ImplicitTypeDeclaration implicitTypeDeclaration = (ImplicitTypeDeclaration) compilationUnit.types().get(0);
assertEquals("Not an ImplicitTypeDeclaration Type", implicitTypeDeclaration.getNodeType(), ASTNode.UNNAMED_CLASS);
assertEquals("Not an ImplicitTypeDeclaration Name Type", implicitTypeDeclaration.getName().getNodeType(), ASTNode.SIMPLE_NAME);
assertEquals("Identifier is not empty String", implicitTypeDeclaration.getName().getIdentifier(), "");
MethodDeclaration bodyDeclaration = (MethodDeclaration) implicitTypeDeclaration.bodyDeclarations().get(0);
assertEquals("Not a Method Declaration", bodyDeclaration.getNodeType(), ASTNode.METHOD_DECLARATION);
assertEquals("Method Declaration start is not one", bodyDeclaration.getStartPosition(), 1);
Javadoc javaDoc = bodyDeclaration.getJavadoc();
assertEquals("Not a JavaDoc", javaDoc.getNodeType(), ASTNode.JAVADOC);
assertEquals("JavaDoc startPosition is not One", javaDoc.getStartPosition(), 1);
Block block = bodyDeclaration.getBody();
assertEquals("Not a Block", block.getNodeType(), ASTNode.BLOCK);
assertEquals("Block startPosition is not correct", block.getStartPosition(), 21);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
/*******************************************************************************
* Copyright (c) 2024 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* This is an implementation of an early-draft specification developed under the Java
* Community Process (JCP) and is made available for testing and evaluation purposes
* only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/

package org.eclipse.jdt.core.tests.rewrite.describing;

import java.util.List;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ExpressionStatement;
import org.eclipse.jdt.core.dom.ImplicitTypeDeclaration;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.TagElement;
import org.eclipse.jdt.core.dom.TextElement;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;

import junit.framework.Test;

public class ASTRewritingImplicitTypeDeclarationTest extends ASTRewritingTest{

public ASTRewritingImplicitTypeDeclarationTest(String name, int apiLevel) {
super(name, apiLevel);
}

public static Test suite() {
return createSuite(ASTRewritingImplicitTypeDeclarationTest.class, 23);
}

@Override
protected void setUp() throws Exception {
super.setUp();
if (this.apiLevel == AST.JLS23 ) {
this.project1.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_23);
this.project1.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_23);
this.project1.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_23);
this.project1.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
}
}

public void test001() throws Exception {
AST ast = AST.newAST(AST.JLS23, true);
// Create CompilationUnit
CompilationUnit compilationUnit = ast.newCompilationUnit();

ImplicitTypeDeclaration implicitTypeDeclaration = ast.newImplicitTypeDeclaration();

Javadoc javaDoc= ast.newJavadoc();
TextElement textElem= ast.newTextElement();
textElem.setText("Hello");
TagElement tagElement= ast.newTagElement();
tagElement.fragments().add(textElem);
javaDoc.tags().add(tagElement);
implicitTypeDeclaration.setJavadoc(javaDoc);

QualifiedName qualifiedName = ast.newQualifiedName(ast.newName("System"), ast.newSimpleName("out"));
MethodInvocation methodInvocation = ast.newMethodInvocation();
methodInvocation.setExpression(qualifiedName);
methodInvocation.setName(ast.newSimpleName("println"));

StringLiteral literal = ast.newStringLiteral();
literal.setLiteralValue("Eclipse");
methodInvocation.arguments().add(literal);
ExpressionStatement expressionStatement = ast.newExpressionStatement(methodInvocation);

Block block= ast.newBlock();
block.statements().add(expressionStatement);
MethodDeclaration methodDeclaration = ast.newMethodDeclaration();
methodDeclaration.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID));
methodDeclaration.setName(ast.newSimpleName("main"));
methodDeclaration.setBody(block);
implicitTypeDeclaration.bodyDeclarations().add(methodDeclaration);
// Add Implicity Type class to compilation unit
compilationUnit.types().add(implicitTypeDeclaration);

StringBuilder buf = new StringBuilder();
buf.append("/** \n");
buf.append(" * Hello\n");
buf.append(" */\n");
buf.append(" void main(){\n");
buf.append(" System.out.println(\"Eclipse\");\n");
buf.append(" }\n");

assertEqualString(compilationUnit.toString(), buf.toString());
}

//javaDoc
public void test002() throws Exception {
AST ast = AST.newAST(AST.JLS23, true);
IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null);
StringBuilder buf = new StringBuilder();
buf= new StringBuilder();
buf.append("/** \n");
buf.append(" * Hello\n");
buf.append(" */\n");
buf.append("void main(){\n");
buf.append(" System.out.println(\"Eclipse\");\n");
buf.append("}\n");

ICompilationUnit cu= pack1.createCompilationUnit("X.java", buf.toString(), false, null);
CompilationUnit astRoot= createAST(cu);
ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());

assertTrue("Parse errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);

ImplicitTypeDeclaration implicitTypeDeclaration= findImplicitDeclaration(astRoot, "");
List<MethodDeclaration> methodDeclarationsList = implicitTypeDeclaration.bodyDeclarations();
MethodDeclaration methodDeclaration = methodDeclarationsList.get(0);
{

Javadoc javaDoc = methodDeclaration.getJavadoc();

Javadoc newJavaDoc= ast.newJavadoc();
TextElement textElem= ast.newTextElement();
textElem.setText("Eclipse");
TagElement tagElement= ast.newTagElement();
tagElement.fragments().add(textElem);
newJavaDoc.tags().add(tagElement);

rewrite.replace(javaDoc, newJavaDoc, null);
}

String preview = evaluateRewrite(cu, rewrite);
buf= new StringBuilder();

buf.append("/**\n");
buf.append(" * Eclipse\n");
buf.append(" */\n");
buf.append("void main(){\n");
buf.append(" System.out.println(\"Eclipse\");\n");
buf.append("}\n");

assertEqualString(preview, buf.toString());

{
Javadoc javaDoc = methodDeclaration.getJavadoc();
Javadoc newJavaDoc = null;

rewrite.replace(javaDoc, newJavaDoc, null);
}

preview = evaluateRewrite(cu, rewrite);
buf= new StringBuilder();

buf.append("void main(){\n");
buf.append(" System.out.println(\"Eclipse\");\n");
buf.append("}\n");

assertEqualString(preview, buf.toString());
}

//adding more MEthodDeclaration
public void test003() throws Exception {
AST ast = AST.newAST(AST.JLS23, true);
IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null);
StringBuilder buf = new StringBuilder();
buf= new StringBuilder();
buf.append("/** \n");
buf.append(" * Hello\n");
buf.append(" */\n");
buf.append("void main(){\n");
buf.append(" System.out.println(\"Eclipse\");\n");
buf.append("}\n");

ICompilationUnit cu= pack1.createCompilationUnit("X.java", buf.toString(), false, null);
CompilationUnit astRoot= createAST(cu);
ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());

assertTrue("Parse errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
ImplicitTypeDeclaration implicitTypeDeclaration= findImplicitDeclaration(astRoot, "");
{
MethodInvocation methodInvocation = ast.newMethodInvocation();
methodInvocation.setName(ast.newSimpleName("println"));

StringLiteral literal = ast.newStringLiteral();
literal.setLiteralValue("abc");

QualifiedName qualifiedName = ast.newQualifiedName(ast.newName("System"), ast.newSimpleName("out"));

methodInvocation.setExpression(qualifiedName);
methodInvocation.arguments().add(literal);

ExpressionStatement expressionStatement = ast.newExpressionStatement(methodInvocation);

Block block = ast.newBlock();
block.statements().add(expressionStatement);

MethodDeclaration methodDeclaration = ast.newMethodDeclaration();
methodDeclaration.setBody(block);
methodDeclaration.setName(ast.newSimpleName("abc"));
methodDeclaration.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID));

ListRewrite listRewrite= rewrite.getListRewrite(implicitTypeDeclaration, ImplicitTypeDeclaration.BODY_DECLARATIONS_PROPERTY);
listRewrite.insertAt(methodDeclaration, 1, null);
}

String preview = evaluateRewrite(cu, rewrite);
buf= new StringBuilder();

buf.append("/** \n");
buf.append(" * Hello\n");
buf.append(" */\n");
buf.append("void main(){\n");
buf.append(" System.out.println(\"Eclipse\");\n");
buf.append("}\n");
buf.append("\n");
buf.append("void abc() {\n");
buf.append(" System.out.println(\"abc\");\n");
buf.append("}\n");

assertEqualString(preview, buf.toString());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ImplicitTypeDeclaration;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.PrimitiveType;
Expand Down Expand Up @@ -170,6 +171,7 @@ public static Test suite() {
suite.addTest(ImportRewrite_RecordTest.suite());
suite.addTest(ASTRewritingSuperAfterStatementsTest.suite());
suite.addTest(ASTRewritingEitherOrMultiPatternNodeTest.suite());
suite.addTest(ASTRewritingImplicitTypeDeclarationTest.suite());

return suite;
}
Expand Down Expand Up @@ -463,4 +465,15 @@ protected static MethodDeclaration createNewMethod(AST ast, String name, boolean
return decl;
}

public static ImplicitTypeDeclaration findImplicitDeclaration(CompilationUnit astRoot, String simpleTypeName) {
List types= astRoot.types();
for (int i= 0; i < types.size(); i++) {
ImplicitTypeDeclaration elem= (ImplicitTypeDeclaration) types.get(i);
if (simpleTypeName.equals(elem.getName().getIdentifier())) {
return elem;
}
}
return null;
}

}
17 changes: 17 additions & 0 deletions org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
Original file line number Diff line number Diff line change
Expand Up @@ -3195,6 +3195,23 @@ public TryStatement newTryStatement() {
return new TryStatement(this);
}

/**
* Creates an unparented class declaration node owned by this AST.
* The name of the class is an unspecified, but legal, name;
* no modifiers; no doc comment; no superclass or superinterfaces;
* and an empty class body.
* <p>
* To create an interface, use this method and then call
* <code>ImplicitTypeDeclaration</code>.
* </p>
*
* @return a new unparented type declaration node
* @since 3.39
*/
public ImplicitTypeDeclaration newImplicitTypeDeclaration() {
return new ImplicitTypeDeclaration(this);
}

/**
* Creates an unparented class declaration node owned by this AST.
* The name of the class is an unspecified, but legal, name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ int treeSize() {
return memSize() + this.bodyDeclarations.listSize();
}

@Override
int memSize() {
return BASE_NODE_SIZE + 2 * 4 ;
}

@Override
final ChildListPropertyDescriptor internalBodyDeclarationsProperty() {
return BODY_DECLARATIONS_PROPERTY;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1913,6 +1913,25 @@ public boolean visit(TryStatement node) {
return false;
}

@Override
public boolean visit(ImplicitTypeDeclaration node) {
//javaDoc
if (node.getJavadoc() != null) {
node.getJavadoc().accept(this);
}

//bodyDeclaration
this.indent++;
for (Object element : node.bodyDeclarations()) {
BodyDeclaration d = (BodyDeclaration) element;
d.accept(this);
}
this.indent--;
printIndent();

return false;
}

@Override
public boolean visit(TypeDeclaration node) {
if (node.getJavadoc() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1859,6 +1859,20 @@ public boolean visit(CompilationUnit node) {
return false;
}

@Override
public boolean visit(ImplicitTypeDeclaration node) {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
//javaDoc
int pos= rewriteJavadoc(node, ImplicitTypeDeclaration.JAVADOC_PROPERTY);

int startIndent= getIndent(node.getStartPosition()) + 1;
int startPos= getPosAfterLeftBrace(pos);
rewriteParagraphList(node, ImplicitTypeDeclaration.BODY_DECLARATIONS_PROPERTY, startPos, startIndent, -1, 2);
return false;
}

@Override
public boolean visit(TypeDeclaration node) {
if (!hasChildrenChanges(node)) {
Expand Down
Loading

0 comments on commit c44358d

Please sign in to comment.