|
@@ -54,9 +54,11 @@ import org.openzen.zenscript.codemodel.type.TypeID;
|
54
|
54
|
import org.openzen.zenscript.codemodel.type.member.BuiltinID;
|
55
|
55
|
import org.openzen.zenscript.codemodel.type.member.TypeMembers;
|
56
|
56
|
import org.openzen.zenscript.codemodel.type.storage.AutoStorageTag;
|
|
57
|
+import org.openzen.zenscript.codemodel.type.storage.StorageTag;
|
57
|
58
|
import org.openzen.zenscript.javashared.JavaClass;
|
58
|
59
|
import org.openzen.zenscript.javashared.JavaCompiledModule;
|
59
|
60
|
import org.openzen.zenscript.javashared.JavaField;
|
|
61
|
+import org.openzen.zenscript.javashared.JavaFunctionalInterfaceStorageTag;
|
60
|
62
|
import org.openzen.zenscript.javashared.JavaImplementation;
|
61
|
63
|
import org.openzen.zenscript.javashared.JavaMethod;
|
62
|
64
|
import stdlib.Strings;
|
|
@@ -251,7 +253,7 @@ public class JavaNativeModule {
|
251
|
253
|
TypeVariable<Class<T>> typeVariable = javaTypeParameters[i];
|
252
|
254
|
TypeParameter parameter = new TypeParameter(CodePosition.NATIVE, typeVariable.getName());
|
253
|
255
|
for (AnnotatedType bound : typeVariable.getAnnotatedBounds()) {
|
254
|
|
- TypeID type = loadType(context, bound);
|
|
256
|
+ TypeID type = loadType(context, bound).type;
|
255
|
257
|
parameter.addBound(new ParameterTypeBound(CodePosition.NATIVE, type));
|
256
|
258
|
}
|
257
|
259
|
typeParameters[i] = parameter;
|
|
@@ -275,13 +277,13 @@ public class JavaNativeModule {
|
275
|
277
|
javaClass = JavaClass.fromInternalName(internalName, JavaClass.Kind.CLASS);
|
276
|
278
|
|
277
|
279
|
if (cls.getAnnotatedSuperclass() != null && shouldLoadType(cls.getAnnotatedSuperclass().getType())) {
|
278
|
|
- definition.setSuperType(loadType(context, cls.getAnnotatedSuperclass()));
|
|
280
|
+ definition.setSuperType(loadType(context, cls.getAnnotatedSuperclass()).type);
|
279
|
281
|
}
|
280
|
282
|
}
|
281
|
283
|
|
282
|
284
|
for (AnnotatedType iface : cls.getAnnotatedInterfaces()) {
|
283
|
285
|
if (shouldLoadType(iface.getType())) {
|
284
|
|
- TypeID type = loadType(context, iface);
|
|
286
|
+ TypeID type = loadType(context, iface).type;
|
285
|
287
|
ImplementationMember member = new ImplementationMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC, type);
|
286
|
288
|
definition.members.add(member);
|
287
|
289
|
compiled.setImplementationInfo(member, new JavaImplementation(true, javaClass));
|
|
@@ -515,7 +517,7 @@ public class JavaNativeModule {
|
515
|
517
|
context.put(javaTypeParameter, typeParameters[i]);
|
516
|
518
|
|
517
|
519
|
for (AnnotatedType bound : javaTypeParameter.getAnnotatedBounds())
|
518
|
|
- typeParameters[i].addBound(new ParameterTypeBound(CodePosition.NATIVE, loadType(context, bound)));
|
|
520
|
+ typeParameters[i].addBound(new ParameterTypeBound(CodePosition.NATIVE, loadType(context, bound).type));
|
519
|
521
|
}
|
520
|
522
|
|
521
|
523
|
if (exceptionTypes.length > 1)
|
|
@@ -526,15 +528,14 @@ public class JavaNativeModule {
|
526
|
528
|
}
|
527
|
529
|
|
528
|
530
|
private StoredType loadStoredType(TypeVariableContext context, AnnotatedType annotatedType) {
|
529
|
|
- TypeID baseType = loadType(context, annotatedType);
|
530
|
|
- return baseType.stored();
|
|
531
|
+ return loadType(context, annotatedType);
|
531
|
532
|
}
|
532
|
533
|
|
533
|
|
- private TypeID loadType(TypeVariableContext context, AnnotatedType annotatedType) {
|
|
534
|
+ private StoredType loadType(TypeVariableContext context, AnnotatedType annotatedType) {
|
534
|
535
|
if (annotatedType.isAnnotationPresent(ZenCodeType.USize.class))
|
535
|
|
- return BasicTypeID.USIZE;
|
|
536
|
+ return BasicTypeID.USIZE.stored;
|
536
|
537
|
else if (annotatedType.isAnnotationPresent(ZenCodeType.NullableUSize.class))
|
537
|
|
- return registry.getOptional(BasicTypeID.USIZE);
|
|
538
|
+ return registry.getOptional(BasicTypeID.USIZE).stored();
|
538
|
539
|
|
539
|
540
|
boolean nullable = annotatedType.isAnnotationPresent(ZenCodeType.Nullable.class);
|
540
|
541
|
boolean unsigned = annotatedType.isAnnotationPresent(ZenCodeType.Unsigned.class);
|
|
@@ -543,42 +544,86 @@ public class JavaNativeModule {
|
543
|
544
|
return loadType(context, type, nullable, unsigned);
|
544
|
545
|
}
|
545
|
546
|
|
546
|
|
- private TypeID loadType(TypeVariableContext context, Type type, boolean nullable, boolean unsigned) {
|
|
547
|
+ private StoredType loadType(TypeVariableContext context, Type type, boolean nullable, boolean unsigned) {
|
547
|
548
|
if (type instanceof Class) {
|
548
|
549
|
Class<?> classType = (Class<?>) type;
|
549
|
550
|
if (unsigned) {
|
550
|
551
|
if (unsignedByClass.containsKey(classType))
|
551
|
|
- return unsignedByClass.get(classType);
|
|
552
|
+ return unsignedByClass.get(classType).stored();
|
552
|
553
|
else
|
553
|
554
|
throw new IllegalArgumentException("This class cannot be used as unsigned: " + classType);
|
554
|
555
|
} else if (classType.isArray()) {
|
555
|
|
- return registry.getArray(loadType(context, classType.getComponentType(), false, false).stored(), 1);
|
|
556
|
+ return registry.getArray(loadType(context, classType.getComponentType(), false, false), 1).stored();
|
|
557
|
+ } else if (classType.isAnnotationPresent(FunctionalInterface.class)) {
|
|
558
|
+ return loadFunctionalInterface(context, classType, new Type[0]);
|
556
|
559
|
}
|
557
|
560
|
|
558
|
561
|
if (typeByClass.containsKey(classType))
|
559
|
|
- return typeByClass.get(classType);
|
|
562
|
+ return typeByClass.get(classType).stored();
|
560
|
563
|
|
561
|
564
|
HighLevelDefinition definition = addClass(classType);
|
562
|
|
- return registry.getForDefinition(definition);
|
|
565
|
+ return registry.getForDefinition(definition).stored();
|
563
|
566
|
} else if (type instanceof ParameterizedType) {
|
564
|
567
|
ParameterizedType parameterizedType = (ParameterizedType) type;
|
565
|
568
|
Class<?> rawType = (Class) parameterizedType.getRawType();
|
|
569
|
+ if (rawType.isAnnotationPresent(FunctionalInterface.class))
|
|
570
|
+ return loadFunctionalInterface(context, rawType, parameterizedType.getActualTypeArguments());
|
566
|
571
|
|
567
|
572
|
HighLevelDefinition definition = addClass(rawType);
|
568
|
573
|
Type[] parameters = parameterizedType.getActualTypeArguments();
|
569
|
574
|
StoredType[] codeParameters = new StoredType[parameters.length];
|
570
|
575
|
for (int i = 0; i < parameters.length; i++)
|
571
|
|
- codeParameters[i] = loadType(context, parameters[i], false, false).stored();
|
|
576
|
+ codeParameters[i] = loadType(context, parameters[i], false, false);
|
572
|
577
|
|
573
|
|
- return registry.getForDefinition(definition, codeParameters);
|
|
578
|
+ return registry.getForDefinition(definition, codeParameters).stored();
|
574
|
579
|
} else if (type instanceof TypeVariable) {
|
575
|
580
|
TypeVariable variable = (TypeVariable)type;
|
576
|
|
- return registry.getGeneric(context.get(variable));
|
|
581
|
+ return registry.getGeneric(context.get(variable)).stored();
|
577
|
582
|
} else {
|
578
|
583
|
throw new IllegalArgumentException("Could not analyze type: " + type);
|
579
|
584
|
}
|
580
|
585
|
}
|
581
|
586
|
|
|
587
|
+ private StoredType loadFunctionalInterface(TypeVariableContext loadContext, Class<?> cls, Type[] parameters) {
|
|
588
|
+ Method functionalInterfaceMethod = getFunctionalInterfaceMethod(cls);
|
|
589
|
+ TypeVariableContext context = convertTypeParameters(cls);
|
|
590
|
+ FunctionHeader header = getHeader(context, functionalInterfaceMethod);
|
|
591
|
+
|
|
592
|
+ Map<TypeParameter, StoredType> mapping = new HashMap<>();
|
|
593
|
+ TypeVariable[] javaParameters = cls.getTypeParameters();
|
|
594
|
+ for (int i = 0; i < javaParameters.length; i++)
|
|
595
|
+ mapping.put(context.get(javaParameters[i]), loadType(loadContext, parameters[i], false, false));
|
|
596
|
+
|
|
597
|
+ StorageTag tag = new JavaFunctionalInterfaceStorageTag(functionalInterfaceMethod);
|
|
598
|
+ return registry.getFunction(header).stored(tag);
|
|
599
|
+ }
|
|
600
|
+
|
|
601
|
+ private <T> TypeVariableContext convertTypeParameters(Class<T> cls) {
|
|
602
|
+ TypeVariableContext context = new TypeVariableContext();
|
|
603
|
+ TypeVariable<Class<T>>[] javaTypeParameters = cls.getTypeParameters();
|
|
604
|
+ TypeParameter[] typeParameters = new TypeParameter[cls.getTypeParameters().length];
|
|
605
|
+ for (int i = 0; i < javaTypeParameters.length; i++) {
|
|
606
|
+ TypeVariable<Class<T>> typeVariable = javaTypeParameters[i];
|
|
607
|
+ TypeParameter parameter = new TypeParameter(CodePosition.NATIVE, typeVariable.getName());
|
|
608
|
+ for (AnnotatedType bound : typeVariable.getAnnotatedBounds()) {
|
|
609
|
+ TypeID type = loadType(context, bound).type;
|
|
610
|
+ parameter.addBound(new ParameterTypeBound(CodePosition.NATIVE, type));
|
|
611
|
+ }
|
|
612
|
+ typeParameters[i] = parameter;
|
|
613
|
+ context.put(typeVariable, parameter);
|
|
614
|
+ }
|
|
615
|
+ return context;
|
|
616
|
+ }
|
|
617
|
+
|
|
618
|
+ private Method getFunctionalInterfaceMethod(Class<?> functionalInterface) {
|
|
619
|
+ for (Method method : functionalInterface.getDeclaredMethods()) {
|
|
620
|
+ if (!method.isDefault())
|
|
621
|
+ return method;
|
|
622
|
+ }
|
|
623
|
+
|
|
624
|
+ return null;
|
|
625
|
+ }
|
|
626
|
+
|
582
|
627
|
private int getMethodModifiers(Method method) {
|
583
|
628
|
int result = Modifiers.PUBLIC;
|
584
|
629
|
if (isStatic(method.getModifiers()))
|