fix: generate correct type name

This commit is contained in:
金戟 2022-11-14 22:40:34 +08:00
parent 46e4499035
commit f8501b0722
2 changed files with 63 additions and 10 deletions

View File

@ -78,10 +78,8 @@ public class ConstructionUtil {
private static String getClassName(Type clazz) {
if (clazz instanceof Class) {
return ((Class<?>)clazz).getName().replace(DOLLAR, DOT);
} else if (clazz instanceof TypeVariable) {
return ((TypeVariable<?>)clazz).getName();
}
return clazz.toString().replaceAll("@.*$", "").replaceAll("^.* ", "");
return clazz.toString();
}
private static String getParameterName(Type parameter) {

View File

@ -1,27 +1,52 @@
package com.alibaba.testable.core.util;
import org.junit.jupiter.api.Test;
import sun.reflect.generics.factory.CoreReflectionFactory;
import sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
import sun.reflect.generics.reflectiveObjects.TypeVariableImpl;
import sun.reflect.generics.reflectiveObjects.WildcardTypeImpl;
import sun.reflect.generics.scope.MethodScope;
import sun.reflect.generics.tree.SimpleClassTypeSignature;
import sun.reflect.generics.tree.TypeArgument;
import static org.junit.jupiter.api.Assertions.*;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Map;
import static com.alibaba.testable.core.tool.PrivateAccessor.construct;
import static com.alibaba.testable.core.tool.PrivateAccessor.invokeStatic;
import static com.alibaba.testable.core.util.CollectionUtil.arrayOf;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
class ConstructionUtilTest {
public interface EmptyInterface {}
public interface RealInterface {
void fun1();
int func2(double d, boolean b);
String fun3(String s, byte[] b);
EmptyInterface fun4(RealInterface i);
<T> T fun5(T i);
void noParameterMethod();
int primaryTypeParameterMethod(double d, boolean b);
String clazzAndArrayParameterMethod(String s, byte[] b);
EmptyInterface interfaceAndSelfReferenceParameterMethod(RealInterface i, EmptyInterface[] e);
<T> T templatedParameterMethod(T i);
}
public static abstract class AbstractClazz implements RealInterface {
@Override
public void fun1() {}
public void noParameterMethod() {}
public abstract <T extends String> T getById(T id);
public abstract String getByTags(List<? extends String> tags);
public static <T> T useless() { return null; }
}
public static abstract class ParameterizedClazz<T> extends AbstractClazz implements RealInterface, EmptyInterface {
public abstract int getById(T id);
public abstract int getByIds(List<T> id);
public abstract int getByMap(Map<String, T> m);
}
@Test
void should_generate_empty_interface() throws Exception {
EmptyInterface ins = ConstructionUtil.generateSubClassOf(EmptyInterface.class);
@ -39,4 +64,34 @@ class ConstructionUtilTest {
RealInterface ins = ConstructionUtil.generateSubClassOf(AbstractClazz.class);
assertNotNull(ins);
}
@Test
void should_generate_parameterized_class() throws Exception {
RealInterface ins = ConstructionUtil.generateSubClassOf(ParameterizedClazz.class);
assertNotNull(ins);
}
@Test
void should_get_class_name() throws Exception {
// common class, e.g. String
assertEquals("java.lang.String",
invokeStatic(ConstructionUtil.class, "getClassName", String.class));
// array class, e.g. String[]
assertEquals("java.lang.String[]",
invokeStatic(ConstructionUtil.class, "getClassName", GenericArrayTypeImpl.make(String.class)));
// typed class, e.g. T
Method fakeMethod = construct(Method.class, String.class, "fake", new Class[0], String.class, new Class[0], Modifier.PUBLIC, 0, "", null, null, null);
assertEquals("T", invokeStatic(ConstructionUtil.class, "getClassName", TypeVariableImpl.make(
fakeMethod, "T", arrayOf(SimpleClassTypeSignature.make("java.lang.String", false, new TypeArgument[0])),
CoreReflectionFactory.make(fakeMethod, MethodScope.make(fakeMethod)))));
// wildcard class, e.g. ? extends String
assertEquals("? extends java.lang.String", invokeStatic(ConstructionUtil.class, "getClassName", WildcardTypeImpl.make(
arrayOf(SimpleClassTypeSignature.make("java.lang.String", false, new TypeArgument[0])),
new SimpleClassTypeSignature[0],
CoreReflectionFactory.make(String.class, MethodScope.make(fakeMethod)))));
// parameterized class, e.g. Map<String, Object>
assertEquals("java.util.Map<java.lang.String, java.lang.Object>",
invokeStatic(ConstructionUtil.class, "getClassName", ParameterizedTypeImpl.make(Map.class,
arrayOf(String.class, Object.class), null)));
}
}