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,9 +389,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
389 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 398
 				typeParameters = parameters.stream().distinct().collect(Collectors.toList());
397 399
 			}
@@ -1307,6 +1309,15 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1307 1309
 	public Void visitCast(CastExpression expression) {
1308 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 1321
 		BuiltinID builtin = expression.member.member.builtin;
1311 1322
 		if (builtin == null) {
1312 1323
 			if (!checkAndExecuteMethodInfo(expression.member, expression.type, expression))
@@ -1982,12 +1993,12 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1982 1993
 				final Method functionalInterfaceMethod = ((JavaFunctionalInterfaceStorageTag) actualStorage).functionalInterfaceMethod;
1983 1994
 				
1984 1995
 				//Should be the same, should it not?
1985
-				signature = context.getMethodSignature(expression.header);
1996
+				signature = context.getMethodSignature(expression.header, true);
1986 1997
 				descriptor = context.getMethodDescriptor(expression.header);
1987 1998
 				interfaces = new String[]{Type.getInternalName(functionalInterfaceMethod.getDeclaringClass())};
1988 1999
 			} else {
1989 2000
 				//Normal way, no casting to functional interface
1990
-				signature = context.getMethodSignature(expression.header);
2001
+				signature = context.getMethodSignature(expression.header, true);
1991 2002
 				descriptor = context.getMethodDescriptor(expression.header);
1992 2003
 				interfaces = new String[]{context.getInternalName(new FunctionTypeID(null, expression.header).stored(UniqueStorageTag.INSTANCE))};
1993 2004
 			}
@@ -2021,7 +2032,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
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 2036
 			if(expression.header.getReturnType().type != BasicTypeID.VOID) {
2026 2037
 				bridgeWriter.returnType(context.getType(expression.header.getReturnType()));
2027 2038
 			}
@@ -4266,8 +4277,8 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
4266 4277
 
4267 4278
 		//Make sure that method results are popped if ZC thinks its a void but it actually is not.
4268 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 4282
 			getJavaWriter().pop(isLarge);
4272 4283
 		}
4273 4284
 
@@ -4332,6 +4343,17 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
4332 4343
 
4333 4344
 	@Override
4334 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 4357
 		return null;
4336 4358
 	}
4337 4359
 

+ 6
- 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,11 @@ public class JavaNonPushingExpressionVisitor implements ExpressionVisitor<Void>
624 625
 	@Override
625 626
 	public Void visitSetter(SetterExpression expression) {
626 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 633
 		expression.value.accept(original);
628 634
 		original.checkAndExecuteMethodInfo(expression.setter, expression.type, expression);
629 635
 		return null;

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

@@ -211,6 +211,13 @@ public class JavaWriter {
211 211
 		
212 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 222
 	public void dup() {
216 223
 		if (debug)

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

@@ -15,6 +15,7 @@ import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
15 15
 import org.openzen.zenscript.javashared.JavaCompiledModule;
16 16
 import org.openzen.zenscript.javashared.JavaField;
17 17
 import org.openzen.zenscript.javashared.JavaMethod;
18
+import org.openzen.zenscript.javashared.JavaParameterInfo;
18 19
 
19 20
 import java.util.ArrayList;
20 21
 import java.util.stream.Collectors;
@@ -175,32 +176,36 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
175 176
 
176 177
 		final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
177 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 211
 		final Label methodStart = new Label();
@@ -236,16 +241,101 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
236 241
 
237 242
 	@Override
238 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 291
 		return null;
240 292
 	}
241 293
 
242 294
 	@Override
243 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 305
 	@Override
248 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 339
 		return null;
250 340
 	}
251 341
 
@@ -256,7 +346,14 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
256 346
 
257 347
 	@Override
258 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 359
 	@Override

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

@@ -238,6 +238,10 @@ public abstract class JavaContext {
238 238
 
239 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 246
     public String getMethodSignature(FunctionHeader header) {
243 247
         return getMethodSignature(header, true);

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

@@ -6,6 +6,7 @@ import org.openzen.zenscript.codemodel.generic.*;
6 6
 import org.openzen.zenscript.codemodel.type.*;
7 7
 import org.openzen.zenscript.codemodel.type.storage.ValueStorageTag;
8 8
 
9
+import java.util.ArrayList;
9 10
 import java.util.Arrays;
10 11
 import java.util.Collection;
11 12
 
@@ -195,4 +196,36 @@ public class JavaTypeGenericVisitor implements TypeVisitorWithContext<StoredType
195 196
 	public String visitOptional(StoredType context, OptionalTypeID type) {
196 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