diff --git a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java index d22b4f125..5790f25a2 100644 --- a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java +++ b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java @@ -328,7 +328,7 @@ public boolean isSimilarTo(FunctionHeader other) { public FunctionHeader instanceForCall(CallArguments arguments) { if (arguments.getNumberOfTypeArguments() > 0) { Map typeParameters = TypeID.getMapping(this.typeParameters, arguments.typeArguments); - return instance(new GenericMapper(typeParameters)); + return instance(new GenericMapper(typeParameters, arguments.expansionTypeArguments)); } else { return this; } diff --git a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/GenericMapper.java b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/GenericMapper.java index 16a0eb74c..267004dc1 100644 --- a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/GenericMapper.java +++ b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/GenericMapper.java @@ -14,15 +14,17 @@ public class GenericMapper { - public static final GenericMapper EMPTY = new GenericMapper(Collections.emptyMap()); + public static final GenericMapper EMPTY = new GenericMapper(Collections.emptyMap(), TypeID.NONE); private final Map mapping; + private final TypeID[] expansionTypeArguments; - public GenericMapper(Map mapping) { + public GenericMapper(Map mapping, TypeID[] expansionTypeArguments) { if (mapping == null) throw new IllegalArgumentException(); this.mapping = mapping; + this.expansionTypeArguments = expansionTypeArguments; } public static GenericMapper create(TypeParameter[] typeParameters, TypeID[] typeArguments) { @@ -33,11 +35,11 @@ public static GenericMapper create(TypeParameter[] typeParameters, TypeID[] type for (int i = 0; i < typeParameters.length; i++) { mapping.put(typeParameters[i], typeArguments[i]); } - return new GenericMapper(mapping); + return new GenericMapper(mapping, TypeID.NONE); } public static GenericMapper single(TypeParameter parameter, TypeID argument) { - return new GenericMapper(Collections.singletonMap(parameter, argument)); + return new GenericMapper(Collections.singletonMap(parameter, argument), TypeID.NONE); } public Map getMapping() { @@ -74,7 +76,7 @@ public FieldInstance map(FieldSymbol field) { } public MethodInstance map(TypeID target, MethodSymbol method) { - return new MethodInstance(method, map(method.getHeader()), target); + return new MethodInstance(method, map(method.getHeader()), target, expansionTypeArguments); } public GenericMapper getInner(Map mapping) { @@ -87,14 +89,14 @@ public GenericMapper getInner(Map mapping) { resultMap.put(typeParameter, type); }); - return new GenericMapper(resultMap); + return new GenericMapper(resultMap, expansionTypeArguments); } public GenericMapper getInner(TypeParameter[] parameters) { Map resultMap = new HashMap<>(this.mapping); for (TypeParameter parameter : parameters) resultMap.put(parameter, new GenericTypeID(parameter)); - return new GenericMapper(resultMap); + return new GenericMapper(resultMap, expansionTypeArguments); } @Override diff --git a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/CompileContext.java b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/CompileContext.java index c5e3cdfd0..aeedfbe8f 100644 --- a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/CompileContext.java +++ b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/CompileContext.java @@ -21,6 +21,7 @@ import org.openzen.zenscript.codemodel.type.member.ExpandedResolvedType; import java.util.*; +import java.util.stream.Stream; public class CompileContext extends AbstractTypeBuilder implements TypeResolver { private final ZSPackage rootPackage; @@ -93,8 +94,9 @@ public ResolvedType resolve(TypeID type) { if (mapping == null) continue; + TypeID[] expansionTypeArguments = Stream.of(expansion.typeParameters).map(mapping::get).toArray(TypeID[]::new); MemberSet.Builder resolution = MemberSet.create(); - GenericMapper mapper = new GenericMapper(mapping); + GenericMapper mapper = new GenericMapper(mapping, expansionTypeArguments); for (IDefinitionMember member : expansion.members) member.registerTo(type, resolution, mapper); diff --git a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/MatchedCallArguments.java b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/MatchedCallArguments.java index b2e310fd7..59e06b1e1 100644 --- a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/MatchedCallArguments.java +++ b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/MatchedCallArguments.java @@ -7,6 +7,7 @@ import org.openzen.zenscript.codemodel.expression.CallArguments; import org.openzen.zenscript.codemodel.expression.Expression; import org.openzen.zenscript.codemodel.generic.TypeParameter; +import org.openzen.zenscript.codemodel.identifiers.instances.MethodInstance; import org.openzen.zenscript.codemodel.type.ArrayTypeID; import org.openzen.zenscript.codemodel.type.BasicTypeID; import org.openzen.zenscript.codemodel.type.TypeID; @@ -109,9 +110,12 @@ private static CallArguments match( TypeID[] typeArguments, CompilingExpression... arguments ) { + TypeID[] expansionTypeArguments = method.asMethod().map(MethodInstance::getExpansionTypeArguments).orElse(TypeID.NONE); + if (!method.getHeader().accepts(arguments.length)) return new CallArguments( CastedExpression.Level.INVALID, + expansionTypeArguments, typeArguments, Expression.NONE); @@ -124,7 +128,7 @@ private static CallArguments match( // create a mapping with everything found so far // NOTE - this means that inference is sensitive to order of parameters - GenericMapper mapper = new GenericMapper(typeArgumentMap); + GenericMapper mapper = new GenericMapper(typeArgumentMap, expansionTypeArguments); // now try to infer type arguments from the arguments for (int i = 0; i < arguments.length; i++) { @@ -152,7 +156,7 @@ private static CallArguments match( } if (hasUnknowns) { // TODO: improve type inference - return new CallArguments(CastedExpression.Level.INVALID, typeArguments, Expression.NONE); + return new CallArguments(CastedExpression.Level.INVALID, TypeID.NONE, typeArguments, Expression.NONE); } typeArguments = typeArguments2; @@ -195,6 +199,6 @@ private static CallArguments match( cArguments[cArguments.length - 1] = compiler.at(position).newArray(new ArrayTypeID(variadicType), varargArguments.toArray(Expression.NONE)); levelNormalCall = levelVarargCall; } - return new CallArguments(levelNormalCall, typeArguments, cArguments); + return new CallArguments(levelNormalCall, expansionTypeArguments, typeArguments, cArguments); } } diff --git a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallArguments.java b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallArguments.java index 038067b77..8c7b52914 100644 --- a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallArguments.java +++ b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallArguments.java @@ -7,39 +7,44 @@ public class CallArguments { public static final CallArguments EMPTY = new CallArguments(Expression.NONE); public final CastedExpression.Level level; + public final TypeID[] expansionTypeArguments; public final TypeID[] typeArguments; public final Expression[] arguments; public CallArguments(Expression... arguments) { this.level = CastedExpression.Level.EXACT; + this.expansionTypeArguments = TypeID.NONE; this.typeArguments = TypeID.NONE; this.arguments = arguments; } - public CallArguments(TypeID[] typeArguments, Expression[] arguments) { + public CallArguments(TypeID[] expansionTypeArguments, TypeID[] typeArguments, Expression[] arguments) { if (typeArguments == null) typeArguments = TypeID.NONE; if (arguments == null) throw new IllegalArgumentException("Arguments cannot be null!"); this.level = CastedExpression.Level.EXACT; + this.expansionTypeArguments = expansionTypeArguments; this.typeArguments = typeArguments; this.arguments = arguments; } - public CallArguments(CastedExpression.Level level, TypeID[] typeArguments, Expression[] arguments) { + public CallArguments(CastedExpression.Level level, TypeID[] expansionTypeArguments, TypeID[] typeArguments, Expression[] arguments) { if (typeArguments == null) typeArguments = TypeID.NONE; if (arguments == null) throw new IllegalArgumentException("Arguments cannot be null!"); this.level = level; + this.expansionTypeArguments = expansionTypeArguments; this.typeArguments = typeArguments; this.arguments = arguments; } public CallArguments(TypeID... dummy) { this.level = CastedExpression.Level.EXACT; + this.expansionTypeArguments = TypeID.NONE; this.typeArguments = TypeID.NONE; this.arguments = new Expression[dummy.length]; for (int i = 0; i < dummy.length; i++) @@ -50,7 +55,7 @@ public CallArguments bind(Expression target) { Expression[] newArguments = new Expression[arguments.length + 1]; newArguments[0] = target; System.arraycopy(arguments, 0, newArguments, 1, arguments.length); - return new CallArguments(typeArguments, newArguments); + return new CallArguments(level, expansionTypeArguments, typeArguments, newArguments); } public int getNumberOfTypeArguments() { @@ -59,6 +64,6 @@ public int getNumberOfTypeArguments() { public CallArguments transform(ExpressionTransformer transformer) { Expression[] tArguments = Expression.transform(arguments, transformer); - return tArguments == arguments ? this : new CallArguments(level, typeArguments, tArguments); + return tArguments == arguments ? this : new CallArguments(level, expansionTypeArguments, typeArguments, tArguments); } } diff --git a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/identifiers/instances/MethodInstance.java b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/identifiers/instances/MethodInstance.java index 41bb385c3..7a901e4cd 100644 --- a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/identifiers/instances/MethodInstance.java +++ b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/identifiers/instances/MethodInstance.java @@ -17,17 +17,27 @@ public class MethodInstance implements InstanceCallableMethod, StaticCallableMet public final MethodSymbol method; private final FunctionHeader header; private final TypeID target; + private final TypeID[] expansionTypeArguments; public MethodInstance(MethodSymbol method) { this.method = method; this.header = method.getHeader(); this.target = method.getTargetType(); + this.expansionTypeArguments = TypeID.NONE; } public MethodInstance(MethodSymbol method, FunctionHeader header, TypeID target) { this.method = method; this.header = header; this.target = target; + this.expansionTypeArguments = TypeID.NONE; + } + + public MethodInstance(MethodSymbol method, FunctionHeader header, TypeID target, TypeID[] expansionTypeArguments) { + this.method = method; + this.header = header; + this.target = target; + this.expansionTypeArguments = expansionTypeArguments; } public TypeID getTarget() { @@ -66,4 +76,8 @@ public Expression call(ExpressionBuilder builder, CallArguments arguments) { public boolean isImplicit() { return method.getModifiers().isImplicit(); } + + public TypeID[] getExpansionTypeArguments() { + return expansionTypeArguments; + } } diff --git a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/builtin/GenericMapTypeSymbol.java b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/builtin/GenericMapTypeSymbol.java index c0feb7151..c0e2dcf2f 100644 --- a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/builtin/GenericMapTypeSymbol.java +++ b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/builtin/GenericMapTypeSymbol.java @@ -82,7 +82,7 @@ public ResolvedType resolve(TypeID[] typeArguments) { Map parameterFilled = new HashMap<>(); parameterFilled.put(PARAMETER, typeArguments[0]); parameterFilled.put(VALUE, value); - GenericMapper mapper = new GenericMapper(parameterFilled); + GenericMapper mapper = new GenericMapper(parameterFilled, TypeID.NONE); TypeID valueType = mapper.map(value); diff --git a/JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java b/JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java index bceae8afa..73742a2c9 100644 --- a/JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java +++ b/JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java @@ -36,6 +36,10 @@ public static boolean isLarge(TypeID type) { return type == BasicTypeID.DOUBLE || type == BasicTypeID.LONG || type == BasicTypeID.ULONG; } + private boolean isGenericReturn(TypeID type) { + return type.isGeneric() || type.asArray().map(array -> isGenericReturn(type)).orElse(false); + } + public static int calcAccess(Modifiers modifiers) { int out = 0; if (modifiers.isStatic()) diff --git a/JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java b/JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java index 0bf62938e..19a1b2bda 100644 --- a/JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java +++ b/JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java @@ -23,6 +23,7 @@ import org.openzen.zenscript.javashared.expressions.JavaFunctionInterfaceCastExpression; import org.openzen.zenscript.javashared.types.JavaFunctionalInterfaceTypeID; +import java.lang.reflect.Array; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; @@ -31,6 +32,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor { private static final JavaNativeMethod MAP_PUT = JavaNativeMethod.getInterface(JavaClass.MAP, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + private static final JavaNativeMethod ARRAY_NEWINSTANCE = JavaNativeMethod.getNativeStatic(JavaClass.ARRAY, "newInstance", "(Ljava/lang/Class;I)Ljava/lang/Object;"); private static final MethodID CONSTRUCTOR = MethodID.staticOperator(OperatorType.CONSTRUCTOR); final JavaWriter javaWriter; @@ -108,9 +110,17 @@ public Void visitAndAnd(AndAndExpression expression) { @Override public Void visitArray(ArrayExpression expression) { - javaWriter.constant(expression.expressions.length); - Type type = context.getType(((ArrayTypeID) expression.type).elementType); - javaWriter.newArray(type); + Type type = context.getType(expression.arrayType.elementType); + if (expression.arrayType.elementType.isGeneric()) { + + expression.arrayType.elementType.accept(javaWriter, new JavaTypeExpressionVisitor(context)); + javaWriter.constant(expression.expressions.length); + javaWriter.invokeStatic(ARRAY_NEWINSTANCE); + javaWriter.checkCast(context.getInternalName(expression.arrayType)); + } else { + javaWriter.constant(expression.expressions.length); + javaWriter.newArray(type); + } for (int i = 0; i < expression.expressions.length; i++) { javaWriter.dup(); javaWriter.constant(i); diff --git a/JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaMethodBytecodeCompiler.java b/JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaMethodBytecodeCompiler.java index 62d828a37..fd34c24f3 100644 --- a/JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaMethodBytecodeCompiler.java +++ b/JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaMethodBytecodeCompiler.java @@ -202,6 +202,9 @@ private void handleTypeArguments(JavaNativeMethod method, CallArguments argument if (arguments.typeArguments.length != method.typeParameterArguments.length) throw new IllegalArgumentException("Number of type parameters doesn't match"); + for (int i = 0; i < arguments.expansionTypeArguments.length; i++) { + arguments.expansionTypeArguments[i].accept(javaWriter, javaTypeExpressionVisitor); + } for (int i = 0; i < arguments.typeArguments.length; i++) { if (method.typeParameterArguments[i]) arguments.typeArguments[i].accept(javaWriter, javaTypeExpressionVisitor); diff --git a/JavaIntegration/src/main/java/org/openzen/zencode/java/impl/conversion/JavaRuntimeTypeConverterImpl.java b/JavaIntegration/src/main/java/org/openzen/zencode/java/impl/conversion/JavaRuntimeTypeConverterImpl.java index 6a5b21090..4e08086be 100644 --- a/JavaIntegration/src/main/java/org/openzen/zencode/java/impl/conversion/JavaRuntimeTypeConverterImpl.java +++ b/JavaIntegration/src/main/java/org/openzen/zencode/java/impl/conversion/JavaRuntimeTypeConverterImpl.java @@ -144,7 +144,7 @@ private TypeID loadAnnotatedParameterizedType(TypeVariableContext context, Annot map.put(typeParameter, codeParameters[i]); } - return rawTypeId.instance(new GenericMapper(map)); + return rawTypeId.instance(new GenericMapper(map, TypeID.NONE)); } return this.loadType(context, JavaAnnotatedType.of(type), unsigned); } @@ -302,7 +302,7 @@ private TypeID loadFunctionalInterface(TypeVariableContext loadContext, Class mapping.put(context.get(javaParameters[i]), loadType(loadContext, parameters[i], false)); } - header = header.withGenericArguments(new GenericMapper(mapping)); + header = header.withGenericArguments(new GenericMapper(mapping, TypeID.NONE)); JavaNativeMethod method = new JavaNativeMethod( JavaClass.fromInternalName(getInternalName(cls), JavaClass.Kind.INTERFACE), JavaNativeMethod.Kind.INTERFACE, diff --git a/JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaClass.java b/JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaClass.java index bcb0fee67..112894f82 100644 --- a/JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaClass.java +++ b/JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaClass.java @@ -35,6 +35,7 @@ public class JavaClass implements Comparable { public static final JavaClass COLLECTION = new JavaClass("java.util", "Collection", Kind.INTERFACE); public static final JavaClass COLLECTIONS = new JavaClass("java.util", "Collections", Kind.CLASS); public static final JavaClass STRINGBUILDER = new JavaClass("java.lang", "StringBuilder", Kind.CLASS); + public static final JavaClass ARRAY = new JavaClass("java.lang.reflect", "Array", Kind.CLASS); public static final JavaClass SHARED = new JavaClass("zsynthetic", "Shared", Kind.CLASS); public final JavaClass outer; diff --git a/JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaContext.java b/JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaContext.java index 6ec3f3e55..70a008659 100644 --- a/JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaContext.java +++ b/JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaContext.java @@ -382,6 +382,10 @@ public String getMethodDescriptor(FunctionHeader header) { return getMethodDescriptor(header, false, ""); } + public boolean isGenericReturn(TypeID type) { + return type.isGeneric() || type.asArray().map(array -> isGenericReturn(array.elementType)).orElse(false); + } + public String getMethodDescriptorExpansion(FunctionHeader header, TypeID expandedType) { StringBuilder startBuilder = new StringBuilder(getDescriptor(expandedType)); final List typeParameters = new ArrayList<>(); @@ -579,7 +583,11 @@ public String getMethodDescriptor(FunctionHeader header, boolean isEnumConstruct descBuilder.append(getDescriptor(parameter.type)); } descBuilder.append(")"); - descBuilder.append(getDescriptor(header.getReturnType())); + if (isGenericReturn(header.getReturnType())) { + descBuilder.append("Ljava/lang/Object;"); + } else { + descBuilder.append(getDescriptor(header.getReturnType())); + } return descBuilder.toString(); } diff --git a/JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaTypeInternalNameVisitor.java b/JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaTypeInternalNameVisitor.java index 8b12752e1..6865d416d 100644 --- a/JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaTypeInternalNameVisitor.java +++ b/JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaTypeInternalNameVisitor.java @@ -94,7 +94,7 @@ public String visitBasic(BasicTypeID basic) { @Override public String visitArray(ArrayTypeID array) { - return "[" + array.elementType.accept(this); + return "[" + array.elementType.accept(new JavaTypeDescriptorVisitor(context)); } @Override diff --git a/JavaShared/src/main/java/org/openzen/zenscript/javashared/compiling/JavaCompilingClass.java b/JavaShared/src/main/java/org/openzen/zenscript/javashared/compiling/JavaCompilingClass.java index 64c4ddd97..89f180032 100644 --- a/JavaShared/src/main/java/org/openzen/zenscript/javashared/compiling/JavaCompilingClass.java +++ b/JavaShared/src/main/java/org/openzen/zenscript/javashared/compiling/JavaCompilingClass.java @@ -140,7 +140,7 @@ public void addMethod(MethodSymbol method, NativeTag native_) { true, descriptor, JavaModifiers.getJavaModifiers(method.getModifiers()), - method.getHeader().getReturnType() instanceof GenericTypeID, + getContext().isGenericReturn(method.getHeader().getReturnType()), method.getHeader().useTypeParameters()); addMethod(method, new JavaCompilingMethod(compiled, javaMethod, signature)); } diff --git a/JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareClassMethodVisitor.java b/JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareClassMethodVisitor.java index 71e6a9bdf..ba89d871d 100644 --- a/JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareClassMethodVisitor.java +++ b/JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareClassMethodVisitor.java @@ -13,6 +13,7 @@ import org.openzen.zenscript.codemodel.member.*; import org.openzen.zenscript.codemodel.type.BasicTypeID; import org.openzen.zenscript.codemodel.type.GenericTypeID; +import org.openzen.zenscript.codemodel.type.TypeID; import org.openzen.zenscript.javashared.*; import org.openzen.zenscript.javashared.compiling.JavaCompilingClass; import org.openzen.zenscript.javashared.compiling.JavaCompilingMethod; @@ -261,7 +262,7 @@ private void visitFunctional(FunctionalMember member, FunctionHeader header, Str true, context.getMethodDescriptor(header), modifiers | JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()), - header.getReturnType() instanceof GenericTypeID, + context.isGenericReturn(header.getReturnType()), header.useTypeParameters()), signature); } else if (method == null) { @@ -302,7 +303,7 @@ private void visitFunctional(FunctionalMember member, FunctionHeader header, Str true, context.getMethodDescriptor(header), modifiers | JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()), - header.getReturnType() instanceof GenericTypeID, + context.isGenericReturn(header.getReturnType()), header.useTypeParameters()), signature); } diff --git a/ModuleDeserializer/src/main/java/org/openzen/zenscript/moduledeserializer/CodeReader.java b/ModuleDeserializer/src/main/java/org/openzen/zenscript/moduledeserializer/CodeReader.java index e3dc81c45..b80ca38d9 100644 --- a/ModuleDeserializer/src/main/java/org/openzen/zenscript/moduledeserializer/CodeReader.java +++ b/ModuleDeserializer/src/main/java/org/openzen/zenscript/moduledeserializer/CodeReader.java @@ -425,6 +425,10 @@ private void readTypeParameterBounds(TypeSerializationContext context, int[] all @Override public CallArguments deserializeArguments(StatementSerializationContext context) { + TypeID[] expansionTypeArguments = new TypeID[readUInt()]; + for (int i = 0; i < expansionTypeArguments.length; i++) + expansionTypeArguments[i] = deserializeType(context.types()); + TypeID[] typeArguments = new TypeID[readUInt()]; for (int i = 0; i < typeArguments.length; i++) typeArguments[i] = deserializeType(context.types()); @@ -433,7 +437,7 @@ public CallArguments deserializeArguments(StatementSerializationContext context) for (int i = 0; i < arguments.length; i++) arguments[i] = deserializeExpression(context); - return new CallArguments(typeArguments, arguments); + return new CallArguments(expansionTypeArguments, typeArguments, arguments); } @Override diff --git a/ScriptingEngineTester/src/main/resources/zencode-tests/expansions/expansions-3.zc b/ScriptingEngineTester/src/main/resources/zencode-tests/expansions/expansions-3.zc index a14b1c086..dd7c75b83 100644 --- a/ScriptingEngineTester/src/main/resources/zencode-tests/expansions/expansions-3.zc +++ b/ScriptingEngineTester/src/main/resources/zencode-tests/expansions/expansions-3.zc @@ -6,5 +6,5 @@ public expand X[] { } } -var array = [0,0,0]; +var array = ["a", "b", "c"]; array.printSize(); diff --git a/ScriptingEngineTester/src/main/resources/zencode-tests/expansions/expansions-4.zc b/ScriptingEngineTester/src/main/resources/zencode-tests/expansions/expansions-4.zc new file mode 100644 index 000000000..45436ee81 --- /dev/null +++ b/ScriptingEngineTester/src/main/resources/zencode-tests/expansions/expansions-4.zc @@ -0,0 +1,15 @@ +#output: hello + +public expand X { + getMe(): X { + return this; + } + + twice(): X[] { + return [this, this]; + } +} + +var value = "hello"; +var twice = value.twice(); +println(twice[1]); diff --git a/ScriptingEngineTester/src/main/resources/zencode-tests/generics/generic-array-1.zc b/ScriptingEngineTester/src/main/resources/zencode-tests/generics/generic-array-1.zc new file mode 100644 index 000000000..1aa396851 --- /dev/null +++ b/ScriptingEngineTester/src/main/resources/zencode-tests/generics/generic-array-1.zc @@ -0,0 +1,11 @@ +#output: 0 + +class ArrayFactory { + public newInstance(length: int): T[] { + return new T[length]; + } +} + +var a = new ArrayFactory(); +var b = a.newInstance(10); +println(b[1]);