Browse Source

Fixed results from generic methods not being cast to the right type. Also fixed some bugs related to variants and added the variant value creation syntax VariantName.Option(arguments).

Stan Hebben 6 years ago
parent
commit
fe2ccea44d
25 changed files with 186 additions and 74 deletions
  1. 5
    4
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java
  2. 2
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/GenericMapper.java
  3. 2
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/definition/VariantDefinition.java
  4. 3
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/ref/VariantOptionRef.java
  5. 73
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialVariantOptionExpression.java
  6. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/scope/DefinitionScope.java
  7. 2
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/scope/ExpressionScope.java
  8. 2
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/DefinitionTypeID.java
  9. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/DefinitionMemberGroup.java
  10. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java
  11. 3
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMembers.java
  12. 2
    2
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java
  13. 19
    15
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java
  14. 3
    3
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java
  15. 9
    9
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java
  16. 2
    2
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaMemberVisitor.java
  17. 15
    8
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaMethod.java
  18. 2
    2
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaNativeClass.java
  19. 17
    3
      JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareClassMethodVisitor.java
  20. 8
    9
      JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareDefinitionVisitor.java
  21. 2
    1
      JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareExpansionMethodVisitor.java
  22. 2
    3
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceSyntheticHelperGenerator.java
  23. 1
    1
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedCallArguments.java
  24. 7
    2
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionFunction.java
  25. 2
    1
      Shared/src/main/java/org/openzen/zencode/shared/CompileExceptionCode.java

+ 5
- 4
CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java View File

@@ -321,13 +321,13 @@ public class FunctionHeader {
321 321
 		return true;
322 322
 	}
323 323
 	
324
-	public FunctionHeader withGenericArguments(GenericMapper mapper) {
324
+	public FunctionHeader withGenericArguments(GlobalTypeRegistry registry, GenericMapper mapper) {
325 325
 		if (typeParameters.length > 0) {
326 326
 			Map<TypeParameter, ITypeID> innerMap = new HashMap<>();
327 327
 			for (TypeParameter parameter : typeParameters)
328 328
 				innerMap.put(parameter, mapper.registry.getGeneric(parameter));
329 329
 			
330
-			mapper = mapper.getInner(innerMap);
330
+			mapper = mapper.getInner(registry, innerMap);
331 331
 		}
332 332
 		
333 333
 		ITypeID returnType = this.returnType.instance(mapper);
@@ -345,7 +345,7 @@ public class FunctionHeader {
345 345
 		Map<TypeParameter, ITypeID> typeArguments = new HashMap<>();
346 346
 		for (int i = 0; i < typeParameters.length; i++)
347 347
 			typeArguments.put(typeParameters[i], arguments[i]);
348
-		GenericMapper mapper = typeParameterMapping.getInner(typeArguments);
348
+		GenericMapper mapper = typeParameterMapping.getInner(registry, typeArguments);
349 349
 		
350 350
 		ITypeID returnType = this.returnType.instance(mapper);
351 351
 		FunctionParameter[] parameters = new FunctionParameter[this.parameters.length];
@@ -410,7 +410,8 @@ public class FunctionHeader {
410 410
 				result.append(", ");
411 411
 			result.append(parameters[i].toString());
412 412
 		}
413
-		result.append(")");
413
+		result.append(") as ");
414
+		result.append(returnType.toString());
414 415
 		return result.toString();
415 416
 	}
416 417
 

+ 2
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/GenericMapper.java View File

@@ -54,10 +54,10 @@ public class GenericMapper {
54 54
 	}
55 55
 	
56 56
 	public FunctionHeader map(FunctionHeader original) {
57
-		return mapping.isEmpty() ? original : original.withGenericArguments(this);
57
+		return mapping.isEmpty() ? original : original.withGenericArguments(registry, this);
58 58
 	}
59 59
 	
60
-	public GenericMapper getInner(Map<TypeParameter, ITypeID> mapping) {
60
+	public GenericMapper getInner(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> mapping) {
61 61
 		Map<TypeParameter, ITypeID> resultMap = new HashMap<>(this.mapping);
62 62
 		resultMap.putAll(mapping);
63 63
 		return new GenericMapper(registry, resultMap);

+ 2
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/definition/VariantDefinition.java View File

@@ -41,8 +41,8 @@ public class VariantDefinition extends HighLevelDefinition {
41 41
 			this.types = types;
42 42
 		}
43 43
 		
44
-		public VariantOptionRef instance(GenericMapper mapper) {
45
-			return new VariantOptionRef(this, mapper.map(types));
44
+		public VariantOptionRef instance(ITypeID variantType, GenericMapper mapper) {
45
+			return new VariantOptionRef(this, variantType, mapper.map(types));
46 46
 		}
47 47
 	}
48 48
 }

+ 3
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/ref/VariantOptionRef.java View File

@@ -14,10 +14,12 @@ import org.openzen.zenscript.codemodel.type.ITypeID;
14 14
  */
15 15
 public class VariantOptionRef {
16 16
 	private final VariantDefinition.Option option;
17
+	public final ITypeID variant;
17 18
 	public final ITypeID[] types;
18 19
 	
19
-	public VariantOptionRef(VariantDefinition.Option option, ITypeID[] types) {
20
+	public VariantOptionRef(VariantDefinition.Option option, ITypeID variant, ITypeID[] types) {
20 21
 		this.option = option;
22
+		this.variant = variant;
21 23
 		this.types = types;
22 24
 	}
23 25
 	

+ 73
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialVariantOptionExpression.java View File

@@ -0,0 +1,73 @@
1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.codemodel.partial;
7
+
8
+import java.util.Arrays;
9
+import java.util.Collections;
10
+import java.util.List;
11
+import org.openzen.zencode.shared.CodePosition;
12
+import org.openzen.zencode.shared.CompileException;
13
+import org.openzen.zencode.shared.CompileExceptionCode;
14
+import org.openzen.zenscript.codemodel.FunctionHeader;
15
+import org.openzen.zenscript.codemodel.expression.CallArguments;
16
+import org.openzen.zenscript.codemodel.expression.Expression;
17
+import org.openzen.zenscript.codemodel.expression.VariantValueExpression;
18
+import org.openzen.zenscript.codemodel.member.ref.VariantOptionRef;
19
+import org.openzen.zenscript.codemodel.scope.TypeScope;
20
+import org.openzen.zenscript.codemodel.type.GenericName;
21
+import org.openzen.zenscript.codemodel.type.ITypeID;
22
+
23
+/**
24
+ *
25
+ * @author Hoofdgebruiker
26
+ */
27
+public class PartialVariantOptionExpression implements IPartialExpression {
28
+	private final CodePosition position;
29
+	private final TypeScope scope;
30
+	private final VariantOptionRef option;
31
+	
32
+	public PartialVariantOptionExpression(CodePosition position, TypeScope scope, VariantOptionRef option) {
33
+		this.position = position;
34
+		this.scope = scope;
35
+		this.option = option;
36
+	}
37
+	
38
+	@Override
39
+	public Expression eval() {
40
+		throw new CompileException(position, CompileExceptionCode.VARIANT_OPTION_NOT_AN_EXPRESSION, "Cannot use a variant option as expression");
41
+	}
42
+
43
+	@Override
44
+	public List<ITypeID>[] predictCallTypes(TypeScope scope, List<ITypeID> hints, int arguments) {
45
+		if (arguments != option.getOption().types.length)
46
+			return new List[0];
47
+		
48
+		return new List[] { Arrays.asList(option.getOption().types) };
49
+	}
50
+
51
+	@Override
52
+	public List<FunctionHeader> getPossibleFunctionHeaders(TypeScope scope, List<ITypeID> hints, int arguments) {
53
+		if (arguments != option.getOption().types.length)
54
+			return Collections.emptyList();
55
+		
56
+		return Collections.singletonList(new FunctionHeader(option.variant, option.types));
57
+	}
58
+
59
+	@Override
60
+	public IPartialExpression getMember(CodePosition position, TypeScope scope, List<ITypeID> hints, GenericName name) {
61
+		throw new CompileException(position, CompileExceptionCode.NO_SUCH_MEMBER, "Variant options don't have members");
62
+	}
63
+
64
+	@Override
65
+	public Expression call(CodePosition position, TypeScope scope, List<ITypeID> hints, CallArguments arguments) {
66
+		return new VariantValueExpression(position, option.variant, option, arguments.arguments);
67
+	}
68
+
69
+	@Override
70
+	public ITypeID[] getGenericCallTypes() {
71
+		return ITypeID.NONE;
72
+	}
73
+}

+ 1
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/scope/DefinitionScope.java View File

@@ -76,7 +76,7 @@ public class DefinitionScope extends BaseScope {
76 76
 		}
77 77
 		
78 78
 		members = withMembers ? outer.getMemberCache().get(type) : null;
79
-		typeParameterMap = outer.getLocalTypeParameters().getInner(typeParameters);
79
+		typeParameterMap = outer.getLocalTypeParameters().getInner(getTypeRegistry(), typeParameters);
80 80
 	}
81 81
 	
82 82
 	public void addInnerType(String name, Supplier<HighLevelDefinition> innerType) {

+ 2
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/scope/ExpressionScope.java View File

@@ -22,6 +22,7 @@ import org.openzen.zenscript.codemodel.generic.TypeParameter;
22 22
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
23 23
 import org.openzen.zenscript.codemodel.statement.LoopStatement;
24 24
 import org.openzen.zenscript.codemodel.statement.VarStatement;
25
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
25 26
 import org.openzen.zenscript.codemodel.type.GenericName;
26 27
 import org.openzen.zenscript.codemodel.type.ITypeID;
27 28
 import org.openzen.zenscript.codemodel.type.member.LocalMemberCache;
@@ -55,7 +56,7 @@ public class ExpressionScope extends BaseScope {
55 56
 	
56 57
 	public ExpressionScope(BaseScope scope, ITypeID hint) {
57 58
 		this.outer = scope;
58
-		this.hints = Collections.singletonList(hint);
59
+		this.hints = hint == BasicTypeID.UNDETERMINED ? Collections.emptyList() : Collections.singletonList(hint);
59 60
 		this.dollar = null;
60 61
 		this.genericInferenceMap = Collections.emptyMap();
61 62
 	}

+ 2
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/DefinitionTypeID.java View File

@@ -133,6 +133,8 @@ public class DefinitionTypeID implements ITypeID {
133 133
 			return this;
134 134
 		if (mapper.getMapping().isEmpty())
135 135
 			return this;
136
+		if (mapper.registry == null)
137
+			throw new NullPointerException();
136 138
 		
137 139
 		ITypeID[] instancedArguments = ITypeID.NONE;
138 140
 		if (hasTypeParameters()) {

+ 1
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/DefinitionMemberGroup.java View File

@@ -264,7 +264,7 @@ public class DefinitionMemberGroup {
264 264
 				for (ITypeID resultHint : typeHints) {
265 265
 					Map<TypeParameter, ITypeID> mapping = new HashMap<>();
266 266
 					if (header.returnType.inferTypeParameters(scope.getMemberCache(), resultHint, mapping)) {
267
-						header = header.withGenericArguments(scope.getLocalTypeParameters().getInner(mapping));
267
+						header = header.withGenericArguments(scope.getTypeRegistry(), scope.getLocalTypeParameters().getInner(scope.getTypeRegistry(), mapping));
268 268
 						break;
269 269
 					}
270 270
 				}

+ 1
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java View File

@@ -399,7 +399,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
399 399
 		if (definition instanceof VariantDefinition) {
400 400
 			VariantDefinition variant = (VariantDefinition) definition;
401 401
 			for (VariantDefinition.Option option : variant.options)
402
-				members.addVariantOption(option.instance(mapper));
402
+				members.addVariantOption(option.instance(type, mapper));
403 403
 		}
404 404
 		
405 405
 		if (definition instanceof EnumDefinition) {

+ 3
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMembers.java View File

@@ -39,6 +39,7 @@ import org.openzen.zenscript.codemodel.partial.IPartialExpression;
39 39
 import org.openzen.zenscript.codemodel.partial.PartialMemberGroupExpression;
40 40
 import org.openzen.zenscript.codemodel.partial.PartialStaticMemberGroupExpression;
41 41
 import org.openzen.zenscript.codemodel.partial.PartialTypeExpression;
42
+import org.openzen.zenscript.codemodel.partial.PartialVariantOptionExpression;
42 43
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
43 44
 import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
44 45
 import org.openzen.zenscript.codemodel.type.GenericName;
@@ -483,6 +484,8 @@ public final class TypeMembers {
483 484
 			return new PartialStaticMemberGroupExpression(position, scope, type, members.get(name.name), name.arguments);
484 485
 		if (innerTypes.containsKey(name.name))
485 486
 			return new PartialTypeExpression(position, innerTypes.get(name.name).instance(cache.getRegistry(), name.arguments, (DefinitionTypeID)type), name.arguments);
487
+		if (variantOptions.containsKey(name.name))
488
+			return new PartialVariantOptionExpression(position, scope, variantOptions.get(name.name));
486 489
 		
487 490
 		return null;
488 491
 	}

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

@@ -136,7 +136,7 @@ public class JavaCompiler implements ZenCodeCompiler {
136 136
 			// convert scripts into methods (add them to a Scripts class?)
137 137
 			// (TODO: can we break very long scripts into smaller methods? for the extreme scripts)
138 138
 			final JavaClassWriter visitor = scriptFile.classWriter;
139
-			JavaMethod method = new JavaMethod(new JavaClass(script.pkg.fullName, className, JavaClass.Kind.CLASS), JavaMethod.Kind.STATIC, methodName, true, "()V", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
139
+			JavaMethod method = JavaMethod.getStatic(new JavaClass(script.pkg.fullName, className, JavaClass.Kind.CLASS), methodName, "()V", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
140 140
 			scriptFile.scriptMethods.add(method);
141 141
 
142 142
 			final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, new JavaWriter(visitor, method, null, null, null));
@@ -147,7 +147,7 @@ public class JavaCompiler implements ZenCodeCompiler {
147 147
 			statementVisitor.end();
148 148
 		}
149 149
 		
150
-		JavaMethod runMethod = new JavaMethod(new JavaClass("script", "Scripts", JavaClass.Kind.CLASS), JavaMethod.Kind.STATIC, "run", true, "()V", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
150
+		JavaMethod runMethod = JavaMethod.getStatic(new JavaClass("script", "Scripts", JavaClass.Kind.CLASS), "run", "()V", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
151 151
 		final JavaWriter runWriter = new JavaWriter(scriptsClassWriter, runMethod, null, null, null);
152 152
 		runWriter.start();
153 153
 		for (Map.Entry<String, JavaScriptFile> entry : scriptBlocks.entrySet()) {

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

@@ -274,7 +274,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
274 274
 					throw new UnsupportedOperationException("Unknown builtin comparator: " + expression.operator.getBuiltin());
275 275
 			}
276 276
 		} else {
277
-			if (!checkAndExecuteMethodInfo(expression.operator))
277
+			if (!checkAndExecuteMethodInfo(expression.operator, expression.type))
278 278
 				throw new IllegalStateException("Call target has no method info!");
279 279
 
280 280
 			expression.left.accept(this);
@@ -358,7 +358,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
358 358
 				argument.accept(this);
359 359
 			}
360 360
 
361
-			if (!checkAndExecuteMethodInfo(expression.member))
361
+			if (!checkAndExecuteMethodInfo(expression.member, expression.type))
362 362
 				throw new IllegalStateException("Call target has no method info!");
363 363
 			return null;
364 364
 		}
@@ -792,7 +792,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
792 792
 					}
793 793
 				} else {
794 794
 					javaWriter.invokeStatic(ARRAYS_COPY_OF_RANGE_OBJECTS);
795
-					javaWriter.checkCast(context.getDescriptor(type));
795
+					javaWriter.checkCast(context.getInternalName(type));
796 796
 				}
797 797
 				break;
798 798
 			}
@@ -870,7 +870,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
870 870
 
871 871
 		BuiltinID builtin = expression.member.getBuiltin();
872 872
 		if (builtin == null) {
873
-			if (!checkAndExecuteMethodInfo(expression.member))
873
+			if (!checkAndExecuteMethodInfo(expression.member, expression.type))
874 874
 				throw new IllegalStateException("Call target has no method info!");
875 875
 
876 876
 			return null;
@@ -977,7 +977,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
977 977
 
978 978
 		BuiltinID builtin = expression.member.member.builtin;
979 979
 		if (builtin == null) {
980
-			if (!checkAndExecuteMethodInfo(expression.member))
980
+			if (!checkAndExecuteMethodInfo(expression.member, expression.type))
981 981
 				throw new IllegalStateException("Call target has no method info!");
982 982
 
983 983
 			return null;
@@ -1719,9 +1719,9 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1719 1719
 	public Void visitGetMatchingVariantField(GetMatchingVariantField expression) {
1720 1720
 		javaWriter.loadObject(0);
1721 1721
 		final ITypeID type = expression.value.option.getParameterType(expression.index);
1722
-		final JavaClass tag = expression.value.option.getTag(JavaClass.class);
1723
-		javaWriter.checkCast("L" + tag.internalName + ";");
1724
-		javaWriter.getField(new JavaField(tag, "field" + expression.index, context.getDescriptor(type)));
1722
+		final JavaVariantOption tag = expression.value.option.getTag(JavaVariantOption.class);
1723
+		javaWriter.checkCast(tag.variantOptionClass.internalName);
1724
+		javaWriter.getField(new JavaField(tag.variantOptionClass, "field" + expression.index, context.getDescriptor(type)));
1725 1725
 		return null;
1726 1726
 	}
1727 1727
 
@@ -1738,7 +1738,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1738 1738
 
1739 1739
 		BuiltinID builtin = expression.getter.member.builtin;
1740 1740
 		if (builtin == null) {
1741
-			if (!checkAndExecuteMethodInfo(expression.getter))
1741
+			if (!checkAndExecuteMethodInfo(expression.getter, expression.type))
1742 1742
 				throw new IllegalStateException("Call target has no method info!");
1743 1743
 
1744 1744
 			return null;
@@ -1940,14 +1940,14 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1940 1940
     @Override
1941 1941
     public Void visitInterfaceCast(InterfaceCastExpression expression) {
1942 1942
         expression.value.accept(this);
1943
-        javaWriter.checkCast(context.getDescriptor(expression.type));
1943
+        javaWriter.checkCast(context.getInternalName(expression.type));
1944 1944
         return null;
1945 1945
     }
1946 1946
 
1947 1947
     @Override
1948 1948
     public Void visitIs(IsExpression expression) {
1949 1949
         expression.value.accept(this);
1950
-        javaWriter.instanceOf(context.getDescriptor(expression.isType));
1950
+        javaWriter.instanceOf(context.getInternalName(expression.isType));
1951 1951
         return null;
1952 1952
     }
1953 1953
 
@@ -2108,7 +2108,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2108 2108
 	public Void visitPostCall(PostCallExpression expression) {
2109 2109
 		expression.target.accept(this);
2110 2110
 		javaWriter.dup(context.getType(expression.type));
2111
-		if (!checkAndExecuteMethodInfo(expression.member))
2111
+		if (!checkAndExecuteMethodInfo(expression.member, expression.type))
2112 2112
 			throw new IllegalStateException("Call target has no method info!");
2113 2113
 
2114 2114
 		return null;
@@ -2199,7 +2199,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2199 2199
 	public Void visitStaticGetter(StaticGetterExpression expression) {
2200 2200
 		BuiltinID builtin = expression.getter.member.builtin;
2201 2201
 		if (builtin == null) {
2202
-			if (!checkAndExecuteMethodInfo(expression.getter))
2202
+			if (!checkAndExecuteMethodInfo(expression.getter, expression.type))
2203 2203
 				throw new IllegalStateException("Call target has no method info!");
2204 2204
 
2205 2205
 			return null;
@@ -2325,7 +2325,8 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2325 2325
 
2326 2326
 	@Override
2327 2327
 	public Void visitVariantValue(VariantValueExpression expression) {
2328
-		final String internalName = expression.option.getTag(JavaClass.class).internalName;
2328
+		JavaVariantOption tag = expression.option.getTag(JavaVariantOption.class);
2329
+		final String internalName = tag.variantOptionClass.internalName;
2329 2330
 		javaWriter.newObject(internalName);
2330 2331
 		javaWriter.dup();
2331 2332
 
@@ -2357,7 +2358,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2357 2358
     }
2358 2359
 
2359 2360
     //Will return true if a JavaMethodInfo.class tag exists, and will compile that tag
2360
-    private boolean checkAndExecuteMethodInfo(DefinitionMemberRef member) {
2361
+    private boolean checkAndExecuteMethodInfo(DefinitionMemberRef member, ITypeID resultType) {
2361 2362
         JavaMethod methodInfo = member.getTag(JavaMethod.class);
2362 2363
         if (methodInfo == null)
2363 2364
             return false;
@@ -2367,6 +2368,9 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2367 2368
         } else {
2368 2369
             getJavaWriter().invokeVirtual(methodInfo);
2369 2370
         }
2371
+		if (methodInfo.genericResult)
2372
+			getJavaWriter().checkCast(context.getInternalName(resultType));
2373
+		
2370 2374
         return true;
2371 2375
     }
2372 2376
 

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

@@ -349,11 +349,11 @@ public class JavaWriter {
349 349
         }
350 350
     }
351 351
 
352
-    public void checkCast(String descriptor) {
352
+    public void checkCast(String internalName) {
353 353
         if (debug)
354
-            System.out.println("checkCast " + descriptor);
354
+            System.out.println("checkCast " + internalName);
355 355
 
356
-        visitor.visitTypeInsn(CHECKCAST, descriptor);
356
+        visitor.visitTypeInsn(CHECKCAST, internalName);
357 357
     }
358 358
 
359 359
     public void checkCast(Type type) {

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

@@ -101,7 +101,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
101 101
             member.accept(visitor);
102 102
         }
103 103
 		
104
-		JavaMethod valuesMethod = new JavaMethod(toClass, JavaMethod.Kind.STATIC, "values", true, "()[L" + toClass.internalName + ";", Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
104
+		JavaMethod valuesMethod = JavaMethod.getStatic(toClass, "values", "()[L" + toClass.internalName + ";", Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
105 105
 		JavaWriter valuesWriter = new JavaWriter(writer, true, valuesMethod, definition, null, null);
106 106
 		valuesWriter.start();
107 107
 		valuesWriter.getStaticField(toClass.internalName, "$VALUES", "[L" + toClass.internalName + ";");
@@ -110,13 +110,13 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
110 110
 		valuesWriter.returnObject();
111 111
 		valuesWriter.end();
112 112
 
113
-		JavaMethod valueOfMethod = new JavaMethod(toClass, JavaMethod.Kind.STATIC, "valueOf", true, "(Ljava/lang/String;)L" + toClass.internalName + ";", Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
113
+		JavaMethod valueOfMethod = JavaMethod.getStatic(toClass, "valueOf", "(Ljava/lang/String;)L" + toClass.internalName + ";", Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
114 114
 		JavaWriter valueOfWriter = new JavaWriter(writer, true, valueOfMethod, definition, null, null);
115 115
 		valueOfWriter.start();
116 116
 		valueOfWriter.invokeStatic(CLASS_FORNAME);
117 117
 		valueOfWriter.loadObject(0);
118 118
 		valueOfWriter.invokeStatic(ENUM_VALUEOF);
119
-		valueOfWriter.checkCast("L" + toClass.internalName + ";");
119
+		valueOfWriter.checkCast(toClass.internalName);
120 120
 		valueOfWriter.returnObject();
121 121
 		valueOfWriter.end();
122 122
 		
@@ -202,13 +202,13 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
202 202
 
203 203
 			ITypeID[] types = option.types;
204 204
 			for (int i = 0; i < types.length; ++i) {
205
-				final String internalName = context.getInternalName(types[i]);
206
-				optionInitDescBuilder.append(internalName);
207
-				optionWriter.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "field" + i, internalName, "TT" + i + ";", null).visitEnd();
205
+				final String descriptor = context.getDescriptor(types[i]);
206
+				optionInitDescBuilder.append(descriptor);
207
+				optionWriter.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "field" + i, descriptor, "TT" + i + ";", null).visitEnd();
208 208
 			}
209 209
 			optionInitDescBuilder.append(")V");
210 210
 			
211
-			JavaMethod constructorMethod = new JavaMethod(optionTag.variantOptionClass, JavaMethod.Kind.CONSTRUCTOR, "<init>", true, optionInitDescBuilder.toString(), JavaModifiers.PUBLIC);
211
+			JavaMethod constructorMethod = JavaMethod.getConstructor(optionTag.variantOptionClass, optionInitDescBuilder.toString(), JavaModifiers.PUBLIC);
212 212
 			final JavaWriter initWriter = new JavaWriter(optionWriter, constructorMethod, variant, optionInitDescBuilder.toString(), null);
213 213
 			initWriter.start();
214 214
 			initWriter.loadObject(0);
@@ -226,7 +226,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
226 226
 			initWriter.end();
227 227
 			
228 228
 			//Denominator for switch-cases
229
-			JavaMethod denominator = new JavaMethod(optionTag.variantOptionClass, JavaMethod.Kind.INSTANCE, "getDenominator", true, "()I", JavaModifiers.PUBLIC);
229
+			JavaMethod denominator = JavaMethod.getVirtual(optionTag.variantOptionClass, "getDenominator", "()I", JavaModifiers.PUBLIC);
230 230
 			final JavaWriter getDenominator = new JavaWriter(optionWriter, denominator, null, null, null, "java/lang/Override");
231 231
 			getDenominator.start();
232 232
 			getDenominator.constant(option.ordinal);
@@ -251,7 +251,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
251 251
 			member.accept(visitor);
252 252
 		}
253 253
 
254
-		final JavaWriter superInitWriter = new JavaWriter(writer, new JavaMethod(toClass, JavaMethod.Kind.CONSTRUCTOR, "<init>", true, "()V", Opcodes.ACC_PUBLIC), variant, "()V", null);
254
+		final JavaWriter superInitWriter = new JavaWriter(writer, JavaMethod.getConstructor(toClass, "()V", Opcodes.ACC_PUBLIC), variant, "()V", null);
255 255
 		superInitWriter.start();
256 256
 		superInitWriter.loadObject(0);
257 257
 		superInitWriter.invokeSpecial("java/lang/Object", "<init>", "()V");

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

@@ -33,7 +33,7 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
33 33
         this.definition = definition;
34 34
 		this.context = context;
35 35
 
36
-        final JavaWriter javaWriter = new JavaWriter(writer, new JavaMethod(toClass, JavaMethod.Kind.STATICINIT, "<clinit>", true, "()V", 0), definition, null, null);
36
+        final JavaWriter javaWriter = new JavaWriter(writer, new JavaMethod(toClass, JavaMethod.Kind.STATICINIT, "<clinit>", true, "()V", 0, false), definition, null, null);
37 37
         this.clinitStatementVisitor = new JavaStatementVisitor(context, javaWriter);
38 38
         this.clinitStatementVisitor.start();
39 39
         CompilerUtils.writeDefaultFieldInitializers(context, javaWriter, definition, true);
@@ -99,7 +99,7 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
99 99
 
100 100
 	@Override
101 101
 	public Void visitDestructor(DestructorMember member) {
102
-		final JavaMethod method = new JavaMethod(toClass, JavaMethod.Kind.INSTANCE, "close", true, "()V", Opcodes.ACC_PUBLIC);
102
+		final JavaMethod method = JavaMethod.getVirtual(toClass, "close", "()V", Opcodes.ACC_PUBLIC);
103 103
 
104 104
 		final Label constructorStart = new Label();
105 105
 		final Label constructorEnd = new Label();

+ 15
- 8
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaMethod.java View File

@@ -11,31 +11,35 @@ package org.openzen.zenscript.javashared;
11 11
  */
12 12
 public class JavaMethod {
13 13
 	public static JavaMethod getConstructor(JavaClass cls, String descriptor, int modifiers) {
14
-		return new JavaMethod(cls, Kind.CONSTRUCTOR, "<init>", true, descriptor, modifiers);
14
+		return new JavaMethod(cls, Kind.CONSTRUCTOR, "<init>", true, descriptor, modifiers, false);
15 15
 	}
16 16
 	
17 17
 	public static JavaMethod getNativeConstructor(JavaClass cls, String descriptor) {
18
-		return new JavaMethod(cls, Kind.CONSTRUCTOR, "<init>", false, descriptor, JavaModifiers.PUBLIC);
18
+		return new JavaMethod(cls, Kind.CONSTRUCTOR, "<init>", false, descriptor, JavaModifiers.PUBLIC, false);
19 19
 	}
20 20
 	
21 21
 	public static JavaMethod getDestructor(JavaClass cls, int modifiers) {
22
-		return new JavaMethod(cls, Kind.INSTANCE, "close", true, "()V", modifiers);
22
+		return new JavaMethod(cls, Kind.INSTANCE, "close", true, "()V", modifiers, false);
23 23
 	}
24 24
 	
25 25
 	public static JavaMethod getStatic(JavaClass cls, String name, String descriptor, int modifiers) {
26
-		return new JavaMethod(cls, Kind.STATIC, name, true, descriptor, modifiers | JavaModifiers.STATIC);
26
+		return new JavaMethod(cls, Kind.STATIC, name, true, descriptor, modifiers | JavaModifiers.STATIC, false);
27 27
 	}
28 28
 	
29 29
 	public static JavaMethod getNativeStatic(JavaClass cls, String name, String descriptor) {
30
-		return new JavaMethod(cls, Kind.STATIC, name, false, descriptor, JavaModifiers.STATIC | JavaModifiers.PUBLIC);
30
+		return new JavaMethod(cls, Kind.STATIC, name, false, descriptor, JavaModifiers.STATIC | JavaModifiers.PUBLIC, false);
31 31
 	}
32 32
 	
33 33
 	public static JavaMethod getVirtual(JavaClass cls, String name, String descriptor, int modifiers) {
34
-		return new JavaMethod(cls, Kind.INSTANCE, name, true, descriptor, modifiers);
34
+		return new JavaMethod(cls, Kind.INSTANCE, name, true, descriptor, modifiers, false);
35 35
 	}
36 36
 	
37 37
 	public static JavaMethod getNativeVirtual(JavaClass cls, String name, String descriptor) {
38
-		return new JavaMethod(cls, Kind.INSTANCE, name, false, descriptor, JavaModifiers.PUBLIC);
38
+		return new JavaMethod(cls, Kind.INSTANCE, name, false, descriptor, JavaModifiers.PUBLIC, false);
39
+	}
40
+
41
+	public static JavaMethod getNativeExpansion(JavaClass cls, String name, String descriptor) {
42
+		return new JavaMethod(cls, Kind.EXPANSION, name, false, descriptor, JavaModifiers.PUBLIC | JavaModifiers.STATIC, false);
39 43
 	}
40 44
 	
41 45
 	public final JavaClass cls;
@@ -46,8 +50,9 @@ public class JavaMethod {
46 50
 	
47 51
 	public final String descriptor;
48 52
 	public final int modifiers;
53
+	public final boolean genericResult;
49 54
 	
50
-	public JavaMethod(JavaClass cls, Kind kind, String name, boolean compile, String descriptor, int modifiers) {
55
+	public JavaMethod(JavaClass cls, Kind kind, String name, boolean compile, String descriptor, int modifiers, boolean genericResult) {
51 56
 		this.cls = cls;
52 57
 		this.kind = kind;
53 58
 		this.name = name;
@@ -56,6 +61,7 @@ public class JavaMethod {
56 61
 		
57 62
 		this.descriptor = descriptor;
58 63
 		this.modifiers = modifiers;
64
+		this.genericResult = genericResult;
59 65
 	}
60 66
 	
61 67
 	public JavaMethod(JavaNativeTranslation<?> translation) {
@@ -66,6 +72,7 @@ public class JavaMethod {
66 72
 		this.translation = translation;
67 73
 		this.descriptor = "";
68 74
 		this.modifiers = 0;
75
+		this.genericResult = false;
69 76
 	}
70 77
 	
71 78
 	public enum Kind {

+ 2
- 2
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaNativeClass.java View File

@@ -31,11 +31,11 @@ public class JavaNativeClass {
31 31
 	}
32 32
 	
33 33
 	public void addConstructor(String key, String descriptor) {
34
-		methods.put(key, new JavaMethod(cls, JavaMethod.Kind.CONSTRUCTOR, "<init>", false, descriptor, JavaModifiers.PUBLIC));
34
+		methods.put(key, new JavaMethod(cls, JavaMethod.Kind.CONSTRUCTOR, "<init>", false, descriptor, JavaModifiers.PUBLIC, false));
35 35
 	}
36 36
 	
37 37
 	public void addInstanceMethod(String key, String name, String descriptor) {
38
-		methods.put(key, new JavaMethod(cls, JavaMethod.Kind.INSTANCE, name, false, descriptor, JavaModifiers.PUBLIC));
38
+		methods.put(key, new JavaMethod(cls, JavaMethod.Kind.INSTANCE, name, false, descriptor, JavaModifiers.PUBLIC, false));
39 39
 	}
40 40
 	
41 41
 	public JavaMethod getMethod(String name) {

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

@@ -7,7 +7,6 @@ package org.openzen.zenscript.javashared.prepare;
7 7
 
8 8
 import org.openzen.zenscript.javashared.JavaNativeClass;
9 9
 import org.openzen.zencode.shared.StringExpansion;
10
-import org.openzen.zenscript.codemodel.Modifiers;
11 10
 import org.openzen.zenscript.codemodel.OperatorType;
12 11
 import org.openzen.zenscript.codemodel.annotations.NativeTag;
13 12
 import org.openzen.zenscript.codemodel.member.CallerMember;
@@ -29,6 +28,7 @@ import org.openzen.zenscript.codemodel.member.OperatorMember;
29 28
 import org.openzen.zenscript.codemodel.member.SetterMember;
30 29
 import org.openzen.zenscript.codemodel.member.StaticInitializerMember;
31 30
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
31
+import org.openzen.zenscript.codemodel.type.GenericTypeID;
32 32
 import org.openzen.zenscript.javashared.JavaTypeNameVisitor;
33 33
 import org.openzen.zenscript.javashared.JavaClass;
34 34
 import org.openzen.zenscript.javashared.JavaField;
@@ -291,9 +291,23 @@ public class JavaPrepareClassMethodVisitor implements MemberVisitor<Void> {
291 291
 			if (baseMethod == null)
292 292
 				throw new IllegalStateException("Base method not yet prepared!");
293 293
 			
294
-			method = new JavaMethod(cls, baseMethod.kind, baseMethod.name, true, context.getMethodDescriptor(member.header), JavaModifiers.getJavaModifiers(member.modifiers));
294
+			method = new JavaMethod(
295
+					cls,
296
+					baseMethod.kind,
297
+					baseMethod.name,
298
+					true,
299
+					context.getMethodDescriptor(member.header),
300
+					JavaModifiers.getJavaModifiers(member.modifiers),
301
+					member.header.returnType instanceof GenericTypeID);
295 302
 		} else if (method == null) {
296
-			method = new JavaMethod(cls, getKind(member), name, true, context.getMethodDescriptor(member.header), JavaModifiers.getJavaModifiers(member.modifiers));
303
+			method = new JavaMethod(
304
+					cls,
305
+					getKind(member),
306
+					name,
307
+					true,
308
+					context.getMethodDescriptor(member.header),
309
+					JavaModifiers.getJavaModifiers(member.modifiers),
310
+					member.header.returnType instanceof GenericTypeID);
297 311
 		}
298 312
 		
299 313
 		if (method.compile) {

+ 8
- 9
JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareDefinitionVisitor.java View File

@@ -29,7 +29,6 @@ import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
29 29
 import org.openzen.zenscript.codemodel.type.ITypeID;
30 30
 import org.openzen.zenscript.javashared.JavaClass;
31 31
 import org.openzen.zenscript.javashared.JavaMethod;
32
-import org.openzen.zenscript.javashared.JavaModifiers;
33 32
 import org.openzen.zenscript.javashared.JavaVariantOption;
34 33
 
35 34
 /**
@@ -67,7 +66,7 @@ public class JavaPrepareDefinitionVisitor implements DefinitionVisitor<JavaClass
67 66
 		{
68 67
 			JavaNativeClass list = new JavaNativeClass(new JavaClass("java.util", "List", JavaClass.Kind.INTERFACE));
69 68
 			JavaClass arrayList = new JavaClass("java.util", "ArrayList", JavaClass.Kind.CLASS);
70
-			list.addMethod("constructor", new JavaMethod(arrayList, JavaMethod.Kind.CONSTRUCTOR, "", false, "()V", JavaModifiers.PUBLIC));
69
+			list.addMethod("constructor", JavaMethod.getNativeConstructor(arrayList, "()V"));
71 70
 			list.addInstanceMethod("add", "add", "(Ljava/lang/Object;)Z"); List<?> l;
72 71
 			list.addInstanceMethod("insert", "add", "(Ljava/lang/Object;I)V");
73 72
 			list.addInstanceMethod("remove", "remove", "(java/lang/Object;)Z");
@@ -107,9 +106,9 @@ public class JavaPrepareDefinitionVisitor implements DefinitionVisitor<JavaClass
107 106
 			JavaClass math = new JavaClass("java.lang", "Math", JavaClass.Kind.CLASS);
108 107
 			
109 108
 			JavaNativeClass cls = new JavaNativeClass(integer);
110
-			cls.addMethod("min", new JavaMethod(math, JavaMethod.Kind.STATIC, "min", false, "(II)I", JavaModifiers.PUBLIC | JavaModifiers.STATIC));
111
-			cls.addMethod("max", new JavaMethod(math, JavaMethod.Kind.STATIC, "max", false, "(II)I", JavaModifiers.PUBLIC | JavaModifiers.STATIC));
112
-			cls.addMethod("toHexString", new JavaMethod(integer, JavaMethod.Kind.EXPANSION, "toHexString", false, "()Ljava/lang/String;", JavaModifiers.PUBLIC | JavaModifiers.STATIC));
109
+			cls.addMethod("min", JavaMethod.getNativeStatic(math, "min", "(II)I"));
110
+			cls.addMethod("max", JavaMethod.getNativeStatic(math, "max", "(II)I"));
111
+			cls.addMethod("toHexString", JavaMethod.getNativeExpansion(integer, "toHexString", "(I)Ljava/lang/String;"));
113 112
 			nativeClasses.put("stdlib::Integer", cls);
114 113
 		}
115 114
 		
@@ -132,11 +131,11 @@ public class JavaPrepareDefinitionVisitor implements DefinitionVisitor<JavaClass
132 131
 		{
133 132
 			JavaClass arrays = new JavaClass("java.lang", "Arrays", JavaClass.Kind.CLASS);
134 133
 			JavaNativeClass cls = new JavaNativeClass(arrays);
135
-			cls.addMethod("sort", new JavaMethod(arrays, JavaMethod.Kind.EXPANSION, "sort", false, "([Ljava/lang/Object;)[Ljava/lang/Object;", JavaModifiers.PUBLIC | JavaModifiers.STATIC));
134
+			cls.addMethod("sort", JavaMethod.getNativeExpansion(arrays, "sort", "([Ljava/lang/Object;)[Ljava/lang/Object;"));
136 135
 			cls.addMethod("sorted", new JavaMethod((expression, translator) -> {
137 136
 				return translator.sorted(((CallExpression)expression).target);
138 137
 			}));
139
-			cls.addMethod("sortWithComparator", new JavaMethod(arrays, JavaMethod.Kind.EXPANSION, "sort", false, "([Ljava/lang/Object;Ljava/lang/Comparator;)[Ljava/lang/Object;", JavaModifiers.PUBLIC | JavaModifiers.STATIC));
138
+			cls.addMethod("sortWithComparator", JavaMethod.getNativeExpansion(arrays, "sort", "([Ljava/lang/Object;Ljava/lang/Comparator;)[Ljava/lang/Object;"));
140 139
 			cls.addMethod("sortedWithComparator", new JavaMethod((expression, translator) -> {
141 140
 				return translator.sortedWithComparator(
142 141
 						((CallExpression)expression).target,
@@ -145,7 +144,7 @@ public class JavaPrepareDefinitionVisitor implements DefinitionVisitor<JavaClass
145 144
 			cls.addMethod("copy", new JavaMethod((expression, translator) -> {
146 145
 				return translator.copy(((CallExpression)expression).target);
147 146
 			}));
148
-			cls.addMethod("copyResize", new JavaMethod(arrays, JavaMethod.Kind.EXPANSION, "copyOf", false, "([Ljava/lang/Object;I)[Ljava/lang/Object;", JavaModifiers.PUBLIC | JavaModifiers.STATIC));
147
+			cls.addMethod("copyResize", JavaMethod.getNativeExpansion(arrays, "copyOf", "([Ljava/lang/Object;I)[Ljava/lang/Object;"));
149 148
 			cls.addMethod("copyTo", new JavaMethod((expression, translator) -> {
150 149
 				return translator.copyTo((CallExpression)expression);
151 150
 			}));
@@ -286,7 +285,7 @@ public class JavaPrepareDefinitionVisitor implements DefinitionVisitor<JavaClass
286 285
 		variant.setTag(JavaClass.class, cls);
287 286
 		
288 287
 		for (VariantDefinition.Option option : variant.options) {
289
-			JavaClass variantCls = new JavaClass(cls.fullName, option.name, JavaClass.Kind.CLASS);
288
+			JavaClass variantCls = new JavaClass(cls, option.name, JavaClass.Kind.CLASS);
290 289
 			option.setTag(JavaVariantOption.class, new JavaVariantOption(cls, variantCls));
291 290
 		}
292 291
 		

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

@@ -27,6 +27,7 @@ import org.openzen.zenscript.codemodel.member.MethodMember;
27 27
 import org.openzen.zenscript.codemodel.member.OperatorMember;
28 28
 import org.openzen.zenscript.codemodel.member.SetterMember;
29 29
 import org.openzen.zenscript.codemodel.member.StaticInitializerMember;
30
+import org.openzen.zenscript.codemodel.type.GenericTypeID;
30 31
 import org.openzen.zenscript.javashared.JavaTypeNameVisitor;
31 32
 import org.openzen.zenscript.javashared.JavaClass;
32 33
 import org.openzen.zenscript.javashared.JavaField;
@@ -159,7 +160,7 @@ public class JavaPrepareExpansionMethodVisitor implements MemberVisitor<Void> {
159 160
 		if (nativeTag != null && nativeClass != null)
160 161
 			method = nativeClass.getMethod(nativeTag.value);
161 162
 		if (method == null)
162
-			method = new JavaMethod(cls, getKind(member), name, true, context.getMethodDescriptor(member.header), JavaModifiers.getJavaModifiers(member.modifiers)); 
163
+			method = new JavaMethod(cls, getKind(member), name, true, context.getMethodDescriptor(member.header), JavaModifiers.getJavaModifiers(member.modifiers), member.header.returnType instanceof GenericTypeID); 
163 164
 		
164 165
 		if (method.compile) {
165 166
 			if (DEBUG_EMPTY && cls.empty)

+ 2
- 3
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceSyntheticHelperGenerator.java View File

@@ -30,7 +30,6 @@ import org.openzen.zenscript.codemodel.type.RangeTypeID;
30 30
 import org.openzen.zenscript.javashared.JavaClass;
31 31
 import org.openzen.zenscript.javashared.JavaContext;
32 32
 import org.openzen.zenscript.javashared.JavaMethod;
33
-import org.openzen.zenscript.javashared.JavaModifiers;
34 33
 
35 34
 /**
36 35
  *
@@ -60,7 +59,7 @@ public class JavaSourceSyntheticHelperGenerator {
60 59
 		addMember(arrayHelpers, method);
61 60
 		
62 61
 		String descriptor = "(" + context.getDescriptor(type) + context.getDescriptor(type.elementType) + ")Z";
63
-		JavaMethod sourceMethod = new JavaMethod(arrayHelpers, JavaMethod.Kind.EXPANSION, kind.containsName, false, descriptor, JavaModifiers.PUBLIC | JavaModifiers.STATIC);
62
+		JavaMethod sourceMethod = JavaMethod.getNativeExpansion(arrayHelpers, kind.containsName, descriptor);
64 63
 		existingContains.put(kind, sourceMethod);
65 64
 		return sourceMethod;
66 65
 	}
@@ -74,7 +73,7 @@ public class JavaSourceSyntheticHelperGenerator {
74 73
 		addMember(arrayHelpers, method);
75 74
 		
76 75
 		String descriptor = "(" + context.getDescriptor(type) + ")I";
77
-		JavaMethod sourceMethod = new JavaMethod(arrayHelpers, JavaMethod.Kind.EXPANSION, kind.containsName, false, descriptor, JavaModifiers.PUBLIC | JavaModifiers.STATIC);
76
+		JavaMethod sourceMethod = JavaMethod.getNativeExpansion(arrayHelpers, kind.containsName, descriptor);
78 77
 		existingContains.put(kind, sourceMethod);
79 78
 		return sourceMethod;
80 79
 	}

+ 1
- 1
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedCallArguments.java View File

@@ -158,7 +158,7 @@ public class ParsedCallArguments {
158 158
 		}
159 159
 		
160 160
 		ITypeID[] typeParameters = genericParameters;
161
-		if (typeParameters == null) {
161
+		if (typeParameters == null || typeParameters.length == 0) {
162 162
 			for (FunctionHeader candidate : candidates) {
163 163
 				if (candidate.typeParameters != null) {
164 164
 					typeParameters = new ITypeID[candidate.typeParameters.length];

+ 7
- 2
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionFunction.java View File

@@ -24,6 +24,7 @@ import org.openzen.zenscript.codemodel.scope.BaseScope;
24 24
 import org.openzen.zenscript.codemodel.scope.ExpressionScope;
25 25
 import org.openzen.zenscript.codemodel.scope.LambdaScope;
26 26
 import org.openzen.zenscript.codemodel.scope.StatementScope;
27
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
27 28
 import org.openzen.zenscript.parser.definitions.ParsedFunctionHeader;
28 29
 import org.openzen.zenscript.parser.statements.ParsedFunctionBody;
29 30
 
@@ -67,17 +68,21 @@ public class ParsedExpressionFunction extends ParsedExpression {
67 68
 		LambdaClosure closure = new LambdaClosure();
68 69
 		StatementScope innerScope = new LambdaScope(scope, closure, header);
69 70
 		Statement statements = body.compile(innerScope, header);
71
+		
72
+		if (header.returnType == BasicTypeID.UNDETERMINED) {
73
+			header.returnType = statements.getReturnType();
74
+		}
70 75
 		if (!scope.genericInferenceMap.isEmpty()) {
71 76
 			// perform type parameter inference
72 77
 			ITypeID returnType = statements.getReturnType();
73 78
 			Map<TypeParameter, ITypeID> inferredTypes = new HashMap<>();
74
-			if (!genericHeader.returnType.inferTypeParameters(scope.getMemberCache(), returnType, inferredTypes))
79
+			if (!returnType.inferTypeParameters(scope.getMemberCache(), genericHeader.returnType, inferredTypes))
75 80
 				throw new CompileException(position, CompileExceptionCode.TYPE_ARGUMENTS_NOT_INFERRABLE, "Could not infer generic type parameters");
76 81
 			
77 82
 			scope.genericInferenceMap.putAll(inferredTypes);
78 83
 		}
79 84
 		
80
-		FunctionTypeID functionType = scope.getTypeRegistry().getFunction(genericHeader.withGenericArguments(new GenericMapper(scope.getTypeRegistry(), scope.genericInferenceMap)));
85
+		FunctionTypeID functionType = scope.getTypeRegistry().getFunction(genericHeader.withGenericArguments(scope.getTypeRegistry(), new GenericMapper(scope.getTypeRegistry(), scope.genericInferenceMap)));
81 86
 		return new FunctionExpression(position, functionType, closure, header, statements);
82 87
 	}
83 88
 	

+ 2
- 1
Shared/src/main/java/org/openzen/zencode/shared/CompileExceptionCode.java View File

@@ -65,5 +65,6 @@ public enum CompileExceptionCode {
65 65
 	UNTYPED_EMPTY_MAP(),
66 66
 	VAR_WITHOUT_TYPE_OR_INITIALIZER(),
67 67
 	NO_BRACKET_PARSER(),
68
-	INVALID_BRACKET_EXPRESSION()
68
+	INVALID_BRACKET_EXPRESSION(),
69
+	VARIANT_OPTION_NOT_AN_EXPRESSION
69 70
 }

Loading…
Cancel
Save