Skip to content

Commit 1f293ac

Browse files
Added ASTRewrite support(Unit test & Rewrite) and ASTConverter unit test
1 parent 5780a5e commit 1f293ac

File tree

7 files changed

+338
-0
lines changed

7 files changed

+338
-0
lines changed

org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter_23Test.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@
2020
import org.eclipse.jdt.core.JavaCore;
2121
import org.eclipse.jdt.core.dom.AST;
2222
import org.eclipse.jdt.core.dom.ASTNode;
23+
import org.eclipse.jdt.core.dom.Block;
2324
import org.eclipse.jdt.core.dom.CompilationUnit;
25+
import org.eclipse.jdt.core.dom.ImplicitTypeDeclaration;
2426
import org.eclipse.jdt.core.dom.ImportDeclaration;
27+
import org.eclipse.jdt.core.dom.Javadoc;
28+
import org.eclipse.jdt.core.dom.MethodDeclaration;
2529
import org.eclipse.jdt.core.dom.Modifier;
2630

2731
import junit.framework.Test;
@@ -105,4 +109,30 @@ void m() {
105109
assertEquals("Incorrect name", "java.lang.System.out", imp.getName().toString());
106110
}
107111
}
112+
113+
public void test002() throws CoreException {
114+
String contents = """
115+
/** */
116+
void main() {
117+
System.out.println("Eclipse");
118+
}
119+
""";
120+
this.workingCopy = getWorkingCopy("/Converter_23/src/X.java", true/*resolve*/);
121+
ASTNode node = buildAST(contents, this.workingCopy);
122+
assertEquals("Wrong type of statement", ASTNode.COMPILATION_UNIT, node.getNodeType());
123+
CompilationUnit compilationUnit = (CompilationUnit) node;
124+
ImplicitTypeDeclaration implicitTypeDeclaration = (ImplicitTypeDeclaration) compilationUnit.types().get(0);
125+
assertEquals("Not an ImplicitTypeDeclaration Type", implicitTypeDeclaration.getNodeType(), ASTNode.UNNAMED_CLASS);
126+
assertEquals("Not an ImplicitTypeDeclaration Name Type", implicitTypeDeclaration.getName().getNodeType(), ASTNode.SIMPLE_NAME);
127+
assertEquals("Identifier is not empty String", implicitTypeDeclaration.getName().getIdentifier(), "");
128+
MethodDeclaration bodyDeclaration = (MethodDeclaration) implicitTypeDeclaration.bodyDeclarations().get(0);
129+
assertEquals("Not a Method Declaration", bodyDeclaration.getNodeType(), ASTNode.METHOD_DECLARATION);
130+
assertEquals("Method Declaration start is not one", bodyDeclaration.getStartPosition(), 1);
131+
Javadoc javaDoc = bodyDeclaration.getJavadoc();
132+
assertEquals("Not a JavaDoc", javaDoc.getNodeType(), ASTNode.JAVADOC);
133+
assertEquals("JavaDoc startPosition is not One", javaDoc.getStartPosition(), 1);
134+
Block block = bodyDeclaration.getBody();
135+
assertEquals("Not a Block", block.getNodeType(), ASTNode.BLOCK);
136+
assertEquals("Block startPosition is not correct", block.getStartPosition(), 21);
137+
}
108138
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 IBM Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
15+
package org.eclipse.jdt.core.tests.rewrite.describing;
16+
17+
import java.util.List;
18+
19+
import org.eclipse.jdt.core.ICompilationUnit;
20+
import org.eclipse.jdt.core.IPackageFragment;
21+
import org.eclipse.jdt.core.JavaCore;
22+
import org.eclipse.jdt.core.dom.AST;
23+
import org.eclipse.jdt.core.dom.ASTNode;
24+
import org.eclipse.jdt.core.dom.Block;
25+
import org.eclipse.jdt.core.dom.CompilationUnit;
26+
import org.eclipse.jdt.core.dom.ExpressionStatement;
27+
import org.eclipse.jdt.core.dom.ImplicitTypeDeclaration;
28+
import org.eclipse.jdt.core.dom.Javadoc;
29+
import org.eclipse.jdt.core.dom.MethodDeclaration;
30+
import org.eclipse.jdt.core.dom.MethodInvocation;
31+
import org.eclipse.jdt.core.dom.PrimitiveType;
32+
import org.eclipse.jdt.core.dom.QualifiedName;
33+
import org.eclipse.jdt.core.dom.StringLiteral;
34+
import org.eclipse.jdt.core.dom.TagElement;
35+
import org.eclipse.jdt.core.dom.TextElement;
36+
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
37+
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
38+
39+
import junit.framework.Test;
40+
41+
public class ASTRewritingImplicitTypeDeclarationTest extends ASTRewritingTest{
42+
43+
public ASTRewritingImplicitTypeDeclarationTest(String name, int apiLevel) {
44+
super(name, apiLevel);
45+
}
46+
47+
public static Test suite() {
48+
return createSuite(ASTRewritingImplicitTypeDeclarationTest.class, 23);
49+
}
50+
51+
@Override
52+
protected void setUp() throws Exception {
53+
super.setUp();
54+
if (this.apiLevel == AST.JLS23 ) {
55+
this.project1.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_23);
56+
this.project1.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_23);
57+
this.project1.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_23);
58+
this.project1.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
59+
}
60+
}
61+
62+
public void test001() throws Exception {
63+
AST ast = AST.newAST(AST.JLS23, true);
64+
// Create CompilationUnit
65+
CompilationUnit compilationUnit = ast.newCompilationUnit();
66+
67+
ImplicitTypeDeclaration implicitTypeDeclaration = ast.newImplicitTypeDeclaration();
68+
69+
Javadoc javaDoc= ast.newJavadoc();
70+
TextElement textElem= ast.newTextElement();
71+
textElem.setText("Hello");
72+
TagElement tagElement= ast.newTagElement();
73+
tagElement.fragments().add(textElem);
74+
javaDoc.tags().add(tagElement);
75+
implicitTypeDeclaration.setJavadoc(javaDoc);
76+
77+
QualifiedName qualifiedName = ast.newQualifiedName(ast.newName("System"), ast.newSimpleName("out"));
78+
MethodInvocation methodInvocation = ast.newMethodInvocation();
79+
methodInvocation.setExpression(qualifiedName);
80+
methodInvocation.setName(ast.newSimpleName("println"));
81+
82+
StringLiteral literal = ast.newStringLiteral();
83+
literal.setLiteralValue("Eclipse");
84+
methodInvocation.arguments().add(literal);
85+
ExpressionStatement expressionStatement = ast.newExpressionStatement(methodInvocation);
86+
87+
Block block= ast.newBlock();
88+
block.statements().add(expressionStatement);
89+
MethodDeclaration methodDeclaration = ast.newMethodDeclaration();
90+
methodDeclaration.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID));
91+
methodDeclaration.setName(ast.newSimpleName("main"));
92+
methodDeclaration.setBody(block);
93+
implicitTypeDeclaration.bodyDeclarations().add(methodDeclaration);
94+
// Add Implicity Type class to compilation unit
95+
compilationUnit.types().add(implicitTypeDeclaration);
96+
97+
StringBuilder buf = new StringBuilder();
98+
buf.append("/** \n");
99+
buf.append(" * Hello\n");
100+
buf.append(" */\n");
101+
buf.append(" void main(){\n");
102+
buf.append(" System.out.println(\"Eclipse\");\n");
103+
buf.append(" }\n");
104+
105+
assertEqualString(compilationUnit.toString(), buf.toString());
106+
}
107+
108+
//javaDoc
109+
public void test002() throws Exception {
110+
AST ast = AST.newAST(AST.JLS23, true);
111+
IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null);
112+
StringBuilder buf = new StringBuilder();
113+
buf= new StringBuilder();
114+
buf.append("/** \n");
115+
buf.append(" * Hello\n");
116+
buf.append(" */\n");
117+
buf.append("void main(){\n");
118+
buf.append(" System.out.println(\"Eclipse\");\n");
119+
buf.append("}\n");
120+
121+
ICompilationUnit cu= pack1.createCompilationUnit("X.java", buf.toString(), false, null);
122+
CompilationUnit astRoot= createAST(cu);
123+
ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());
124+
125+
assertTrue("Parse errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
126+
127+
ImplicitTypeDeclaration implicitTypeDeclaration= findImplicitDeclaration(astRoot, "");
128+
List<MethodDeclaration> methodDeclarationsList = implicitTypeDeclaration.bodyDeclarations();
129+
MethodDeclaration methodDeclaration = methodDeclarationsList.get(0);
130+
{
131+
132+
Javadoc javaDoc = methodDeclaration.getJavadoc();
133+
134+
Javadoc newJavaDoc= ast.newJavadoc();
135+
TextElement textElem= ast.newTextElement();
136+
textElem.setText("Eclipse");
137+
TagElement tagElement= ast.newTagElement();
138+
tagElement.fragments().add(textElem);
139+
newJavaDoc.tags().add(tagElement);
140+
141+
rewrite.replace(javaDoc, newJavaDoc, null);
142+
}
143+
144+
String preview = evaluateRewrite(cu, rewrite);
145+
buf= new StringBuilder();
146+
147+
buf.append("/**\n");
148+
buf.append(" * Eclipse\n");
149+
buf.append(" */\n");
150+
buf.append("void main(){\n");
151+
buf.append(" System.out.println(\"Eclipse\");\n");
152+
buf.append("}\n");
153+
154+
assertEqualString(preview, buf.toString());
155+
156+
{
157+
Javadoc javaDoc = methodDeclaration.getJavadoc();
158+
Javadoc newJavaDoc = null;
159+
160+
rewrite.replace(javaDoc, newJavaDoc, null);
161+
}
162+
163+
preview = evaluateRewrite(cu, rewrite);
164+
buf= new StringBuilder();
165+
166+
buf.append("void main(){\n");
167+
buf.append(" System.out.println(\"Eclipse\");\n");
168+
buf.append("}\n");
169+
170+
assertEqualString(preview, buf.toString());
171+
}
172+
173+
//adding more MEthodDeclaration
174+
public void test003() throws Exception {
175+
AST ast = AST.newAST(AST.JLS23, true);
176+
IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null);
177+
StringBuilder buf = new StringBuilder();
178+
buf= new StringBuilder();
179+
buf.append("/** \n");
180+
buf.append(" * Hello\n");
181+
buf.append(" */\n");
182+
buf.append("void main(){\n");
183+
buf.append(" System.out.println(\"Eclipse\");\n");
184+
buf.append("}\n");
185+
186+
ICompilationUnit cu= pack1.createCompilationUnit("X.java", buf.toString(), false, null);
187+
CompilationUnit astRoot= createAST(cu);
188+
ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());
189+
190+
assertTrue("Parse errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
191+
ImplicitTypeDeclaration implicitTypeDeclaration= findImplicitDeclaration(astRoot, "");
192+
{
193+
MethodInvocation methodInvocation = ast.newMethodInvocation();
194+
methodInvocation.setName(ast.newSimpleName("println"));
195+
196+
StringLiteral literal = ast.newStringLiteral();
197+
literal.setLiteralValue("abc");
198+
199+
QualifiedName qualifiedName = ast.newQualifiedName(ast.newName("System"), ast.newSimpleName("out"));
200+
201+
methodInvocation.setExpression(qualifiedName);
202+
methodInvocation.arguments().add(literal);
203+
204+
ExpressionStatement expressionStatement = ast.newExpressionStatement(methodInvocation);
205+
206+
Block block = ast.newBlock();
207+
block.statements().add(expressionStatement);
208+
209+
MethodDeclaration methodDeclaration = ast.newMethodDeclaration();
210+
methodDeclaration.setBody(block);
211+
methodDeclaration.setName(ast.newSimpleName("abc"));
212+
methodDeclaration.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID));
213+
214+
ListRewrite listRewrite= rewrite.getListRewrite(implicitTypeDeclaration, ImplicitTypeDeclaration.BODY_DECLARATIONS_PROPERTY);
215+
listRewrite.insertAt(methodDeclaration, 1, null);
216+
}
217+
218+
String preview = evaluateRewrite(cu, rewrite);
219+
buf= new StringBuilder();
220+
221+
buf.append("/** \n");
222+
buf.append(" * Hello\n");
223+
buf.append(" */\n");
224+
buf.append("void main(){\n");
225+
buf.append(" System.out.println(\"Eclipse\");\n");
226+
buf.append("}\n");
227+
buf.append("\n");
228+
buf.append("void abc() {\n");
229+
buf.append(" System.out.println(\"abc\");\n");
230+
buf.append("}\n");
231+
232+
assertEqualString(preview, buf.toString());
233+
}
234+
235+
}

org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
2727
import org.eclipse.jdt.core.dom.CompilationUnit;
2828
import org.eclipse.jdt.core.dom.FieldDeclaration;
29+
import org.eclipse.jdt.core.dom.ImplicitTypeDeclaration;
2930
import org.eclipse.jdt.core.dom.MethodDeclaration;
3031
import org.eclipse.jdt.core.dom.Modifier;
3132
import org.eclipse.jdt.core.dom.PrimitiveType;
@@ -459,4 +460,15 @@ protected static MethodDeclaration createNewMethod(AST ast, String name, boolean
459460
return decl;
460461
}
461462

463+
public static ImplicitTypeDeclaration findImplicitDeclaration(CompilationUnit astRoot, String simpleTypeName) {
464+
List types= astRoot.types();
465+
for (int i= 0; i < types.size(); i++) {
466+
ImplicitTypeDeclaration elem= (ImplicitTypeDeclaration) types.get(i);
467+
if (simpleTypeName.equals(elem.getName().getIdentifier())) {
468+
return elem;
469+
}
470+
}
471+
return null;
472+
}
473+
462474
}

org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3190,6 +3190,23 @@ public TryStatement newTryStatement() {
31903190
return new TryStatement(this);
31913191
}
31923192

3193+
/**
3194+
* Creates an unparented class declaration node owned by this AST.
3195+
* The name of the class is an unspecified, but legal, name;
3196+
* no modifiers; no doc comment; no superclass or superinterfaces;
3197+
* and an empty class body.
3198+
* <p>
3199+
* To create an interface, use this method and then call
3200+
* <code>ImplicitTypeDeclaration</code>.
3201+
* </p>
3202+
*
3203+
* @return a new unparented type declaration node
3204+
* @since 3.40
3205+
*/
3206+
public ImplicitTypeDeclaration newImplicitTypeDeclaration() {
3207+
return new ImplicitTypeDeclaration(this);
3208+
}
3209+
31933210
/**
31943211
* Creates an unparented class declaration node owned by this AST.
31953212
* The name of the class is an unspecified, but legal, name;

org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1913,6 +1913,25 @@ public boolean visit(TryStatement node) {
19131913
return false;
19141914
}
19151915

1916+
@Override
1917+
public boolean visit(ImplicitTypeDeclaration node) {
1918+
//javaDoc
1919+
if (node.getJavadoc() != null) {
1920+
node.getJavadoc().accept(this);
1921+
}
1922+
1923+
//bodyDeclaration
1924+
this.indent++;
1925+
for (Object element : node.bodyDeclarations()) {
1926+
BodyDeclaration d = (BodyDeclaration) element;
1927+
d.accept(this);
1928+
}
1929+
this.indent--;
1930+
printIndent();
1931+
1932+
return false;
1933+
}
1934+
19161935
@Override
19171936
public boolean visit(TypeDeclaration node) {
19181937
if (node.getJavadoc() != null) {

org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,20 @@ public boolean visit(CompilationUnit node) {
18591859
return false;
18601860
}
18611861

1862+
@Override
1863+
public boolean visit(ImplicitTypeDeclaration node) {
1864+
if (!hasChildrenChanges(node)) {
1865+
return doVisitUnchangedChildren(node);
1866+
}
1867+
//javaDoc
1868+
int pos= rewriteJavadoc(node, ImplicitTypeDeclaration.JAVADOC_PROPERTY);
1869+
1870+
int startIndent= getIndent(node.getStartPosition()) + 1;
1871+
int startPos= getPosAfterLeftBrace(pos);
1872+
rewriteParagraphList(node, ImplicitTypeDeclaration.BODY_DECLARATIONS_PROPERTY, startPos, startIndent, -1, 2);
1873+
return false;
1874+
}
1875+
18621876
@Override
18631877
public boolean visit(TypeDeclaration node) {
18641878
if (!hasChildrenChanges(node)) {

org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,17 @@ public boolean visit(TryStatement node) {
12101210
return false;
12111211
}
12121212

1213+
@Override
1214+
public boolean visit(ImplicitTypeDeclaration node) {
1215+
ASTNode javadoc= getChildNode(node, TypeDeclaration.JAVADOC_PROPERTY);
1216+
if (javadoc != null) {
1217+
javadoc.accept(this);
1218+
}
1219+
1220+
visitList(node, TypeDeclaration.BODY_DECLARATIONS_PROPERTY, null);
1221+
return false;
1222+
}
1223+
12131224
@Override
12141225
public boolean visit(TypeDeclaration node) {
12151226
int apiLevel= node.getAST().apiLevel();

0 commit comments

Comments
 (0)