|  | @@ -9,6 +9,7 @@ import java.lang.reflect.AnnotatedType;
 | 
		
	
		
			
			| 9 | 9 |  import java.lang.reflect.Field;
 | 
		
	
		
			
			| 10 | 10 |  import java.lang.reflect.Method;
 | 
		
	
		
			
			| 11 | 11 |  import java.lang.reflect.Modifier;
 | 
		
	
		
			
			|  | 12 | +import java.lang.reflect.Parameter;
 | 
		
	
		
			
			| 12 | 13 |  import java.lang.reflect.ParameterizedType;
 | 
		
	
		
			
			| 13 | 14 |  import java.lang.reflect.Type;
 | 
		
	
		
			
			| 14 | 15 |  import java.lang.reflect.TypeVariable;
 | 
		
	
	
		
			
			|  | @@ -31,8 +32,21 @@ import org.openzen.zenscript.codemodel.definition.EnumDefinition;
 | 
		
	
		
			
			| 31 | 32 |  import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
 | 
		
	
		
			
			| 32 | 33 |  import org.openzen.zenscript.codemodel.definition.StructDefinition;
 | 
		
	
		
			
			| 33 | 34 |  import org.openzen.zenscript.codemodel.definition.ZSPackage;
 | 
		
	
		
			
			|  | 35 | +import org.openzen.zenscript.codemodel.expression.ConstantByteExpression;
 | 
		
	
		
			
			|  | 36 | +import org.openzen.zenscript.codemodel.expression.ConstantDoubleExpression;
 | 
		
	
		
			
			|  | 37 | +import org.openzen.zenscript.codemodel.expression.ConstantFloatExpression;
 | 
		
	
		
			
			|  | 38 | +import org.openzen.zenscript.codemodel.expression.ConstantIntExpression;
 | 
		
	
		
			
			|  | 39 | +import org.openzen.zenscript.codemodel.expression.ConstantLongExpression;
 | 
		
	
		
			
			|  | 40 | +import org.openzen.zenscript.codemodel.expression.ConstantSByteExpression;
 | 
		
	
		
			
			|  | 41 | +import org.openzen.zenscript.codemodel.expression.ConstantShortExpression;
 | 
		
	
		
			
			|  | 42 | +import org.openzen.zenscript.codemodel.expression.ConstantStringExpression;
 | 
		
	
		
			
			|  | 43 | +import org.openzen.zenscript.codemodel.expression.ConstantUIntExpression;
 | 
		
	
		
			
			|  | 44 | +import org.openzen.zenscript.codemodel.expression.ConstantULongExpression;
 | 
		
	
		
			
			|  | 45 | +import org.openzen.zenscript.codemodel.expression.ConstantUShortExpression;
 | 
		
	
		
			
			|  | 46 | +import org.openzen.zenscript.codemodel.expression.Expression;
 | 
		
	
		
			
			| 34 | 47 |  import org.openzen.zenscript.codemodel.expression.ExpressionSymbol;
 | 
		
	
		
			
			| 35 | 48 |  import org.openzen.zenscript.codemodel.expression.StaticGetterExpression;
 | 
		
	
		
			
			|  | 49 | +import org.openzen.zenscript.codemodel.expression.StorageCastExpression;
 | 
		
	
		
			
			| 36 | 50 |  import org.openzen.zenscript.codemodel.generic.ParameterTypeBound;
 | 
		
	
		
			
			| 37 | 51 |  import org.openzen.zenscript.codemodel.generic.TypeParameter;
 | 
		
	
		
			
			| 38 | 52 |  import org.openzen.zenscript.codemodel.member.CasterMember;
 | 
		
	
	
		
			
			|  | @@ -54,6 +68,7 @@ import org.openzen.zenscript.codemodel.type.TypeID;
 | 
		
	
		
			
			| 54 | 68 |  import org.openzen.zenscript.codemodel.type.member.BuiltinID;
 | 
		
	
		
			
			| 55 | 69 |  import org.openzen.zenscript.codemodel.type.member.TypeMembers;
 | 
		
	
		
			
			| 56 | 70 |  import org.openzen.zenscript.codemodel.type.storage.AutoStorageTag;
 | 
		
	
		
			
			|  | 71 | +import org.openzen.zenscript.codemodel.type.storage.StaticStorageTag;
 | 
		
	
		
			
			| 57 | 72 |  import org.openzen.zenscript.codemodel.type.storage.StorageTag;
 | 
		
	
		
			
			| 58 | 73 |  import org.openzen.zenscript.javashared.JavaClass;
 | 
		
	
		
			
			| 59 | 74 |  import org.openzen.zenscript.javashared.JavaCompiledModule;
 | 
		
	
	
		
			
			|  | @@ -499,7 +514,7 @@ public class JavaNativeModule {
 | 
		
	
		
			
			| 499 | 514 |  		return getHeader(
 | 
		
	
		
			
			| 500 | 515 |  				context,
 | 
		
	
		
			
			| 501 | 516 |  				null,
 | 
		
	
		
			
			| 502 |  | -				constructor.getAnnotatedParameterTypes(),
 | 
		
	
		
			
			|  | 517 | +				constructor.getParameters(),
 | 
		
	
		
			
			| 503 | 518 |  				constructor.getTypeParameters(),
 | 
		
	
		
			
			| 504 | 519 |  				constructor.getAnnotatedExceptionTypes());
 | 
		
	
		
			
			| 505 | 520 |  	}
 | 
		
	
	
		
			
			|  | @@ -508,22 +523,84 @@ public class JavaNativeModule {
 | 
		
	
		
			
			| 508 | 523 |  		return getHeader(
 | 
		
	
		
			
			| 509 | 524 |  				context,
 | 
		
	
		
			
			| 510 | 525 |  				method.getAnnotatedReturnType(),
 | 
		
	
		
			
			| 511 |  | -				method.getAnnotatedParameterTypes(),
 | 
		
	
		
			
			|  | 526 | +				method.getParameters(),
 | 
		
	
		
			
			| 512 | 527 |  				method.getTypeParameters(),
 | 
		
	
		
			
			| 513 | 528 |  				method.getAnnotatedExceptionTypes());
 | 
		
	
		
			
			| 514 | 529 |  	}
 | 
		
	
		
			
			| 515 | 530 |  	
 | 
		
	
		
			
			|  | 531 | +	private Expression getDefaultValue(Parameter parameter, StoredType type) {
 | 
		
	
		
			
			|  | 532 | +		if (parameter.isAnnotationPresent(ZenCodeType.Optional.class)) {
 | 
		
	
		
			
			|  | 533 | +			Expression defaultValue = type.type.getDefaultValue();
 | 
		
	
		
			
			|  | 534 | +			if (defaultValue == null)
 | 
		
	
		
			
			|  | 535 | +				throw new IllegalArgumentException(type.toString() + " doesn't have a default value");
 | 
		
	
		
			
			|  | 536 | +			return defaultValue;
 | 
		
	
		
			
			|  | 537 | +		} else if (parameter.isAnnotationPresent(ZenCodeType.OptionalInt.class)) {
 | 
		
	
		
			
			|  | 538 | +			ZenCodeType.OptionalInt annotation = parameter.getAnnotation(ZenCodeType.OptionalInt.class);
 | 
		
	
		
			
			|  | 539 | +			if (type.type == BasicTypeID.BYTE)
 | 
		
	
		
			
			|  | 540 | +				return new ConstantByteExpression(CodePosition.NATIVE, annotation.value());
 | 
		
	
		
			
			|  | 541 | +			else if (type.type == BasicTypeID.SBYTE)
 | 
		
	
		
			
			|  | 542 | +				return new ConstantSByteExpression(CodePosition.NATIVE, (byte)annotation.value());
 | 
		
	
		
			
			|  | 543 | +			else if (type.type == BasicTypeID.SHORT)
 | 
		
	
		
			
			|  | 544 | +				return new ConstantShortExpression(CodePosition.NATIVE, (short)annotation.value());
 | 
		
	
		
			
			|  | 545 | +			else if (type.type == BasicTypeID.USHORT)
 | 
		
	
		
			
			|  | 546 | +				return new ConstantUShortExpression(CodePosition.NATIVE, annotation.value());
 | 
		
	
		
			
			|  | 547 | +			else if (type.type == BasicTypeID.INT)
 | 
		
	
		
			
			|  | 548 | +				return new ConstantIntExpression(CodePosition.NATIVE, annotation.value());
 | 
		
	
		
			
			|  | 549 | +			else if (type.type == BasicTypeID.UINT)
 | 
		
	
		
			
			|  | 550 | +				return new ConstantUIntExpression(CodePosition.NATIVE, annotation.value());
 | 
		
	
		
			
			|  | 551 | +			else
 | 
		
	
		
			
			|  | 552 | +				throw new IllegalArgumentException("Cannot use int default values for " + type.toString());
 | 
		
	
		
			
			|  | 553 | +		} else if (parameter.isAnnotationPresent(ZenCodeType.OptionalLong.class)) {
 | 
		
	
		
			
			|  | 554 | +			ZenCodeType.OptionalLong annotation = parameter.getAnnotation(ZenCodeType.OptionalLong.class);
 | 
		
	
		
			
			|  | 555 | +			if (type.type == BasicTypeID.LONG)
 | 
		
	
		
			
			|  | 556 | +				return new ConstantLongExpression(CodePosition.NATIVE, annotation.value());
 | 
		
	
		
			
			|  | 557 | +			else if (type.type == BasicTypeID.ULONG)
 | 
		
	
		
			
			|  | 558 | +				return new ConstantULongExpression(CodePosition.NATIVE, annotation.value());
 | 
		
	
		
			
			|  | 559 | +			else
 | 
		
	
		
			
			|  | 560 | +				throw new IllegalArgumentException("Cannot use long default values for " + type.toString());
 | 
		
	
		
			
			|  | 561 | +		} else if (parameter.isAnnotationPresent(ZenCodeType.OptionalFloat.class)) {
 | 
		
	
		
			
			|  | 562 | +			ZenCodeType.OptionalFloat annotation = parameter.getAnnotation(ZenCodeType.OptionalFloat.class);
 | 
		
	
		
			
			|  | 563 | +			if (type.type == BasicTypeID.FLOAT)
 | 
		
	
		
			
			|  | 564 | +				return new ConstantFloatExpression(CodePosition.NATIVE, annotation.value());
 | 
		
	
		
			
			|  | 565 | +			else
 | 
		
	
		
			
			|  | 566 | +				throw new IllegalArgumentException("Cannot use float default values for " + type.toString());
 | 
		
	
		
			
			|  | 567 | +		} else if (parameter.isAnnotationPresent(ZenCodeType.OptionalDouble.class)) {
 | 
		
	
		
			
			|  | 568 | +			ZenCodeType.OptionalDouble annotation = parameter.getAnnotation(ZenCodeType.OptionalDouble.class);
 | 
		
	
		
			
			|  | 569 | +			if (type.type == BasicTypeID.DOUBLE)
 | 
		
	
		
			
			|  | 570 | +				return new ConstantDoubleExpression(CodePosition.NATIVE, annotation.value());
 | 
		
	
		
			
			|  | 571 | +			else
 | 
		
	
		
			
			|  | 572 | +				throw new IllegalArgumentException("Cannot use double default values for " + type.toString());
 | 
		
	
		
			
			|  | 573 | +		} else if (parameter.isAnnotationPresent(ZenCodeType.OptionalString.class)) {
 | 
		
	
		
			
			|  | 574 | +			ZenCodeType.OptionalString annotation = parameter.getAnnotation(ZenCodeType.OptionalString.class);
 | 
		
	
		
			
			|  | 575 | +			if (type.type == StringTypeID.INSTANCE) {
 | 
		
	
		
			
			|  | 576 | +				Expression result = new ConstantStringExpression(CodePosition.NATIVE, annotation.value());
 | 
		
	
		
			
			|  | 577 | +				if (type.getActualStorage() != StaticStorageTag.INSTANCE)
 | 
		
	
		
			
			|  | 578 | +					result = new StorageCastExpression(CodePosition.NATIVE, result, type);
 | 
		
	
		
			
			|  | 579 | +				return result;
 | 
		
	
		
			
			|  | 580 | +			} else {
 | 
		
	
		
			
			|  | 581 | +				throw new IllegalArgumentException("Cannot use string default values for " + type.toString());
 | 
		
	
		
			
			|  | 582 | +			}
 | 
		
	
		
			
			|  | 583 | +		} else {
 | 
		
	
		
			
			|  | 584 | +			return null;
 | 
		
	
		
			
			|  | 585 | +		}
 | 
		
	
		
			
			|  | 586 | +	}
 | 
		
	
		
			
			|  | 587 | +	
 | 
		
	
		
			
			| 516 | 588 |  	private FunctionHeader getHeader(
 | 
		
	
		
			
			| 517 | 589 |  			TypeVariableContext context,
 | 
		
	
		
			
			| 518 | 590 |  			AnnotatedType javaReturnType,
 | 
		
	
		
			
			| 519 |  | -			AnnotatedType[] parameterTypes,
 | 
		
	
		
			
			|  | 591 | +			Parameter[] javaParameters,
 | 
		
	
		
			
			| 520 | 592 |  			TypeVariable<Method>[] javaTypeParameters,
 | 
		
	
		
			
			| 521 | 593 |  			AnnotatedType[] exceptionTypes) {
 | 
		
	
		
			
			| 522 | 594 |  		StoredType returnType = javaReturnType == null ? BasicTypeID.VOID.stored : loadStoredType(context, javaReturnType);
 | 
		
	
		
			
			| 523 | 595 |  		
 | 
		
	
		
			
			| 524 |  | -		FunctionParameter[] parameters = new FunctionParameter[parameterTypes.length];
 | 
		
	
		
			
			|  | 596 | +		FunctionParameter[] parameters = new FunctionParameter[javaParameters.length];
 | 
		
	
		
			
			| 525 | 597 |  		for (int i = 0; i < parameters.length; i++) {
 | 
		
	
		
			
			| 526 |  | -			parameters[i] = new FunctionParameter(loadStoredType(context, parameterTypes[i]));
 | 
		
	
		
			
			|  | 598 | +			Parameter parameter = javaParameters[i];
 | 
		
	
		
			
			|  | 599 | +			
 | 
		
	
		
			
			|  | 600 | +			AnnotatedType parameterType = parameter.getAnnotatedType();
 | 
		
	
		
			
			|  | 601 | +			StoredType type = loadStoredType(context, parameter.getAnnotatedType());
 | 
		
	
		
			
			|  | 602 | +			Expression defaultValue = getDefaultValue(parameter, type);
 | 
		
	
		
			
			|  | 603 | +			parameters[i] = new FunctionParameter(type, parameter.getName(), defaultValue, parameter.isVarArgs());
 | 
		
	
		
			
			| 527 | 604 |  		}
 | 
		
	
		
			
			| 528 | 605 |  		
 | 
		
	
		
			
			| 529 | 606 |  		TypeParameter[] typeParameters = new TypeParameter[javaTypeParameters.length];
 |