Fix #340
Some checks failed
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 44s
Some checks failed
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 44s
This commit is contained in:
parent
ba8810e5df
commit
edafbbc5a0
@ -1641,7 +1641,7 @@ public class Codegen {
|
||||
var fromParams = converter.convert(fromMethod.getParameterList(), converter.generics.javaGenerics()).stream().map(m -> m.pattern().type()).toArray(TargetType[]::new);
|
||||
fromDescriptor = TargetMethod.getDescriptor(fromReturn, fromParams);
|
||||
} else {
|
||||
fromReturn = funNType.arity() > 1 ? TargetType.Object : null;
|
||||
fromReturn = funNType.returnArguments() > 0 ? TargetType.Object : null;
|
||||
fromDescriptor = funNType.toMethodDescriptor();
|
||||
}
|
||||
|
||||
|
@ -34,13 +34,12 @@ public class FunNGenerator {
|
||||
int start;
|
||||
public List<TargetType> parameters = new ArrayList<>();
|
||||
final String descriptor;
|
||||
final List<TargetType> inParams;
|
||||
public final List<TargetType> inParams;
|
||||
|
||||
public GenericParameters(List<TargetType> params) {
|
||||
public GenericParameters(List<TargetType> params, int numReturns) {
|
||||
this.inParams = params;
|
||||
var type = new TargetRefType(FunNGenerator.getSuperClassName(params.size() - 1), params);
|
||||
var type = new TargetRefType(FunNGenerator.getSuperClassName(params.size() - 1, numReturns), params);
|
||||
descriptor = applyDescriptor(type, this);
|
||||
System.out.println(this.parameters);
|
||||
}
|
||||
|
||||
public TargetType getReturnType() {
|
||||
@ -86,7 +85,7 @@ public class FunNGenerator {
|
||||
return applyNameDescriptor(type).replace("/", "$").replace(";", "$_$");
|
||||
}
|
||||
|
||||
public static byte[] generateSuperBytecode(int numberArguments) {
|
||||
public static byte[] generateSuperBytecode(int numberArguments, int numReturnTypes) {
|
||||
StringBuilder superFunNClassSignature = new StringBuilder("<");
|
||||
StringBuilder superFunNMethodSignature = new StringBuilder("(");
|
||||
StringBuilder superFunNMethodDescriptor = new StringBuilder("(");
|
||||
@ -97,22 +96,27 @@ public class FunNGenerator {
|
||||
superFunNMethodDescriptor.append(objectSignature);
|
||||
}
|
||||
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
|
||||
if (numReturnTypes > 0) {
|
||||
superFunNMethodSignature.append(String.format(")T%s;", returnGeneric));
|
||||
superFunNMethodDescriptor.append(String.format(")%s", objectSignature));
|
||||
} else {
|
||||
superFunNMethodSignature.append(")V");
|
||||
superFunNMethodDescriptor.append(")V");
|
||||
}
|
||||
|
||||
System.out.println(superFunNMethodSignature);
|
||||
|
||||
ClassWriter classWriter = new ClassWriter(0);
|
||||
MethodVisitor methodVisitor;
|
||||
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSuperClassName(numberArguments), superFunNClassSignature.toString(), objectSuperType, null);
|
||||
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSuperClassName(numberArguments, numReturnTypes), superFunNClassSignature.toString(), objectSuperType, null);
|
||||
methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, methodName, superFunNMethodDescriptor.toString(), superFunNMethodSignature.toString(), null);
|
||||
methodVisitor.visitEnd();
|
||||
classWriter.visitEnd();
|
||||
return classWriter.toByteArray();
|
||||
}
|
||||
|
||||
public static String getSuperClassName(int numberArguments) {
|
||||
return String.format("Fun%d$$", numberArguments);
|
||||
public static String getSuperClassName(int numberArguments, int returnArguments) {
|
||||
return returnArguments > 0 ? String.format("Fun%d$$", numberArguments) : String.format("FunVoid%d$$", numberArguments);
|
||||
}
|
||||
|
||||
public static byte[] generateSpecializedBytecode(GenericParameters gep, List<String> superInterfaces) {
|
||||
@ -138,7 +142,7 @@ public class FunNGenerator {
|
||||
}
|
||||
|
||||
var interfaces = new ArrayList<>(superInterfaces);
|
||||
interfaces.add(getSuperClassName(argumentTypes.size()));
|
||||
interfaces.add(getSuperClassName(argumentTypes.size(), returnType != null ? 1 : 0));
|
||||
|
||||
ClassWriter classWriter = new ClassWriter(0);
|
||||
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSpecializedClassName(argumentTypes, returnType), funNClassSignature.toString(), objectSuperType, interfaces.toArray(String[]::new));
|
||||
@ -162,13 +166,19 @@ public class FunNGenerator {
|
||||
}
|
||||
|
||||
public static String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) {
|
||||
return String.format("Fun%d$$%s%s",
|
||||
argumentTypes.size(),
|
||||
argumentTypes
|
||||
var arguments = argumentTypes
|
||||
.stream()
|
||||
.map(FunNGenerator::encodeType)
|
||||
.collect(Collectors.joining()),
|
||||
.collect(Collectors.joining());
|
||||
|
||||
if (returnType != null)
|
||||
return String.format("Fun%d$$%s%s",
|
||||
argumentTypes.size(),
|
||||
arguments,
|
||||
encodeType(returnType));
|
||||
else return String.format("FunVoidImpl%d$$%s",
|
||||
argumentTypes.size(),
|
||||
arguments);
|
||||
}
|
||||
|
||||
public static List<TargetType> getArguments(List<TargetType> list) {
|
||||
@ -179,8 +189,8 @@ public class FunNGenerator {
|
||||
}
|
||||
|
||||
public static TargetType getReturnType(List<TargetType> list) {
|
||||
if(list.size() == 0)
|
||||
if(list.isEmpty())
|
||||
throw new IndexOutOfBoundsException();
|
||||
return list.get(list.size() - 1);
|
||||
return list.getLast();
|
||||
}
|
||||
}
|
||||
|
@ -480,10 +480,10 @@ public class ASTToTargetAST {
|
||||
}
|
||||
var filteredParams = new ArrayList<TargetType>();
|
||||
for (var i = 0; i < newParams.size(); i++) {
|
||||
if (gep.parameters.get(i) != null)
|
||||
if (i < gep.inParams.size() && gep.inParams.get(i) != null)
|
||||
filteredParams.add(newParams.get(i));
|
||||
}
|
||||
return TargetFunNType.fromParams(params, filteredParams, params.size());
|
||||
return TargetFunNType.fromParams(params, filteredParams, gep.getReturnType() != null ? 1 : 0);
|
||||
}
|
||||
|
||||
private boolean isSubtype(TargetType test, TargetType other) {
|
||||
@ -547,17 +547,16 @@ public class ASTToTargetAST {
|
||||
}
|
||||
|
||||
var params = refType.getParaList().stream().map(type -> {
|
||||
var res = convert(type, generics);
|
||||
if (res == null) res = new TargetRefType("java.lang.Void");
|
||||
return res;
|
||||
return convert(type, generics);
|
||||
}).toList();
|
||||
|
||||
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea
|
||||
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
|
||||
var returnType = FunNGenerator.getReturnType(params);
|
||||
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), returnType);
|
||||
if (!usedFunNSuperTypes.contains(params.size())) {
|
||||
usedFunNSuperTypes.add(params.size());
|
||||
var code = FunNGenerator.generateSuperBytecode(params.size() - 1);
|
||||
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1);
|
||||
var code = FunNGenerator.generateSuperBytecode(params.size() - 1, returnType != null ? 1 : 0);
|
||||
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1, returnType != null ? 1 : 0);
|
||||
try {
|
||||
classLoader.findClass(superClassName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
@ -569,7 +568,7 @@ public class ASTToTargetAST {
|
||||
}
|
||||
FunNGenerator.GenericParameters gep = null;
|
||||
if (!usedFunN.containsKey(className)) {
|
||||
gep = new FunNGenerator.GenericParameters(params);
|
||||
gep = new FunNGenerator.GenericParameters(params, returnType != null ? 1 : 0);
|
||||
usedFunN.put(className, gep);
|
||||
} else {
|
||||
gep = usedFunN.get(className);
|
||||
|
@ -4,24 +4,24 @@ import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record TargetFunNType(String name, List<TargetType> params, int arity) implements TargetSpecializedType {
|
||||
public record TargetFunNType(String name, List<TargetType> funNParams, List<TargetType> params, int returnArguments) implements TargetSpecializedType {
|
||||
|
||||
public static TargetFunNType fromParams(List<TargetType> params, int arity) {
|
||||
return fromParams(params, params, arity);
|
||||
public static TargetFunNType fromParams(List<TargetType> params, int returnArguments) {
|
||||
return fromParams(params, params, returnArguments);
|
||||
}
|
||||
|
||||
public static TargetFunNType fromParams(List<TargetType> params, List<TargetType> realParams, int arity) {
|
||||
public static TargetFunNType fromParams(List<TargetType> params, List<TargetType> realParams, int returnArguments) {
|
||||
var name = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
|
||||
return new TargetFunNType(name, realParams, arity);
|
||||
return new TargetFunNType(name, params, realParams, returnArguments);
|
||||
}
|
||||
|
||||
public String toMethodDescriptor() {
|
||||
var res = "(";
|
||||
for (var i = 0; i < arity - 1; i++) {
|
||||
for (var i = 0; i < funNParams.size() - 1; i++) {
|
||||
res += "Ljava/lang/Object;";
|
||||
}
|
||||
res += ")";
|
||||
if (arity > 0) {
|
||||
if (returnArguments > 0) {
|
||||
res += "Ljava/lang/Object;";
|
||||
} else {
|
||||
res += "V";
|
||||
|
Loading…
Reference in New Issue
Block a user