diff --git a/api/src/main/java/org/jboss/forge/roaster/model/Initializer.java b/api/src/main/java/org/jboss/forge/roaster/model/Initializer.java new file mode 100644 index 00000000..b8dfcaef --- /dev/null +++ b/api/src/main/java/org/jboss/forge/roaster/model/Initializer.java @@ -0,0 +1,16 @@ +package org.jboss.forge.roaster.model; + +import org.jboss.forge.roaster.Internal; +import org.jboss.forge.roaster.Origin; + +/** + * Represents a initializer of a {@link JavaClass}, {@link JavaRecord} or {@link JavaEnum}. + */ +public interface Initializer, T extends Initializer> extends StaticCapable, Internal, Origin { + + /** + * Get the inner body of this {@link Initializer} + */ + String getBody(); + +} diff --git a/api/src/main/java/org/jboss/forge/roaster/model/InitializerHolder.java b/api/src/main/java/org/jboss/forge/roaster/model/InitializerHolder.java new file mode 100644 index 00000000..5b467313 --- /dev/null +++ b/api/src/main/java/org/jboss/forge/roaster/model/InitializerHolder.java @@ -0,0 +1,21 @@ +package org.jboss.forge.roaster.model; + +import java.util.List; + +/** + * Represents a {@link JavaType} that may define initializers. + */ +public interface InitializerHolder> { + + /** + * Get a {@link List} of all {@link Initializer}s declared by this {@link O} instance, if any; otherwise return an empty + * {@link List} + */ + List> getInitializers(); + + /** + * Return true if this {@link O} instance has the provided {@link Initializer}; otherwise false. + */ + boolean hasInitializer(Initializer initializer); + +} diff --git a/api/src/main/java/org/jboss/forge/roaster/model/JavaClass.java b/api/src/main/java/org/jboss/forge/roaster/model/JavaClass.java index 5d9e4513..2745d9f8 100644 --- a/api/src/main/java/org/jboss/forge/roaster/model/JavaClass.java +++ b/api/src/main/java/org/jboss/forge/roaster/model/JavaClass.java @@ -18,6 +18,7 @@ public interface JavaClass> extends JavaType, PropertyHolder, + InitializerHolder, GenericCapable, Extendable, Abstractable, diff --git a/api/src/main/java/org/jboss/forge/roaster/model/JavaEnum.java b/api/src/main/java/org/jboss/forge/roaster/model/JavaEnum.java index 4a3f6dff..0b1dfb26 100644 --- a/api/src/main/java/org/jboss/forge/roaster/model/JavaEnum.java +++ b/api/src/main/java/org/jboss/forge/roaster/model/JavaEnum.java @@ -17,7 +17,7 @@ * * @author Lincoln Baxter, III */ -public interface JavaEnum> extends JavaType, PropertyHolder, TypeHolder, StaticCapable +public interface JavaEnum> extends JavaType, PropertyHolder, InitializerHolder, TypeHolder, StaticCapable { /** * Return the {@link EnumConstant} with the given name, or return null if no such constant exists. diff --git a/api/src/main/java/org/jboss/forge/roaster/model/JavaRecord.java b/api/src/main/java/org/jboss/forge/roaster/model/JavaRecord.java index fd29a64a..d87a1d77 100644 --- a/api/src/main/java/org/jboss/forge/roaster/model/JavaRecord.java +++ b/api/src/main/java/org/jboss/forge/roaster/model/JavaRecord.java @@ -11,6 +11,7 @@ public interface JavaRecord> extends JavaType, MethodHolder, + InitializerHolder, TypeHolder, InterfaceCapable { diff --git a/api/src/main/java/org/jboss/forge/roaster/model/source/InitializerHolderSource.java b/api/src/main/java/org/jboss/forge/roaster/model/source/InitializerHolderSource.java new file mode 100644 index 00000000..55028852 --- /dev/null +++ b/api/src/main/java/org/jboss/forge/roaster/model/source/InitializerHolderSource.java @@ -0,0 +1,41 @@ +package org.jboss.forge.roaster.model.source; + +import java.util.List; + +import org.jboss.forge.roaster.model.Initializer; +import org.jboss.forge.roaster.model.InitializerHolder; + +/** + * Represents a {@link JavaSource} that may declare initializers. + */ +public interface InitializerHolderSource> extends InitializerHolder, MemberHolderSource { + + /** + * Get a {@link List} of all {@link InitializerSource}s declared by this {@link O} instance, if any; otherwise return an + * empty {@link List} + */ + @Override + List> getInitializers(); + + /** + * Add an uninitialized {@link InitializerSource} declaration to this {@link O} instance. This {@link InitializerSource} will + * be a stub until further modified. + */ + InitializerSource addInitializer(); + + /** + * Add a new {@link InitializerSource} declaration to this {@link O} instance, using the given {@link String} as the + * initializer declaration. + *

+ * For example:
+ * Initializer initializer = javaClass.addInitializer("static { System.out.println(\"Hello\") }") + */ + InitializerSource addInitializer(final String body); + + /** + * Remove the given {@link InitializerSource} declaration from this {@link O} instance, if it exists; otherwise, do + * nothing. + */ + O removeInitializer(final Initializer initializer); + +} diff --git a/api/src/main/java/org/jboss/forge/roaster/model/source/InitializerSource.java b/api/src/main/java/org/jboss/forge/roaster/model/source/InitializerSource.java new file mode 100644 index 00000000..9b16d444 --- /dev/null +++ b/api/src/main/java/org/jboss/forge/roaster/model/source/InitializerSource.java @@ -0,0 +1,16 @@ +package org.jboss.forge.roaster.model.source; + +import org.jboss.forge.roaster.model.Initializer; + +/** + * Represents a Java initializer in source form. + */ +public interface InitializerSource> extends Initializer>, + JavaDocCapableSource>, StaticCapableSource>, LocationCapable { + + /** + * Set the inner body of this {@link Initializer} + */ + InitializerSource setBody(String body); + +} diff --git a/api/src/main/java/org/jboss/forge/roaster/model/source/JavaClassSource.java b/api/src/main/java/org/jboss/forge/roaster/model/source/JavaClassSource.java index 9d02ca63..3f8858ee 100644 --- a/api/src/main/java/org/jboss/forge/roaster/model/source/JavaClassSource.java +++ b/api/src/main/java/org/jboss/forge/roaster/model/source/JavaClassSource.java @@ -22,6 +22,7 @@ public interface JavaClassSource extends JavaClass, GenericCapableSource, ExtendableSource, AbstractableSource, + InitializerHolderSource, PropertyHolderSource, TypeHolderSource, FinalCapableSource, diff --git a/api/src/main/java/org/jboss/forge/roaster/model/source/JavaEnumSource.java b/api/src/main/java/org/jboss/forge/roaster/model/source/JavaEnumSource.java index 7b342946..c96ebe77 100644 --- a/api/src/main/java/org/jboss/forge/roaster/model/source/JavaEnumSource.java +++ b/api/src/main/java/org/jboss/forge/roaster/model/source/JavaEnumSource.java @@ -21,6 +21,7 @@ */ public interface JavaEnumSource extends JavaEnum, JavaSource, InterfaceCapableSource, + InitializerHolderSource, PropertyHolderSource, TypeHolderSource, StaticCapableSource { /** diff --git a/api/src/main/java/org/jboss/forge/roaster/model/source/JavaRecordSource.java b/api/src/main/java/org/jboss/forge/roaster/model/source/JavaRecordSource.java index 3e659934..1c59b557 100644 --- a/api/src/main/java/org/jboss/forge/roaster/model/source/JavaRecordSource.java +++ b/api/src/main/java/org/jboss/forge/roaster/model/source/JavaRecordSource.java @@ -9,6 +9,7 @@ public interface JavaRecordSource extends JavaSource, JavaRecord, MethodHolderSource, + InitializerHolderSource, TypeHolderSource, InterfaceCapableSource { diff --git a/impl/src/main/java/org/jboss/forge/roaster/model/ast/InitializerAccessor.java b/impl/src/main/java/org/jboss/forge/roaster/model/ast/InitializerAccessor.java new file mode 100644 index 00000000..50d7da55 --- /dev/null +++ b/impl/src/main/java/org/jboss/forge/roaster/model/ast/InitializerAccessor.java @@ -0,0 +1,65 @@ +package org.jboss.forge.roaster.model.ast; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; +import org.eclipse.jdt.core.dom.BodyDeclaration; +import org.eclipse.jdt.core.dom.Initializer; +import org.jboss.forge.roaster.model.impl.InitializerImpl; +import org.jboss.forge.roaster.model.source.InitializerSource; +import org.jboss.forge.roaster.model.source.JavaSource; + +public final class InitializerAccessor +{ + + @SuppressWarnings("unchecked") + public static > List> getInitializers(O origin, + AbstractTypeDeclaration declaration) + { + + List> result = new ArrayList<>(); + List bodyDeclarations = declaration.bodyDeclarations(); + for (BodyDeclaration bodyDeclaration : bodyDeclarations) + { + if (bodyDeclaration instanceof Initializer) + { + Initializer initializer = (Initializer) bodyDeclaration; + result.add(new InitializerImpl<>(origin, initializer)); + } + } + return Collections.unmodifiableList(result); + } + + public static > boolean hasInitializer(AbstractTypeDeclaration declaration, + org.jboss.forge.roaster.model.Initializer initializer) + { + return declaration.bodyDeclarations().contains(initializer.getInternal()); + } + + @SuppressWarnings("unchecked") + public static > InitializerSource addInitializer(O origin, + AbstractTypeDeclaration declaration) + { + InitializerImpl init = new InitializerImpl<>(origin); + declaration.bodyDeclarations().add(init.getInternal()); + return init; + } + + @SuppressWarnings("unchecked") + public static > InitializerSource addInitializer(O origin, + AbstractTypeDeclaration declaration, String initializer) + { + InitializerImpl init = new InitializerImpl<>(origin, initializer); + declaration.bodyDeclarations().add(init.getInternal()); + return init; + } + + public static void removeInitializer(AbstractTypeDeclaration declaration, + org.jboss.forge.roaster.model.Initializer initializer) + { + declaration.bodyDeclarations().remove(initializer.getInternal()); + } + +} diff --git a/impl/src/main/java/org/jboss/forge/roaster/model/impl/InitializerImpl.java b/impl/src/main/java/org/jboss/forge/roaster/model/impl/InitializerImpl.java new file mode 100644 index 00000000..ee2b4447 --- /dev/null +++ b/impl/src/main/java/org/jboss/forge/roaster/model/impl/InitializerImpl.java @@ -0,0 +1,213 @@ +package org.jboss.forge.roaster.model.impl; + +import java.util.List; + +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.Block; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.Initializer; +import org.eclipse.jdt.core.dom.Javadoc; +import org.eclipse.jdt.core.dom.Statement; +import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword; +import org.jboss.forge.roaster.ParserException; +import org.jboss.forge.roaster.Problem; +import org.jboss.forge.roaster.Roaster; +import org.jboss.forge.roaster.model.ast.ModifierAccessor; +import org.jboss.forge.roaster.model.source.InitializerSource; +import org.jboss.forge.roaster.model.source.JavaClassSource; +import org.jboss.forge.roaster.model.source.JavaDocSource; +import org.jboss.forge.roaster.model.source.JavaSource; +import org.jboss.forge.roaster.model.util.JDTOptions; + +public class InitializerImpl> implements InitializerSource +{ + private O parent = null; + private AST ast = null; + private CompilationUnit cu = null; + private final Initializer initializer; + + private void init(final O parent) + { + this.parent = parent; + cu = (CompilationUnit) parent.getInternal(); + ast = cu.getAST(); + } + + public InitializerImpl(final O parent) + { + init(parent); + initializer = ast.newInitializer(); + } + + public InitializerImpl(final O parent, final Object internal) + { + init(parent); + initializer = (Initializer) internal; + } + + public InitializerImpl(final O parent, final String initializer) + { + init(parent); + String stub = "public class Stub { " + initializer + " }"; + JavaClassSource temp = (JavaClassSource) Roaster.parse(stub); + Initializer newInitializer = (Initializer) temp.getInitializers().get(0).getInternal(); + this.initializer = (Initializer) ASTNode.copySubtree(cu.getAST(), newInitializer); + } + + @Override + public String getBody() + { + Block body = initializer.getBody(); + if (body != null) + { + StringBuilder result = new StringBuilder(); + List statements = (List) body.getStructuralProperty(Block.STATEMENTS_PROPERTY); + for (Statement statement : statements) { + result.append(statement).append(" "); + } + return result.toString().trim(); + } + return null; + } + + @Override + public InitializerSource setBody(String body) + { + if (body == null) { + initializer.setBody(null); + return this; + } + List problems = Roaster.validateSnippet(body); + if (problems.size() > 0) { + throw new ParserException(problems); + } + ASTParser parser = ASTParser.newParser(AST.getJLSLatest()); + parser.setSource(body.toCharArray()); + parser.setCompilerOptions(JDTOptions.getJDTOptions()); + parser.setKind(ASTParser.K_STATEMENTS); + Block block = (Block) parser.createAST(null); + block = (Block) ASTNode.copySubtree(initializer.getAST(), block); + initializer.setBody(block); + return this; + } + + @Override + public boolean isStatic() + { + return ModifierAccessor.hasModifier(initializer, ModifierKeyword.STATIC_KEYWORD); + } + + @Override + public InitializerSource setStatic(boolean statc) + { + if (statc) + ModifierAccessor.addModifier(initializer, ModifierKeyword.STATIC_KEYWORD); + else + ModifierAccessor.removeModifier(initializer, ModifierKeyword.STATIC_KEYWORD); + return this; + } + + @Override + public Object getInternal() + { + return initializer; + } + + @Override + public O getOrigin() + { + return parent; + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = (prime * result) + ((initializer == null) ? 0 : initializer.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + InitializerImpl other = (InitializerImpl) obj; + if (initializer == null) + { + if (other.initializer != null) + { + return false; + } + } + else if (!initializer.equals(other.initializer)) + { + return false; + } + return true; + } + + @Override + public boolean hasJavaDoc() + { + return initializer.getJavadoc() != null; + } + + @Override + public InitializerSource removeJavaDoc() + { + initializer.setJavadoc(null); + return this; + } + + @Override + public JavaDocSource> getJavaDoc() + { + Javadoc javadoc = initializer.getJavadoc(); + if (javadoc == null) + { + javadoc = initializer.getAST().newJavadoc(); + initializer.setJavadoc(javadoc); + } + return new JavaDocImpl<>(this, javadoc); + } + + @Override + public int getStartPosition() + { + return initializer.getStartPosition(); + } + + @Override + public int getEndPosition() + { + int startPosition = getStartPosition(); + return (startPosition == -1) ? -1 : startPosition + initializer.getLength(); + } + + @Override + public int getLineNumber() + { + return cu.getLineNumber(getStartPosition()); + } + + @Override + public int getColumnNumber() + { + return cu.getColumnNumber(getStartPosition()); + } + +} diff --git a/impl/src/main/java/org/jboss/forge/roaster/model/impl/JavaClassImpl.java b/impl/src/main/java/org/jboss/forge/roaster/model/impl/JavaClassImpl.java index e59012e9..a540a831 100644 --- a/impl/src/main/java/org/jboss/forge/roaster/model/impl/JavaClassImpl.java +++ b/impl/src/main/java/org/jboss/forge/roaster/model/impl/JavaClassImpl.java @@ -6,6 +6,8 @@ */ package org.jboss.forge.roaster.model.impl; +import java.util.List; + import org.eclipse.jdt.core.dom.BodyDeclaration; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword; @@ -14,10 +16,13 @@ import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jface.text.Document; +import org.jboss.forge.roaster.model.Initializer; import org.jboss.forge.roaster.model.JavaClass; import org.jboss.forge.roaster.model.JavaType; +import org.jboss.forge.roaster.model.ast.InitializerAccessor; import org.jboss.forge.roaster.model.ast.ModifierAccessor; import org.jboss.forge.roaster.model.source.Import; +import org.jboss.forge.roaster.model.source.InitializerSource; import org.jboss.forge.roaster.model.source.JavaClassSource; import org.jboss.forge.roaster.model.source.JavaSource; import org.jboss.forge.roaster.model.source.MethodSource; @@ -244,4 +249,35 @@ private boolean handleNullSuperType(Object type) } return false; } + + @Override + public List> getInitializers() + { + return InitializerAccessor.getInitializers(this, getDeclaration()); + } + + @Override + public boolean hasInitializer(Initializer initializer) + { + return InitializerAccessor.hasInitializer(getDeclaration(), initializer); + } + + @Override + public InitializerSource addInitializer() + { + return InitializerAccessor.addInitializer(this, getDeclaration()); + } + + @Override + public InitializerSource addInitializer(final String initializer) + { + return InitializerAccessor.addInitializer(this, getDeclaration(), initializer); + } + + @Override + public JavaClassSource removeInitializer(org.jboss.forge.roaster.model.Initializer initializer) + { + InitializerAccessor.removeInitializer(getDeclaration(), initializer); + return this; + } } \ No newline at end of file diff --git a/impl/src/main/java/org/jboss/forge/roaster/model/impl/JavaEnumImpl.java b/impl/src/main/java/org/jboss/forge/roaster/model/impl/JavaEnumImpl.java index e1254d73..4869e07d 100644 --- a/impl/src/main/java/org/jboss/forge/roaster/model/impl/JavaEnumImpl.java +++ b/impl/src/main/java/org/jboss/forge/roaster/model/impl/JavaEnumImpl.java @@ -15,7 +15,10 @@ import org.eclipse.jdt.core.dom.EnumConstantDeclaration; import org.eclipse.jdt.core.dom.EnumDeclaration; import org.eclipse.jface.text.Document; +import org.jboss.forge.roaster.model.Initializer; +import org.jboss.forge.roaster.model.ast.InitializerAccessor; import org.jboss.forge.roaster.model.source.EnumConstantSource; +import org.jboss.forge.roaster.model.source.InitializerSource; import org.jboss.forge.roaster.model.source.JavaEnumSource; import org.jboss.forge.roaster.model.source.JavaSource; @@ -24,7 +27,7 @@ * * @author Lincoln Baxter, III */ -public class JavaEnumImpl extends AbstractJavaSourceMemberHolderimplements JavaEnumSource +public class JavaEnumImpl extends AbstractJavaSourceMemberHolder implements JavaEnumSource { public JavaEnumImpl(JavaSource enclosingType, final Document document, final CompilationUnit unit, BodyDeclaration body) @@ -90,4 +93,35 @@ protected JavaEnumSource updateTypeNames(final String newName) return this; } + @Override + public List> getInitializers() + { + return InitializerAccessor.getInitializers(this, getDeclaration()); + } + + @Override + public boolean hasInitializer(Initializer initializer) + { + return InitializerAccessor.hasInitializer(getDeclaration(), initializer); + } + + @Override + public InitializerSource addInitializer() + { + return InitializerAccessor.addInitializer(this, getDeclaration()); + } + + @Override + public InitializerSource addInitializer(final String initializer) + { + return InitializerAccessor.addInitializer(this, getDeclaration(), initializer); + } + + @Override + public JavaEnumSource removeInitializer(org.jboss.forge.roaster.model.Initializer initializer) + { + InitializerAccessor.removeInitializer(getDeclaration(), initializer); + return this; + } + } diff --git a/impl/src/main/java/org/jboss/forge/roaster/model/impl/JavaRecordImpl.java b/impl/src/main/java/org/jboss/forge/roaster/model/impl/JavaRecordImpl.java index 7dcb4904..27ad1a17 100644 --- a/impl/src/main/java/org/jboss/forge/roaster/model/impl/JavaRecordImpl.java +++ b/impl/src/main/java/org/jboss/forge/roaster/model/impl/JavaRecordImpl.java @@ -8,27 +8,23 @@ import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.RecordDeclaration; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jface.text.Document; import org.jboss.forge.roaster.Roaster; -import org.jboss.forge.roaster.model.JavaInterface; +import org.jboss.forge.roaster.model.Initializer; import org.jboss.forge.roaster.model.JavaRecordComponent; -import org.jboss.forge.roaster.model.Method; import org.jboss.forge.roaster.model.Type; -import org.jboss.forge.roaster.model.ast.MethodFinderVisitor; +import org.jboss.forge.roaster.model.ast.InitializerAccessor; import org.jboss.forge.roaster.model.source.Import; -import org.jboss.forge.roaster.model.source.InterfaceCapableSource; +import org.jboss.forge.roaster.model.source.InitializerSource; import org.jboss.forge.roaster.model.source.JavaRecordComponentSource; import org.jboss.forge.roaster.model.source.JavaRecordSource; import org.jboss.forge.roaster.model.source.JavaSource; import org.jboss.forge.roaster.model.source.MemberSource; -import org.jboss.forge.roaster.model.source.MethodSource; import org.jboss.forge.roaster.model.util.Types; import java.util.ArrayList; -import java.util.Collections; import java.util.List; /** @@ -121,4 +117,35 @@ public JavaRecordSource removeRecordComponent(JavaRecordComponent recordComponen getDeclaration().recordComponents().remove(recordComponent.getInternal()); return this; } + + @Override + public List> getInitializers() + { + return InitializerAccessor.getInitializers(this, getDeclaration()); + } + + @Override + public boolean hasInitializer(Initializer initializer) + { + return InitializerAccessor.hasInitializer(getDeclaration(), initializer); + } + + @Override + public InitializerSource addInitializer() + { + return InitializerAccessor.addInitializer(this, getDeclaration()); + } + + @Override + public InitializerSource addInitializer(final String initializer) + { + return InitializerAccessor.addInitializer(this, getDeclaration(), initializer); + } + + @Override + public JavaRecordSource removeInitializer(org.jboss.forge.roaster.model.Initializer initializer) + { + InitializerAccessor.removeInitializer(getDeclaration(), initializer); + return this; + } } diff --git a/tests/src/test/java/org/jboss/forge/test/roaster/model/InitializerBodyTest.java b/tests/src/test/java/org/jboss/forge/test/roaster/model/InitializerBodyTest.java new file mode 100644 index 00000000..8b9f5d83 --- /dev/null +++ b/tests/src/test/java/org/jboss/forge/test/roaster/model/InitializerBodyTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Eclipse Public License version 1.0, available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.jboss.forge.test.roaster.model; + +import org.jboss.forge.roaster.Roaster; +import org.jboss.forge.roaster.model.source.InitializerSource; +import org.jboss.forge.roaster.model.source.JavaClassSource; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Test for initializer bodies + */ +public class InitializerBodyTest +{ + @Test + public void testSetInitializerBody() + { + String body = "System.out.println(\"Hello world!\");"; + JavaClassSource source = Roaster.create(JavaClassSource.class); + InitializerSource initializer = source.addInitializer().setBody(body); + assertEquals(body, initializer.getBody()); + } + + @Test + public void testInitializerBodyWithLambdas() + { + String body = "foo((c) -> System.out::println);"; + JavaClassSource source = Roaster.create(JavaClassSource.class); + InitializerSource method = source.addInitializer().setBody(body); + assertEquals(body, method.getBody()); + } + + @Test + public void testBodyShouldBeSet() + { + JavaClassSource javaClass = Roaster.create(JavaClassSource.class); + InitializerSource initializer = javaClass.addInitializer() + .setBody("OpenIabHelper.Options.Builder builder = new OpenIabHelper.Options.Builder(); \n\t builder.setStoreSearchStrategy(OpenIabHelper.Options.SEARCH_STRATEGY_INSTALLER);"); + assertNotNull(initializer.getBody()); + assertThat(initializer.getBody()).isNotEmpty(); + } +} \ No newline at end of file diff --git a/tests/src/test/java/org/jboss/forge/test/roaster/model/InitializerImplementationTest.java b/tests/src/test/java/org/jboss/forge/test/roaster/model/InitializerImplementationTest.java new file mode 100644 index 00000000..497a799f --- /dev/null +++ b/tests/src/test/java/org/jboss/forge/test/roaster/model/InitializerImplementationTest.java @@ -0,0 +1,39 @@ +package org.jboss.forge.test.roaster.model; + +import org.jboss.forge.roaster.ParserException; +import org.jboss.forge.roaster.Roaster; +import org.jboss.forge.roaster.model.source.InitializerSource; +import org.jboss.forge.roaster.model.source.JavaClassSource; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class InitializerImplementationTest +{ + + @Test + public void testInitializerBodyShouldNotBeEmptyOnInvalidCode() { + JavaClassSource source = Roaster.create(JavaClassSource.class); + InitializerSource initializer = source.addInitializer(); + assertThrows(ParserException.class, () -> initializer.setBody("{}{{}{dasfasdfasdfga")); + } + + @Test + public void testEmptyInitializerBodyShouldNotThrowException() { + JavaClassSource source = Roaster.create(JavaClassSource.class); + InitializerSource initializer = source.addInitializer(); + initializer.setBody(""); + assertEquals("", initializer.getBody()); + } + + @Test + public void testInitializerBodyShouldParseCorrectly() + { + JavaClassSource source = Roaster.create(JavaClassSource.class); + InitializerSource initializer = source.addInitializer(); + initializer.setBody("System.out.println(\"Hello world!\");"); + assertEquals("System.out.println(\"Hello world!\");", initializer.getBody()); + } + +} diff --git a/tests/src/test/java/org/jboss/forge/test/roaster/model/JavaClassInitializerTest.java b/tests/src/test/java/org/jboss/forge/test/roaster/model/JavaClassInitializerTest.java new file mode 100644 index 00000000..7c42165e --- /dev/null +++ b/tests/src/test/java/org/jboss/forge/test/roaster/model/JavaClassInitializerTest.java @@ -0,0 +1,65 @@ +package org.jboss.forge.test.roaster.model; + +import java.io.IOException; +import java.io.InputStream; + +import org.jboss.forge.roaster.Roaster; +import org.jboss.forge.roaster.model.source.InitializerSource; +import org.jboss.forge.roaster.model.source.JavaClassSource; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class JavaClassInitializerTest +{ + + private JavaClassSource javaClass; + private InitializerSource initializer; + + @BeforeEach + public void reset() throws IOException + { + String fileName = "/org/jboss/forge/grammar/java/MockClass.java"; + try (InputStream stream = JavaClassInitializerTest.class.getResourceAsStream(fileName)) + { + javaClass = Roaster.parse(JavaClassSource.class, stream); + javaClass.addInitializer("{ System.out.println(\"Hello world!\") }"); + initializer = javaClass.getInitializers().get(javaClass.getInitializers().size() - 1); + } + } + + @Test + public void testIsNonStatic() { + assertFalse(initializer.isStatic()); + } + + @Test + public void testSetStatic() { + assertFalse(initializer.isStatic()); + initializer.setStatic(true); + assertTrue(initializer.isStatic()); + } + + @Test + public void testGetInitializers() { + assertEquals(3, javaClass.getInitializers().size()); + } + + @Test + public void testRemoveInitializer() { + assertTrue(javaClass.hasInitializer(initializer)); + javaClass.removeInitializer(initializer); + assertFalse(javaClass.hasInitializer(initializer)); + } + + @Test + public void testAddInitializer() { + assertEquals(3, javaClass.getInitializers().size()); + javaClass.addInitializer(); + assertEquals(4, javaClass.getInitializers().size()); + } + +} diff --git a/tests/src/test/java/org/jboss/forge/test/roaster/model/JavaDocTest.java b/tests/src/test/java/org/jboss/forge/test/roaster/model/JavaDocTest.java index 262d4577..6c0586ef 100644 --- a/tests/src/test/java/org/jboss/forge/test/roaster/model/JavaDocTest.java +++ b/tests/src/test/java/org/jboss/forge/test/roaster/model/JavaDocTest.java @@ -12,6 +12,7 @@ import org.jboss.forge.roaster.model.JavaDocTag; import org.jboss.forge.roaster.model.source.EnumConstantSource; import org.jboss.forge.roaster.model.source.FieldSource; +import org.jboss.forge.roaster.model.source.InitializerSource; import org.jboss.forge.roaster.model.source.JavaClassSource; import org.jboss.forge.roaster.model.source.JavaDocSource; import org.jboss.forge.roaster.model.source.JavaEnumSource; @@ -154,6 +155,24 @@ public void testJavaDocMethod() assertEquals(expected, javaDoc.getFullText()); } + @Test + public void testJavaDocInitializer() + { + String text = "public class MyClass {" + + "/**" + LINE_SEPARATOR + + " * Do Something" + LINE_SEPARATOR + + " * @author George Gastaldi" + LINE_SEPARATOR + " */" + LINE_SEPARATOR + "" + + "{};}"; + JavaClassSource javaClass = Roaster.parse(JavaClassSource.class, text); + assertFalse(javaClass.hasJavaDoc()); + assertEquals(1, javaClass.getInitializers().size()); + InitializerSource initializer = javaClass.getInitializers().get(0); + assertTrue(initializer.hasJavaDoc()); + JavaDocSource> javaDoc = initializer.getJavaDoc(); + String expected = "Do Something" + LINE_SEPARATOR + "@author George Gastaldi"; + assertEquals(expected, javaDoc.getFullText()); + } + @Test public void testJavaDocEnumConstant() { diff --git a/tests/src/test/java/org/jboss/forge/test/roaster/model/JavaEnumInitializerTest.java b/tests/src/test/java/org/jboss/forge/test/roaster/model/JavaEnumInitializerTest.java new file mode 100644 index 00000000..9495ddc7 --- /dev/null +++ b/tests/src/test/java/org/jboss/forge/test/roaster/model/JavaEnumInitializerTest.java @@ -0,0 +1,65 @@ +package org.jboss.forge.test.roaster.model; + +import java.io.IOException; +import java.io.InputStream; + +import org.jboss.forge.roaster.Roaster; +import org.jboss.forge.roaster.model.source.InitializerSource; +import org.jboss.forge.roaster.model.source.JavaEnumSource; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class JavaEnumInitializerTest +{ + + private JavaEnumSource javaEnum; + private InitializerSource initializer; + + @BeforeEach + public void reset() throws IOException + { + String fileName = "/org/jboss/forge/grammar/java/MockEnum.java"; + try (InputStream stream = JavaEnumInitializerTest.class.getResourceAsStream(fileName)) + { + javaEnum = Roaster.parse(JavaEnumSource.class, stream); + javaEnum.addInitializer("{ System.out.println(\"Hello world!\") }"); + initializer = javaEnum.getInitializers().get(javaEnum.getInitializers().size() - 1); + } + } + + @Test + public void testIsNonStatic() { + assertFalse(initializer.isStatic()); + } + + @Test + public void testSetStatic() { + assertFalse(initializer.isStatic()); + initializer.setStatic(true); + assertTrue(initializer.isStatic()); + } + + @Test + public void testGetInitializers() { + assertEquals(3, javaEnum.getInitializers().size()); + } + + @Test + public void testRemoveInitializer() { + assertTrue(javaEnum.hasInitializer(initializer)); + javaEnum.removeInitializer(initializer); + assertFalse(javaEnum.hasInitializer(initializer)); + } + + @Test + public void testAddInitializer() { + assertEquals(3, javaEnum.getInitializers().size()); + javaEnum.addInitializer(); + assertEquals(4, javaEnum.getInitializers().size()); + } + +} diff --git a/tests/src/test/java/org/jboss/forge/test/roaster/model/JavaRecordInitializerTest.java b/tests/src/test/java/org/jboss/forge/test/roaster/model/JavaRecordInitializerTest.java new file mode 100644 index 00000000..69acef04 --- /dev/null +++ b/tests/src/test/java/org/jboss/forge/test/roaster/model/JavaRecordInitializerTest.java @@ -0,0 +1,60 @@ +package org.jboss.forge.test.roaster.model; + +import java.io.IOException; + +import org.jboss.forge.roaster.Roaster; +import org.jboss.forge.roaster.model.source.InitializerSource; +import org.jboss.forge.roaster.model.source.JavaRecordSource; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class JavaRecordInitializerTest +{ + + private JavaRecordSource javaRecord; + private InitializerSource initializer; + + @BeforeEach + public void reset() throws IOException + { + javaRecord = Roaster.parse(JavaRecordSource.class, "public record MockRecord(int foo, String bar) { { System.out.println(\"Hello world!\") } \n static { System.out.println(\"Hello world!\") } }"); + javaRecord.addInitializer("{ System.out.println(\"Hello world!\") }"); + initializer = javaRecord.getInitializers().get(javaRecord.getInitializers().size() - 1); + } + + @Test + public void testIsNonStatic() { + assertFalse(initializer.isStatic()); + } + + @Test + public void testSetStatic() { + assertFalse(initializer.isStatic()); + initializer.setStatic(true); + assertTrue(initializer.isStatic()); + } + + @Test + public void testGetInitializers() { + assertEquals(3, javaRecord.getInitializers().size()); + } + + @Test + public void testRemoveInitializer() { + assertTrue(javaRecord.hasInitializer(initializer)); + javaRecord.removeInitializer(initializer); + assertFalse(javaRecord.hasInitializer(initializer)); + } + + @Test + public void testAddInitializer() { + assertEquals(3, javaRecord.getInitializers().size()); + javaRecord.addInitializer(); + assertEquals(4, javaRecord.getInitializers().size()); + } + +} diff --git a/tests/src/test/resources/org/jboss/forge/grammar/java/MockClass.java b/tests/src/test/resources/org/jboss/forge/grammar/java/MockClass.java index c224cdba..18ab7c22 100644 --- a/tests/src/test/resources/org/jboss/forge/grammar/java/MockClass.java +++ b/tests/src/test/resources/org/jboss/forge/grammar/java/MockClass.java @@ -15,4 +15,12 @@ public class MockClass { public String valueOf(URL url) { return url.getPath(); } + + static { + System.out.println("Hello world!"); + } + + { + System.out.println("Hello world!"); + } } diff --git a/tests/src/test/resources/org/jboss/forge/grammar/java/MockEnum.java b/tests/src/test/resources/org/jboss/forge/grammar/java/MockEnum.java index 33092122..fb92ffdf 100644 --- a/tests/src/test/resources/org/jboss/forge/grammar/java/MockEnum.java +++ b/tests/src/test/resources/org/jboss/forge/grammar/java/MockEnum.java @@ -23,4 +23,12 @@ String getName() { return name(); } + + static { + System.out.println("Hello world!"); + } + + { + System.out.println("Hello world!"); + } }