|
@@ -15,8 +15,15 @@ import java.lang.reflect.ParameterizedType;
|
|
|
import java.lang.reflect.Type;
|
|
import java.lang.reflect.Type;
|
|
|
import java.lang.reflect.TypeVariable;
|
|
import java.lang.reflect.TypeVariable;
|
|
|
import java.lang.reflect.WildcardType;
|
|
import java.lang.reflect.WildcardType;
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+
|
|
|
|
|
+import net.ranides.assira.collection.arrays.NativeArrayBuilder;
|
|
|
|
|
+import net.ranides.assira.lexer.StringTokenizer;
|
|
|
import net.ranides.assira.reflection.IClass;
|
|
import net.ranides.assira.reflection.IClass;
|
|
|
import net.ranides.assira.reflection.IContext;
|
|
import net.ranides.assira.reflection.IContext;
|
|
|
|
|
+import net.ranides.assira.reflection.IReflectiveException;
|
|
|
|
|
+import net.ranides.assira.reflection.util.ClassUtils;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* This is internal factory for IClass implementations.
|
|
* This is internal factory for IClass implementations.
|
|
@@ -133,5 +140,54 @@ public final class FClass {
|
|
|
public static IClass<?> newClass(IContext context, GenericArrayType gtype) {
|
|
public static IClass<?> newClass(IContext context, GenericArrayType gtype) {
|
|
|
return new RGClass<>(context, gtype);
|
|
return new RGClass<>(context, gtype);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ public static IClass<?> newClass(IContext context, String typename) {
|
|
|
|
|
+ int iparam = typename.indexOf('<');
|
|
|
|
|
+ if(iparam == -1) {
|
|
|
|
|
+ return context.typeinfo(newSimpleClass(typename));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ StringTokenizer tokenizer = new StringTokenizer(typename);
|
|
|
|
|
+ return parseClassName(context, tokenizer);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static IClass<?> parseClassName(IContext context, StringTokenizer tokenizer) {
|
|
|
|
|
+ tokenizer.skip(Character::isWhitespace);
|
|
|
|
|
+ String typename = tokenizer.get(c -> Character.isJavaIdentifierPart(c) || c == '.');
|
|
|
|
|
+ Class<?> type = newSimpleClass(typename);
|
|
|
|
|
+
|
|
|
|
|
+ tokenizer.skip(Character::isWhitespace);
|
|
|
|
|
+ if (tokenizer.peek() != '<') {
|
|
|
|
|
+ return context.typeinfo(type);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ tokenizer.skip();
|
|
|
|
|
+ IClass<?>[] params = parseClassNames(context, tokenizer);
|
|
|
|
|
+ return IClass.generic(type, params);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static IClass<?>[] parseClassNames(IContext context, StringTokenizer tokenizer) {
|
|
|
|
|
+ NativeArrayBuilder out = new NativeArrayBuilder(IClass.class);
|
|
|
|
|
+
|
|
|
|
|
+ while (true){
|
|
|
|
|
+ out.value(parseClassName(context, tokenizer));
|
|
|
|
|
+
|
|
|
|
|
+ if(tokenizer.end()) {
|
|
|
|
|
+ throw new IllegalArgumentException("Expected > at the end of list");
|
|
|
|
|
+ }
|
|
|
|
|
+ char ch = tokenizer.get();
|
|
|
|
|
+ if(ch == '>') {
|
|
|
|
|
+ break;
|
|
|
|
|
+ } else if(ch != ',') {
|
|
|
|
|
+ throw new IllegalArgumentException("Expected , inside parameter list");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return out.toArray();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static Class<?> newSimpleClass(String typename) {
|
|
|
|
|
+ return ClassUtils.forName(typename).orElseThrow(() -> new IReflectiveException("Unknown class name: " + typename));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|