Browse Source

WIP: More work on Generics in Expansions

kindlich 4 years ago
parent
commit
1a3075532c
No known key found for this signature in database

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

389
 						Arrays.asList(expression.member.getTarget().definition.typeParameters)
389
 						Arrays.asList(expression.member.getTarget().definition.typeParameters)
390
 				);
390
 				);
391
 
391
 
392
-				expression.member.getOwnerType().type.extractTypeParameters(parameters);
393
-				for (FunctionParameter parameter : expression.instancedHeader.parameters) {
394
-					parameter.type.type.extractTypeParameters(parameters);
392
+				//expression.member.getOwnerType().type.extractTypeParameters(parameters);
393
+				for (TypeParameter typeParameter : expression.instancedHeader.typeParameters) {
394
+					if(!parameters.contains(typeParameter)) {
395
+						parameters.add(typeParameter);
396
+					}
395
 				}
397
 				}
396
 				typeParameters = parameters.stream().distinct().collect(Collectors.toList());
398
 				typeParameters = parameters.stream().distinct().collect(Collectors.toList());
397
 			}
399
 			}
1307
 	public Void visitCast(CastExpression expression) {
1309
 	public Void visitCast(CastExpression expression) {
1308
 		expression.target.accept(this);
1310
 		expression.target.accept(this);
1309
 
1311
 
1312
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>(Arrays.asList(expression.member.member.definition.typeParameters));
1313
+		//expression.member.type.type.extractTypeParameters(typeParameters);
1314
+		expression.member.toType.type.extractTypeParameters(typeParameters);
1315
+
1316
+		for (TypeParameter typeParameter : typeParameters) {
1317
+			javaWriter.aConstNull(); //Todo: Replace with actual Type
1318
+			javaWriter.checkCast("java/lang/Class");
1319
+		}
1320
+
1310
 		BuiltinID builtin = expression.member.member.builtin;
1321
 		BuiltinID builtin = expression.member.member.builtin;
1311
 		if (builtin == null) {
1322
 		if (builtin == null) {
1312
 			if (!checkAndExecuteMethodInfo(expression.member, expression.type, expression))
1323
 			if (!checkAndExecuteMethodInfo(expression.member, expression.type, expression))
1982
 				final Method functionalInterfaceMethod = ((JavaFunctionalInterfaceStorageTag) actualStorage).functionalInterfaceMethod;
1993
 				final Method functionalInterfaceMethod = ((JavaFunctionalInterfaceStorageTag) actualStorage).functionalInterfaceMethod;
1983
 				
1994
 				
1984
 				//Should be the same, should it not?
1995
 				//Should be the same, should it not?
1985
-				signature = context.getMethodSignature(expression.header);
1996
+				signature = context.getMethodSignature(expression.header, true);
1986
 				descriptor = context.getMethodDescriptor(expression.header);
1997
 				descriptor = context.getMethodDescriptor(expression.header);
1987
 				interfaces = new String[]{Type.getInternalName(functionalInterfaceMethod.getDeclaringClass())};
1998
 				interfaces = new String[]{Type.getInternalName(functionalInterfaceMethod.getDeclaringClass())};
1988
 			} else {
1999
 			} else {
1989
 				//Normal way, no casting to functional interface
2000
 				//Normal way, no casting to functional interface
1990
-				signature = context.getMethodSignature(expression.header);
2001
+				signature = context.getMethodSignature(expression.header, true);
1991
 				descriptor = context.getMethodDescriptor(expression.header);
2002
 				descriptor = context.getMethodDescriptor(expression.header);
1992
 				interfaces = new String[]{context.getInternalName(new FunctionTypeID(null, expression.header).stored(UniqueStorageTag.INSTANCE))};
2003
 				interfaces = new String[]{context.getInternalName(new FunctionTypeID(null, expression.header).stored(UniqueStorageTag.INSTANCE))};
1993
 			}
2004
 			}
2021
 				}
2032
 				}
2022
 			}
2033
 			}
2023
 			
2034
 			
2024
-			bridgeWriter.invokeVirtual(new JavaMethod(JavaClass.fromInternalName(className, JavaClass.Kind.CLASS), JavaMethod.Kind.INSTANCE, methodInfo.name, methodInfo.compile, signature, methodInfo.modifiers, methodInfo.genericResult));
2035
+			bridgeWriter.invokeVirtual(new JavaMethod(JavaClass.fromInternalName(className, JavaClass.Kind.CLASS), JavaMethod.Kind.INSTANCE, methodInfo.name, methodInfo.compile, descriptor, methodInfo.modifiers, methodInfo.genericResult));
2025
 			if(expression.header.getReturnType().type != BasicTypeID.VOID) {
2036
 			if(expression.header.getReturnType().type != BasicTypeID.VOID) {
2026
 				bridgeWriter.returnType(context.getType(expression.header.getReturnType()));
2037
 				bridgeWriter.returnType(context.getType(expression.header.getReturnType()));
2027
 			}
2038
 			}
4266
 
4277
 
4267
 		//Make sure that method results are popped if ZC thinks its a void but it actually is not.
4278
 		//Make sure that method results are popped if ZC thinks its a void but it actually is not.
4268
 		//Fixes an issue for List#add() returning void in ZC but Z in Java.
4279
 		//Fixes an issue for List#add() returning void in ZC but Z in Java.
4269
-		if(resultType.type == BasicTypeID.VOID && !methodInfo.descriptor.endsWith(")V")) {
4270
-			final boolean isLarge = methodInfo.descriptor.endsWith(")D") && methodInfo.descriptor.endsWith(")L");
4280
+		if(resultType.type == BasicTypeID.VOID && !methodInfo.descriptor.equals("") && !methodInfo.descriptor.endsWith(")V")) {
4281
+			final boolean isLarge = methodInfo.descriptor.endsWith(")D") && methodInfo.descriptor.endsWith(")J");
4271
 			getJavaWriter().pop(isLarge);
4282
 			getJavaWriter().pop(isLarge);
4272
 		}
4283
 		}
4273
 
4284
 
4332
 
4343
 
4333
 	@Override
4344
 	@Override
4334
 	public Void copyTo(CallExpression call) {
4345
 	public Void copyTo(CallExpression call) {
4346
+		//Copy this (source) to dest
4347
+		//              source.copyTo(dest, sourceOffset, destOffset, length)
4348
+		//=> System.arraycopy(source, sourceOffset, dest, destOffset, length);
4349
+		javaWriter.dup2X2();
4350
+		javaWriter.pop2();
4351
+		javaWriter.swap();
4352
+		javaWriter.dup2X2();
4353
+		javaWriter.pop2();
4354
+		final JavaClass system = JavaClass.fromInternalName("java/lang/System", JavaClass.Kind.CLASS);
4355
+		final JavaMethod javaMethod = JavaMethod.getStatic(system, "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V", JavaModifiers.PUBLIC);
4356
+		javaWriter.invokeStatic(javaMethod);
4335
 		return null;
4357
 		return null;
4336
 	}
4358
 	}
4337
 
4359
 

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

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

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

211
 		
211
 		
212
 		visitor.visitInsn(large ? POP2 : POP);
212
 		visitor.visitInsn(large ? POP2 : POP);
213
 	}
213
 	}
214
+
215
+	public void pop2() {
216
+		if(debug)
217
+			System.out.println("pop2");
218
+
219
+		visitor.visitInsn(POP2);
220
+	}
214
 	
221
 	
215
 	public void dup() {
222
 	public void dup() {
216
 		if (debug)
223
 		if (debug)

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

15
 import org.openzen.zenscript.javashared.JavaCompiledModule;
15
 import org.openzen.zenscript.javashared.JavaCompiledModule;
16
 import org.openzen.zenscript.javashared.JavaField;
16
 import org.openzen.zenscript.javashared.JavaField;
17
 import org.openzen.zenscript.javashared.JavaMethod;
17
 import org.openzen.zenscript.javashared.JavaMethod;
18
+import org.openzen.zenscript.javashared.JavaParameterInfo;
18
 
19
 
19
 import java.util.ArrayList;
20
 import java.util.ArrayList;
20
 import java.util.stream.Collectors;
21
 import java.util.stream.Collectors;
175
 
176
 
176
 		final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
177
 		final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
177
 		expandedClass.type.extractTypeParameters(typeParameters);
178
 		expandedClass.type.extractTypeParameters(typeParameters);
179
+		{
178
 
180
 
179
-		final String descMiddle, signatureMiddle, signatureStart;
180
-		if(typeParameters.isEmpty()) {
181
-			descMiddle = signatureMiddle = signatureStart = "";
182
-		} else {
183
-			final StringBuilder descMiddleBuilder = new StringBuilder();
184
-			final StringBuilder signatureMiddleBuilder = new StringBuilder();
185
-			final StringBuilder signatureStartBuilder = new StringBuilder("<");
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
+				}
186
 
194
 
187
-			for (TypeParameter typeParameter : typeParameters) {
188
-				descMiddleBuilder.append("Ljava/lang/Class;");
189
-				signatureMiddleBuilder.append("Ljava/lang/Class<T").append(typeParameter.name).append(";>;");
190
-				signatureStartBuilder.append(typeParameter.name).append(":Ljava/lang/Object;");
195
+				descMiddle = descMiddleBuilder.toString();
196
+				signatureMiddle = signatureMiddleBuilder.toString();
197
+				signatureStart = signatureStartBuilder.append(">").toString();
191
 			}
198
 			}
192
 
199
 
193
-			descMiddle = descMiddleBuilder.toString();
194
-			signatureMiddle = signatureMiddleBuilder.toString();
195
-			signatureStart = signatureStartBuilder.append(">").toString();
196
-		}
197
 
200
 
198
-		if (isStatic) {
199
-			descriptor = "(" + descMiddle + ")" + context.getDescriptor(returnType);
200
-			signature = signatureStart + "(" + signatureMiddle + ")" + context.getSignature(returnType);
201
-		} else {
202
-			descriptor = "(" + context.getDescriptor(expandedClass) + descMiddle + ")" + context.getDescriptor(returnType);
203
-			signature = signatureStart + "(" + context.getSignature(expandedClass) + signatureMiddle + ")" + context.getSignature(returnType);
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
+			}
204
 		}
209
 		}
205
 
210
 
206
 		final Label methodStart = new Label();
211
 		final Label methodStart = new Label();
236
 
241
 
237
 	@Override
242
 	@Override
238
 	public Void visitSetter(SetterMember member) {
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
+
239
 		return null;
291
 		return null;
240
 	}
292
 	}
241
 
293
 
242
 	@Override
294
 	@Override
243
 	public Void visitOperator(OperatorMember member) {
295
 	public Void visitOperator(OperatorMember member) {
244
-		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);
245
 	}
303
 	}
246
 
304
 
247
 	@Override
305
 	@Override
248
 	public Void visitCaster(CasterMember member) {
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);
249
 		return null;
339
 		return null;
250
 	}
340
 	}
251
 
341
 
256
 
346
 
257
 	@Override
347
 	@Override
258
 	public Void visitCaller(CallerMember member) {
348
 	public Void visitCaller(CallerMember member) {
259
-		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);
260
 	}
357
 	}
261
 
358
 
262
 	@Override
359
 	@Override

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

238
 
238
 
239
 		return getMethodDescriptor(header, false, startBuilder.toString());
239
 		return getMethodDescriptor(header, false, startBuilder.toString());
240
 	}
240
 	}
241
+
242
+	public String getMethodSignatureExpansion(FunctionHeader header, StoredType expandedClass) {
243
+		return new JavaTypeGenericVisitor(this).getMethodSignatureExpansion(header, expandedClass);
244
+	}
241
 	
245
 	
242
     public String getMethodSignature(FunctionHeader header) {
246
     public String getMethodSignature(FunctionHeader header) {
243
         return getMethodSignature(header, true);
247
         return getMethodSignature(header, true);

+ 33
- 0
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaTypeGenericVisitor.java View File

6
 import org.openzen.zenscript.codemodel.type.*;
6
 import org.openzen.zenscript.codemodel.type.*;
7
 import org.openzen.zenscript.codemodel.type.storage.ValueStorageTag;
7
 import org.openzen.zenscript.codemodel.type.storage.ValueStorageTag;
8
 
8
 
9
+import java.util.ArrayList;
9
 import java.util.Arrays;
10
 import java.util.Arrays;
10
 import java.util.Collection;
11
 import java.util.Collection;
11
 
12
 
195
 	public String visitOptional(StoredType context, OptionalTypeID type) {
196
 	public String visitOptional(StoredType context, OptionalTypeID type) {
196
 		return type.baseType.accept(context, this);
197
 		return type.baseType.accept(context, this);
197
 	}
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
+	}
198
 }
231
 }

Loading…
Cancel
Save