5 Commits

Author SHA1 Message Date
  kindlich c984531cc3
More work on generics 5 years ago
  kindlich 4ad3331928
Added Signature to JavaField constructor 5 years ago
  kindlich 1a3075532c
WIP: More work on Generics in Expansions 5 years ago
  kindlich 8f1960209a
WIP: More work on generic parameters in expansions 5 years ago
  kindlich 45029d5e80
Fixed compilation with generic arguments 5 years ago

+ 47
- 4
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java View File

@@ -12,12 +12,15 @@ import org.openzen.zenscript.codemodel.member.IDefinitionMember;
12 12
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
13 13
 import org.openzen.zenscript.codemodel.type.StoredType;
14 14
 import org.openzen.zenscript.codemodel.type.TypeID;
15
+import org.openzen.zenscript.javashared.JavaField;
15 16
 import org.openzen.zenscript.javashared.JavaParameterInfo;
16 17
 
17 18
 import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
18 19
 import org.openzen.zenscript.javashared.JavaCompiledModule;
19 20
 import org.openzen.zenscript.javashared.JavaTypeParameterInfo;
20 21
 
22
+import java.util.List;
23
+
21 24
 public class CompilerUtils {
22 25
 
23 26
 	private CompilerUtils() {}
@@ -48,21 +51,60 @@ public class CompilerUtils {
48 51
 		return out;
49 52
 	}
50 53
 
51
-    public static void tagMethodParameters(JavaBytecodeContext context, JavaCompiledModule module, FunctionHeader header, boolean isStatic) {
52
-		int index = header.getNumberOfTypeParameters();
54
+    public static void tagMethodParameters(JavaBytecodeContext context, JavaCompiledModule module, FunctionHeader header, boolean isStatic, List<TypeParameter> baseTypeTypeParameters) {
55
+		int index = isStatic ? 0 : 1;
56
+
57
+		for (TypeParameter baseTypeTypeParameter : baseTypeTypeParameters) {
58
+			module.setTypeParameterInfo(baseTypeTypeParameter, new JavaTypeParameterInfo(index));
59
+			index++;
60
+		}
61
+
53 62
 		for (int i = 0; i < header.typeParameters.length; i++) {
54 63
 			TypeParameter parameter = header.typeParameters[i];
55
-			module.setTypeParameterInfo(parameter, new JavaTypeParameterInfo(index++));
64
+			module.setTypeParameterInfo(parameter, new JavaTypeParameterInfo(index));
65
+			index++;
56 66
 		}
57 67
         for (int i = 0; i < header.parameters.length; i++) {
58 68
             FunctionParameter parameter = header.parameters[i];
59 69
             String parameterType = context.getDescriptor(parameter.type);
60
-            module.setParameterInfo(parameter, new JavaParameterInfo(isStatic ? index : index + 1, parameterType));
70
+            module.setParameterInfo(parameter, new JavaParameterInfo(index, parameterType));
61 71
 			index++;
62 72
         }
63 73
     }
64 74
 
65 75
     public static void tagConstructorParameters(JavaBytecodeContext context, JavaCompiledModule module, HighLevelDefinition definition, FunctionHeader header, boolean isEnum) {
76
+		int index = 1;
77
+		for (TypeParameter typeParameter : definition.typeParameters) {
78
+			final JavaField field = new JavaField(context.getJavaClass(definition),
79
+					"typeOf" + typeParameter.name,
80
+					"Ljava/lang/Class;",
81
+					//"Ljava/lang/Class;"
82
+					"Ljava/lang/Class<T" + typeParameter.name + ";>;"
83
+			);
84
+			final JavaTypeParameterInfo info = new JavaTypeParameterInfo(index, field);
85
+			module.setTypeParameterInfo(typeParameter, info);
86
+			index++;
87
+		}
88
+
89
+		for (int i = 0; i < header.typeParameters.length; i++) {
90
+			TypeParameter typeParameter = header.typeParameters[i];
91
+			final JavaField field = new JavaField(context.getJavaClass(definition),
92
+					"typeOf" + typeParameter.name,
93
+					"Ljava/lang/Class;",
94
+					//"Ljava/lang/Class;"
95
+					"Ljava/lang/Class<T" + typeParameter.name + ";>;"
96
+					);
97
+			final JavaTypeParameterInfo info = new JavaTypeParameterInfo(index, field);
98
+			module.setTypeParameterInfo(typeParameter, info);
99
+			index++;
100
+		}
101
+		for (int i = 0; i < header.parameters.length; i++) {
102
+			FunctionParameter parameter = header.parameters[i];
103
+			String parameterType = context.getDescriptor(parameter.type);
104
+			module.setParameterInfo(parameter, new JavaParameterInfo(index, parameterType));
105
+			index++;
106
+		}
107
+		/*
66 108
 		int index = header.getNumberOfTypeParameters();
67 109
 		for (int i = 0; i < definition.typeParameters.length; i++) {
68 110
 			JavaTypeParameterInfo info = module.getTypeParameterInfo(definition.typeParameters[i]);
@@ -78,6 +120,7 @@ public class CompilerUtils {
78 120
             String parameterType = context.getDescriptor(parameter.type);
79 121
 			module.setParameterInfo(parameter, new JavaParameterInfo(isEnum ? i + 3 : i + 1, parameterType));
80 122
         }
123
+		 */
81 124
     }
82 125
 
83 126
     public static void writeDefaultFieldInitializers(JavaBytecodeContext context, JavaWriter constructorWriter, HighLevelDefinition definition, boolean staticFields) {

+ 80
- 14
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java View File

@@ -6,8 +6,10 @@ import org.objectweb.asm.Opcodes;
6 6
 import org.objectweb.asm.Type;
7 7
 import org.openzen.zenscript.codemodel.CompareType;
8 8
 import org.openzen.zenscript.codemodel.FunctionParameter;
9
+import org.openzen.zenscript.codemodel.annotations.NativeTag;
9 10
 import org.openzen.zenscript.codemodel.expression.*;
10 11
 import org.openzen.zenscript.codemodel.expression.switchvalue.VariantOptionSwitchValue;
12
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
11 13
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
12 14
 import org.openzen.zenscript.codemodel.member.ref.FieldMemberRef;
13 15
 import org.openzen.zenscript.codemodel.statement.ReturnStatement;
@@ -23,10 +25,8 @@ import org.openzen.zenscript.javashared.*;
23 25
 
24 26
 import java.lang.reflect.Method;
25 27
 import java.lang.reflect.Modifier;
26
-import java.util.Arrays;
27
-import java.util.Comparator;
28
-import java.util.Objects;
29
-import java.util.StringJoiner;
28
+import java.util.*;
29
+import java.util.stream.Collectors;
30 30
 
31 31
 public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativeTranslator<Void> {
32 32
     private static final JavaMethod OBJECTS_TOSTRING = JavaMethod.getNativeStatic(new JavaClass("java.util", "Objects", JavaClass.Kind.CLASS), "toString", "(Ljava/lang/Object;)Ljava/lang/String;");
@@ -384,11 +384,30 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
384 384
 		if (builtin == null) {
385 385
 			expression.target.accept(this);
386 386
 
387
+			final List<TypeParameter> typeParameters;
388
+			{
389
+
390
+				final List<TypeParameter> parameters = new ArrayList<>();
391
+				if(expression.member.getTarget().definition.isExpansion()) {
392
+					parameters.addAll(Arrays.asList(expression.member.getTarget().definition.typeParameters));
393
+				}
394
+
395
+				//expression.member.getOwnerType().type.extractTypeParameters(parameters);
396
+				//expression.instancedHeader.typeParameters
397
+				for (TypeParameter typeParameter : expression.member.getTarget().getHeader().typeParameters) {
398
+					if(!parameters.contains(typeParameter)) {
399
+						parameters.add(typeParameter);
400
+					}
401
+				}
402
+				typeParameters = parameters.stream().distinct().collect(Collectors.toList());
403
+			}
404
+
387 405
 			JavaMethod methodInfo = context.getJavaMethod(expression.member);
388
-			for (int i = 0; i < expression.arguments.typeArguments.length; i++) {
389
-				if (methodInfo.typeParameterArguments[i]) {
390
-					StoredType arguments = expression.arguments.typeArguments[i];
391 406
 
407
+			if(methodInfo.compile) {
408
+				for (TypeParameter typeParameter : typeParameters) {
409
+					javaWriter.aConstNull(); // TODO: Replace with actual class
410
+					javaWriter.checkCast("java/lang/Class");
392 411
 				}
393 412
 			}
394 413
 
@@ -1295,6 +1314,17 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1295 1314
 	public Void visitCast(CastExpression expression) {
1296 1315
 		expression.target.accept(this);
1297 1316
 
1317
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>(Arrays.asList(expression.member.member.definition.typeParameters));
1318
+		//expression.member.type.type.extractTypeParameters(typeParameters);
1319
+		expression.member.toType.type.extractTypeParameters(typeParameters);
1320
+
1321
+		if (expression.member.member.definition.isExpansion()) {
1322
+			for (TypeParameter typeParameter : typeParameters) {
1323
+				javaWriter.aConstNull(); //Todo: Replace with actual Type
1324
+				javaWriter.checkCast("java/lang/Class");
1325
+			}
1326
+		}
1327
+
1298 1328
 		BuiltinID builtin = expression.member.member.builtin;
1299 1329
 		if (builtin == null) {
1300 1330
 			if (!checkAndExecuteMethodInfo(expression.member, expression.type, expression))
@@ -1951,7 +1981,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1951 1981
 
1952 1982
 	@Override
1953 1983
 	public Void visitFunction(FunctionExpression expression) {
1954
-		CompilerUtils.tagMethodParameters(context, module, expression.header, false);
1984
+		CompilerUtils.tagMethodParameters(context, module, expression.header, false, Collections.emptyList());
1955 1985
 
1956 1986
         /*if (expression.header.parameters.length == 0 && expression.body instanceof ReturnStatement && expression.body.hasTag(MatchExpression.class) && expression.closure.captures.isEmpty()) {
1957 1987
             ((ReturnStatement) expression.body).value.accept(this);
@@ -1970,12 +2000,12 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1970 2000
 				final Method functionalInterfaceMethod = ((JavaFunctionalInterfaceStorageTag) actualStorage).functionalInterfaceMethod;
1971 2001
 				
1972 2002
 				//Should be the same, should it not?
1973
-				signature = context.getMethodSignature(expression.header);
2003
+				signature = context.getMethodSignature(expression.header, true);
1974 2004
 				descriptor = context.getMethodDescriptor(expression.header);
1975 2005
 				interfaces = new String[]{Type.getInternalName(functionalInterfaceMethod.getDeclaringClass())};
1976 2006
 			} else {
1977 2007
 				//Normal way, no casting to functional interface
1978
-				signature = context.getMethodSignature(expression.header);
2008
+				signature = context.getMethodSignature(expression.header, true);
1979 2009
 				descriptor = context.getMethodDescriptor(expression.header);
1980 2010
 				interfaces = new String[]{context.getInternalName(new FunctionTypeID(null, expression.header).stored(UniqueStorageTag.INSTANCE))};
1981 2011
 			}
@@ -2009,7 +2039,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
2009 2039
 				}
2010 2040
 			}
2011 2041
 			
2012
-			bridgeWriter.invokeVirtual(new JavaMethod(JavaClass.fromInternalName(className, JavaClass.Kind.CLASS), JavaMethod.Kind.INSTANCE, methodInfo.name, methodInfo.compile, signature, methodInfo.modifiers, methodInfo.genericResult));
2042
+			bridgeWriter.invokeVirtual(new JavaMethod(JavaClass.fromInternalName(className, JavaClass.Kind.CLASS), JavaMethod.Kind.INSTANCE, methodInfo.name, methodInfo.compile, descriptor, methodInfo.modifiers, methodInfo.genericResult));
2013 2043
 			if(expression.header.getReturnType().type != BasicTypeID.VOID) {
2014 2044
 				bridgeWriter.returnType(context.getType(expression.header.getReturnType()));
2015 2045
 			}
@@ -2137,6 +2167,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
2137 2167
 	public Void visitGetField(GetFieldExpression expression) {
2138 2168
 		expression.target.accept(this);
2139 2169
 		getField(expression.field);
2170
+		javaWriter.checkCast(context.getType(expression.field.getType()));
2140 2171
 		return null;
2141 2172
 	}
2142 2173
 
@@ -2186,11 +2217,25 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
2186 2217
 		if (builtin == null) {
2187 2218
 			if (context.hasJavaField(expression.getter)) {
2188 2219
 				javaWriter.getField(context.getJavaField(expression.getter));
2220
+				javaWriter.checkCast(context.getType(expression.getter.getType()));
2189 2221
 				return null;
2190 2222
 			}
2223
+
2224
+
2225
+			final List<TypeParameter> typeParameters = new ArrayList<>();
2226
+			expression.getter.member.getType().type.extractTypeParameters(typeParameters);
2227
+
2228
+			if(expression.getter.member.definition.isExpansion()) {
2229
+				for (TypeParameter typeParameter : typeParameters) {
2230
+					javaWriter.aConstNull(); //TODO: Replace with actual type
2231
+					javaWriter.checkCast("java/lang/Class");
2232
+				}
2233
+			}
2234
+
2191 2235
 			if (!checkAndExecuteMethodInfo(expression.getter, expression.type, expression))
2192 2236
 				throw new IllegalStateException("Call target has no method info!");
2193 2237
 
2238
+			javaWriter.checkCast(context.getType(expression.getter.getType()));
2194 2239
 			return null;
2195 2240
 		}
2196 2241
 
@@ -2503,6 +2548,15 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
2503 2548
 		javaWriter.newObject(method.cls);
2504 2549
 		javaWriter.dup();
2505 2550
 
2551
+
2552
+		if(!expression.constructor.getTarget().hasTag(NativeTag.class)) {
2553
+			for (StoredType typeArgument : expression.type.asDefinition().typeArguments) {
2554
+				javaWriter.aConstNull();
2555
+				javaWriter.checkCast("java/lang/Class");
2556
+			}
2557
+		}
2558
+
2559
+
2506 2560
 		for (Expression argument : expression.arguments.arguments) {
2507 2561
 			argument.accept(this);
2508 2562
 		}
@@ -3516,7 +3570,8 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
3516 3570
 								}
3517 3571
 								
3518 3572
 								if (funcExpression instanceof FunctionExpression && ((FunctionExpression) funcExpression).body instanceof ReturnStatement) {
3519
-									CompilerUtils.tagMethodParameters(context, module, ((FunctionExpression) funcExpression).header, false);
3573
+									CompilerUtils.tagMethodParameters(context, module, ((FunctionExpression) funcExpression).header, false, Collections
3574
+                                            .emptyList());
3520 3575
 									((ReturnStatement) ((FunctionExpression) funcExpression).body).value.accept(visitor);
3521 3576
 									javaWriter.addVariableInfo(new JavaLocalVariableInfo(projectedElementType, projectedElementLocal, inlineBegin, ((FunctionExpression) funcExpression).header.parameters[0].name, inlineEnd));
3522 3577
 									
@@ -4244,8 +4299,8 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
4244 4299
 
4245 4300
 		//Make sure that method results are popped if ZC thinks its a void but it actually is not.
4246 4301
 		//Fixes an issue for List#add() returning void in ZC but Z in Java.
4247
-		if(resultType.type == BasicTypeID.VOID && !methodInfo.descriptor.endsWith(")V")) {
4248
-			final boolean isLarge = methodInfo.descriptor.endsWith(")D") && methodInfo.descriptor.endsWith(")L");
4302
+		if(resultType.type == BasicTypeID.VOID && !methodInfo.descriptor.equals("") && !methodInfo.descriptor.endsWith(")V")) {
4303
+			final boolean isLarge = methodInfo.descriptor.endsWith(")D") && methodInfo.descriptor.endsWith(")J");
4249 4304
 			getJavaWriter().pop(isLarge);
4250 4305
 		}
4251 4306
 
@@ -4310,6 +4365,17 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
4310 4365
 
4311 4366
 	@Override
4312 4367
 	public Void copyTo(CallExpression call) {
4368
+		//Copy this (source) to dest
4369
+		//              source.copyTo(dest, sourceOffset, destOffset, length)
4370
+		//=> System.arraycopy(source, sourceOffset, dest, destOffset, length);
4371
+		javaWriter.dup2X2();
4372
+		javaWriter.pop2();
4373
+		javaWriter.swap();
4374
+		javaWriter.dup2X2();
4375
+		javaWriter.pop2();
4376
+		final JavaClass system = JavaClass.fromInternalName("java/lang/System", JavaClass.Kind.CLASS);
4377
+		final JavaMethod javaMethod = JavaMethod.getStatic(system, "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V", JavaModifiers.PUBLIC);
4378
+		javaWriter.invokeStatic(javaMethod);
4313 4379
 		return null;
4314 4380
 	}
4315 4381
 

+ 9
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaNonPushingExpressionVisitor.java View File

@@ -77,6 +77,7 @@ import org.openzen.zenscript.codemodel.expression.TryRethrowAsExceptionExpressio
77 77
 import org.openzen.zenscript.codemodel.expression.TryRethrowAsResultExpression;
78 78
 import org.openzen.zenscript.codemodel.expression.VariantValueExpression;
79 79
 import org.openzen.zenscript.codemodel.expression.WrapOptionalExpression;
80
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
80 81
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
81 82
 import org.openzen.zenscript.codemodel.type.member.BuiltinID;
82 83
 import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
@@ -624,6 +625,14 @@ public class JavaNonPushingExpressionVisitor implements ExpressionVisitor<Void>
624 625
 	@Override
625 626
 	public Void visitSetter(SetterExpression expression) {
626 627
 		expression.target.accept(original);
628
+
629
+		if (expression.setter.member.definition.isExpansion()) {
630
+			for (TypeParameter typeParameter : expression.setter.member.definition.typeParameters) {
631
+				javaWriter.aConstNull(); //TODO replace with actual type
632
+				javaWriter.checkCast("java/lang/Class");
633
+			}
634
+		}
635
+
627 636
 		expression.value.accept(original);
628 637
 		original.checkAndExecuteMethodInfo(expression.setter, expression.type, expression);
629 638
 		return null;

+ 12
- 3
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java View File

@@ -49,6 +49,7 @@ public class JavaWriter {
49 49
 			String[] exceptions,
50 50
 			String... annotations) {
51 51
 		this(position, visitor, nameVariables, method, forDefinition, false, signature, method.descriptor, exceptions, annotations);
52
+		this.position(position.fromLine);
52 53
 	}
53 54
 	
54 55
 	
@@ -67,14 +68,15 @@ public class JavaWriter {
67 68
 		this.method = method;
68 69
 		this.forDefinition = forDefinition;
69 70
 		this.position = position;
70
-		
71
-		final MethodVisitor methodVisitor = visitor.visitMethod(isExtension ? method.modifiers | Opcodes.ACC_STATIC : method.modifiers, method.name, descriptor, signature, exceptions);
71
+
72
+		final int access = isExtension ? method.modifiers | ACC_STATIC : method.modifiers;
73
+		final MethodVisitor methodVisitor = visitor.visitMethod(access, method.name, descriptor, signature, exceptions);
72 74
 		
73 75
 		for (String annotation : annotations) {
74 76
 			methodVisitor.visitAnnotation(annotation, true).visitEnd();
75 77
 		}
76 78
 		
77
-		this.visitor = new LocalVariablesSorter(isExtension ? method.modifiers | Opcodes.ACC_STATIC : method.modifiers, descriptor, methodVisitor);
79
+		this.visitor = new LocalVariablesSorter(access, descriptor, methodVisitor);
78 80
 		this.nameVariables = nameVariables;
79 81
 	}
80 82
 	
@@ -210,6 +212,13 @@ public class JavaWriter {
210 212
 		
211 213
 		visitor.visitInsn(large ? POP2 : POP);
212 214
 	}
215
+
216
+	public void pop2() {
217
+		if(debug)
218
+			System.out.println("pop2");
219
+
220
+		visitor.visitInsn(POP2);
221
+	}
213 222
 	
214 223
 	public void dup() {
215 224
 		if (debug)

+ 38
- 2
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java View File

@@ -29,6 +29,7 @@ import org.openzen.zenscript.javashared.JavaTypeGenericVisitor;
29 29
 import org.openzen.zenscript.javashared.JavaVariantOption;
30 30
 
31 31
 import java.util.ArrayList;
32
+import java.util.Collections;
32 33
 import java.util.List;
33 34
 
34 35
 
@@ -63,9 +64,43 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
63 64
 			if (member instanceof ImplementationMember)
64 65
 				interfaces.add(context.getInternalName(((ImplementationMember) member).type));
65 66
 		}
66
-        String signature = null;
67
+        String signature;
68
+
69
+		{
70
+			final StringBuilder signatureBuilder = new StringBuilder();
71
+			if(definition.typeParameters.length != 0) {
72
+				signatureBuilder.append("<");
73
+				for (TypeParameter typeParameter : definition.typeParameters) {
74
+					signatureBuilder.append(typeParameter.name);
75
+					signatureBuilder.append(":");
76
+					signatureBuilder.append("Ljava/lang/Object;");
77
+				}
78
+				signatureBuilder.append(">");
79
+			}
80
+
81
+			signatureBuilder.append("L").append(superTypeInternalName).append(";");
82
+			for (IDefinitionMember member : definition.members) {
83
+				if(member instanceof ImplementationMember) {
84
+					signatureBuilder.append(context.getInternalName(((ImplementationMember) member).type));
85
+				}
86
+			}
87
+
88
+			signature = signatureBuilder.toString();
89
+		}
67 90
 
68 91
         writer.visit(Opcodes.V1_8, definition.modifiers, toClass.internalName, signature, superTypeInternalName, interfaces.toArray(new String[0]));
92
+		for (TypeParameter typeParameter : definition.typeParameters) {
93
+			//Add it to the class
94
+			writer.visitField(
95
+					Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL,
96
+					"typeOf" + typeParameter.name,
97
+					"Ljava/lang/Class;",
98
+					"Ljava/lang/Class<T" + typeParameter.name + ";>;",
99
+					//"Ljava/lang/Class;",
100
+					null
101
+			);
102
+		}
103
+
69 104
 		JavaMemberVisitor memberVisitor = new JavaMemberVisitor(context, writer, toClass, definition);
70 105
         for (IDefinitionMember member : definition.members) {
71 106
             member.accept(memberVisitor);
@@ -145,7 +180,8 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
145 180
 
146 181
 	@Override
147 182
 	public byte[] visitFunction(FunctionDefinition definition) {
148
-		CompilerUtils.tagMethodParameters(context, context.getJavaModule(definition.module), definition.header, true);
183
+		CompilerUtils.tagMethodParameters(context, context.getJavaModule(definition.module), definition.header, true, Collections
184
+                .emptyList());
149 185
 
150 186
         final String signature = context.getMethodSignature(definition.header);
151 187
 		final JavaMethod method = context.getJavaMethod(definition.caller);

+ 215
- 13
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaExpansionMemberVisitor.java View File

@@ -5,6 +5,7 @@ import org.objectweb.asm.Label;
5 5
 import org.objectweb.asm.Type;
6 6
 import org.openzen.zenscript.codemodel.FunctionParameter;
7 7
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
8
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
8 9
 import org.openzen.zenscript.codemodel.member.*;
9 10
 import org.openzen.zenscript.codemodel.type.StoredType;
10 11
 import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
@@ -14,6 +15,10 @@ import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
14 15
 import org.openzen.zenscript.javashared.JavaCompiledModule;
15 16
 import org.openzen.zenscript.javashared.JavaField;
16 17
 import org.openzen.zenscript.javashared.JavaMethod;
18
+import org.openzen.zenscript.javashared.JavaParameterInfo;
19
+
20
+import java.util.ArrayList;
21
+import java.util.stream.Collectors;
17 22
 
18 23
 public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
19 24
 
@@ -79,38 +84,76 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
79 84
 		if (!method.compile)
80 85
 			return null;
81 86
 
87
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
88
+		expandedClass.type.extractTypeParameters(typeParameters);
82 89
 
83
-		CompilerUtils.tagMethodParameters(context, javaModule, member.header, member.isStatic());
90
+		CompilerUtils.tagMethodParameters(context, javaModule, member.header, member.isStatic(), typeParameters);
84 91
 
85 92
 		final String expandedClassDescriptor = context.getDescriptor(expandedClass);
93
+		final String expandedClassSignature = context.getSignature(expandedClass);
86 94
 		final Label methodStart = new Label();
87 95
 		final Label methodEnd = new Label();
88 96
 		final String methodSignature;
97
+		final String methodDescriptor;
98
+
99
+
89 100
 
90 101
 		if (!isStatic) {
91
-			methodSignature = "(" + expandedClassDescriptor + context.getMethodSignature(member.header).substring(1);
102
+			String methodSignature1 = context.getMethodSignature(member.header);
103
+
104
+			//Add the expanded type as first generic parameter to the list.
105
+			if(!typeParameters.isEmpty()){
106
+				final String collect = typeParameters.stream()
107
+						.map(t -> t.name + ":" + "Ljava/lang/Object;")
108
+						.collect(Collectors.joining("", "<", ""));
109
+				if(methodSignature1.startsWith("<")) {
110
+					methodSignature1 = collect + methodSignature1.substring(1);
111
+				} else {
112
+					methodSignature1 = collect + ">" + methodSignature1;
113
+				}
114
+			}
115
+
116
+			final StringBuilder typeParamSigBuilder = new StringBuilder();
117
+			final StringBuilder typeParamDescBuilder = new StringBuilder();
118
+			int i = 1;
119
+			for (TypeParameter typeParameter : typeParameters) {
120
+				typeParamSigBuilder.append("Ljava/lang/Class<T").append(typeParameter.name).append(";>;");
121
+				typeParamDescBuilder.append("Ljava/lang/Class;");
122
+			}
123
+
124
+
125
+			final int index = methodSignature1.lastIndexOf('(') + 1;
126
+			methodSignature = methodSignature1.substring(0, index) + expandedClassSignature + typeParamSigBuilder.toString() + methodSignature1.substring(index);
127
+			methodDescriptor = "(" + expandedClassDescriptor + typeParamDescBuilder.toString() + context.getMethodDescriptor(member.header).substring(1);
92 128
 		} else {
93 129
 			methodSignature = context.getMethodSignature(member.header);
130
+			methodDescriptor = context.getMethodDescriptor(member.header);
94 131
 		}
95 132
 
96 133
 
97
-		final JavaWriter methodWriter = new JavaWriter(member.position, writer, true, method, definition, true, methodSignature, methodSignature, null);
134
+		final JavaWriter methodWriter = new JavaWriter(member.position, writer, true, method, definition, true, methodSignature, methodDescriptor, null);
98 135
 		methodWriter.label(methodStart);
99 136
 
100 137
 		if (!isStatic) {
101 138
 			methodWriter.nameVariable(0, "expandedObj", methodStart, methodEnd, Type.getType(expandedClassDescriptor));
102 139
 			methodWriter.nameParameter(0, "expandedObj");
103
-			for (final FunctionParameter parameter : member.header.parameters) {
104
-				methodWriter.nameParameter(0, parameter.name);
105
-				methodWriter.nameVariable(javaModule.getParameterInfo(parameter).index, parameter.name, methodStart, methodEnd, context.getType(parameter.type));
106
-			}
107
-		} else {
108
-			for (final FunctionParameter parameter : member.header.parameters) {
109
-				methodWriter.nameParameter(0, parameter.name);
110
-				methodWriter.nameVariable(javaModule.getParameterInfo(parameter).index, parameter.name, methodStart, methodEnd, context.getType(parameter.type));
140
+
141
+			for (TypeParameter typeParameter : typeParameters) {
142
+				methodWriter.nameParameter(0, "typeOf" + typeParameter.name);
143
+				methodWriter.nameVariable(javaModule.getTypeParameterInfo(typeParameter).parameterIndex, "typeOf" + typeParameter.name, methodStart, methodEnd, Type.getType(Class.class));
111 144
 			}
112 145
 		}
113 146
 
147
+		for (TypeParameter typeParameter : member.header.typeParameters) {
148
+			methodWriter.nameParameter(0, "typeOf" + typeParameter.name);
149
+			methodWriter.nameVariable(javaModule.getTypeParameterInfo(typeParameter).parameterIndex, "typeOf" + typeParameter.name, methodStart, methodEnd, Type.getType(Class.class));
150
+		}
151
+
152
+		for (final FunctionParameter parameter : member.header.parameters) {
153
+			methodWriter.nameParameter(0, parameter.name);
154
+			methodWriter.nameVariable(javaModule.getParameterInfo(parameter).index, parameter.name, methodStart, methodEnd, context.getType(parameter.type));
155
+		}
156
+
114 157
 
115 158
 		{
116 159
 			final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
@@ -126,21 +169,173 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
126 169
 
127 170
 	@Override
128 171
 	public Void visitGetter(GetterMember member) {
172
+		final boolean isStatic = member.isStatic();
173
+		final StoredType returnType = member.getType();
174
+		final String descriptor;
175
+		final String signature;
176
+
177
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
178
+		expandedClass.type.extractTypeParameters(typeParameters);
179
+		{
180
+
181
+			final String descMiddle, signatureMiddle, signatureStart;
182
+			if (typeParameters.isEmpty()) {
183
+				descMiddle = signatureMiddle = signatureStart = "";
184
+			} else {
185
+				final StringBuilder descMiddleBuilder = new StringBuilder();
186
+				final StringBuilder signatureMiddleBuilder = new StringBuilder();
187
+				final StringBuilder signatureStartBuilder = new StringBuilder("<");
188
+
189
+				for (TypeParameter typeParameter : typeParameters) {
190
+					descMiddleBuilder.append("Ljava/lang/Class;");
191
+					signatureMiddleBuilder.append("Ljava/lang/Class<T").append(typeParameter.name).append(";>;");
192
+					signatureStartBuilder.append(typeParameter.name).append(":Ljava/lang/Object;");
193
+				}
194
+
195
+				descMiddle = descMiddleBuilder.toString();
196
+				signatureMiddle = signatureMiddleBuilder.toString();
197
+				signatureStart = signatureStartBuilder.append(">").toString();
198
+			}
199
+
200
+
201
+			if (isStatic) {
202
+				descriptor = "(" + descMiddle + ")" + context.getDescriptor(returnType);
203
+				signature = signatureStart + "(" + signatureMiddle + ")" + context.getSignature(returnType);
204
+			} else {
205
+				descriptor = "(" + context.getDescriptor(expandedClass) + descMiddle + ")" + context.getDescriptor(returnType);
206
+				signature = signatureStart + "(" + context.getSignature(expandedClass) + signatureMiddle + ")" + context
207
+						.getSignature(returnType);
208
+			}
209
+		}
210
+
211
+		final Label methodStart = new Label();
212
+		final Label methodEnd = new Label();
213
+
214
+		final JavaMethod method = context.getJavaMethod(member);
215
+		final JavaWriter methodWriter = new JavaWriter(member.position, this.writer, true, method, definition, true, signature, descriptor, new String[0]);
216
+
217
+		methodWriter.label(methodStart);
218
+
219
+		if (!isStatic) {
220
+			methodWriter.nameVariable(0, "expandedObj", methodStart, methodEnd, context.getType(this.expandedClass));
221
+			methodWriter.nameParameter(0, "expandedObj");
222
+		}
223
+
224
+		int i = isStatic ? 0 : 1;
225
+		for (TypeParameter typeParameter : typeParameters) {
226
+			final String name = "typeOf" + typeParameter.name;
227
+			methodWriter.nameVariable(i, name, methodStart, methodEnd, Type.getType(Class.class));
228
+			methodWriter.nameParameter(0, name);
229
+		}
230
+
231
+		{
232
+			final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
233
+			statementVisitor.start();
234
+			member.body.accept(statementVisitor);
235
+			methodWriter.label(methodEnd);
236
+			statementVisitor.end();
237
+		}
238
+
129 239
 		return null;
130 240
 	}
131 241
 
132 242
 	@Override
133 243
 	public Void visitSetter(SetterMember member) {
244
+		final boolean isStatic = member.isStatic();
245
+		final StoredType setterType = member.parameter.type;
246
+
247
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
248
+		expandedClass.type.extractTypeParameters(typeParameters);
249
+		CompilerUtils.tagMethodParameters(context, javaModule, member.getHeader(), isStatic, typeParameters);
250
+		setterType.type.extractTypeParameters(typeParameters);
251
+
252
+
253
+		final String signature = context.getMethodSignatureExpansion(member.getHeader(), expandedClass);
254
+		final String description = context.getMethodDescriptorExpansion(member.getHeader(), expandedClass);
255
+
256
+		final Label methodStart = new Label();
257
+		final Label methodEnd = new Label();
258
+
259
+		final JavaMethod javaMethod = context.getJavaMethod(member);
260
+		final JavaWriter methodWriter = new JavaWriter(member.position, writer, true, javaMethod, member.definition, true, signature, description, new String[0]);
261
+
262
+
263
+		methodWriter.label(methodStart);
264
+		if (!isStatic) {
265
+			methodWriter.nameVariable(0, "expandedObj", methodStart, methodEnd, context.getType(this.expandedClass));
266
+			methodWriter.nameParameter(0, "expandedObj");
267
+		}
268
+
269
+		int i = isStatic ? 0 : 1;
270
+		for (TypeParameter typeParameter : typeParameters) {
271
+			final String name = "typeOf" + typeParameter.name;
272
+			methodWriter.nameVariable(i, name, methodStart, methodEnd, Type.getType(Class.class));
273
+			methodWriter.nameParameter(0, name);
274
+			i++;
275
+		}
276
+
277
+		//in script you use $ but the parameter is named "value", which to choose?
278
+		//final String name = member.parameter.name;
279
+		final String name = "$";
280
+		methodWriter.nameVariable(i, name, methodStart, methodEnd, context.getType(setterType));
281
+		methodWriter.nameParameter(0, name);
282
+
283
+		javaModule.setParameterInfo(member.parameter, new JavaParameterInfo(i, context.getDescriptor(setterType)));
284
+
285
+		final JavaStatementVisitor javaStatementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
286
+		javaStatementVisitor.start();
287
+		member.body.accept(javaStatementVisitor);
288
+		javaStatementVisitor.end();
289
+		methodWriter.label(methodEnd);
290
+
134 291
 		return null;
135 292
 	}
136 293
 
137 294
 	@Override
138 295
 	public Void visitOperator(OperatorMember member) {
139
-		return null;
296
+		final JavaMethod javaMethod = context.getJavaMethod(member);
297
+		final MethodMember methodMember = new MethodMember(member.position, member.definition, member.getEffectiveModifiers(), javaMethod.name, member.header, member.builtin);
298
+		methodMember.body = member.body;
299
+		methodMember.annotations = member.annotations;
300
+		javaModule.setMethodInfo(methodMember, javaMethod);
301
+
302
+		return methodMember.accept(this);
140 303
 	}
141 304
 
142 305
 	@Override
143 306
 	public Void visitCaster(CasterMember member) {
307
+
308
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
309
+		expandedClass.type.extractTypeParameters(typeParameters);
310
+
311
+		CompilerUtils.tagMethodParameters(context, javaModule, member.getHeader(), false, typeParameters);
312
+		member.toType.type.extractTypeParameters(typeParameters);
313
+
314
+		final String methodSignature = context.getMethodSignatureExpansion(member.getHeader(), expandedClass);
315
+		final String methodDescriptor = context.getMethodDescriptorExpansion(member.getHeader(), expandedClass);
316
+
317
+		final Label methodStart = new Label();
318
+		final Label methodEnd = new Label();
319
+
320
+		final JavaMethod javaMethod = context.getJavaMethod(member);
321
+		final JavaWriter methodWriter = new JavaWriter(member.position, writer, true, javaMethod, member.definition, true, methodSignature, methodDescriptor, new String[0]);
322
+
323
+		methodWriter.label(methodStart);
324
+		methodWriter.nameVariable(0, "expandedObj", methodStart, methodEnd, context.getType(this.expandedClass));
325
+		methodWriter.nameParameter(0, "expandedObj");
326
+
327
+		int i = 1;
328
+		for (TypeParameter typeParameter : typeParameters) {
329
+			final String name = "typeOf" + typeParameter.name;
330
+			methodWriter.nameVariable(i, name, methodStart, methodEnd, Type.getType(Class.class));
331
+			methodWriter.nameParameter(0, name);
332
+		}
333
+
334
+		final JavaStatementVisitor javaStatementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
335
+		javaStatementVisitor.start();
336
+		member.body.accept(javaStatementVisitor);
337
+		javaStatementVisitor.end();
338
+		methodWriter.label(methodEnd);
144 339
 		return null;
145 340
 	}
146 341
 
@@ -151,7 +346,14 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
151 346
 
152 347
 	@Override
153 348
 	public Void visitCaller(CallerMember member) {
154
-		return null;
349
+		//It's gonna be a method anyways, so why not reuse the code ^^
350
+		final JavaMethod javaMethod = context.getJavaMethod(member);
351
+		final MethodMember call = new MethodMember(member.position, member.definition, member.getEffectiveModifiers(), javaMethod.name, member.header, member.builtin);
352
+		call.body = member.body;
353
+		call.annotations = member.annotations;
354
+
355
+		javaModule.setMethodInfo(call, javaMethod);
356
+		return call.accept(this);
155 357
 	}
156 358
 
157 359
 	@Override

+ 128
- 8
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaMemberVisitor.java View File

@@ -7,18 +7,20 @@ import org.objectweb.asm.Type;
7 7
 import org.openzen.zenscript.codemodel.FunctionParameter;
8 8
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
9 9
 import org.openzen.zenscript.codemodel.Modifiers;
10
+import org.openzen.zenscript.codemodel.annotations.NativeTag;
10 11
 import org.openzen.zenscript.codemodel.definition.EnumDefinition;
11 12
 import org.openzen.zenscript.codemodel.expression.Expression;
13
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
12 14
 import org.openzen.zenscript.codemodel.member.*;
15
+import org.openzen.zenscript.codemodel.type.StoredType;
13 16
 import org.openzen.zenscript.javabytecode.compiler.*;
14 17
 
18
+import java.util.ArrayList;
19
+import java.util.Arrays;
20
+import java.util.Collections;
15 21
 import java.util.List;
16 22
 import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
17
-import org.openzen.zenscript.javashared.JavaClass;
18
-import org.openzen.zenscript.javashared.JavaCompiledModule;
19
-import org.openzen.zenscript.javashared.JavaField;
20
-import org.openzen.zenscript.javashared.JavaImplementation;
21
-import org.openzen.zenscript.javashared.JavaMethod;
23
+import org.openzen.zenscript.javashared.*;
22 24
 
23 25
 public class JavaMemberVisitor implements MemberVisitor<Void> {
24 26
     private final ClassWriter writer;
@@ -66,6 +68,22 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
66 68
         final JavaWriter constructorWriter = new JavaWriter(member.position, writer, method, definition, context.getMethodSignature(member.header), null);
67 69
         constructorWriter.label(constructorStart);
68 70
         CompilerUtils.tagConstructorParameters(context, javaModule, member.definition, member.header, isEnum);
71
+        if(isEnum) {
72
+			constructorWriter.nameParameter(0, "name");
73
+			constructorWriter.nameParameter(0, "index");
74
+		}
75
+
76
+		for (TypeParameter typeParameter : definition.typeParameters) {
77
+			constructorWriter.nameParameter(0, "typeof" + typeParameter.name);
78
+			constructorWriter.nameVariable(
79
+					javaModule.getTypeParameterInfo(typeParameter).parameterIndex,
80
+					"typeOf" + typeParameter.name,
81
+					constructorStart,
82
+					constructorEnd,
83
+					Type.getType(Class.class)
84
+			);
85
+		}
86
+
69 87
         for (FunctionParameter parameter : member.header.parameters) {
70 88
             constructorWriter.nameVariable(
71 89
                     javaModule.getParameterInfo(parameter).index,
@@ -94,6 +112,17 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
94 112
 			}
95 113
         }
96 114
 
115
+		for (TypeParameter typeParameter : definition.typeParameters) {
116
+			final JavaTypeParameterInfo typeParameterInfo = javaModule.getTypeParameterInfo(typeParameter);
117
+			final JavaField field = typeParameterInfo.field;
118
+
119
+			//Init from Constructor
120
+			final int parameterIndex = typeParameterInfo.parameterIndex;
121
+			constructorWriter.loadObject(0);
122
+			constructorWriter.loadObject(parameterIndex);
123
+			constructorWriter.putField(field);
124
+		}
125
+
97 126
 		if (member.body != null) {
98 127
 			member.body.accept(statementVisitor);
99 128
 		}
@@ -129,7 +158,7 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
129 158
 
130 159
     @Override
131 160
     public Void visitMethod(MethodMember member) {
132
-        CompilerUtils.tagMethodParameters(context, javaModule, member.header, member.isStatic());
161
+        CompilerUtils.tagMethodParameters(context, javaModule, member.header, member.isStatic(), Collections.emptyList());
133 162
 
134 163
         final boolean isAbstract = member.body == null || Modifiers.isAbstract(member.getEffectiveModifiers());
135 164
         final JavaMethod method = context.getJavaMethod(member);
@@ -155,21 +184,105 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
155 184
 
156 185
 	@Override
157 186
 	public Void visitGetter(GetterMember member) {
187
+		if (member.hasTag(NativeTag.class)) {
188
+			return null;
189
+		}
190
+
191
+		final String descriptor = context.getMethodDescriptor(member.getHeader());
192
+		final String signature = context.getMethodSignature(member.getHeader(), true);
193
+
194
+		final Label methodStart = new Label();
195
+		final Label methodEnd = new Label();
196
+
197
+		final JavaMethod method = context.getJavaMethod(member);
198
+		final JavaWriter methodWriter = new JavaWriter(member.position, this.writer, true, method, definition, false, signature, descriptor, new String[0]);
199
+
200
+		methodWriter.label(methodStart);
201
+		final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
202
+		statementVisitor.start();
203
+		member.body.accept(statementVisitor);
204
+		methodWriter.label(methodEnd);
205
+		statementVisitor.end();
206
+
158 207
 		return null;
159 208
 	}
160 209
 
161 210
 	@Override
162 211
 	public Void visitSetter(SetterMember member) {
212
+		final String signature = context.getMethodSignature(member.getHeader());
213
+		final String description = context.getMethodDescriptor(member.getHeader());
214
+
215
+		final Label methodStart = new Label();
216
+		final Label methodEnd = new Label();
217
+
218
+		final JavaMethod javaMethod = context.getJavaMethod(member);
219
+		final JavaWriter methodWriter = new JavaWriter(member.position, writer, true, javaMethod, member.definition, false, signature, description, new String[0]);
220
+		methodWriter.label(methodStart);
221
+
222
+		//in script you use $ but the parameter is named "value", which to choose?
223
+		//final String name = member.parameter.name;
224
+		final String name = "$";
225
+		methodWriter.nameVariable(1, name, methodStart, methodEnd, context.getType(member.getType()));
226
+		methodWriter.nameParameter(0, name);
227
+
228
+		javaModule.setParameterInfo(member.parameter, new JavaParameterInfo(1, context.getDescriptor(member.getType())));
229
+
230
+		final JavaStatementVisitor javaStatementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
231
+		javaStatementVisitor.start();
232
+		member.body.accept(javaStatementVisitor);
233
+		javaStatementVisitor.end();
234
+		methodWriter.label(methodEnd);
235
+
163 236
 		return null;
164 237
 	}
165 238
 
166 239
 	@Override
167 240
 	public Void visitOperator(OperatorMember member) {
168
-		return null;
241
+
242
+		final JavaMethod javaMethod = context.getJavaMethod(member);
243
+		final MethodMember methodMember = new MethodMember(member.position, member.definition, member.getEffectiveModifiers(), javaMethod.name, member.header, member.builtin);
244
+		methodMember.body = member.body;
245
+		methodMember.annotations = member.annotations;
246
+		javaModule.setMethodInfo(methodMember, javaMethod);
247
+
248
+		return methodMember.accept(this);
169 249
 	}
170 250
 
171 251
 	@Override
172 252
 	public Void visitCaster(CasterMember member) {
253
+		final JavaMethod javaMethod = context.getJavaMethod(member);
254
+		if(javaMethod == null || !javaMethod.compile) {
255
+			return null;
256
+		}
257
+
258
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>(Arrays.asList(this.definition.typeParameters));
259
+
260
+		CompilerUtils.tagMethodParameters(context, javaModule, member.getHeader(), false, typeParameters);
261
+		member.toType.type.extractTypeParameters(typeParameters);
262
+
263
+		final String methodSignature = context.getMethodSignature(member.getHeader());
264
+		final String methodDescriptor = context.getMethodDescriptor(member.getHeader());
265
+
266
+		final Label methodStart = new Label();
267
+		final Label methodEnd = new Label();
268
+
269
+
270
+		final JavaWriter methodWriter = new JavaWriter(member.position, writer, true, javaMethod, member.definition, false, methodSignature, methodDescriptor, new String[0]);
271
+
272
+		methodWriter.label(methodStart);
273
+
274
+		int i = 1;
275
+		for (TypeParameter typeParameter : typeParameters) {
276
+			final String name = "typeOf" + typeParameter.name;
277
+			methodWriter.nameVariable(i, name, methodStart, methodEnd, Type.getType(Class.class));
278
+			methodWriter.nameParameter(0, name);
279
+		}
280
+
281
+		final JavaStatementVisitor javaStatementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
282
+		javaStatementVisitor.start();
283
+		member.body.accept(javaStatementVisitor);
284
+		javaStatementVisitor.end();
285
+		methodWriter.label(methodEnd);
173 286
 		return null;
174 287
 	}
175 288
 
@@ -180,7 +293,14 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
180 293
 
181 294
 	@Override
182 295
 	public Void visitCaller(CallerMember member) {
183
-		return null;
296
+		//It's gonna be a method anyways, so why not reuse the code ^^
297
+		final JavaMethod javaMethod = context.getJavaMethod(member);
298
+		final MethodMember call = new MethodMember(member.position, member.definition, member.getEffectiveModifiers(), javaMethod.name, member.header, member.builtin);
299
+		call.body = member.body;
300
+		call.annotations = member.annotations;
301
+
302
+		javaModule.setMethodInfo(call, javaMethod);
303
+		return call.accept(this);
184 304
 	}
185 305
 
186 306
 	@Override

+ 33
- 4
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaContext.java View File

@@ -15,9 +15,11 @@ import org.openzen.zenscript.codemodel.FunctionParameter;
15 15
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
16 16
 import org.openzen.zenscript.codemodel.Modifiers;
17 17
 import org.openzen.zenscript.codemodel.Module;
18
+import org.openzen.zenscript.codemodel.definition.EnumDefinition;
18 19
 import org.openzen.zenscript.codemodel.definition.VariantDefinition;
19 20
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
20 21
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
22
+import org.openzen.zenscript.codemodel.member.DefinitionMember;
21 23
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
22 24
 import org.openzen.zenscript.codemodel.member.ImplementationMember;
23 25
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
@@ -125,7 +127,11 @@ public abstract class JavaContext {
125 127
 	public abstract String getDescriptor(TypeID type);
126 128
 	
127 129
 	public abstract String getDescriptor(StoredType type);
128
-	
130
+
131
+	public String getSignature(StoredType type) {
132
+		return new JavaTypeGenericVisitor(this).getGenericSignature(type);
133
+	}
134
+
129 135
 	public void addModule(Module module, JavaCompiledModule target) {
130 136
 		modules.put(module, target);
131 137
 
@@ -225,12 +231,27 @@ public abstract class JavaContext {
225 231
 	}
226 232
 
227 233
 	public String getMethodDescriptorExpansion(FunctionHeader header, StoredType expandedType) {
228
-		return getMethodDescriptor(header, false, getDescriptor(expandedType));
234
+		StringBuilder startBuilder = new StringBuilder(getDescriptor(expandedType));
235
+		final List<TypeParameter> typeParameters = new ArrayList<>();
236
+		expandedType.type.extractTypeParameters(typeParameters);
237
+		for (TypeParameter typeParameter : typeParameters) {
238
+			startBuilder.append("Ljava/lang/Class;");
239
+		}
240
+
241
+		return getMethodDescriptor(header, false, startBuilder.toString());
242
+	}
243
+
244
+	public String getMethodSignatureExpansion(FunctionHeader header, StoredType expandedClass) {
245
+		return new JavaTypeGenericVisitor(this).getMethodSignatureExpansion(header, expandedClass);
229 246
 	}
230 247
 	
231 248
     public String getMethodSignature(FunctionHeader header) {
232
-        return new JavaTypeGenericVisitor(this).getGenericMethodSignature(header);
249
+        return getMethodSignature(header, true);
233 250
     }
251
+
252
+    public String getMethodSignature(FunctionHeader header, boolean withGenerics) {
253
+		return new JavaTypeGenericVisitor(this).getGenericMethodSignature(header, withGenerics);
254
+	}
234 255
 	
235 256
 	public String getEnumConstructorDescriptor(FunctionHeader header) {
236 257
 		return getMethodDescriptor(header, true, "");
@@ -351,7 +372,7 @@ public abstract class JavaContext {
351 372
 	 *                        Can be null or an empty string if this is not an expansion method header
352 373
 	 * @return Method descriptor {@code (<LClass;*No.TypeParameters><LString;I if enum><expandedType><headerTypes>)<retType> }
353 374
 	 */
354
-	private String getMethodDescriptor(FunctionHeader header, boolean isEnumConstructor, String expandedType) {
375
+	public String getMethodDescriptor(FunctionHeader header, boolean isEnumConstructor, String expandedType) {
355 376
         StringBuilder descBuilder = new StringBuilder("(");
356 377
 		for (int i = 0; i < header.getNumberOfTypeParameters(); i++)
357 378
 			descBuilder.append("Ljava/lang/Class;");
@@ -370,4 +391,12 @@ public abstract class JavaContext {
370 391
         descBuilder.append(getDescriptor(header.getReturnType()));
371 392
         return descBuilder.toString();
372 393
     }
394
+
395
+	public String getMethodDescriptorConstructor(FunctionHeader header, DefinitionMember member) {
396
+		StringBuilder startBuilder = new StringBuilder();
397
+		for (TypeParameter typeParameter : member.definition.typeParameters) {
398
+			startBuilder.append("Ljava/lang/Class;");
399
+		}
400
+		return getMethodDescriptor(header, member.definition instanceof EnumDefinition, startBuilder.toString());
401
+	}
373 402
 }

+ 6
- 1
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaField.java View File

@@ -13,12 +13,17 @@ public class JavaField {
13 13
 	public final JavaClass cls;
14 14
 	public final String name;
15 15
 	public final String descriptor;
16
-	public final String signature = null; // TODO: calculate signature too
16
+	public final String signature; // TODO: calculate signature too
17 17
 	
18 18
 	public JavaField(JavaClass cls, String name, String descriptor) {
19
+		this(cls, name, descriptor, null);
20
+	}
21
+
22
+	public JavaField(JavaClass cls, String name, String descriptor, String signature) {
19 23
 		this.cls = cls;
20 24
 		this.name = name;
21 25
 		this.descriptor = descriptor;
26
+		this.signature = signature;
22 27
 	}
23 28
 	
24 29
 	public String getMapping(JavaClass definition) {

+ 85
- 3
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaTypeGenericVisitor.java View File

@@ -4,7 +4,10 @@ import org.openzen.zenscript.codemodel.FunctionHeader;
4 4
 import org.openzen.zenscript.codemodel.FunctionParameter;
5 5
 import org.openzen.zenscript.codemodel.generic.*;
6 6
 import org.openzen.zenscript.codemodel.type.*;
7
+import org.openzen.zenscript.codemodel.type.storage.ValueStorageTag;
7 8
 
9
+import java.util.ArrayList;
10
+import java.util.Arrays;
8 11
 import java.util.Collection;
9 12
 
10 13
 public class JavaTypeGenericVisitor implements TypeVisitorWithContext<StoredType, String, RuntimeException> {
@@ -59,6 +62,34 @@ public class JavaTypeGenericVisitor implements TypeVisitorWithContext<StoredType
59 62
 				getGenericSignature(header.getReturnType());
60 63
 	}
61 64
 
65
+	public String getGenericMethodSignature(FunctionHeader header, boolean addGenerics) {
66
+		final StringBuilder sb = new StringBuilder();
67
+		final boolean doGenerics = addGenerics && header.typeParameters.length > 0;
68
+
69
+		if(doGenerics) {
70
+			sb.append("<");
71
+			for (TypeParameter typeParameter : header.typeParameters) {
72
+				//TODO: Eventually replace with upper bound
73
+				sb.append(typeParameter.name).append(":").append("Ljava/lang/Object;");
74
+			}
75
+			sb.append(">");
76
+		}
77
+
78
+
79
+		sb.append("(");
80
+		if(doGenerics) {
81
+			for (TypeParameter typeParameter : header.typeParameters) {
82
+				//TODO: Eventually replace with -TT; or +TT; for "? super T" and "? extends T"
83
+				sb.append("Ljava/lang/Class<T").append(typeParameter.name).append(";>;");
84
+			}
85
+		}
86
+
87
+		sb.append(getGenericSignature(header.parameters));
88
+		sb.append(")");
89
+		sb.append(getGenericSignature(header.getReturnType()));
90
+		return sb.toString();
91
+	}
92
+
62 93
 
63 94
 	public String getGenericBounds(Collection<TypeParameterBound> collection) {
64 95
 		if (collection == null)
@@ -93,12 +124,17 @@ public class JavaTypeGenericVisitor implements TypeVisitorWithContext<StoredType
93 124
 
94 125
 	@Override
95 126
 	public String visitArray(StoredType context, ArrayTypeID array) {
96
-		return this.context.getDescriptor(array);
127
+		final char[] dim = new char[array.dimension];
128
+		Arrays.fill(dim, '[');
129
+		return new String(dim) + this.context.getSignature(array.elementType);
97 130
 	}
98 131
 
99 132
 	@Override
100 133
 	public String visitAssoc(StoredType context, AssocTypeID assoc) {
101
-		return this.context.getDescriptor(assoc);
134
+		return "Ljava/util/Map<"
135
+				+ assoc.keyType.type.accept(context, this)
136
+				+ assoc.valueType.type.accept(context, this)
137
+				+ ">;";
102 138
 	}
103 139
 
104 140
 	@Override
@@ -113,7 +149,21 @@ public class JavaTypeGenericVisitor implements TypeVisitorWithContext<StoredType
113 149
 
114 150
 	@Override
115 151
 	public String visitFunction(StoredType context, FunctionTypeID function) {
116
-		return this.context.getDescriptor(function);
152
+		final JavaSynthesizedFunctionInstance function1 = this.context.getFunction(function);
153
+		if(function1.typeArguments == null || function1.typeArguments.length == 0) {
154
+			return this.context.getDescriptor(function);
155
+		}
156
+
157
+		StringBuilder sb = new StringBuilder("L").append(function1.getCls().internalName).append("<");
158
+		for (TypeID typeArgument : function1.typeArguments) {
159
+			final String n = typeArgument instanceof GenericTypeID
160
+					? ((GenericTypeID) typeArgument).parameter.name
161
+					: "Ljava/lang/Object"; //Can latter even happen?
162
+
163
+			sb.append("T").append(n).append(";");
164
+		}
165
+
166
+		return sb.append(">;").toString();
117 167
 	}
118 168
 
119 169
 	@Override
@@ -146,4 +196,36 @@ public class JavaTypeGenericVisitor implements TypeVisitorWithContext<StoredType
146 196
 	public String visitOptional(StoredType context, OptionalTypeID type) {
147 197
 		return type.baseType.accept(context, this);
148 198
 	}
199
+
200
+	public String getMethodSignatureExpansion(FunctionHeader header, StoredType expandedClass) {
201
+		final StringBuilder stringBuilder = new StringBuilder();
202
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
203
+		expandedClass.type.extractTypeParameters(typeParameters);
204
+		for (TypeParameter typeParameter : header.typeParameters) {
205
+			if(!typeParameters.contains(typeParameter)){
206
+				typeParameters.add(typeParameter);
207
+			}
208
+		}
209
+
210
+		if(typeParameters.size() != 0) {
211
+			stringBuilder.append("<");
212
+			for (TypeParameter typeParameter : typeParameters) {
213
+				stringBuilder.append(typeParameter.name);
214
+				stringBuilder.append(":Ljava/lang/Object;");
215
+			}
216
+			stringBuilder.append(">");
217
+		}
218
+		stringBuilder.append("(");
219
+		stringBuilder.append(context.getSignature(expandedClass));
220
+		for (TypeParameter typeParameter : typeParameters) {
221
+			stringBuilder.append("Ljava/lang/Class<T");
222
+			stringBuilder.append(typeParameter.name);
223
+			stringBuilder.append(";>;");
224
+		}
225
+		stringBuilder.append(getGenericSignature(header.parameters));
226
+		stringBuilder.append(")");
227
+		stringBuilder.append(context.getSignature(header.getReturnType()));
228
+
229
+		return stringBuilder.toString();
230
+	}
149 231
 }

+ 5
- 0
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaTypeParameterInfo.java View File

@@ -22,4 +22,9 @@ public class JavaTypeParameterInfo {
22 22
 		this.parameterIndex = -1;
23 23
 		this.field = field;
24 24
 	}
25
+
26
+	public JavaTypeParameterInfo(int parameterIndex, JavaField field) {
27
+		this.parameterIndex = parameterIndex;
28
+		this.field = field;
29
+	}
25 30
 }

+ 24
- 11
JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareClassMethodVisitor.java View File

@@ -76,13 +76,13 @@ public class JavaPrepareClassMethodVisitor implements MemberVisitor<Void> {
76 76
 			System.out.println("Class " + cls.fullName + " not empty because of const " + member.name);
77 77
 		
78 78
 		cls.empty = false;
79
-		module.setFieldInfo(member, new JavaField(cls, member.name, context.getDescriptor(member.getType())));
79
+		module.setFieldInfo(member, new JavaField(cls, member.name, context.getDescriptor(member.getType()), context.getSignature(member.getType())));
80 80
 		return null;
81 81
 	}
82 82
 	
83 83
 	@Override
84 84
 	public Void visitField(FieldMember member) {
85
-		JavaField field = new JavaField(cls, member.name, context.getDescriptor(member.getType()));
85
+		JavaField field = new JavaField(cls, member.name, context.getDescriptor(member.getType()), context.getSignature(member.getType()));
86 86
 		module.setFieldInfo(member, field);
87 87
 		if (member.hasAutoGetter()) {
88 88
 			visitGetter(member.autoGetter);
@@ -313,15 +313,28 @@ public class JavaPrepareClassMethodVisitor implements MemberVisitor<Void> {
313 313
 					header.getReturnType().type instanceof GenericTypeID,
314 314
 					header.useTypeParameters());
315 315
 		} else if (method == null) {
316
-			method = new JavaMethod(
317
-					cls,
318
-					getKind(member),
319
-					name,
320
-					true,
321
-					context.getMethodDescriptor(header),
322
-					modifiers | JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
323
-					header.getReturnType().type instanceof GenericTypeID,
324
-					header.useTypeParameters());
316
+			if(member instanceof ConstructorMember) {
317
+				method = new JavaMethod(
318
+						cls,
319
+						getKind(member),
320
+						name,
321
+						true,
322
+						context.getMethodDescriptorConstructor(header, member),
323
+						modifiers | JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
324
+						false,
325
+						header.useTypeParameters()
326
+				);
327
+			} else {
328
+				method = new JavaMethod(
329
+						cls,
330
+						getKind(member),
331
+						name,
332
+						true,
333
+						context.getMethodDescriptor(header),
334
+						modifiers | JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
335
+						header.getReturnType().type instanceof GenericTypeID,
336
+						header.useTypeParameters());
337
+			}
325 338
 		}
326 339
 		
327 340
 		if (method.compile && member.getBuiltin() != BuiltinID.CLASS_DEFAULT_CONSTRUCTOR) {

+ 30
- 16
JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareExpansionMethodVisitor.java View File

@@ -61,7 +61,7 @@ public class JavaPrepareExpansionMethodVisitor implements MemberVisitor<Void> {
61 61
 	
62 62
 	@Override
63 63
 	public Void visitConst(ConstMember member) {
64
-		JavaField field = new JavaField(cls, member.name, context.getDescriptor(member.getType()));
64
+		JavaField field = new JavaField(cls, member.name, context.getDescriptor(member.getType()), context.getSignature(member.getType()));
65 65
 		module.setFieldInfo(member, field);
66 66
 		
67 67
 		if (DEBUG_EMPTY && cls.empty)
@@ -74,7 +74,7 @@ public class JavaPrepareExpansionMethodVisitor implements MemberVisitor<Void> {
74 74
 	@Override
75 75
 	public Void visitField(FieldMember member) {
76 76
 		// TODO: expansion fields
77
-		JavaField field = new JavaField(cls, member.name, context.getDescriptor(member.getType()));
77
+		JavaField field = new JavaField(cls, member.name, context.getDescriptor(member.getType()), context.getSignature(member.getType()));
78 78
 		module.setFieldInfo(member, field);
79 79
 		
80 80
 		if (member.hasAutoGetter() || member.hasAutoSetter())
@@ -168,22 +168,36 @@ public class JavaPrepareExpansionMethodVisitor implements MemberVisitor<Void> {
168 168
 		if (nativeTag != null && nativeClass != null)
169 169
 			method = nativeClass.getMethod(nativeTag.value);
170 170
 		if (method == null) {
171
-			final JavaMethod.Kind kind = getKind(member);
172
-			final String descriptor;
173
-			if (kind == JavaMethod.Kind.EXPANSION && member.definition instanceof ExpansionDefinition) {
174
-				descriptor = context.getMethodDescriptorExpansion(header, ((ExpansionDefinition) member.definition).target);
171
+
172
+			if(member instanceof ConstructorMember) {
173
+				method = new JavaMethod(
174
+						cls,
175
+						getKind(member),
176
+						name,
177
+						true,
178
+						context.getMethodDescriptorConstructor(header, member),
179
+						JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
180
+						false,
181
+						header.useTypeParameters()
182
+				);
175 183
 			} else {
176
-				descriptor = context.getMethodDescriptor(header);
184
+				final JavaMethod.Kind kind = getKind(member);
185
+				final String descriptor;
186
+				if (kind == JavaMethod.Kind.EXPANSION && member.definition instanceof ExpansionDefinition) {
187
+					descriptor = context.getMethodDescriptorExpansion(header, ((ExpansionDefinition) member.definition).target);
188
+				} else {
189
+					descriptor = context.getMethodDescriptor(header);
190
+				}
191
+				method = new JavaMethod(
192
+						cls,
193
+						kind,
194
+						name,
195
+						true,
196
+						descriptor,
197
+						JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
198
+						header.getReturnType().type instanceof GenericTypeID,
199
+						header.useTypeParameters());
177 200
 			}
178
-			method = new JavaMethod(
179
-					cls,
180
-					kind,
181
-					name,
182
-					true,
183
-					descriptor,
184
-					JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
185
-					header.getReturnType().type instanceof GenericTypeID,
186
-					header.useTypeParameters());
187 201
 		}
188 202
 		
189 203
 		if (method.compile) {

Loading…
Cancel
Save