Browse Source

Merge remote-tracking branch 'kindlich/development' into development

# Conflicts:
#	JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaSynthesizedClassNamer.java
Stan Hebben 6 years ago
parent
commit
4572ccabb9

+ 2
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaBytecodeContext.java View File

8
 import org.objectweb.asm.ClassWriter;
8
 import org.objectweb.asm.ClassWriter;
9
 import org.objectweb.asm.Opcodes;
9
 import org.objectweb.asm.Opcodes;
10
 import org.objectweb.asm.Type;
10
 import org.objectweb.asm.Type;
11
+import org.openzen.zenscript.codemodel.FunctionHeader;
11
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
12
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
12
 import org.openzen.zenscript.codemodel.type.ITypeID;
13
 import org.openzen.zenscript.codemodel.type.ITypeID;
14
+import org.openzen.zenscript.javashared.JavaTypeGenericVisitor;
13
 import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
15
 import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
14
 import org.openzen.zenscript.javashared.JavaContext;
16
 import org.openzen.zenscript.javashared.JavaContext;
15
 import org.openzen.zenscript.javashared.JavaMethod;
17
 import org.openzen.zenscript.javashared.JavaMethod;

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

2
 
2
 
3
 import org.objectweb.asm.ClassWriter;
3
 import org.objectweb.asm.ClassWriter;
4
 
4
 
5
+import java.util.HashMap;
6
+import java.util.Map;
7
+
5
 public class JavaClassWriter extends ClassWriter {
8
 public class JavaClassWriter extends ClassWriter {
9
+
10
+	private static final Map<String, String> super_classes = new HashMap<>();
11
+
12
+	public static void registerSuperClass(String child, String superClass) {
13
+		super_classes.put(child, superClass);
14
+	}
15
+
16
+	public static Map<String, String> getSuper_classes() {
17
+		return super_classes;
18
+	}
19
+
6
 	public JavaClassWriter(int flags) {
20
 	public JavaClassWriter(int flags) {
7
 		super(flags);
21
 		super(flags);
8
 	}
22
 	}
23
+
24
+	@Override
25
+	protected String getCommonSuperClass(String type1, String type2) {
26
+
27
+		//FIXME big TODO, make this more efficient!!!
28
+		try {
29
+			return super.getCommonSuperClass(type1, type2);
30
+		} catch (Exception ignored){}
31
+
32
+
33
+		if(type1.equals(type2))
34
+			return type1;
35
+
36
+		String newType2 = type2;
37
+		while(super_classes.containsKey(newType2)){
38
+			newType2 = super_classes.get(newType2);
39
+			if(type1.equals(newType2))
40
+				return type1;
41
+		}
42
+
43
+		String newType1 = type1;
44
+		while(super_classes.containsKey(newType1)){
45
+			newType1 = super_classes.get(newType1);
46
+			if(type2.equals(newType1))
47
+				return type2;
48
+		}
49
+
50
+		return super_classes.containsKey(type1) ? getCommonSuperClass(super_classes.get(type1), type2) : super_classes.containsKey(type2) ? getCommonSuperClass(type1, super_classes.get(type2)) : "java/lang/Object";
51
+
52
+	}
53
+
54
+
9
 }
55
 }

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

373
 
373
 
374
 			if (!checkAndExecuteMethodInfo(expression.member, expression.type))
374
 			if (!checkAndExecuteMethodInfo(expression.member, expression.type))
375
 				throw new IllegalStateException("Call target has no method info!");
375
 				throw new IllegalStateException("Call target has no method info!");
376
+			//if (expression.member.getHeader().returnType != expression.type)
377
+
378
+			//TODO see if the types differ (e.g. if a generic method was invoked) and only cast then
379
+			if(expression.type != BasicTypeID.VOID)
380
+				javaWriter.checkCast(context.getInternalName(expression.type));
376
 			return null;
381
 			return null;
377
 		}
382
 		}
378
 
383
 
1622
 				context.getInternalName(expression.objectType),
1627
 				context.getInternalName(expression.objectType),
1623
 				"<init>",
1628
 				"<init>",
1624
 				context.getMethodDescriptor(expression.constructor.getHeader()));
1629
 				context.getMethodDescriptor(expression.constructor.getHeader()));
1625
-			
1630
+
1626
         CompilerUtils.writeDefaultFieldInitializers(context, javaWriter, javaWriter.forDefinition, false);
1631
         CompilerUtils.writeDefaultFieldInitializers(context, javaWriter, javaWriter.forDefinition, false);
1627
         return null;
1632
         return null;
1628
     }
1633
     }
1645
 		final String name = context.getLambdaCounter();
1650
 		final String name = context.getLambdaCounter();
1646
 
1651
 
1647
 		final JavaMethod methodInfo = JavaMethod.getNativeVirtual(javaWriter.method.cls, "accept", signature);
1652
 		final JavaMethod methodInfo = JavaMethod.getNativeVirtual(javaWriter.method.cls, "accept", signature);
1648
-		final ClassWriter lambdaCW = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
1653
+		final ClassWriter lambdaCW = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
1649
 		lambdaCW.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name, null, "java/lang/Object", new String[]{context.getInternalName(new FunctionTypeID(null, expression.header))});
1654
 		lambdaCW.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name, null, "java/lang/Object", new String[]{context.getInternalName(new FunctionTypeID(null, expression.header))});
1650
 		final JavaWriter functionWriter = new JavaWriter(lambdaCW, methodInfo, null, signature, null, "java/lang/Override");
1655
 		final JavaWriter functionWriter = new JavaWriter(lambdaCW, methodInfo, null, signature, null, "java/lang/Override");
1651
-		
1656
+
1652
 		javaWriter.newObject(name);
1657
 		javaWriter.newObject(name);
1653
 		javaWriter.dup();
1658
 		javaWriter.dup();
1654
 
1659
 
1666
 			constructorWriter.dup();
1671
 			constructorWriter.dup();
1667
 			Type type = context.getType(capture.type);
1672
 			Type type = context.getType(capture.type);
1668
 			lambdaCW.visitField(Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE, "captured" + ++i, type.getDescriptor(), null, null).visitEnd();
1673
 			lambdaCW.visitField(Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE, "captured" + ++i, type.getDescriptor(), null, null).visitEnd();
1669
-			
1674
+
1670
 			capture.accept(this);
1675
 			capture.accept(this);
1671
 
1676
 
1672
 			constructorWriter.load(type, i);
1677
 			constructorWriter.load(type, i);
1701
 				return null;
1706
 				return null;
1702
 			}
1707
 			}
1703
 		});
1708
 		});
1704
-		
1709
+
1705
 		expression.body.accept(CSV);
1710
 		expression.body.accept(CSV);
1706
-		
1711
+
1707
         functionWriter.ret();
1712
         functionWriter.ret();
1708
 		functionWriter.end();
1713
 		functionWriter.end();
1709
 		lambdaCW.visitEnd();
1714
 		lambdaCW.visitEnd();
2116
     public Void visitNew(NewExpression expression) {
2121
     public Void visitNew(NewExpression expression) {
2117
 		// TODO: this code is incorrect!
2122
 		// TODO: this code is incorrect!
2118
 		JavaMethod method = expression.constructor.getTag(JavaMethod.class);
2123
 		JavaMethod method = expression.constructor.getTag(JavaMethod.class);
2119
-		
2124
+
2120
         final String type;
2125
         final String type;
2121
         if (expression.type instanceof DefinitionTypeID)
2126
         if (expression.type instanceof DefinitionTypeID)
2122
             type = ((DefinitionTypeID) expression.type).definition.name;
2127
             type = ((DefinitionTypeID) expression.type).definition.name;
2125
 
2130
 
2126
         javaWriter.newObject(type);
2131
         javaWriter.newObject(type);
2127
         javaWriter.dup();
2132
         javaWriter.dup();
2128
-		
2133
+
2129
 		for (Expression argument : expression.arguments.arguments) {
2134
 		for (Expression argument : expression.arguments.arguments) {
2130
 			argument.accept(this);
2135
 			argument.accept(this);
2131
 		}
2136
 		}
2132
-		
2137
+
2133
         javaWriter.invokeSpecial(method);
2138
         javaWriter.invokeSpecial(method);
2134
 		return null;
2139
 		return null;
2135
 	}
2140
 	}
2444
         }
2449
         }
2445
 		if (methodInfo.genericResult)
2450
 		if (methodInfo.genericResult)
2446
 			getJavaWriter().checkCast(context.getInternalName(resultType));
2451
 			getJavaWriter().checkCast(context.getInternalName(resultType));
2447
-		
2452
+
2448
         return true;
2453
         return true;
2449
     }
2454
     }
2450
 
2455
 

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

22
 		this.startLabel = start;
22
 		this.startLabel = start;
23
 		this.endLabel = end;
23
 		this.endLabel = end;
24
 	}
24
 	}
25
-	
25
+
26
 	public void visitIntRange() {
26
 	public void visitIntRange() {
27
 		javaWriter.dup();
27
 		javaWriter.dup();
28
 		javaWriter.getField("zsynthetic/IntRange", "to", "I");
28
 		javaWriter.getField("zsynthetic/IntRange", "to", "I");
49
 	}
49
 	}
50
 
50
 
51
 	public void visitStringCharacterIterator() {
51
 	public void visitStringCharacterIterator() {
52
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
52
+		//TODO UNTESTED!
53
+		javaWriter.invokeSpecial("java/lang/String", "toCharArray()", "()[C");
54
+		handleArray(javaWriter.local(int.class), variables[0].getTag(JavaLocalVariableInfo.class));
53
 	}
55
 	}
54
 
56
 
55
 	private void handleArray(final int z, final JavaLocalVariableInfo arrayTypeInfo) {
57
 	private void handleArray(final int z, final JavaLocalVariableInfo arrayTypeInfo) {

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

1
 package org.openzen.zenscript.javabytecode.compiler.definitions;
1
 package org.openzen.zenscript.javabytecode.compiler.definitions;
2
 
2
 
3
+import org.openzen.zenscript.javashared.JavaTypeGenericVisitor;
3
 import org.objectweb.asm.ClassWriter;
4
 import org.objectweb.asm.ClassWriter;
4
 import org.objectweb.asm.Opcodes;
5
 import org.objectweb.asm.Opcodes;
5
 import org.openzen.zenscript.codemodel.definition.*;
6
 import org.openzen.zenscript.codemodel.definition.*;
7
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
6
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
8
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
7
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
9
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
10
+import org.openzen.zenscript.codemodel.type.GenericTypeID;
8
 import org.openzen.zenscript.codemodel.type.ITypeID;
11
 import org.openzen.zenscript.codemodel.type.ITypeID;
9
 import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
12
 import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
10
 import org.openzen.zenscript.javabytecode.compiler.*;
13
 import org.openzen.zenscript.javabytecode.compiler.*;
27
 			= JavaMethod.getNativeStatic(JavaClass.CLASS, "valueOf", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;");
30
 			= JavaMethod.getNativeStatic(JavaClass.CLASS, "valueOf", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;");
28
 	private static final JavaMethod ARRAY_CLONE
31
 	private static final JavaMethod ARRAY_CLONE
29
 			= JavaMethod.getNativeVirtual(JavaClass.ARRAYS, "clone", "()Ljava/lang/Object;");
32
 			= JavaMethod.getNativeVirtual(JavaClass.ARRAYS, "clone", "()Ljava/lang/Object;");
30
-	
33
+
31
 	private final JavaClassWriter outerWriter;
34
 	private final JavaClassWriter outerWriter;
32
 	private final JavaBytecodeContext context;
35
 	private final JavaBytecodeContext context;
36
+	final JavaTypeGenericVisitor javaTypeGenericVisitor;
33
 
37
 
34
     public JavaDefinitionVisitor(JavaBytecodeContext context, JavaClassWriter outerWriter) {
38
     public JavaDefinitionVisitor(JavaBytecodeContext context, JavaClassWriter outerWriter) {
35
 		this.context = context;
39
 		this.context = context;
36
 		this.outerWriter = outerWriter;
40
 		this.outerWriter = outerWriter;
41
+	    this.javaTypeGenericVisitor = new JavaTypeGenericVisitor(context);
37
 	}
42
 	}
38
 
43
 
39
 	@Override
44
 	@Override
50
 				interfaces.add(context.getInternalName(((ImplementationMember) member).type));
55
 				interfaces.add(context.getInternalName(((ImplementationMember) member).type));
51
 		}
56
 		}
52
         String signature = null;
57
         String signature = null;
53
-		
58
+
54
         writer.visit(Opcodes.V1_8, definition.modifiers, toClass.internalName, signature, superTypeInternalName, interfaces.toArray(new String[interfaces.size()]));
59
         writer.visit(Opcodes.V1_8, definition.modifiers, toClass.internalName, signature, superTypeInternalName, interfaces.toArray(new String[interfaces.size()]));
55
-		JavaMemberVisitor memberVisitor = new JavaMemberVisitor(context, writer, toClass, definition); 
60
+		JavaMemberVisitor memberVisitor = new JavaMemberVisitor(context, writer, toClass, definition);
56
         for (IDefinitionMember member : definition.members) {
61
         for (IDefinitionMember member : definition.members) {
57
             member.accept(memberVisitor);
62
             member.accept(memberVisitor);
58
         }
63
         }
64
 	@Override
69
 	@Override
65
 	public byte[] visitInterface(InterfaceDefinition definition) {
70
 	public byte[] visitInterface(InterfaceDefinition definition) {
66
 		JavaClass toClass = definition.getTag(JavaClass.class);
71
 		JavaClass toClass = definition.getTag(JavaClass.class);
67
-		ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
72
+		ClassWriter writer = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
68
 
73
 
69
 		//TODO: Calculate signature from generic parameters
74
 		//TODO: Calculate signature from generic parameters
70
 		String signature = null;
75
 		String signature = null;
71
 		String[] baseInterfaces = new String[definition.baseInterfaces.size()];
76
 		String[] baseInterfaces = new String[definition.baseInterfaces.size()];
72
 		for (int i = 0; i < baseInterfaces.length; i++)
77
 		for (int i = 0; i < baseInterfaces.length; i++)
73
 			baseInterfaces[i] = context.getInternalName(definition.baseInterfaces.get(i));
78
 			baseInterfaces[i] = context.getInternalName(definition.baseInterfaces.get(i));
74
-		
79
+
75
 		writer.visit(Opcodes.V1_8, definition.modifiers | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT, toClass.internalName, signature, "java/lang/Object", baseInterfaces);
80
 		writer.visit(Opcodes.V1_8, definition.modifiers | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT, toClass.internalName, signature, "java/lang/Object", baseInterfaces);
76
 		JavaMemberVisitor memberVisitor = new JavaMemberVisitor(context, writer, toClass, definition);
81
 		JavaMemberVisitor memberVisitor = new JavaMemberVisitor(context, writer, toClass, definition);
77
 		for (IDefinitionMember member : definition.members) {
82
 		for (IDefinitionMember member : definition.members) {
85
 	@Override
90
 	@Override
86
 	public byte[] visitEnum(EnumDefinition definition) {
91
 	public byte[] visitEnum(EnumDefinition definition) {
87
 		System.out.println("Compiling enum " + definition.name + " in " + definition.position.getFilename());
92
 		System.out.println("Compiling enum " + definition.name + " in " + definition.position.getFilename());
88
-		
93
+
89
 		String superTypeInternalName = definition.getSuperType() == null ? "java/lang/Object" : context.getInternalName(definition.getSuperType());
94
 		String superTypeInternalName = definition.getSuperType() == null ? "java/lang/Object" : context.getInternalName(definition.getSuperType());
90
 
95
 
91
-		ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
96
+		ClassWriter writer = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
92
 
97
 
93
 		JavaClass toClass = definition.getTag(JavaClass.class);
98
 		JavaClass toClass = definition.getTag(JavaClass.class);
94
 		writer.visit(Opcodes.V1_8, Opcodes.ACC_ENUM | Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL, toClass.internalName, "Ljava/lang/Enum<L" + toClass.internalName + ";>;", superTypeInternalName, null);
99
 		writer.visit(Opcodes.V1_8, Opcodes.ACC_ENUM | Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL, toClass.internalName, "Ljava/lang/Enum<L" + toClass.internalName + ";>;", superTypeInternalName, null);
100
         for (IDefinitionMember member : definition.members) {
105
         for (IDefinitionMember member : definition.members) {
101
             member.accept(visitor);
106
             member.accept(visitor);
102
         }
107
         }
103
-		
108
+
104
 		JavaMethod valuesMethod = JavaMethod.getStatic(toClass, "values", "()[L" + toClass.internalName + ";", Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
109
 		JavaMethod valuesMethod = JavaMethod.getStatic(toClass, "values", "()[L" + toClass.internalName + ";", Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
105
 		JavaWriter valuesWriter = new JavaWriter(writer, true, valuesMethod, definition, null, null);
110
 		JavaWriter valuesWriter = new JavaWriter(writer, true, valuesMethod, definition, null, null);
106
 		valuesWriter.start();
111
 		valuesWriter.start();
119
 		valueOfWriter.checkCast(toClass.internalName);
124
 		valueOfWriter.checkCast(toClass.internalName);
120
 		valueOfWriter.returnObject();
125
 		valueOfWriter.returnObject();
121
 		valueOfWriter.end();
126
 		valueOfWriter.end();
122
-		
127
+
123
 		writer.visitEnd();
128
 		writer.visitEnd();
124
 		return writer.toByteArray();
129
 		return writer.toByteArray();
125
 	}
130
 	}
132
 	@Override
137
 	@Override
133
 	public byte[] visitFunction(FunctionDefinition definition) {
138
 	public byte[] visitFunction(FunctionDefinition definition) {
134
 		CompilerUtils.tagMethodParameters(context, definition.header, true);
139
 		CompilerUtils.tagMethodParameters(context, definition.header, true);
135
-		
140
+
136
         final String signature = context.getMethodSignature(definition.header);
141
         final String signature = context.getMethodSignature(definition.header);
137
-		
142
+
138
 		final JavaMethod method = definition.caller.getTag(JavaMethod.class);
143
 		final JavaMethod method = definition.caller.getTag(JavaMethod.class);
139
 
144
 
140
 		final JavaWriter writer = new JavaWriter(outerWriter, true, method, definition, signature, null);
145
 		final JavaWriter writer = new JavaWriter(outerWriter, true, method, definition, signature, null);
169
 		final JavaClass toClass = variant.getTag(JavaClass.class);
174
 		final JavaClass toClass = variant.getTag(JavaClass.class);
170
 		final JavaClassWriter writer = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
175
 		final JavaClassWriter writer = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
171
 
176
 
172
-		writer.visit(Opcodes.V1_8, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, toClass.internalName, null, "java/lang/Object", null);
177
+		final String variantName = variant.name;
178
+
179
+
180
+		final String ss = "<" + javaTypeGenericVisitor.getGenericSignature(variant.genericParameters) + ">Ljava/lang/Object;";
181
+		JavaClassWriter.registerSuperClass(variantName, "java/lang/Object");
182
+
183
+		writer.visit(Opcodes.V1_8, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, toClass.internalName, ss, "java/lang/Object", null);
173
 		writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "getDenominator", "()I", null, null).visitEnd();
184
 		writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "getDenominator", "()I", null, null).visitEnd();
174
 
185
 
175
 		final JavaMemberVisitor visitor = new JavaMemberVisitor(context, writer, toClass, variant);
186
 		final JavaMemberVisitor visitor = new JavaMemberVisitor(context, writer, toClass, variant);
179
 		for (final VariantDefinition.Option option : options) {
190
 		for (final VariantDefinition.Option option : options) {
180
 			JavaVariantOption optionTag = option.getTag(JavaVariantOption.class);
191
 			JavaVariantOption optionTag = option.getTag(JavaVariantOption.class);
181
 			final JavaClassWriter optionWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
192
 			final JavaClassWriter optionWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
193
+			final String optionClassName = variantName + "$" + option.name;
194
+			JavaClassWriter.registerSuperClass(optionClassName, variantName);
182
 
195
 
183
 			writer.visitInnerClass(optionTag.variantOptionClass.internalName, optionTag.variantClass.internalName, option.name, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL);
196
 			writer.visitInnerClass(optionTag.variantOptionClass.internalName, optionTag.variantClass.internalName, option.name, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL);
184
 
197
 
186
 			final String signature;
199
 			final String signature;
187
 			{
200
 			{
188
 				StringBuilder builder = new StringBuilder();
201
 				StringBuilder builder = new StringBuilder();
189
-				for (int i = 0; i < option.types.length; ++i) {
190
-					builder.append("<T").append(i).append(":");
191
-					builder.append(context.getDescriptor(option.types[i]));
202
+				//TODO check if this can be changed to what Stan was up to
203
+				builder.append("<");
204
+				for (final ITypeID type : option.types) {
205
+					builder.append(javaTypeGenericVisitor.getSignatureWithBound(type));
192
 				}
206
 				}
193
 				builder.append(">");
207
 				builder.append(">");
194
-				builder.append("L").append(toClass.internalName).append(";");
195
-				
196
-				signature = builder.toString();
208
+				builder.append("L").append(toClass.internalName).append("<");
209
+
210
+				for (final TypeParameter genericParameter : variant.genericParameters) {
211
+					boolean t = true;
212
+					for (final ITypeID type : option.types)
213
+						if (type instanceof GenericTypeID) {
214
+							final GenericTypeID genericTypeID = (GenericTypeID) type;
215
+							if (genericParameter == genericTypeID.parameter) {
216
+								builder.append("T").append(genericParameter.name).append(";");
217
+								t = false;
218
+							}
219
+						}
220
+					if (t)
221
+						builder.append(javaTypeGenericVisitor.getGenericBounds(genericParameter.bounds));
222
+
223
+				}
224
+
225
+
226
+				signature = builder.append(">;").toString();
197
 			}
227
 			}
198
 
228
 
199
 			optionWriter.visit(Opcodes.V1_8, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, optionTag.variantOptionClass.internalName, signature, optionTag.variantClass.internalName, null);
229
 			optionWriter.visit(Opcodes.V1_8, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, optionTag.variantOptionClass.internalName, signature, optionTag.variantClass.internalName, null);
200
 			final JavaMemberVisitor optionVisitor = new JavaMemberVisitor(context, optionWriter, optionTag.variantOptionClass, variant);
230
 			final JavaMemberVisitor optionVisitor = new JavaMemberVisitor(context, optionWriter, optionTag.variantOptionClass, variant);
201
 			final StringBuilder optionInitDescBuilder = new StringBuilder("(");
231
 			final StringBuilder optionInitDescBuilder = new StringBuilder("(");
232
+			final StringBuilder optionInitSignatureBuilder = new StringBuilder("(");
202
 
233
 
203
 			ITypeID[] types = option.types;
234
 			ITypeID[] types = option.types;
204
 			for (int i = 0; i < types.length; ++i) {
235
 			for (int i = 0; i < types.length; ++i) {
205
 				final String descriptor = context.getDescriptor(types[i]);
236
 				final String descriptor = context.getDescriptor(types[i]);
206
 				optionInitDescBuilder.append(descriptor);
237
 				optionInitDescBuilder.append(descriptor);
207
-				optionWriter.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "field" + i, descriptor, "TT" + i + ";", null).visitEnd();
238
+				optionInitSignatureBuilder.append("T").append(((GenericTypeID) types[i]).parameter.name).append(";");
239
+				optionWriter.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "field" + i, descriptor, "T" + ((GenericTypeID) types[i]).parameter.name + ";", null).visitEnd();
208
 			}
240
 			}
209
 			optionInitDescBuilder.append(")V");
241
 			optionInitDescBuilder.append(")V");
210
-			
211
-			JavaMethod constructorMethod = JavaMethod.getConstructor(optionTag.variantOptionClass, optionInitDescBuilder.toString(), JavaModifiers.PUBLIC);
212
-			final JavaWriter initWriter = new JavaWriter(optionWriter, constructorMethod, variant, optionInitDescBuilder.toString(), null);
242
+			optionInitSignatureBuilder.append(")V");
243
+
244
+JavaMethod constructorMethod = JavaMethod.getConstructor(optionTag.variantOptionClass, optionInitDescBuilder.toString(), JavaModifiers.PUBLIC);
245
+			final JavaWriter initWriter = new JavaWriter(optionWriter, constructorMethod, variant, optionInitSignatureBuilder.toString(), null);
213
 			initWriter.start();
246
 			initWriter.start();
214
 			initWriter.loadObject(0);
247
 			initWriter.loadObject(0);
215
 			initWriter.dup();
248
 			initWriter.dup();
224
 			initWriter.pop();
257
 			initWriter.pop();
225
 			initWriter.ret();
258
 			initWriter.ret();
226
 			initWriter.end();
259
 			initWriter.end();
227
-			
260
+
228
 			//Denominator for switch-cases
261
 			//Denominator for switch-cases
229
 			JavaMethod denominator = JavaMethod.getVirtual(optionTag.variantOptionClass, "getDenominator", "()I", JavaModifiers.PUBLIC);
262
 			JavaMethod denominator = JavaMethod.getVirtual(optionTag.variantOptionClass, "getDenominator", "()I", JavaModifiers.PUBLIC);
230
 			final JavaWriter getDenominator = new JavaWriter(optionWriter, denominator, null, null, null, "java/lang/Override");
263
 			final JavaWriter getDenominator = new JavaWriter(optionWriter, denominator, null, null, null, "java/lang/Override");
232
 			getDenominator.constant(option.ordinal);
265
 			getDenominator.constant(option.ordinal);
233
 			getDenominator.returnInt();
266
 			getDenominator.returnInt();
234
 			getDenominator.end();
267
 			getDenominator.end();
235
-			
268
+
236
 			optionVisitor.end();
269
 			optionVisitor.end();
237
 			optionWriter.visitEnd();
270
 			optionWriter.visitEnd();
238
 			final byte[] byteArray = optionWriter.toByteArray();
271
 			final byte[] byteArray = optionWriter.toByteArray();

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

1
 package org.openzen.zenscript.javabytecode.compiler.definitions;
1
 package org.openzen.zenscript.javabytecode.compiler.definitions;
2
 
2
 
3
+import org.openzen.zenscript.javashared.JavaTypeGenericVisitor;
3
 import org.objectweb.asm.ClassWriter;
4
 import org.objectweb.asm.ClassWriter;
4
 import org.objectweb.asm.Label;
5
 import org.objectweb.asm.Label;
5
 import org.objectweb.asm.Opcodes;
6
 import org.objectweb.asm.Opcodes;
38
         this.clinitStatementVisitor.start();
39
         this.clinitStatementVisitor.start();
39
         CompilerUtils.writeDefaultFieldInitializers(context, javaWriter, definition, true);
40
         CompilerUtils.writeDefaultFieldInitializers(context, javaWriter, definition, true);
40
     }
41
     }
41
-	
42
+
42
 	@Override
43
 	@Override
43
 	public Void visitConst(ConstMember member) {
44
 	public Void visitConst(ConstMember member) {
44
 		JavaField field = member.getTag(JavaField.class);
45
 		JavaField field = member.getTag(JavaField.class);
122
         final boolean isAbstract = member.body == null || Modifiers.isAbstract(member.modifiers);
123
         final boolean isAbstract = member.body == null || Modifiers.isAbstract(member.modifiers);
123
         final JavaMethod method = member.getTag(JavaMethod.class);
124
         final JavaMethod method = member.getTag(JavaMethod.class);
124
 
125
 
125
-        final Label methodStart = new Label();
126
-        final Label methodEnd = new Label();
127
-        final JavaWriter methodWriter = new JavaWriter(writer, method, definition, context.getMethodSignature(member.header), null);
128
-        methodWriter.label(methodStart);
129
-        for (final FunctionParameter parameter : member.header.parameters) {
130
-            methodWriter.nameParameter(0, parameter.name);
131
-            if (!isAbstract)
132
-                methodWriter.nameVariable(parameter.getTag(JavaParameterInfo.class).index, parameter.name, methodStart, methodEnd, context.getType(parameter.type));
133
-        }
126
+		final Label methodStart = new Label();
127
+		final Label methodEnd = new Label();
128
+	    final JavaWriter methodWriter = new JavaWriter(writer, method, definition, context.getMethodSignature(member.header), null);
129
+		methodWriter.label(methodStart);
130
+		for (final FunctionParameter parameter : member.header.parameters) {
131
+			methodWriter.nameParameter(0, parameter.name);
132
+			if (!isAbstract)
133
+				methodWriter.nameVariable(parameter.getTag(JavaParameterInfo.class).index, parameter.name, methodStart, methodEnd, context.getType(parameter.type));
134
+		}
134
 
135
 
135
         final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, methodWriter);
136
         final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, methodWriter);
136
 
137
 

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

77
 	}
77
 	}
78
 	
78
 	
79
     public String getMethodSignature(FunctionHeader header) {
79
     public String getMethodSignature(FunctionHeader header) {
80
-        StringBuilder signatureBuilder = new StringBuilder("(");
81
-        for (FunctionParameter parameter : header.parameters) {
82
-            signatureBuilder.append(getDescriptor(parameter.type));
83
-        }
84
-        signatureBuilder.append(")").append(getDescriptor(header.getReturnType()));
85
-        return signatureBuilder.toString();
80
+        return new JavaTypeGenericVisitor(this).getGenericMethodSignature(header);
86
     }
81
     }
87
 	
82
 	
88
 	public String getEnumConstructorDescriptor(FunctionHeader header) {
83
 	public String getEnumConstructorDescriptor(FunctionHeader header) {

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

1
+package org.openzen.zenscript.javashared;
2
+
3
+import org.openzen.zenscript.codemodel.FunctionHeader;
4
+import org.openzen.zenscript.codemodel.FunctionParameter;
5
+import org.openzen.zenscript.codemodel.generic.*;
6
+import org.openzen.zenscript.codemodel.type.*;
7
+
8
+import java.util.Collection;
9
+
10
+public class JavaTypeGenericVisitor implements ITypeVisitor<String> {
11
+
12
+	private final JavaContext context;
13
+
14
+	public JavaTypeGenericVisitor(JavaContext context) {
15
+		this.context = context;
16
+	}
17
+
18
+
19
+	public String getGenericSignature(ITypeID... types) {
20
+		if (types == null || types.length == 0)
21
+			return "";
22
+		final StringBuilder builder = new StringBuilder();
23
+		for (ITypeID type : types) {
24
+			builder.append(type.accept(this));
25
+		}
26
+
27
+		return builder.toString();
28
+	}
29
+
30
+
31
+	public String getGenericSignature(TypeParameter... parameters) {
32
+		if (parameters == null || parameters.length == 0)
33
+			return "";
34
+
35
+		final StringBuilder builder = new StringBuilder();
36
+		for (TypeParameter parameter : parameters) {
37
+			builder.append(parameter.name).append(":").append(getGenericBounds(parameter.bounds));
38
+		}
39
+		return builder.toString();
40
+	}
41
+
42
+	public String getSignatureWithBound(ITypeID type) {
43
+		if(type instanceof GenericTypeID){
44
+			final TypeParameter parameter = ((GenericTypeID) type).parameter;
45
+			return parameter.name + ":" + getGenericBounds(parameter.bounds);
46
+		}
47
+		throw new IllegalStateException("Type " + type + " is of the wrong class");
48
+	}
49
+
50
+	private String getGenericSignature(FunctionParameter... parameters) {
51
+		if(parameters == null || parameters.length == 0)
52
+			return "";
53
+		final StringBuilder builder = new StringBuilder();
54
+		for (FunctionParameter parameter : parameters) {
55
+			builder.append(parameter.type.accept(this));
56
+		}
57
+		return builder.toString();
58
+	}
59
+
60
+	public String getGenericMethodSignature(FunctionHeader header) {
61
+		return "(" + getGenericSignature(header.parameters) +
62
+				")" +
63
+				getGenericSignature(header.getReturnType());
64
+	}
65
+
66
+
67
+	public String getGenericBounds(Collection<TypeParameterBound> collection) {
68
+		if (collection == null)
69
+			return "";
70
+		for (TypeParameterBound parameterBound : collection) {
71
+			String s = parameterBound.accept(new GenericParameterBoundVisitor<String>() {
72
+				@Override
73
+				public String visitSuper(ParameterSuperBound bound) {
74
+					return null;
75
+				}
76
+
77
+				@Override
78
+				public String visitType(ParameterTypeBound bound) {
79
+					return bound.type.accept(JavaTypeGenericVisitor.this);
80
+				}
81
+			});
82
+			if (s != null)
83
+				return s;
84
+		}
85
+		return "Ljava/lang/Object;";
86
+	}
87
+
88
+	@Override
89
+	public String visitBasic(BasicTypeID basic) {
90
+		return context.getDescriptor(basic);
91
+	}
92
+
93
+	@Override
94
+	public String visitArray(ArrayTypeID array) {
95
+		return context.getDescriptor(array);
96
+	}
97
+
98
+	@Override
99
+	public String visitAssoc(AssocTypeID assoc) {
100
+		return context.getDescriptor(assoc);
101
+	}
102
+
103
+	@Override
104
+	public String visitGenericMap(GenericMapTypeID map) {
105
+		return context.getDescriptor(map);
106
+	}
107
+
108
+	@Override
109
+	public String visitIterator(IteratorTypeID iterator) {
110
+		return context.getDescriptor(iterator);
111
+	}
112
+
113
+	@Override
114
+	public String visitFunction(FunctionTypeID function) {
115
+		return context.getDescriptor(function);
116
+	}
117
+
118
+	@Override
119
+	public String visitDefinition(DefinitionTypeID definition) {
120
+		StringBuilder builder = new StringBuilder("L").append(definition.definition.name);
121
+
122
+		if (definition.typeParameters.length > 0) {
123
+			builder.append("<");
124
+			for (ITypeID typeParameter : definition.typeParameters) {
125
+				builder.append(typeParameter.accept(this));
126
+			}
127
+			builder.append(">");
128
+		}
129
+
130
+		return builder.append(";").toString();
131
+	}
132
+
133
+	@Override
134
+	public String visitGeneric(GenericTypeID generic) {
135
+		return "T" + generic.parameter.name + ";";
136
+		//return generic.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
137
+	}
138
+
139
+	@Override
140
+	public String visitRange(RangeTypeID range) {
141
+		return context.getDescriptor(range);
142
+	}
143
+
144
+	@Override
145
+	public String visitModified(ModifiedTypeID type) {
146
+		return type.baseType.accept(this);
147
+	}
148
+}

+ 1
- 1
ScriptingExample/build.gradle View File

18
 	compile project(':JavaBytecodeCompiler')
18
 	compile project(':JavaBytecodeCompiler')
19
 	compile project(':JavaShared')
19
 	compile project(':JavaShared')
20
 	compile project(':CodeFormatter')
20
 	compile project(':CodeFormatter')
21
-	//compile project(':ScriptingHost')
21
+    //compile project(':ScriptingHost')
22
 }
22
 }

Loading…
Cancel
Save