/*
* Copyright (c) 2013-2015 Chris Newland.
* Licensed under https://github.com/AdoptOpenJDK/jitwatch/blob/master/LICENSE-BSD
* Instructions: https://github.com/AdoptOpenJDK/jitwatch/wiki
*/
package org.adoptopenjdk.jitwatch.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_TYPE_NAME_VOID;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_EMPTY;
import org.adoptopenjdk.jitwatch.model.IMetaMember;
import org.adoptopenjdk.jitwatch.model.MemberSignatureParts;
import org.adoptopenjdk.jitwatch.model.MetaClass;
import org.adoptopenjdk.jitwatch.model.MetaConstructor;
import org.adoptopenjdk.jitwatch.model.MetaMethod;
import org.adoptopenjdk.jitwatch.model.MetaPackage;
import org.adoptopenjdk.jitwatch.model.bytecode.ClassBC;
import org.adoptopenjdk.jitwatch.util.StringUtil;
import org.junit.Test;
// needed to test generics mappings declared at class level
class TestClassWithGenerics<K extends java.lang.Object>
{
// ==========================
// methods used by this test
// ==========================
public int primitiveReturnPrimitiveParam(int foo)
{
return 1337;
}
public void voidReturnPrimitiveParam(int foo)
{
}
public void voidReturnNoParams()
{
}
public String objectReturnObjectParam(String foo)
{
return "When the daylight weighs a tonne";
}
public String[] arrayReturnArrayParam(int[] foo)
{
return new String[] { "and all my friends are gone" };
}
public static <T extends java.lang.Object> T genericReturnAndParams(T object, java.lang.String string)
{
return null;
}
public K genericReturnDeclaredOnClass()
{
return null;
}
public void genericParamTypeWildcard(Class<?>[] fooClasses)
{
}
public Class<?>[] genericReturnTypeWildcard()
{
return null;
}
}
public class TestMetaClass
{
// test constructor
public TestMetaClass()
{
}
@Test
public void testGetMemberFromSignature1() throws NoSuchMethodException, SecurityException
{
String thisClassName = "TestClassWithGenerics";
MetaPackage metaPackage = new MetaPackage(StringUtil.getPackageName(thisClassName));
MetaClass metaClass = new MetaClass(metaPackage, StringUtil.getUnqualifiedClassName(thisClassName));
String testMethodName = "primitiveReturnPrimitiveParam";
Method method = TestClassWithGenerics.class.getDeclaredMethod(testMethodName, new Class[] { int.class });
MetaMethod testMethod = new MetaMethod(method, metaClass);
metaClass.addMember(testMethod);
String testRetType = "int";
List<String> paramList = new ArrayList<>();
paramList.add("int");
IMetaMember result = metaClass.getMemberForSignature(
MemberSignatureParts.fromParts(metaClass.getFullyQualifiedName(), testMethodName, testRetType, paramList));
assertNotNull(result);
assertEquals(testMethod.toString(), result.toString());
}
@Test
public void testGetMemberFromSignature2() throws NoSuchMethodException, SecurityException
{
String thisClassName = "TestClassWithGenerics";
MetaPackage metaPackage = new MetaPackage(StringUtil.getPackageName(thisClassName));
MetaClass metaClass = new MetaClass(metaPackage, StringUtil.getUnqualifiedClassName(thisClassName));
String testMethodName = "voidReturnPrimitiveParam";
Method method = TestClassWithGenerics.class.getDeclaredMethod(testMethodName, new Class[] { int.class });
MetaMethod testMethod = new MetaMethod(method, metaClass);
metaClass.addMember(testMethod);
String testRetType = S_TYPE_NAME_VOID;
List<String> paramList = new ArrayList<>();
paramList.add("int");
IMetaMember result = metaClass.getMemberForSignature(
MemberSignatureParts.fromParts(metaClass.getFullyQualifiedName(), testMethodName, testRetType, paramList));
assertNotNull(result);
assertEquals(testMethod.toString(), result.toString());
}
@Test
public void testGetMemberFromSignature3() throws NoSuchMethodException, SecurityException
{
String thisClassName = "TestClassWithGenerics";
MetaPackage metaPackage = new MetaPackage(StringUtil.getPackageName(thisClassName));
MetaClass metaClass = new MetaClass(metaPackage, StringUtil.getUnqualifiedClassName(thisClassName));
String testMethodName = "voidReturnNoParams";
Method method = TestClassWithGenerics.class.getDeclaredMethod(testMethodName, new Class[0]);
MetaMethod testMethod = new MetaMethod(method, metaClass);
metaClass.addMember(testMethod);
String testRetType = S_TYPE_NAME_VOID;
List<String> paramList = new ArrayList<>();
IMetaMember result = metaClass.getMemberForSignature(
MemberSignatureParts.fromParts(metaClass.getFullyQualifiedName(), testMethodName, testRetType, paramList));
assertNotNull(result);
assertEquals(testMethod.toString(), result.toString());
}
@Test
public void testGetMemberFromSignature4() throws NoSuchMethodException, SecurityException
{
String thisClassName = "TestClassWithGenerics";
MetaPackage metaPackage = new MetaPackage(StringUtil.getPackageName(thisClassName));
MetaClass metaClass = new MetaClass(metaPackage, StringUtil.getUnqualifiedClassName(thisClassName));
String testMethodName = "objectReturnObjectParam";
Method method = TestClassWithGenerics.class.getDeclaredMethod(testMethodName, new Class[] { java.lang.String.class });
MetaMethod testMethod = new MetaMethod(method, metaClass);
metaClass.addMember(testMethod);
String testRetType = "java.lang.String";
List<String> paramList = new ArrayList<>();
paramList.add("java.lang.String");
IMetaMember result = metaClass.getMemberForSignature(
MemberSignatureParts.fromParts(metaClass.getFullyQualifiedName(), testMethodName, testRetType, paramList));
assertNotNull(result);
assertEquals(testMethod.toString(), result.toString());
}
@Test
public void testGetMemberFromSignature5() throws NoSuchMethodException, SecurityException
{
String thisClassName = "TestClassWithGenerics";
MetaPackage metaPackage = new MetaPackage(StringUtil.getPackageName(thisClassName));
MetaClass metaClass = new MetaClass(metaPackage, StringUtil.getUnqualifiedClassName(thisClassName));
String testMethodName = "arrayReturnArrayParam";
Method method = TestClassWithGenerics.class.getDeclaredMethod(testMethodName, new Class[] { int[].class });
MetaMethod testMethod = new MetaMethod(method, metaClass);
metaClass.addMember(testMethod);
String testRetType = "[Ljava.lang.String;";
List<String> paramList = new ArrayList<>();
paramList.add("[I");
IMetaMember result = metaClass.getMemberForSignature(
MemberSignatureParts.fromParts(metaClass.getFullyQualifiedName(), testMethodName, testRetType, paramList));
assertNotNull(result);
assertEquals(testMethod.toString(), result.toString());
}
@Test
public void testGetMemberFromSignature6() throws NoSuchMethodException, SecurityException
{
String thisClassName = "TestClassWithGenerics";
MetaPackage metaPackage = new MetaPackage(StringUtil.getPackageName(thisClassName));
MetaClass metaClass = new MetaClass(metaPackage, StringUtil.getUnqualifiedClassName(thisClassName));
String testMethodName = "<init>";
Constructor<?> constructor = TestClassWithGenerics.class.getDeclaredConstructor(new Class[0]);
MetaConstructor testConstructor = new MetaConstructor(constructor, metaClass);
metaClass.addMember(testConstructor);
String testRetType = "TestClassWithGenerics";
List<String> paramList = new ArrayList<>();
IMetaMember result = metaClass.getMemberForSignature(
MemberSignatureParts.fromParts(metaClass.getFullyQualifiedName(), testMethodName, testRetType, paramList));
assertNotNull(result);
assertEquals(testConstructor.toString(), result.toString());
}
@Test
public void testRegressionGenericSubstitution() throws NoSuchMethodException, SecurityException
{
String thisClassName = "TestClassWithGenerics";
MetaPackage metaPackage = new MetaPackage(StringUtil.getPackageName(thisClassName));
MetaClass metaClass = new MetaClass(metaPackage, StringUtil.getUnqualifiedClassName(thisClassName));
String testMethodName = "genericReturnAndParams";
Method method = TestClassWithGenerics.class.getDeclaredMethod(testMethodName, new Class[] { Object.class, String.class });
MetaMethod testMethod = new MetaMethod(method, metaClass);
metaClass.addMember(testMethod);
IMetaMember result = metaClass
.getMemberForSignature(MemberSignatureParts.fromBytecodeSignature(metaClass.getFullyQualifiedName(),
"public static <T extends java.lang.Object> T genericReturnAndParams(T, java.lang.String);"));
assertNotNull(result);
assertEquals(testMethod.toString(), result.toString());
}
@Test
public void testRegressionGenericDeclaredAtClassLevel() throws NoSuchMethodException, SecurityException
{
String thisClassName = "TestClassWithGenerics";
MetaPackage metaPackage = new MetaPackage(StringUtil.getPackageName(thisClassName));
MetaClass metaClass = new MetaClass(metaPackage, StringUtil.getUnqualifiedClassName(thisClassName));
String testMethodName = "genericReturnDeclaredOnClass";
Method method = TestClassWithGenerics.class.getDeclaredMethod(testMethodName, new Class[0]);
MetaMethod testMethod = new MetaMethod(method, metaClass);
metaClass.addMember(testMethod);
MemberSignatureParts msp = MemberSignatureParts.fromBytecodeSignature(metaClass.getFullyQualifiedName(),
"public K genericReturnDeclaredOnClass();");
ClassBC classBytecode = new ClassBC(TestClassWithGenerics.class.getName());
classBytecode.addGenericsMapping("K", "java.lang.Object");
msp.setClassBC(classBytecode);
IMetaMember result = metaClass.getMemberForSignature(msp);
assertNotNull(result);
assertEquals(testMethod.toString(), result.toString());
}
@Test
public void testRegressionGenericWildcardReturnType() throws NoSuchMethodException, SecurityException
{
String thisClassName = "TestClassWithGenerics";
MetaPackage metaPackage = new MetaPackage(StringUtil.getPackageName(thisClassName));
MetaClass metaClass = new MetaClass(metaPackage, StringUtil.getUnqualifiedClassName(thisClassName));
String testMethodName = "genericReturnTypeWildcard";
Method method = TestClassWithGenerics.class.getDeclaredMethod(testMethodName, new Class[0]);
MetaMethod testMethod = new MetaMethod(method, metaClass);
metaClass.addMember(testMethod);
MemberSignatureParts msp = MemberSignatureParts.fromBytecodeSignature(metaClass.getFullyQualifiedName(),
"public java.lang.Class<?>[] genericReturnTypeWildcard();");
IMetaMember result = metaClass.getMemberForSignature(msp);
assertNotNull(result);
assertEquals(testMethod.toString(), result.toString());
}
@Test
public void testRegressionGenericWildcardParamType() throws NoSuchMethodException, SecurityException
{
String thisClassName = "TestClassWithGenerics";
MetaPackage metaPackage = new MetaPackage(StringUtil.getPackageName(thisClassName));
MetaClass metaClass = new MetaClass(metaPackage, StringUtil.getUnqualifiedClassName(thisClassName));
String testMethodName = "genericParamTypeWildcard";
Method method = TestClassWithGenerics.class.getDeclaredMethod(testMethodName, new Class[] { Class[].class });
MetaMethod testMethod = new MetaMethod(method, metaClass);
metaClass.addMember(testMethod);
MemberSignatureParts msp = MemberSignatureParts.fromBytecodeSignature(metaClass.getFullyQualifiedName(),
"public void genericParamTypeWildcard(java.lang.Class<?>[]);");
IMetaMember result = metaClass.getMemberForSignature(msp);
assertNotNull(result);
assertEquals(testMethod.toString(), result.toString());
}
@Test
public void testRegressionDefaultPackageParamMatchPrimitive() throws Throwable
{
String className = "FooClassInDefaultPackage";
Class<?> defaultPackageTestClass = Class.forName(className);
Class<?> defaultPackageTestClassParam = int.class;
String expectedParamClassName = "int";
MetaClass metaClass = new MetaClass(new MetaPackage(S_EMPTY), className);
Method getterPrimitiveParam = defaultPackageTestClass.getDeclaredMethod("getPrimitiveParam", new Class[] {});
MetaMethod metaMethodGetPrimitiveParam = new MetaMethod(getterPrimitiveParam, metaClass);
String[] paramTypeNamesGetPrimitiveParam = metaMethodGetPrimitiveParam.getParamTypeNames();
assertEquals(0, paramTypeNamesGetPrimitiveParam.length);
String returnTypeNameGetPrimitiveParam = metaMethodGetPrimitiveParam.getReturnTypeName();
assertEquals(expectedParamClassName, returnTypeNameGetPrimitiveParam);
Method setterPrimitiveParam = defaultPackageTestClass.getDeclaredMethod("setPrimitiveParam",
new Class[] { defaultPackageTestClassParam });
MetaMethod metaMethodSetPrimitiveParam = new MetaMethod(setterPrimitiveParam, metaClass);
String[] paramTypeNamesSetPrimitiveParam = metaMethodSetPrimitiveParam.getParamTypeNames();
assertEquals(1, paramTypeNamesSetPrimitiveParam.length);
assertEquals(expectedParamClassName, paramTypeNamesSetPrimitiveParam[0]);
String returnTypeNameSetParam = metaMethodSetPrimitiveParam.getReturnTypeName();
assertEquals(S_TYPE_NAME_VOID, returnTypeNameSetParam);
}
@Test
public void testRegressionDefaultPackageParamMatchClass() throws Throwable
{
String className = "FooClassInDefaultPackage";
String paramClassName = "IsUsedForTestingDefaultPackage";
Class<?> defaultPackageTestClass = Class.forName(className);
Class<?> defaultPackageTestClassParam = Class.forName(paramClassName);
MetaClass metaClass = new MetaClass(new MetaPackage(S_EMPTY), className);
Method getterPrimitiveParam = defaultPackageTestClass.getDeclaredMethod("getClassParam", new Class[] {});
MetaMethod metaMethodGetPrimitiveParam = new MetaMethod(getterPrimitiveParam, metaClass);
String[] paramTypeNamesGetPrimitiveParam = metaMethodGetPrimitiveParam.getParamTypeNames();
assertEquals(0, paramTypeNamesGetPrimitiveParam.length);
String returnTypeNameGetPrimitiveParam = metaMethodGetPrimitiveParam.getReturnTypeName();
assertEquals(paramClassName, returnTypeNameGetPrimitiveParam);
Method setterPrimitiveParam = defaultPackageTestClass.getDeclaredMethod("setClassParam",
new Class[] { defaultPackageTestClassParam });
MetaMethod metaMethodSetPrimitiveParam = new MetaMethod(setterPrimitiveParam, metaClass);
String[] paramTypeNamesSetPrimitiveParam = metaMethodSetPrimitiveParam.getParamTypeNames();
assertEquals(1, paramTypeNamesSetPrimitiveParam.length);
assertEquals(paramClassName, paramTypeNamesSetPrimitiveParam[0]);
String returnTypeNameSetPrimitive = metaMethodSetPrimitiveParam.getReturnTypeName();
assertEquals(S_TYPE_NAME_VOID, returnTypeNameSetPrimitive);
}
@Test
public void testRegressionDefaultPackageParamMatchPrimitiveArray() throws Throwable
{
String className = "FooClassInDefaultPackage";
Class<?> defaultPackageTestClass = Class.forName(className);
Class<?> defaultPackageTestClassParam = int[].class;
String expectedParamClassName = "int[]";
MetaClass metaClass = new MetaClass(new MetaPackage(S_EMPTY), className);
Method getterPrimitiveArrayParam = defaultPackageTestClass.getDeclaredMethod("getPrimitiveArrayParam", new Class[] {});
MetaMethod metaMethodGetPrimitiveArrayParam = new MetaMethod(getterPrimitiveArrayParam, metaClass);
String[] paramTypeNamesGetPrimitiveArrayParam = metaMethodGetPrimitiveArrayParam.getParamTypeNames();
assertEquals(0, paramTypeNamesGetPrimitiveArrayParam.length);
String returnTypeNameGetPrimitiveArrayParam = metaMethodGetPrimitiveArrayParam.getReturnTypeName();
assertEquals(expectedParamClassName, returnTypeNameGetPrimitiveArrayParam);
Method setterPrimitiveArrayParam = defaultPackageTestClass.getDeclaredMethod("setPrimitiveArrayParam",
new Class[] { defaultPackageTestClassParam });
MetaMethod metaMethodSetPrimitiveArrayParam = new MetaMethod(setterPrimitiveArrayParam, metaClass);
String[] paramTypeNamesSetPrimitiveArrayParam = metaMethodSetPrimitiveArrayParam.getParamTypeNames();
assertEquals(1, paramTypeNamesSetPrimitiveArrayParam.length);
assertEquals(expectedParamClassName, paramTypeNamesSetPrimitiveArrayParam[0]);
String returnTypeNameSetParam = metaMethodSetPrimitiveArrayParam.getReturnTypeName();
assertEquals(S_TYPE_NAME_VOID, returnTypeNameSetParam);
}
@Test
public void testRegressionDefaultPackageParamMatchClassArray() throws Throwable
{
String className = "FooClassInDefaultPackage";
String paramClassName = "IsUsedForTestingDefaultPackage";
Class<?> defaultPackageTestClass = Class.forName(className);
Class<?> defaultPackageTestClassParam = Class.forName("[L" + paramClassName + ";");
String expectedParamClassName = paramClassName + "[]";
MetaClass metaClass = new MetaClass(new MetaPackage(S_EMPTY), className);
Method getterClassArrayParam = defaultPackageTestClass.getDeclaredMethod("getClassArrayParam", new Class[] {});
MetaMethod metaMethodGetClassArrayParam = new MetaMethod(getterClassArrayParam, metaClass);
String[] paramTypeNamesGetClassArrayParam = metaMethodGetClassArrayParam.getParamTypeNames();
assertEquals(0, paramTypeNamesGetClassArrayParam.length);
String returnTypeNameGetClassArrayParam = metaMethodGetClassArrayParam.getReturnTypeName();
assertEquals(expectedParamClassName, returnTypeNameGetClassArrayParam);
Method setterClassArrayParam = defaultPackageTestClass.getDeclaredMethod("setClassArrayParam",
new Class[] { defaultPackageTestClassParam });
MetaMethod metaMethodSetClassArrayParam = new MetaMethod(setterClassArrayParam, metaClass);
String[] paramTypeNamesSetClassArrayParam = metaMethodSetClassArrayParam.getParamTypeNames();
assertEquals(1, paramTypeNamesSetClassArrayParam.length);
assertEquals(expectedParamClassName, paramTypeNamesSetClassArrayParam[0]);
String returnTypeNameSetClassArray = metaMethodSetClassArrayParam.getReturnTypeName();
assertEquals(S_TYPE_NAME_VOID, returnTypeNameSetClassArray);
}
}