Bladeren bron

More work for Variants and generics, WIP

push to merge stan's changes
kindlich 6 jaren geleden
bovenliggende
commit
406ecb18bb
Geen bekende sleutel gevonden voor deze handtekening in de database

+ 2
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java Bestand weergeven

@@ -2046,7 +2046,8 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2046 2046
 
2047 2047
 		if (hasNoDefault) {
2048 2048
 			javaWriter.label(defaultLabel);
2049
-			if (Object.class.isAssignableFrom(expression.type.accept(JavaTypeClassVisitor.INSTANCE)))
2049
+			final Type type = expression.type.accept(JavaTypeVisitor.INSTANCE);
2050
+			if (type == null || type.getOpcode(Opcodes.ISTORE) == Opcodes.ASTORE)
2050 2051
 				javaWriter.aConstNull();
2051 2052
 			else
2052 2053
 				javaWriter.iConst0();

+ 148
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaTypeGenericVisitor.java Bestand weergeven

@@ -0,0 +1,148 @@
1
+package org.openzen.zenscript.javabytecode.compiler;
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
+	public static final JavaTypeGenericVisitor INSTANCE = new JavaTypeGenericVisitor();
13
+
14
+
15
+	public static String getGenericSignature(ITypeID... types) {
16
+		if (types == null || types.length == 0)
17
+			return "";
18
+		final StringBuilder builder = new StringBuilder();
19
+		for (ITypeID type : types) {
20
+			builder.append(type.accept(INSTANCE));
21
+		}
22
+
23
+		return builder.toString();
24
+	}
25
+
26
+
27
+	public static String getGenericSignature(TypeParameter... parameters) {
28
+		if (parameters == null || parameters.length == 0)
29
+			return "";
30
+
31
+		final StringBuilder builder = new StringBuilder();
32
+		for (TypeParameter parameter : parameters) {
33
+			builder.append(parameter.name).append(":").append(getGenericBounds(parameter.bounds));
34
+		}
35
+		return builder.toString();
36
+	}
37
+
38
+	public static String getSignatureWithBound(ITypeID type) {
39
+		if(type instanceof GenericTypeID){
40
+			final TypeParameter parameter = ((GenericTypeID) type).parameter;
41
+			return parameter.name + ":" + getGenericBounds(parameter.bounds);
42
+		}
43
+		throw new IllegalStateException("Type " + type + " is of the wrong class");
44
+	}
45
+
46
+	private static String getGenericSignature(FunctionParameter... parameters) {
47
+		if(parameters == null || parameters.length == 0)
48
+			return "";
49
+		final StringBuilder builder = new StringBuilder();
50
+		for (FunctionParameter parameter : parameters) {
51
+			builder.append(parameter.type.accept(INSTANCE));
52
+		}
53
+		return builder.toString();
54
+	}
55
+
56
+	public static String getGenericMethodSignature(FunctionHeader header) {
57
+		return "(" + getGenericSignature(header.parameters) +
58
+				")" +
59
+				getGenericSignature(header.returnType);
60
+	}
61
+
62
+
63
+	public static String getGenericBounds(Collection<GenericParameterBound> collection) {
64
+		if (collection == null)
65
+			return "";
66
+		for (GenericParameterBound parameterBound : collection) {
67
+			String s = parameterBound.accept(new GenericParameterBoundVisitor<String>() {
68
+				@Override
69
+				public String visitSuper(ParameterSuperBound bound) {
70
+					return null;
71
+				}
72
+
73
+				@Override
74
+				public String visitType(ParameterTypeBound bound) {
75
+					return bound.type.accept(INSTANCE);
76
+				}
77
+			});
78
+			if (s != null)
79
+				return s;
80
+		}
81
+		return "Ljava/lang/Object;";
82
+	}
83
+
84
+
85
+	private JavaTypeGenericVisitor() {
86
+	}
87
+
88
+	@Override
89
+	public String visitBasic(BasicTypeID basic) {
90
+		return basic.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
91
+	}
92
+
93
+	@Override
94
+	public String visitArray(ArrayTypeID array) {
95
+		return array.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
96
+	}
97
+
98
+	@Override
99
+	public String visitAssoc(AssocTypeID assoc) {
100
+		return assoc.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
101
+	}
102
+
103
+	@Override
104
+	public String visitGenericMap(GenericMapTypeID map) {
105
+		return map.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
106
+	}
107
+
108
+	@Override
109
+	public String visitIterator(IteratorTypeID iterator) {
110
+		return iterator.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
111
+	}
112
+
113
+	@Override
114
+	public String visitFunction(FunctionTypeID function) {
115
+		return function.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
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 range.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
142
+	}
143
+
144
+	@Override
145
+	public String visitModified(ModifiedTypeID type) {
146
+		return type.baseType.accept(this);
147
+	}
148
+}

+ 32
- 8
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java Bestand weergeven

@@ -5,8 +5,10 @@ import org.objectweb.asm.Opcodes;
5 5
 import org.objectweb.asm.Type;
6 6
 import org.openzen.zenscript.codemodel.Modifiers;
7 7
 import org.openzen.zenscript.codemodel.definition.*;
8
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
8 9
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
9 10
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
11
+import org.openzen.zenscript.codemodel.type.GenericTypeID;
10 12
 import org.openzen.zenscript.codemodel.type.ITypeID;
11 13
 import org.openzen.zenscript.javabytecode.JavaMethodInfo;
12 14
 import org.openzen.zenscript.javabytecode.JavaModule;
@@ -187,7 +189,11 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
187 189
 		final JavaClass toClass = new JavaClass("", variantName, JavaClass.Kind.CLASS);
188 190
 		final JavaClassWriter writer = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
189 191
 
190
-		writer.visit(Opcodes.V1_8, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, variantName, null, "java/lang/Object", null);
192
+
193
+		final String ss = "<" + JavaTypeGenericVisitor.getGenericSignature(variant.genericParameters) + ">Ljava/lang/Object;";
194
+
195
+
196
+		writer.visit(Opcodes.V1_8, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, variantName, ss, "java/lang/Object", null);
191 197
 		writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "getDenominator", "()I", null, null).visitEnd();
192 198
 
193 199
 
@@ -210,15 +216,30 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
210 216
 			final String signature;
211 217
 			{
212 218
 				StringBuilder builder = new StringBuilder();
213
-				for (int i = 0; i < option.types.length; ++i) {
214
-					builder.append("<T").append(i).append(":");
215
-					builder.append(option.types[i].accept(JavaTypeVisitor.INSTANCE).getDescriptor());
219
+				builder.append("<");
220
+				for (final ITypeID type : option.types) {
221
+					builder.append(JavaTypeGenericVisitor.getSignatureWithBound(type));
216 222
 				}
217 223
 				builder.append(">");
218
-				builder.append("L").append(variantName).append(";");
224
+				builder.append("L").append(variantName).append("<");
225
+
226
+				for (final TypeParameter genericParameter : variant.genericParameters) {
227
+					boolean t = true;
228
+					for (final ITypeID type : option.types)
229
+						if (type instanceof GenericTypeID) {
230
+							final GenericTypeID genericTypeID = (GenericTypeID) type;
231
+							if (genericParameter == genericTypeID.parameter) {
232
+								builder.append("T").append(genericParameter.name).append(";");
233
+								t = false;
234
+							}
235
+						}
236
+					if (t)
237
+						builder.append(JavaTypeGenericVisitor.getGenericBounds(genericParameter.bounds));
238
+
239
+				}
219 240
 
220 241
 
221
-				signature = builder.toString();
242
+				signature = builder.append(">;").toString();
222 243
 			}
223 244
 
224 245
 			optionWriter.visit(Opcodes.V1_8, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, optionClassName, signature, variantName, null);
@@ -226,18 +247,21 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
226 247
 
227 248
 
228 249
 			final StringBuilder optionInitDescBuilder = new StringBuilder("(");
250
+			final StringBuilder optionInitSignatureBuilder = new StringBuilder("(");
229 251
 
230 252
 			ITypeID[] types = option.types;
231 253
 			for (int i = 0; i < types.length; ++i) {
232 254
 				final Type type = types[i].accept(JavaTypeVisitor.INSTANCE);
233 255
 				final String internalName = type.getDescriptor();
234 256
 				optionInitDescBuilder.append(internalName);
235
-				optionWriter.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "Field" + i, internalName, "TT" + i + ";", null).visitEnd();
257
+				optionInitSignatureBuilder.append("T").append(((GenericTypeID) types[i]).parameter.name).append(";");
258
+				optionWriter.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "Field" + i, internalName, "T" + ((GenericTypeID) types[i]).parameter.name + ";", null).visitEnd();
236 259
 			}
237 260
 			optionInitDescBuilder.append(")V");
261
+			optionInitSignatureBuilder.append(")V");
238 262
 
239 263
 
240
-			final JavaWriter initWriter = new JavaWriter(optionWriter, new JavaMethodInfo(optionClass, "<init>", optionInitDescBuilder.toString(), Opcodes.ACC_PUBLIC), variant, optionInitDescBuilder.toString(), null);
264
+			final JavaWriter initWriter = new JavaWriter(optionWriter, new JavaMethodInfo(optionClass, "<init>", optionInitDescBuilder.toString(), Opcodes.ACC_PUBLIC), variant, optionInitSignatureBuilder.toString(), null);
241 265
 			initWriter.start();
242 266
 			initWriter.loadObject(0);
243 267
 			initWriter.dup();

+ 1
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaMemberVisitor.java Bestand weergeven

@@ -138,7 +138,7 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
138 138
 
139 139
 		final Label methodStart = new Label();
140 140
 		final Label methodEnd = new Label();
141
-		final JavaWriter methodWriter = new JavaWriter(writer, method, definition, CompilerUtils.calcSign(member.header, false), null);
141
+		final JavaWriter methodWriter = new JavaWriter(writer, method, definition, JavaTypeGenericVisitor.getGenericMethodSignature(member.header), null);
142 142
 		methodWriter.label(methodStart);
143 143
 		for (final FunctionParameter parameter : member.header.parameters) {
144 144
 			methodWriter.nameParameter(0, parameter.name);

Laden…
Annuleren
Opslaan