/**
* Copyright 2011-2017 Asakusa Framework Team.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.asakusafw.utils.java.internal.model.util;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.RandomAccess;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import org.junit.After;
import org.junit.Test;
import com.asakusafw.utils.java.jsr199.testing.VolatileCompiler;
import com.asakusafw.utils.java.model.syntax.Annotation;
import com.asakusafw.utils.java.model.syntax.AnnotationDeclaration;
import com.asakusafw.utils.java.model.syntax.AnnotationElement;
import com.asakusafw.utils.java.model.syntax.Attribute;
import com.asakusafw.utils.java.model.syntax.BasicTypeKind;
import com.asakusafw.utils.java.model.syntax.CatchClause;
import com.asakusafw.utils.java.model.syntax.ClassDeclaration;
import com.asakusafw.utils.java.model.syntax.CompilationUnit;
import com.asakusafw.utils.java.model.syntax.EnumConstantDeclaration;
import com.asakusafw.utils.java.model.syntax.Expression;
import com.asakusafw.utils.java.model.syntax.FormalParameterDeclaration;
import com.asakusafw.utils.java.model.syntax.ImportDeclaration;
import com.asakusafw.utils.java.model.syntax.ImportKind;
import com.asakusafw.utils.java.model.syntax.InfixOperator;
import com.asakusafw.utils.java.model.syntax.LocalVariableDeclaration;
import com.asakusafw.utils.java.model.syntax.MethodDeclaration;
import com.asakusafw.utils.java.model.syntax.ModelFactory;
import com.asakusafw.utils.java.model.syntax.Modifier;
import com.asakusafw.utils.java.model.syntax.ModifierKind;
import com.asakusafw.utils.java.model.syntax.NamedType;
import com.asakusafw.utils.java.model.syntax.PackageDeclaration;
import com.asakusafw.utils.java.model.syntax.PostfixOperator;
import com.asakusafw.utils.java.model.syntax.ReturnStatement;
import com.asakusafw.utils.java.model.syntax.Statement;
import com.asakusafw.utils.java.model.syntax.TryResource;
import com.asakusafw.utils.java.model.syntax.Type;
import com.asakusafw.utils.java.model.syntax.TypeBodyDeclaration;
import com.asakusafw.utils.java.model.syntax.TypeDeclaration;
import com.asakusafw.utils.java.model.syntax.TypeParameterDeclaration;
import com.asakusafw.utils.java.model.syntax.UnaryOperator;
import com.asakusafw.utils.java.model.syntax.VariableDeclarator;
import com.asakusafw.utils.java.model.syntax.WildcardBoundKind;
import com.asakusafw.utils.java.model.util.CommentEmitTrait;
import com.asakusafw.utils.java.model.util.Models;
/**
* Test for {@link ModelEmitter}.
*/
public class ModelEmitterTest {
private final ModelFactory f = Models.getModelFactory();
private PackageDeclaration packageDecl = null;
private final List<ImportDeclaration> importDecls = new ArrayList<>();
private final VolatileCompiler compiler = new VolatileCompiler();
/**
* disposes compiler.
* @throws Exception if exception was occurred
*/
@After
public void tearDown() throws Exception {
compiler.close();
}
/**
* simple case.
*/
@Test
public void simple() {
assertToString(
fromExpr("Hello", f.newLiteral("\"Hello, world!\"")),
"Hello",
"Hello, world!");
}
/**
* literal - string.
*/
@Test
public void Literal_String() {
assertToString(
fromExpr("Hello", f.newLiteral("\"Hello, world!\"")),
"Hello",
"Hello, world!");
}
/**
* literal - integer.
*/
@Test
public void Literal_Int() {
assertToString(
fromExpr("Hello", f.newLiteral("150")),
"Hello",
"150");
}
/**
* literal - float.
*/
@Test
public void Literal_Float() {
assertToString(
fromExpr("Hello", f.newLiteral("100.f")),
"Hello",
"100.0");
}
/**
* literal - char.
*/
@Test
public void Literal_Char() {
assertToString(
fromExpr("Hello", f.newLiteral("'!'")),
"Hello",
"!");
}
/**
* literal - boolean.
*/
@Test
public void Literal_Boolean() {
assertToString(
fromExpr("Hello", f.newLiteral("true")),
"Hello",
"true");
}
/**
* void type.
*/
@Test
public void Type_void() {
assertType(
f.newBasicType(BasicTypeKind.VOID),
void.class);
}
/**
* primitive type.
*/
@Test
public void Type_primitive() {
assertType(
f.newBasicType(BasicTypeKind.INT),
int.class);
}
/**
* named type.
*/
@Test
public void Type_ClassOrInterface() {
assertType(
f.newNamedType(f.newSimpleName("Runnable")),
Runnable.class);
}
/**
* array type.
*/
@Test
public void Type_Array() {
assertType(
f.newArrayType(f.newBasicType(BasicTypeKind.INT)),
int[].class);
}
/**
* type variable.
*/
@Test
public void Type_variable() {
java.lang.reflect.Type type = getType(
f.newNamedType(f.newSimpleName("T")));
assertThat(type, instanceOf(TypeVariable.class));
TypeVariable<?> typeVar = (TypeVariable<?>) type;
assertThat(typeVar.getName(), is("T"));
}
/**
* parameterized type.
*/
@Test
public void Type_parameterized() {
java.lang.reflect.Type type = getType(
f.newParameterizedType(
f.newNamedType(f.newSimpleName("Comparable")),
Arrays.asList(new Type[] {
f.newNamedType(f.newSimpleName("String"))
})));
assertThat(type, instanceOf(java.lang.reflect.ParameterizedType.class));
java.lang.reflect.ParameterizedType p = (java.lang.reflect.ParameterizedType) type;
assertThat(p.getRawType(), is((java.lang.reflect.Type) Comparable.class));
assertThat(p.getActualTypeArguments()[0],
is((java.lang.reflect.Type) String.class));
}
/**
* type wildcard.
*/
@Test
public void Type_wildcard() {
java.lang.reflect.Type type = getType(
f.newParameterizedType(
f.newNamedType(f.newSimpleName("Comparable")),
Arrays.asList(new Type[] {
f.newWildcard()
})));
assertThat(type, instanceOf(java.lang.reflect.ParameterizedType.class));
java.lang.reflect.Type p = ((java.lang.reflect.ParameterizedType) type).getActualTypeArguments()[0];
assertThat(p, instanceOf(WildcardType.class));
WildcardType w = (WildcardType) p;
assertThat(w.getLowerBounds().length, is(0));
assertThat(w.getUpperBounds().length, is(1));
assertThat(w.getUpperBounds()[0], is((java.lang.reflect.Type) Object.class));
}
/**
* type wildcard w/ upper bound types.
*/
@Test
public void Type_wildcard_upperBounded() {
java.lang.reflect.Type type = getType(
f.newParameterizedType(
f.newNamedType(f.newSimpleName("Comparable")),
Arrays.asList(new Type[] {
f.newWildcard(
WildcardBoundKind.UPPER_BOUNDED,
f.newNamedType(f.newSimpleName("CharSequence")))
})));
assertThat(type, instanceOf(java.lang.reflect.ParameterizedType.class));
java.lang.reflect.Type p = ((java.lang.reflect.ParameterizedType) type).getActualTypeArguments()[0];
assertThat(p, instanceOf(WildcardType.class));
WildcardType w = (WildcardType) p;
assertThat(w.getLowerBounds().length, is(0));
assertThat(w.getUpperBounds().length, is(1));
assertThat(w.getUpperBounds()[0], is((java.lang.reflect.Type) CharSequence.class));
}
/**
* type wildcard w/ lower bound types.
*/
@Test
public void Type_wildcard_lowerBounded() {
java.lang.reflect.Type type = getType(
f.newParameterizedType(
f.newNamedType(f.newSimpleName("Comparable")),
Arrays.asList(new Type[] {
f.newWildcard(
WildcardBoundKind.LOWER_BOUNDED,
f.newNamedType(f.newSimpleName("CharSequence")))
})));
assertThat(type, instanceOf(java.lang.reflect.ParameterizedType.class));
java.lang.reflect.Type p = ((java.lang.reflect.ParameterizedType) type).getActualTypeArguments()[0];
assertThat(p, instanceOf(WildcardType.class));
WildcardType w = (WildcardType) p;
assertThat(w.getLowerBounds().length, is(1));
assertThat(w.getLowerBounds()[0], is((java.lang.reflect.Type) CharSequence.class));
assertThat(w.getUpperBounds().length, is(1));
assertThat(w.getUpperBounds()[0], is((java.lang.reflect.Type) Object.class));
}
/**
* unary operator.
*/
@Test
public void Unary() {
assertToString(
fromExpr("Hello",
f.newUnaryExpression(UnaryOperator.NOT, Models.toLiteral(f, true))),
"Hello",
"false");
}
/**
* cast operator - int.
*/
@Test
public void Cast_Basic() {
assertToString(
fromExpr("Hello",
f.newCastExpression(
f.newBasicType(BasicTypeKind.INT),
Models.toLiteral(f, 'A'))),
"Hello",
"65");
}
/**
* cast operator - object.
*/
@Test
public void Cast_Reference() {
assertToString(
fromExpr("Hello",
f.newCastExpression(
f.newNamedType(f.newSimpleName("Object")),
Models.toLiteral(f, 100))),
"Hello",
"100");
}
/**
* infix operator.
*/
@Test
public void Infix() {
assertToString(
fromExpr("Hello",
f.newInfixExpression(
Models.toLiteral(f, 10),
InfixOperator.PLUS,
Models.toLiteral(f, 20))),
"Hello",
"30");
}
/**
* instance-of operator.
*/
@Test
public void Instanceof() {
assertToString(
fromExpr("Hello",
f.newInstanceofExpression(
f.newCastExpression(
f.newNamedType(f.newSimpleName("Object")),
Models.toLiteral(f, "Hello")),
f.newNamedType(f.newSimpleName("String")))),
"Hello",
"true");
}
/**
* conditional operator.
*/
@Test
public void Conditional() {
assertToString(
fromExpr("Hello",
f.newConditionalExpression(
Models.toLiteral(f, false),
Models.toLiteral(f, 100),
Models.toLiteral(f, 200))),
"Hello",
"200");
}
/**
* parenthesize.
*/
@Test
public void Parenthesize() {
assertToString(
fromExpr("Hello",
f.newInfixExpression(
Models.toLiteral(f, 100),
InfixOperator.MINUS,
f.newParenthesizedExpression(
f.newInfixExpression(
Models.toLiteral(f, 50),
InfixOperator.MINUS,
Models.toLiteral(f, 100))))),
"Hello",
"150");
}
/**
* expression name.
*/
@Test
public void ExpressionName() {
assertToString(
fromExpr("Hello",
Models.toName(f, "Math.PI")),
"Hello",
String.valueOf(Math.PI));
}
/**
* field access.
*/
@Test
public void FieldAccess() {
assertToString(
fromExpr("Hello",
f.newFieldAccessExpression(
f.newClassInstanceCreationExpression(
null,
Collections.emptyList(),
f.newNamedType(Models.toName(f, "java.awt.Point")),
Arrays.asList(
Models.toLiteral(f, 100),
Models.toLiteral(f, 200)),
null),
f.newSimpleName("y"))),
"Hello",
"200");
}
/**
* new array - 1 dimension.
*/
@Test
public void ArrayCreation_Single() {
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
Models.toName(f, "java.util.Arrays"),
Collections.emptyList(),
f.newSimpleName("toString"),
Arrays.asList(
f.newArrayCreationExpression(
f.newArrayType(f.newBasicType(BasicTypeKind.INT)),
Arrays.asList(Models.toLiteral(f, 3)),
null)))),
"Hello",
"[0, 0, 0]");
}
/**
* new array - multiple dimensions.
*/
@Test
public void ArrayCreation_Multi() {
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
Models.toName(f, "java.util.Arrays"),
Collections.emptyList(),
f.newSimpleName("deepToString"),
Arrays.asList(
f.newArrayCreationExpression(
f.newArrayType(
f.newArrayType(f.newBasicType(BasicTypeKind.INT))),
Arrays.asList(Models.toLiteral(f, 3), Models.toLiteral(f, 2)),
null)))),
"Hello",
"[[0, 0], [0, 0], [0, 0]]");
}
/**
* new array - multiple dimensions w/ lacked dimensions.
*/
@Test
public void ArrayCreation_MultiPartial() {
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
Models.toName(f, "java.util.Arrays"),
Collections.emptyList(),
f.newSimpleName("deepToString"),
Arrays.asList(
f.newArrayCreationExpression(
f.newArrayType(
f.newArrayType(f.newBasicType(BasicTypeKind.INT))),
Arrays.asList(Models.toLiteral(f, 3)),
null)))),
"Hello",
"[null, null, null]");
}
/**
* array initializer.
*/
@Test
public void ArrayInitializer() {
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
Models.toName(f, "java.util.Arrays"),
Collections.emptyList(),
f.newSimpleName("toString"),
Arrays.asList(
f.newArrayCreationExpression(
f.newArrayType(f.newBasicType(BasicTypeKind.INT)),
Collections.emptyList(),
f.newArrayInitializer(Arrays.asList(
Models.toLiteral(f, 0),
Models.toLiteral(f, 1),
Models.toLiteral(f, 2))))))),
"Hello",
"[0, 1, 2]");
}
/**
* array access.
*/
@Test
public void ArrayAccess() {
assertToString(
fromExpr("Hello",
f.newArrayAccessExpression(
f.newParenthesizedExpression(
f.newArrayCreationExpression(
f.newArrayType(f.newBasicType(BasicTypeKind.INT)),
Collections.emptyList(),
f.newArrayInitializer(Arrays.asList(
Models.toLiteral(f, 100),
Models.toLiteral(f, 200),
Models.toLiteral(f, 300))))),
Models.toLiteral(f, 1))),
"Hello",
"200");
}
/**
* type literal.
*/
@Test
public void ClassLiteral() {
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
f.newClassLiteral(f.newNamedType(f.newSimpleName("Object"))),
Collections.emptyList(),
f.newSimpleName("getName"),
Collections.emptyList())),
"Hello",
"java.lang.Object");
}
/**
* method invocation.
*/
@Test
public void MethodInvocation() {
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
f.newLiteral("\"Hello, world!\""),
Collections.emptyList(),
f.newSimpleName("toString"),
Collections.emptyList())),
"Hello",
"Hello, world!");
}
/**
* method invocation whose receiver object has cast.
*/
@Test
public void MethodInvocation_cast_object() {
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
f.newCastExpression(
f.newNamedType(f.newSimpleName("Integer")),
f.newLiteral("1")),
Collections.emptyList(),
f.newSimpleName("toString"),
Collections.emptyList())),
"Hello",
"1");
}
/**
* constructor reference.
*/
@Test
public void ConstructorReference_type() {
assertToString(
fromExpr("Hello",
// ((UnaryOperator<String>) String::new).apply("Hello, world!")
f.newMethodInvocationExpression(
f.newCastExpression(
f.newParameterizedType(
Models.toType(f, java.util.function.UnaryOperator.class),
Models.toType(f, String.class)),
f.newConstructorReferenceExpression(
Models.toType(f, String.class))),
f.newSimpleName("apply"),
f.newLiteral("\"Hello, world!\""))),
"Hello",
"Hello, world!");
}
/**
* method reference.
*/
@Test
public void MethodReference_type() {
assertToString(
fromExpr("Hello",
// ((UnaryOperator<String>) String::toString).apply("Hello, world!")
f.newMethodInvocationExpression(
f.newCastExpression(
f.newParameterizedType(
Models.toType(f, java.util.function.UnaryOperator.class),
Models.toType(f, String.class)),
f.newMethodReferenceExpression(
Models.toType(f, String.class),
f.newSimpleName("toString"))),
f.newSimpleName("apply"),
f.newLiteral("\"Hello, world!\""))),
"Hello",
"Hello, world!");
}
/**
* method reference.
*/
@Test
public void MethodReference_expression() {
assertToString(
fromExpr("Hello",
// ((Supplier<String>) "Hello, world!"::toString).get()
f.newMethodInvocationExpression(
f.newCastExpression(
f.newParameterizedType(
Models.toType(f, java.util.function.Supplier.class),
Models.toType(f, String.class)),
f.newMethodReferenceExpression(
f.newLiteral("\"Hello, world!\""),
f.newSimpleName("toString"))),
f.newSimpleName("get"))),
"Hello",
"Hello, world!");
}
/**
* new object.
*/
@Test
public void ClassInstanceCreation() {
assertToString(
fromExpr("Hello",
f.newClassInstanceCreationExpression(
null,
Collections.emptyList(),
f.newNamedType(f.newSimpleName("String")),
Arrays.asList(Models.toLiteral(f, "Hello, world!")),
null)),
"Hello",
"Hello, world!");
}
/**
* new object w/ anonymous class block.
*/
@Test
public void ClassInstanceCreation_Anonymous() {
assertToString(
fromExpr("Hello",
f.newClassInstanceCreationExpression(
null,
Collections.emptyList(),
f.newNamedType(f.newSimpleName("Object")),
Collections.emptyList(),
f.newClassBody(Arrays.asList(new TypeBodyDeclaration[] {
toString(f.newReturnStatement(Models.toLiteral(f, "Anon")))
})))),
"Hello",
"Anon");
}
/**
* lambda expression w/ empty parameters.
*/
@Test
public void LambdaExpression() {
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
f.newCastExpression(
f.newParameterizedType(
Models.toType(f, Supplier.class),
Models.toType(f, String.class)),
f.newLambdaExpression(Models.toLiteral(f, "LAMBDA"))),
f.newSimpleName("get"),
Arrays.asList())),
"Hello",
"LAMBDA");
}
/**
* lambda expression w/ block body.
*/
@Test
public void LambdaExpression_block() {
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
f.newCastExpression(
f.newParameterizedType(
Models.toType(f, Supplier.class),
Models.toType(f, String.class)),
f.newLambdaExpression(f.newBlock(f.newReturnStatement(
Models.toLiteral(f, "LAMBDA"))))),
f.newSimpleName("get"),
Arrays.asList())),
"Hello",
"LAMBDA");
}
/**
* lambda expression w/ single simple parameter.
*/
@Test
public void LambdaExpression_single() {
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
f.newCastExpression(
f.newParameterizedType(
Models.toType(f, Function.class),
Models.toType(f, String.class),
Models.toType(f, String.class)),
f.newLambdaExpression(f.newSimpleName("e"), e -> e)),
f.newSimpleName("apply"),
Arrays.asList(Models.toLiteral(f, "LAMBDA")))),
"Hello",
"LAMBDA");
}
/**
* lambda expression w/ formal parameters.
*/
@Test
public void LambdaExpression_formal() {
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
f.newCastExpression(
f.newParameterizedType(
Models.toType(f, BiFunction.class),
Models.toType(f, String.class),
Models.toType(f, Integer.class),
Models.toType(f, String.class)),
f.newLambdaExpression(
Arrays.asList(new FormalParameterDeclaration[] {
f.newFormalParameterDeclaration(
Models.toType(f, String.class), f.newSimpleName("a")),
f.newFormalParameterDeclaration(
Models.toType(f, Integer.class), f.newSimpleName("b")),
}),
ps -> f.newInfixExpression(ps.get(0), InfixOperator.PLUS, ps.get(1)))),
f.newSimpleName("apply"),
Arrays.asList(Models.toLiteral(f, "LAMBDA"), Models.toLiteral(f, 100)))),
"Hello",
"LAMBDA100");
}
/**
* assert statement.
*/
@Test
public void Assert() {
assertRaise(
fromStmt("Hello",
f.newAssertStatement(Models.toLiteral(f, false), null),
returnAsString(Models.toLiteral(f, "ERROR"))),
"Hello",
AssertionError.class);
}
/**
* assert statement w/ message.
*/
@Test
public void Assert_WithMessage() {
assertRaise(
fromStmt("Hello",
f.newAssertStatement(
Models.toLiteral(f, false),
Models.toLiteral(f, "OK")),
returnAsString(Models.toLiteral(f, "ERROR"))),
"Hello",
AssertionError.class);
}
/**
* local variable declaration.
*/
@Test
public void LocalVariable() {
assertToString(
fromStmt("Hello",
f.newLocalVariableDeclaration(
Collections.emptyList(),
f.newBasicType(BasicTypeKind.INT),
Arrays.asList(new VariableDeclarator[] {
f.newVariableDeclarator(
f.newSimpleName("a"),
0,
Models.toLiteral(f, 100))
})),
returnAsString(f.newSimpleName("a"))),
"Hello",
"100");
}
/**
* local variable declaration w/ multiple declarators.
*/
@Test
public void LocalVariable_Multiple() {
assertToString(
fromStmt("Hello",
f.newLocalVariableDeclaration(
Collections.emptyList(),
f.newBasicType(BasicTypeKind.INT),
Arrays.asList(new VariableDeclarator[] {
f.newVariableDeclarator(
f.newSimpleName("a"),
0,
Models.toLiteral(f, 100)),
f.newVariableDeclarator(
f.newSimpleName("b"),
0,
Models.toLiteral(f, 20)),
f.newVariableDeclarator(
f.newSimpleName("c"),
0,
Models.toLiteral(f, 30))
})),
returnAsString(
f.newInfixExpression(
f.newSimpleName("a"),
InfixOperator.PLUS,
f.newInfixExpression(
f.newSimpleName("b"),
InfixOperator.TIMES,
f.newSimpleName("c"))))),
"Hello",
"700");
}
/**
* assignment expression.
*/
@Test
public void Assignment() {
assertToString(
fromStmt("Hello",
f.newLocalVariableDeclaration(
Collections.emptyList(),
f.newBasicType(BasicTypeKind.INT),
Arrays.asList(new VariableDeclarator[] {
f.newVariableDeclarator(
f.newSimpleName("a"),
0,
null)
})),
f.newExpressionStatement(
f.newAssignmentExpression(
f.newSimpleName("a"),
InfixOperator.ASSIGN,
Models.toLiteral(f, 200))),
returnAsString(f.newSimpleName("a"))),
"Hello",
"200");
}
/**
* empty statement.
*/
@Test
public void Empty() {
assertToString(
fromStmt("Hello",
f.newEmptyStatement(),
returnAsString(Models.toLiteral(f, 100))),
"Hello",
"100");
}
/**
* if statement - true.
*/
@Test
public void If_true() {
assertToString(
fromStmt("Hello",
f.newIfStatement(
Models.toLiteral(f, true),
returnAsString(Models.toLiteral(f, 100)),
null),
returnAsString(Models.toLiteral(f, 200))),
"Hello",
"100");
}
/**
* if statement - false.
*/
@Test
public void If_false() {
assertToString(
fromStmt("Hello",
f.newIfStatement(
Models.toLiteral(f, false),
returnAsString(Models.toLiteral(f, 100)),
null),
returnAsString(Models.toLiteral(f, 200))),
"Hello",
"200");
}
/**
* if-else statement - false.
*/
@Test
public void If_else() {
assertToString(
fromStmt("Hello",
f.newIfStatement(
Models.toLiteral(f, false),
returnAsString(Models.toLiteral(f, 100)),
returnAsString(Models.toLiteral(f, 200)))),
"Hello",
"200");
}
/**
* if-else statement - false.
*/
@Test
public void If_elseIf() {
assertToString(
fromStmt("Hello",
f.newIfStatement(
Models.toLiteral(f, false),
returnAsString(Models.toLiteral(f, 100)),
f.newIfStatement(
Models.toLiteral(f, false),
returnAsString(Models.toLiteral(f, 200)),
returnAsString(Models.toLiteral(f, 300))))),
"Hello",
"300");
}
/**
* while statement.
*/
@Test
public void While() {
assertToString(
fromStmt("Hello",
newStringBuilder("buf"),
var(f.newBasicType(BasicTypeKind.INT), "a", Models.toLiteral(f, 5)),
f.newWhileStatement(
f.newInfixExpression(
f.newSimpleName("a"),
InfixOperator.GREATER_EQUALS,
Models.toLiteral(f, 0)),
f.newBlock(Arrays.asList(new Statement[] {
append("buf",
f.newPostfixExpression(
f.newSimpleName("a"),
PostfixOperator.DECREMENT)),
}))),
returnAsString(f.newSimpleName("buf"))),
"Hello",
"543210");
}
/**
* for statement w/ variable declaration.
*/
@Test
public void For() {
assertToString(
fromStmt("Hello",
newStringBuilder("buf"),
f.newForStatement(
var(f.newBasicType(BasicTypeKind.INT), "i", Models.toLiteral(f, 0)),
f.newInfixExpression(
f.newSimpleName("i"),
InfixOperator.LESS,
Models.toLiteral(f, 5)),
f.newStatementExpressionList(Arrays.asList(
f.newPostfixExpression(
f.newSimpleName("i"),
PostfixOperator.INCREMENT))),
append("buf", f.newSimpleName("i"))),
returnAsString(f.newSimpleName("buf"))),
"Hello",
"01234");
}
/**
* for statement w/o variable declarations.
*/
@Test
public void For_noVar() {
assertToString(
fromStmt("Hello",
newStringBuilder("buf"),
var(f.newBasicType(BasicTypeKind.INT), "i", null),
f.newForStatement(
f.newStatementExpressionList(Arrays.asList(
f.newAssignmentExpression(
f.newSimpleName("i"),
InfixOperator.ASSIGN,
Models.toLiteral(f, 5)))),
f.newInfixExpression(
f.newSimpleName("i"),
InfixOperator.GREATER,
Models.toLiteral(f, 0)),
f.newStatementExpressionList(Arrays.asList(
f.newPostfixExpression(
f.newSimpleName("i"),
PostfixOperator.DECREMENT))),
append("buf", f.newSimpleName("i"))),
returnAsString(f.newSimpleName("buf"))),
"Hello",
"54321");
}
/**
* enhanced for statement.
*/
@Test
public void ForEach() {
assertToString(
fromStmt("Hello",
newStringBuilder("buf"),
f.newEnhancedForStatement(
f.newFormalParameterDeclaration(
Collections.emptyList(),
f.newBasicType(BasicTypeKind.INT),
false,
f.newSimpleName("elem"),
0),
f.newArrayCreationExpression(
f.newArrayType(f.newBasicType(BasicTypeKind.INT)),
Collections.emptyList(),
f.newArrayInitializer(Arrays.asList(new Expression[] {
Models.toLiteral(f, 10),
Models.toLiteral(f, 20),
Models.toLiteral(f, 30),
}))),
append("buf", f.newSimpleName("elem"))),
returnAsString(f.newSimpleName("buf"))),
"Hello",
"102030");
}
/**
* do-while statement.
*/
@Test
public void DoWhile() {
assertToString(
fromStmt("Hello",
newStringBuilder("buf"),
var(f.newBasicType(BasicTypeKind.INT), "a", Models.toLiteral(f, 5)),
f.newDoStatement(
f.newBlock(Arrays.asList(new Statement[] {
append("buf", f.newSimpleName("a")),
})),
f.newInfixExpression(
f.newPostfixExpression(
f.newSimpleName("a"),
PostfixOperator.DECREMENT),
InfixOperator.GREATER_EQUALS,
Models.toLiteral(f, 0))),
returnAsString(f.newSimpleName("buf"))),
"Hello",
"543210-1");
}
/**
* break statement.
*/
@Test
public void Break() {
assertToString(
fromStmt("Hello",
newStringBuilder("buf"),
var(f.newBasicType(BasicTypeKind.INT), "a", Models.toLiteral(f, 5)),
f.newWhileStatement(
f.newInfixExpression(
f.newSimpleName("a"),
InfixOperator.GREATER_EQUALS,
Models.toLiteral(f, 0)),
f.newBlock(Arrays.asList(new Statement[] {
append("buf",
f.newPostfixExpression(
f.newSimpleName("a"),
PostfixOperator.DECREMENT)),
f.newBreakStatement(null),
}))),
returnAsString(f.newSimpleName("buf"))),
"Hello",
"5");
}
/**
* break statement w/ label.
*/
@Test
public void Break_Labeled() {
assertToString(
fromStmt("Hello",
newStringBuilder("buf"),
var(f.newBasicType(BasicTypeKind.INT), "a", Models.toLiteral(f, 5)),
f.newLabeledStatement(f.newSimpleName("LABEL"), f.newWhileStatement(
Models.toLiteral(f, true),
f.newWhileStatement(
f.newInfixExpression(
f.newSimpleName("a"),
InfixOperator.GREATER_EQUALS,
Models.toLiteral(f, 0)),
f.newBlock(Arrays.asList(new Statement[] {
append("buf",
f.newPostfixExpression(
f.newSimpleName("a"),
PostfixOperator.DECREMENT)),
f.newBreakStatement(f.newSimpleName("LABEL")),
}))))),
returnAsString(f.newSimpleName("buf"))),
"Hello",
"5");
}
/**
* continue statement.
*/
@Test
public void Continue() {
assertToString(
fromStmt("Hello",
newStringBuilder("buf"),
f.newForStatement(
var(f.newBasicType(BasicTypeKind.INT), "i", Models.toLiteral(f, 0)),
f.newInfixExpression(
f.newSimpleName("i"),
InfixOperator.LESS,
Models.toLiteral(f, 5)),
f.newStatementExpressionList(Arrays.asList(
f.newPostfixExpression(
f.newSimpleName("i"),
PostfixOperator.INCREMENT))),
f.newBlock(Arrays.asList(new Statement[] {
f.newIfStatement(
f.newInfixExpression(
f.newSimpleName("i"),
InfixOperator.GREATER,
Models.toLiteral(f, 3)),
f.newContinueStatement(null),
null),
append("buf", f.newSimpleName("i"))
}))),
returnAsString(f.newSimpleName("buf"))),
"Hello",
"0123");
}
/**
* continue statement.
*/
@Test
public void Continue_Labeled() {
assertToString(
fromStmt("Hello",
newStringBuilder("buf"),
f.newLabeledStatement(f.newSimpleName("OUT"), f.newForStatement(
var(f.newBasicType(BasicTypeKind.INT), "o", Models.toLiteral(f, 0)),
f.newInfixExpression(
f.newSimpleName("o"),
InfixOperator.LESS,
Models.toLiteral(f, 3)),
f.newStatementExpressionList(Arrays.asList(
f.newPostfixExpression(
f.newSimpleName("o"),
PostfixOperator.INCREMENT))),
f.newForStatement(
var(f.newBasicType(BasicTypeKind.INT), "i", Models.toLiteral(f, 0)),
f.newInfixExpression(
f.newSimpleName("i"),
InfixOperator.LESS,
Models.toLiteral(f, 5)),
f.newStatementExpressionList(Arrays.asList(
f.newPostfixExpression(
f.newSimpleName("i"),
PostfixOperator.INCREMENT))),
f.newBlock(Arrays.asList(new Statement[] {
f.newIfStatement(
f.newInfixExpression(
f.newSimpleName("i"),
InfixOperator.GREATER,
Models.toLiteral(f, 3)),
f.newContinueStatement(f.newSimpleName("OUT")),
null),
append("buf", f.newSimpleName("o")),
append("buf", f.newSimpleName("i")),
}))))),
returnAsString(f.newSimpleName("buf"))),
"Hello",
"000102031011121320212223");
}
/**
* switch-case statement.
*/
@Test
public void Switch_Case() {
assertToString(
fromStmt("Hello",
f.newSwitchStatement(
Models.toLiteral(f, 2),
Arrays.asList(new Statement[] {
f.newSwitchCaseLabel(Models.toLiteral(f, 1)),
returnAsString(Models.toLiteral(f, "a")),
f.newSwitchCaseLabel(Models.toLiteral(f, 2)),
returnAsString(Models.toLiteral(f, "b")),
f.newSwitchDefaultLabel(),
returnAsString(Models.toLiteral(f, "c")),
}))),
"Hello",
"b");
}
/**
* switch-case statement.
*/
@Test
public void Switch_Default() {
assertToString(
fromStmt("Hello",
f.newSwitchStatement(
Models.toLiteral(f, 4),
Arrays.asList(new Statement[] {
f.newSwitchCaseLabel(Models.toLiteral(f, 1)),
returnAsString(Models.toLiteral(f, "a")),
f.newSwitchCaseLabel(Models.toLiteral(f, 2)),
returnAsString(Models.toLiteral(f, "b")),
f.newSwitchDefaultLabel(),
returnAsString(Models.toLiteral(f, "c")),
}))),
"Hello",
"c");
}
/**
* switch-case statement.
*/
@Test
public void Throw() {
assertRaise(
fromStmt("Hello",
f.newThrowStatement(
f.newClassInstanceCreationExpression(
null,
Collections.emptyList(),
f.newNamedType(Models.toName(f, "UnsupportedOperationException")),
Collections.emptyList(),
null))),
"Hello",
UnsupportedOperationException.class);
}
/**
* try-catch statement.
*/
@Test
public void Try_Catch() {
assertToString(
fromStmt("Hello",
newStringBuilder("buf"),
f.newTryStatement(
f.newBlock(Arrays.asList(new Statement[] {
f.newThrowStatement(
f.newClassInstanceCreationExpression(
null,
Collections.emptyList(),
f.newNamedType(Models.toName(f, "UnsupportedOperationException")),
Arrays.asList(new Expression[] {
Models.toLiteral(f, "OK")
}),
null))
})),
Arrays.asList(new CatchClause[] {
f.newCatchClause(
f.newFormalParameterDeclaration(
Collections.emptyList(),
f.newNamedType(f.newSimpleName("Error")),
false,
f.newSimpleName("e"),
0),
f.newBlock(Arrays.asList(new Statement[] {
}))),
f.newCatchClause(
f.newFormalParameterDeclaration(
Collections.emptyList(),
f.newNamedType(f.newSimpleName("UnsupportedOperationException")),
false,
f.newSimpleName("e"),
0),
f.newBlock(Arrays.asList(new Statement[] {
append(
"buf",
f.newMethodInvocationExpression(
f.newSimpleName("e"),
Collections.emptyList(),
f.newSimpleName("getMessage"),
Collections.emptyList()))
})))
})),
returnAsString(f.newSimpleName("buf"))),
"Hello",
"OK");
}
/**
* try with multi-catch.
*/
@Test
public void Try_Catch_multi() {
assertToString(
fromStmt("Hello",
newStringBuilder("buf"),
f.newTryStatement(
f.newBlock(Arrays.asList(new Statement[] {
f.newThrowStatement(
f.newClassInstanceCreationExpression(
null,
Collections.emptyList(),
f.newNamedType(Models.toName(f, "UnsupportedOperationException")),
Arrays.asList(new Expression[] {
Models.toLiteral(f, "OK")
}),
null))
})),
Arrays.asList(new CatchClause[] {
f.newCatchClause(
f.newFormalParameterDeclaration(
Collections.emptyList(),
f.newUnionType(new Type[] {
f.newNamedType(f.newSimpleName("IllegalArgumentException")),
f.newNamedType(f.newSimpleName("UnsupportedOperationException")),
}),
false,
f.newSimpleName("e"),
0),
f.newBlock(Arrays.asList(new Statement[] {
append(
"buf",
f.newMethodInvocationExpression(
f.newSimpleName("e"),
Collections.emptyList(),
f.newSimpleName("getMessage"),
Collections.emptyList()))
})))
})),
returnAsString(f.newSimpleName("buf"))),
"Hello",
"OK");
}
/**
* try-finally statement.
*/
@Test
public void Try_Finally() {
assertToString(
fromStmt("Hello",
newStringBuilder("buf"),
f.newTryStatement(
f.newBlock(Arrays.asList(new Statement[] {
f.newThrowStatement(
f.newClassInstanceCreationExpression(
null,
Collections.emptyList(),
f.newNamedType(Models.toName(f, "UnsupportedOperationException")),
Arrays.asList(new Expression[] {
Models.toLiteral(f, "OK")
}),
null))
})),
Arrays.asList(new CatchClause[] {
f.newCatchClause(
f.newFormalParameterDeclaration(
Collections.emptyList(),
f.newNamedType(f.newSimpleName("UnsupportedOperationException")),
false,
f.newSimpleName("e"),
0),
f.newBlock(Arrays.asList(new Statement[] {
append(
"buf",
f.newMethodInvocationExpression(
f.newSimpleName("e"),
Collections.emptyList(),
f.newSimpleName("getMessage"),
Collections.emptyList()))
})))
}),
f.newBlock(Arrays.asList(new Statement[] {
append("buf", Models.toLiteral(f, "fin"))
}))),
returnAsString(f.newSimpleName("buf"))),
"Hello",
"OKfin");
}
/**
* try with resources.
*/
@Test
public void Try_with_resources() {
assertToString(
fromStmt("Hello",
f.newTryStatement(
Arrays.asList(f.newTryResource(
Models.toType(f, ByteArrayOutputStream.class),
f.newSimpleName("out"),
f.newClassInstanceCreationExpression(Models.toType(f, ByteArrayOutputStream.class)))),
f.newBlock(f.newReturnStatement(Models.toLiteral(f, "OK"))),
Arrays.asList(f.newCatchClause(
Models.toType(f, IOException.class),
f.newSimpleName("e"),
e -> f.newBlock(f.newReturnStatement(Models.toLiteral(f, "NG"))))))),
"Hello",
"OK");
}
/**
* try with resources.
*/
@Test
public void Try_with_resources_multiple() {
assertToString(
fromStmt("Hello",
f.newTryStatement(
Arrays.asList(new TryResource[] {
f.newTryResource(
Models.toType(f, ByteArrayOutputStream.class),
f.newSimpleName("a"),
f.newClassInstanceCreationExpression(Models.toType(f, ByteArrayOutputStream.class))),
f.newTryResource(
Models.toType(f, ByteArrayOutputStream.class),
f.newSimpleName("b"),
f.newClassInstanceCreationExpression(Models.toType(f, ByteArrayOutputStream.class))),
f.newTryResource(
Models.toType(f, ByteArrayOutputStream.class),
f.newSimpleName("c"),
f.newClassInstanceCreationExpression(Models.toType(f, ByteArrayOutputStream.class))),
}),
f.newBlock(f.newReturnStatement(Models.toLiteral(f, "OK"))),
Arrays.asList(f.newCatchClause(
Models.toType(f, IOException.class),
f.newSimpleName("e"),
e -> f.newBlock(f.newReturnStatement(Models.toLiteral(f, "NG"))))))),
"Hello",
"OK");
}
/**
* synchronized statement.
*/
@Test
public void Synchronized() {
assertToString(
fromStmt("Hello",
newStringBuilder("buf"),
f.newSynchronizedStatement(
f.newThis(),
f.newBlock(Arrays.asList(new Statement[] {
f.newExpressionStatement(f.newMethodInvocationExpression(
f.newThis(),
Collections.emptyList(),
f.newSimpleName("notify"),
Collections.emptyList())),
}))),
append("buf", Models.toLiteral(f, "OK")),
returnAsString(f.newSimpleName("buf"))),
"Hello",
"OK");
}
/**
* class declaration.
*/
@Test
public void ClassDeclaration() {
Class<?> klass = getTypeDeclaration(
f.newClassDeclaration(
null,
Collections.emptyList(),
f.newSimpleName("Testing"),
Collections.emptyList(),
null,
Collections.emptyList(),
Collections.emptyList()));
assertThat(klass.getAnnotations().length, is(0));
assertThat(klass.getName(), equalTo("Testing"));
assertThat(klass.getTypeParameters().length, is(0));
assertThat(klass.getSuperclass(), is((Object) Object.class));
assertThat(klass.getInterfaces().length, is(0));
}
/**
* class declaration w/ modifiers.
*/
@Test
public void ClassDeclaration_modifiers() {
Class<?> klass = getTypeDeclaration(
f.newClassDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC),
f.newModifier(ModifierKind.ABSTRACT),
}),
f.newSimpleName("Testing"),
Collections.emptyList(),
null,
Collections.emptyList(),
Collections.emptyList()));
assertThat(java.lang.reflect.Modifier.isPublic(klass.getModifiers()),
is(true));
assertThat(java.lang.reflect.Modifier.isAbstract(klass.getModifiers()),
is(true));
}
/**
* class declaration w/ marker annotation.
*/
@Test
public void ClassDeclaration_markerAnnotation() {
Class<?> klass = getTypeDeclaration(
f.newClassDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newMarkerAnnotation(
(NamedType) Models.toType(f, Deprecated.class))
}),
f.newSimpleName("Testing"),
Collections.emptyList(),
null,
Collections.emptyList(),
Collections.emptyList()));
assertThat(klass.getAnnotation(Deprecated.class),
not(nullValue()));
}
/**
* class declaration - single element annotation.
*/
@Test
public void ClassDeclaration_singleElementAnnotation() {
Class<?> klass = getTypeDeclaration(
f.newClassDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newSingleElementAnnotation(
f.newNamedType(f.newSimpleName("An")),
f.newArrayInitializer(Arrays.asList(new Expression[] {
Models.toLiteral(f, "a"),
Models.toLiteral(f, "b"),
})))
}),
f.newSimpleName("Testing"),
Collections.emptyList(),
null,
Collections.emptyList(),
Collections.emptyList()),
createAnnotation("An"));
String[] value = (String[]) getAnnotationValue(klass, "An", "value");
assertThat(value.length, is(2));
assertThat(value[0], is("a"));
assertThat(value[1], is("b"));
Integer option = (Integer) getAnnotationValue(klass, "An", "option");
assertThat(option, is(100));
}
/**
* class declaration w/ normal annotation.
*/
@Test
public void ClassDeclaration_normalAnnotation() {
Class<?> klass = getTypeDeclaration(
f.newClassDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newNormalAnnotation(
f.newNamedType(f.newSimpleName("An")),
Arrays.asList(new AnnotationElement[] {
f.newAnnotationElement(
f.newSimpleName("value"),
Models.toLiteral(f, "a")),
f.newAnnotationElement(
f.newSimpleName("option"),
Models.toLiteral(f, 500)),
}))
}),
f.newSimpleName("Testing"),
Collections.emptyList(),
null,
Collections.emptyList(),
Collections.emptyList()),
createAnnotation("An"));
String[] value = (String[]) getAnnotationValue(klass, "An", "value");
assertThat(value.length, is(1));
assertThat(value[0], is("a"));
Integer option = (Integer) getAnnotationValue(klass, "An", "option");
assertThat(option, is(500));
}
/**
* class declaration w/ type parameters.
*/
@Test
public void ClassDeclaration_typeParameter() {
Class<?> klass = getTypeDeclaration(
f.newClassDeclaration(
null,
Collections.emptyList(),
f.newSimpleName("Testing"),
Arrays.asList(new TypeParameterDeclaration[] {
f.newTypeParameterDeclaration(
f.newSimpleName("T"),
Collections.emptyList())
}),
null,
Collections.emptyList(),
Collections.emptyList()));
TypeVariable<?>[] tps = klass.getTypeParameters();
assertThat(tps.length, is(1));
assertThat(tps[0].getName(), is("T"));
java.lang.reflect.Type[] bounds = tps[0].getBounds();
if (bounds.length == 1) {
assertThat(bounds[0], is((Object) Object.class));
}
}
/**
* class declaration w/ type parameters.
*/
@Test
public void ClassDeclaration_boundedTypeParameter() {
Class<?> klass = getTypeDeclaration(
f.newClassDeclaration(
null,
Collections.emptyList(),
f.newSimpleName("Testing"),
Arrays.asList(new TypeParameterDeclaration[] {
f.newTypeParameterDeclaration(
f.newSimpleName("T"),
Arrays.asList(new Type[] {
Models.toType(f, CharSequence.class)
}))
}),
null,
Collections.emptyList(),
Collections.emptyList()));
TypeVariable<?>[] tps = klass.getTypeParameters();
assertThat(tps.length, is(1));
assertThat(tps[0].getName(), is("T"));
java.lang.reflect.Type[] bounds = tps[0].getBounds();
assertThat(bounds.length, is(1));
assertThat(bounds[0], is((Object) CharSequence.class));
}
/**
* class declaration w/ super class.
*/
@Test
public void ClassDeclaration_superClass() {
Class<?> klass = getTypeDeclaration(
f.newClassDeclaration(
null,
Collections.emptyList(),
f.newSimpleName("Testing"),
Collections.emptyList(),
Models.toType(f, Date.class),
Collections.emptyList(),
Collections.emptyList()));
assertThat(klass.getSuperclass(), is((Object) Date.class));
}
/**
* class declaration - super interfaces.
*/
@Test
public void ClassDeclaration_superInterfaces() {
Class<?> klass = getTypeDeclaration(
f.newClassDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.ABSTRACT)
}),
f.newSimpleName("Testing"),
Collections.emptyList(),
null,
Arrays.asList(new Type[] {
Models.toType(f, Serializable.class),
Models.toType(f, RandomAccess.class),
}),
Collections.emptyList()));
Class<?>[] interfaces = klass.getInterfaces();
assertThat(interfaces.length, is(2));
assertThat(interfaces, hasItemInArray((Object) Serializable.class));
assertThat(interfaces, hasItemInArray((Object) RandomAccess.class));
}
/**
* interface declaration.
*/
@Test
public void InterfaceDeclaration() {
Class<?> klass = getTypeDeclaration(
f.newInterfaceDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
f.newSimpleName("Testing"),
Arrays.asList(new TypeParameterDeclaration[] {
f.newTypeParameterDeclaration(
f.newSimpleName("A"),
Collections.emptyList())
}),
Arrays.asList(new Type[] {
Models.toType(f, Serializable.class),
Models.toType(f, RandomAccess.class),
}),
Collections.emptyList()));
assertThat(klass.isInterface(), is(true));
assertThat(klass.getName(), equalTo("Testing"));
TypeVariable<?>[] tps = klass.getTypeParameters();
assertThat(tps.length, is(1));
assertThat(tps[0].getName(), is("A"));
Class<?>[] interfaces = klass.getInterfaces();
assertThat(interfaces.length, is(2));
assertThat(interfaces, hasItemInArray((Object) Serializable.class));
assertThat(interfaces, hasItemInArray((Object) RandomAccess.class));
}
/**
* interface declaration w/ default method.
* @throws Exception if failed
*/
@Test
public void InterfaceDeclaration_default() throws Exception {
Class<?> klass = getTypeDeclaration(
f.newInterfaceDeclaration(
null,
Arrays.asList(f.newModifier(ModifierKind.PUBLIC)),
f.newSimpleName("Testing"),
Collections.emptyList(),
Arrays.asList(f.newMethodDeclaration(
null,
Arrays.asList(f.newModifier(ModifierKind.DEFAULT)),
Models.toType(f, String.class),
f.newSimpleName("f"),
Collections.emptyList(),
Arrays.asList(f.newReturnStatement(Models.toLiteral(f, "OK")))))));
assertThat(klass.isInterface(), is(true));
assertThat(klass.getName(), equalTo("Testing"));
assertThat(klass.getMethod("f").isDefault(), is(true));
}
/**
* enum declaration.
* @throws Exception if error occurred
*/
@Test
public void EnumDeclaration() throws Exception {
Class<?> klass = getTypeDeclaration(
f.newEnumDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
f.newSimpleName("Testing"),
Arrays.asList(new Type[] {
Models.toType(f, RandomAccess.class),
}),
Arrays.asList(new EnumConstantDeclaration[] {
f.newEnumConstantDeclaration(
null,
Collections.emptyList(),
f.newSimpleName("A"),
Collections.emptyList(),
null),
f.newEnumConstantDeclaration(
null,
Collections.emptyList(),
f.newSimpleName("B"),
Collections.emptyList(),
null),
}),
Arrays.asList(new TypeBodyDeclaration[] {
f.newMethodDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
Collections.emptyList(),
Models.toType(f, void.class),
f.newSimpleName("example"),
Collections.emptyList(),
0,
Collections.emptyList(),
f.newBlock(Collections.emptyList()))
})));
assertThat(klass.isEnum(), is(true));
assertThat(klass.getName(), equalTo("Testing"));
Object[] constants = klass.getEnumConstants();
assertThat(constants.length, is(2));
assertThat(((Enum<?>) constants[0]).name(), is("A"));
assertThat(((Enum<?>) constants[1]).name(), is("B"));
klass.getDeclaredMethod("example");
Class<?>[] interfaces = klass.getInterfaces();
assertThat(interfaces.length, is(1));
assertThat(interfaces, hasItemInArray((Object) RandomAccess.class));
}
/**
* field declaration.
* @throws Exception if error occurred
*/
@Test
public void FieldDeclaration() throws Exception {
Class<?> klass = getTypeDeclaration(klass("Testing",
f.newFieldDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
Models.toType(f, int.class),
Arrays.asList(new VariableDeclarator[] {
f.newVariableDeclarator(
f.newSimpleName("a"),
0,
null),
f.newVariableDeclarator(
f.newSimpleName("b"),
1,
f.newArrayInitializer(Arrays.asList(new Expression[] {
Models.toLiteral(f, 100)
}))),
}))));
Object obj = create(klass);
Field a = klass.getDeclaredField("a");
assertThat(a.get(obj), is((Object) 0));
Field b = klass.getDeclaredField("b");
assertThat(b.get(obj), is((Object) new int[] { 100 }));
}
/**
* initializer declaration.
* @throws Exception if error occurred
*/
@Test
public void InitializerDeclaration() throws Exception {
Class<?> klass = getTypeDeclaration(klass("Testing",
f.newFieldDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC),
f.newModifier(ModifierKind.STATIC),
}),
Models.toType(f, int.class),
Arrays.asList(new VariableDeclarator[] {
f.newVariableDeclarator(
f.newSimpleName("a"),
0,
null),
})),
f.newInitializerDeclaration(
null,
Arrays.asList(new Modifier[] {
f.newModifier(ModifierKind.STATIC)
}),
f.newBlock(Arrays.asList(new Statement[] {
f.newExpressionStatement(
f.newAssignmentExpression(
f.newSimpleName("a"),
InfixOperator.ASSIGN,
Models.toLiteral(f, 100)))
})))));
Class.forName(klass.getName(), true, klass.getClassLoader());
Field a = klass.getDeclaredField("a");
assertThat(a.get(null), is((Object) 100));
}
/**
* constructor declaration.
* @throws Exception if error occurred
*/
@Test
public void ConstructorDeclaration() throws Exception {
Class<?> klass = getTypeDeclaration(klass("Testing",
f.newFieldDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC),
}),
Models.toType(f, int.class),
Arrays.asList(new VariableDeclarator[] {
f.newVariableDeclarator(
f.newSimpleName("a"),
0,
null),
})),
f.newConstructorDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
Collections.emptyList(),
f.newSimpleName("Testing"),
Collections.emptyList(),
Collections.emptyList(),
f.newBlock(Arrays.asList(new Statement[] {
f.newExpressionStatement(
f.newAssignmentExpression(
f.newSimpleName("a"),
InfixOperator.ASSIGN,
Models.toLiteral(f, 500)))
})))));
Object obj = create(klass);
Field a = klass.getDeclaredField("a");
assertThat(a.get(obj), is((Object) 500));
}
/**
* constructor declaration w/ delegate constructor invocation.
* @throws Exception if error occurred
*/
@Test
public void ConstructorDeclaration_delegate() throws Exception {
Class<?> klass = getTypeDeclaration(klass("Testing",
f.newFieldDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC),
}),
Models.toType(f, int.class),
Arrays.asList(new VariableDeclarator[] {
f.newVariableDeclarator(
f.newSimpleName("a"),
0,
null),
})),
f.newConstructorDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
Collections.emptyList(),
f.newSimpleName("Testing"),
Collections.emptyList(),
Collections.emptyList(),
f.newBlock(Arrays.asList(new Statement[] {
f.newAlternateConstructorInvocation(
Collections.emptyList(),
Arrays.asList(new Expression[] {
Models.toLiteral(f, 100),
})),
f.newExpressionStatement(
f.newAssignmentExpression(
f.newSimpleName("a"),
InfixOperator.PLUS,
Models.toLiteral(f, 30)))
}))),
f.newConstructorDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PRIVATE)
}),
Collections.emptyList(),
f.newSimpleName("Testing"),
Arrays.asList(new FormalParameterDeclaration[] {
f.newFormalParameterDeclaration(
Collections.emptyList(),
Models.toType(f, int.class),
false,
f.newSimpleName("p"),
0)
}),
Collections.emptyList(),
f.newBlock(Arrays.asList(new Statement[] {
f.newSuperConstructorInvocation(
null,
Collections.emptyList(),
Collections.emptyList()),
f.newExpressionStatement(
f.newAssignmentExpression(
f.newSimpleName("a"),
InfixOperator.ASSIGN,
f.newSimpleName("p")))
})))));
Object obj = create(klass);
Field a = klass.getDeclaredField("a");
assertThat(a.get(obj), is((Object) 130));
}
/**
* constructor declaration w/ exception types.
* @throws Exception if error occurred
*/
@Test
public void ConstructorDeclaration_throws() throws Exception {
Class<?> klass = getTypeDeclaration(klass("Testing",
f.newConstructorDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
Collections.emptyList(),
f.newSimpleName("Testing"),
Collections.emptyList(),
Arrays.asList(new Type[] {
Models.toType(f, Exception.class)
}),
f.newBlock(Arrays.asList(new Statement[] {
f.newThrowStatement(
f.newClassInstanceCreationExpression(
null,
Collections.emptyList(),
Models.toType(f, IOException.class),
Collections.emptyList(),
null))
})))));
Constructor<?> ctor = klass.getDeclaredConstructor();
assertThat(ctor.getExceptionTypes(), is((Object) new Class<?>[] {
Exception.class
}));
try {
klass.newInstance();
} catch (Exception e) {
assertThat(e, instanceOf(IOException.class));
}
}
/**
* method declaration.
* @throws Exception if error occurred
*/
@Test
public void MethodDeclaration() throws Exception {
Class<?> klass = getTypeDeclaration(klass("Testing",
f.newMethodDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
Collections.emptyList(),
Models.toType(f, String.class),
f.newSimpleName("method"),
Collections.emptyList(),
0,
Arrays.asList(new Type[] {
Models.toType(f, Exception.class)
}),
f.newBlock(Arrays.asList(new Statement[] {
f.newReturnStatement(Models.toLiteral(f, "hello"))
})))));
Object obj = create(klass);
Method method = klass.getDeclaredMethod("method");
assertThat(method.invoke(obj), is((Object) "hello"));
}
/**
* method declaration w/ parameters.
* @throws Exception if error occurred
*/
@Test
public void MethodDeclaration_parameter() throws Exception {
Class<?> klass = getTypeDeclaration(klass("Testing",
f.newMethodDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
Collections.emptyList(),
Models.toType(f, String.class),
f.newSimpleName("method"),
Arrays.asList(new FormalParameterDeclaration[] {
f.newFormalParameterDeclaration(
Collections.emptyList(),
Models.toType(f, String.class),
false,
f.newSimpleName("a"),
0)
}),
0,
Collections.emptyList(),
f.newBlock(Arrays.asList(new Statement[] {
f.newReturnStatement(f.newSimpleName("a"))
})))));
Object obj = create(klass);
Method method = klass.getDeclaredMethod("method", String.class);
assertThat(method.invoke(obj, "self"), is((Object) "self"));
}
/**
* method declaration w/ varargs.
* @throws Exception if error occurred
*/
@Test
public void MethodDeclaration_varargs() throws Exception {
Class<?> klass = getTypeDeclaration(klass("Testing",
f.newMethodDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
Collections.emptyList(),
Models.toType(f, String[].class),
f.newSimpleName("method"),
Arrays.asList(new FormalParameterDeclaration[] {
f.newFormalParameterDeclaration(
Collections.emptyList(),
Models.toType(f, String.class),
true,
f.newSimpleName("a"),
0)
}),
0,
Collections.emptyList(),
f.newBlock(Arrays.asList(new Statement[] {
f.newReturnStatement(f.newSimpleName("a"))
})))));
Object obj = create(klass);
Method method = klass.getDeclaredMethod("method", String[].class);
assertThat(method.isVarArgs(), is(true));
assertThat(
method.invoke(obj, (Object) new String[] {"a", "b", "c"}),
is((Object) new String[] {"a", "b", "c"}));
}
/**
* method declaration w/ extra dimensions.
* @throws Exception if error occurred
*/
@Test
public void MethodDeclaration_extraDims() throws Exception {
Class<?> klass = getTypeDeclaration(klass("Testing",
f.newMethodDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
Collections.emptyList(),
Models.toType(f, String.class),
f.newSimpleName("method"),
Arrays.asList(new FormalParameterDeclaration[] {
f.newFormalParameterDeclaration(
Collections.emptyList(),
Models.toType(f, String.class),
false,
f.newSimpleName("a"),
1)
}),
1,
Collections.emptyList(),
f.newBlock(Arrays.asList(new Statement[] {
f.newReturnStatement(f.newSimpleName("a"))
})))));
Object obj = create(klass);
Method method = klass.getDeclaredMethod("method", String[].class);
assertThat(
method.invoke(obj, (Object) new String[] {"a", "b", "c"}),
is((Object) new String[] {"a", "b", "c"}));
}
/**
* enum constant declaration w/ constructor arguments.
* @throws Exception if error occurred
*/
@Test
public void EnumConstantDeclaration_arguments() throws Exception {
Class<?> klass = getTypeDeclaration(
f.newEnumDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
f.newSimpleName("Testing"),
Collections.emptyList(),
Arrays.asList(new EnumConstantDeclaration[] {
f.newEnumConstantDeclaration(
null,
Collections.emptyList(),
f.newSimpleName("A"),
Arrays.asList(new Expression[] {
Models.toLiteral(f, 1),
Models.toLiteral(f, "a"),
}),
null),
}),
Arrays.asList(new TypeBodyDeclaration[] {
f.newFieldDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC),
}),
Models.toType(f, Object[].class),
Arrays.asList(new VariableDeclarator[] {
f.newVariableDeclarator(
f.newSimpleName("arguments"),
0,
null),
})),
f.newConstructorDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PRIVATE)
}),
Collections.emptyList(),
f.newSimpleName("Testing"),
Arrays.asList(new FormalParameterDeclaration[] {
f.newFormalParameterDeclaration(
Collections.emptyList(),
Models.toType(f, Object.class),
true,
f.newSimpleName("args"),
0)
}),
Collections.emptyList(),
f.newBlock(Arrays.asList(new Statement[] {
f.newExpressionStatement(
f.newAssignmentExpression(
f.newSimpleName("arguments"),
InfixOperator.ASSIGN,
f.newSimpleName("args"))),
})))
})));
Enum<?> constant = Enum.valueOf(klass.asSubclass(Enum.class), "A");
Field field = klass.getDeclaredField("arguments");
assertThat(field.get(constant), is((Object) new Object[] { 1, "a" }));
}
/**
* enum constant declaration w/ class block.
* @throws Exception if error occurred
*/
@Test
public void EnumConstantDeclaration_body() throws Exception {
Class<?> klass = getTypeDeclaration(
f.newEnumDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
f.newSimpleName("Testing"),
Collections.emptyList(),
Arrays.asList(new EnumConstantDeclaration[] {
f.newEnumConstantDeclaration(
null,
Collections.emptyList(),
f.newSimpleName("A"),
Collections.emptyList(),
f.newClassBody(Arrays.asList(new TypeBodyDeclaration[] {
toString(returnAsString(Models.toLiteral(f, "hello")))
}))),
}),
Collections.emptyList()
));
Enum<?> constant = Enum.valueOf(klass.asSubclass(Enum.class), "A");
assertThat(constant.toString(), is("hello"));
}
/**
* super method invocation.
* @throws Exception if error occurred
*/
@Test
public void Super() throws Exception {
Class<?> klass = getTypeDeclaration(
f.newEnumDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
f.newSimpleName("Testing"),
Collections.emptyList(),
Arrays.asList(new EnumConstantDeclaration[] {
f.newEnumConstantDeclaration(
null,
Collections.emptyList(),
f.newSimpleName("A"),
Collections.emptyList(),
f.newClassBody(Arrays.asList(new TypeBodyDeclaration[] {
toString(returnAsString(f.newMethodInvocationExpression(
f.newSuper(null),
Collections.emptyList(),
f.newSimpleName("name"),
Collections.emptyList())))
}))),
}),
Collections.emptyList()
));
Enum<?> constant = Enum.valueOf(klass.asSubclass(Enum.class), "A");
assertThat(constant.toString(), is("A"));
}
/**
* package declaration.
*/
@Test
public void PackageDeclaration() {
packageDecl = f.newPackageDeclaration(
null,
Collections.emptyList(),
Models.toName(f, "com.example"));
assertToString(
fromExpr("Hello", Models.toLiteral(f, "Hello, world!")),
"com.example.Hello",
"Hello, world!");
}
/**
* import declaration.
*/
@Test
public void ImportDeclaration_type() {
importDecls.add(f.newImportDeclaration(ImportKind.SINGLE_TYPE,
Models.toName(f, "java.util.Arrays")));
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
Models.toName(f, "Arrays"),
Collections.emptyList(),
f.newSimpleName("asList"),
Arrays.asList(Models.toLiteral(f, "Hello, world!")))),
"Hello",
"[Hello, world!]");
}
/**
* import declaration - on-demand import.
*/
@Test
public void ImportDeclaration_onDemand() {
importDecls.add(f.newImportDeclaration(ImportKind.TYPE_ON_DEMAND,
Models.toName(f, "java.util")));
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
Models.toName(f, "Arrays"),
Collections.emptyList(),
f.newSimpleName("asList"),
Arrays.asList(Models.toLiteral(f, "Hello, world!")))),
"Hello",
"[Hello, world!]");
}
/**
* import declaration - static.
*/
@Test
public void ImportDeclaration_singleStatic() {
importDecls.add(f.newImportDeclaration(ImportKind.SINGLE_STATIC,
Models.toName(f, "java.util.Arrays.asList")));
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
null,
Collections.emptyList(),
f.newSimpleName("asList"),
Arrays.asList(Models.toLiteral(f, "Hello, world!")))),
"Hello",
"[Hello, world!]");
}
/**
* import declaration - static on-demand import.
*/
@Test
public void ImportDeclaration_staticOnDemand() {
importDecls.add(f.newImportDeclaration(ImportKind.STATIC_ON_DEMAND,
Models.toName(f, "java.util.Arrays")));
assertToString(
fromExpr("Hello",
f.newMethodInvocationExpression(
null,
Collections.emptyList(),
f.newSimpleName("asList"),
Arrays.asList(Models.toLiteral(f, "Hello, world!")))),
"Hello",
"[Hello, world!]");
}
/**
* auto parenthesize - left term of infix operator.
*/
@Test
public void autoParenthesize_infixLeft() {
assertToString(
fromExpr("Hello", f.newInfixExpression(
f.newInfixExpression(
Models.toLiteral(f, 10),
InfixOperator.MINUS,
Models.toLiteral(f, 5)),
InfixOperator.TIMES,
Models.toLiteral(f, 2))),
"Hello",
"10");
}
/**
* auto parenthesize - right term of infix operator.
*/
@Test
public void autoParenthesize_infixRight() {
assertToString(
fromExpr("Hello", f.newInfixExpression(
Models.toLiteral(f, 100),
InfixOperator.MINUS,
f.newInfixExpression(
Models.toLiteral(f, 100),
InfixOperator.MINUS,
Models.toLiteral(f, 100)))),
"Hello",
"100");
}
private LocalVariableDeclaration var(Type type, String name, Expression init) {
return f.newLocalVariableDeclaration(
Collections.emptyList(),
type,
Arrays.asList(new VariableDeclarator[] {
f.newVariableDeclarator(f.newSimpleName(name), 0, init)
}));
}
private Statement newStringBuilder(String name) {
return var(
f.newNamedType(f.newSimpleName("StringBuilder")),
name,
f.newClassInstanceCreationExpression(
null,
Collections.emptyList(),
f.newNamedType(f.newSimpleName("StringBuilder")),
Collections.emptyList(),
null));
}
private Statement append(String name, Expression value) {
return f.newExpressionStatement(
f.newMethodInvocationExpression(
f.newSimpleName(name),
Collections.emptyList(),
f.newSimpleName("append"),
Arrays.asList(value)));
}
private CompilationUnit unit(TypeDeclaration...types) {
return f.newCompilationUnit(packageDecl, importDecls, Arrays.asList(types));
}
private ClassDeclaration klass(String name, TypeBodyDeclaration...elems) {
return f.newClassDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
f.newSimpleName(name),
Collections.emptyList(),
null,
Arrays.asList(),
Arrays.asList(elems));
}
private MethodDeclaration toString(Statement...statements) {
return f.newMethodDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC)
}),
Collections.emptyList(),
f.newNamedType(Models.toName(f, "String")),
f.newSimpleName("toString"),
Collections.emptyList(),
0,
Collections.emptyList(),
f.newBlock(Arrays.asList(statements)));
}
private CompilationUnit fromExpr(String name, Expression expr) {
return unit(klass(name, toString(returnAsString(expr))));
}
private ReturnStatement returnAsString(Expression expr) {
return f.newReturnStatement(
f.newMethodInvocationExpression(
Models.toName(f, "String"),
Collections.emptyList(),
f.newSimpleName("valueOf"),
Arrays.asList(expr))
);
}
private CompilationUnit fromStmt(String name, Statement...stmts) {
return unit(klass(name, toString(stmts)));
}
private void assertToString(CompilationUnit unit, String name, String actual) {
Class<?> klass = compile(unit, name);
Object object = create(klass);
assertThat(object.toString(), is(actual));
}
private void assertRaise(CompilationUnit unit, String name, Class<?> exception) {
Class<?> klass = compile(unit, name);
Object object = create(klass);
try {
object.toString();
} catch (Throwable t) {
assertThat(t, instanceOf(exception));
}
}
private AnnotationDeclaration createAnnotation(String name) {
return f.newAnnotationDeclaration(
null,
Arrays.asList(new Annotation[] {
f.newSingleElementAnnotation(
(NamedType) Models.toType(f, Retention.class),
Models.toName(f, RetentionPolicy.RUNTIME))
}),
f.newSimpleName(name),
Arrays.asList(new TypeBodyDeclaration[] {
f.newAnnotationElementDeclaration(
null,
Collections.emptyList(),
Models.toType(f, String[].class),
f.newSimpleName("value"),
null),
f.newAnnotationElementDeclaration(
null,
Collections.emptyList(),
Models.toType(f, int.class),
f.newSimpleName("option"),
Models.toLiteral(f, 100)),
}));
}
private Object getAnnotationValue(
Class<?> klass,
String annotationTypeName,
String annotationElementName) {
for (java.lang.annotation.Annotation a : klass.getDeclaredAnnotations()) {
Class<?> annotationType = a.annotationType();
if (annotationType.getName().equals(annotationTypeName)) {
try {
Method element = annotationType.getDeclaredMethod(annotationElementName);
element.setAccessible(true);
return element.invoke(a);
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
throw new AssertionError(klass);
}
private void assertType(Type type, java.lang.reflect.Type expect) {
assertThat(getType(type), is(expect));
}
private Class<?> getTypeDeclaration(TypeDeclaration... decls) {
CompilationUnit unit = unit(decls);
Class<?> klass = compile(unit, decls[0].getName().getToken());
return klass;
}
private java.lang.reflect.Type getType(Type type) {
CompilationUnit unit = unit(
klass("Testing",
f.newMethodDeclaration(
null,
Arrays.asList(new Attribute[] {
f.newModifier(ModifierKind.PUBLIC),
f.newModifier(ModifierKind.NATIVE),
}),
Arrays.asList(new TypeParameterDeclaration[] {
f.newTypeParameterDeclaration(
f.newSimpleName("T"),
Collections.emptyList())
}),
type,
f.newSimpleName("testing"),
Collections.emptyList(),
0,
Collections.emptyList(),
null)));
Class<?> klass = compile(unit, "Testing");
try {
Method method = klass.getDeclaredMethod("testing");
java.lang.reflect.Type result = method.getGenericReturnType();
if (result instanceof GenericArrayType) {
// special case for array (like int[])
GenericArrayType array = (GenericArrayType) result;
if (array.getGenericComponentType() instanceof Class<?>) {
return method.getReturnType();
}
return method.getReturnType();
}
return result;
} catch (Exception e) {
throw new AssertionError(e);
}
}
private Class<?> compile(CompilationUnit unit, String name) {
List<String> lines = new ArrayList<>();
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
for (int i = 1; i < elements.length; i++) {
if (getClass().getName().equals(elements[i].getClassName()) == false) {
break;
}
lines.add(elements[i].toString());
}
unit.putModelTrait(CommentEmitTrait.class, new CommentEmitTrait(lines));
compiler.addSource(new CompilationUnitJavaFile(unit));
List<Diagnostic<? extends JavaFileObject>> diagnostics = compiler.doCompile();
if (diagnostics.isEmpty() == false) {
throw new AssertionError(diagnostics + ":::" + unit);
}
try {
return compiler.getClassLoader().loadClass(name);
} catch (ClassNotFoundException e) {
throw new AssertionError(e);
}
}
@SuppressWarnings("unchecked")
private <T> T create(Class<?> target, Object...args) {
Class<?>[] argTypes = new Class<?>[args.length];
for (int i = 0; i < args.length; i++) {
argTypes[i] = args[i].getClass();
}
try {
return (T) target.getConstructor(argTypes).newInstance(args);
} catch (Exception e) {
throw new AssertionError(e);
}
}
}