From 15e94111d4aa34b656cc09a10364ebd8fd765429 Mon Sep 17 00:00:00 2001 From: Vic Nightfall Date: Mon, 14 Nov 2022 15:28:00 +0100 Subject: [PATCH] Rework FunNGenerator to use target types --- .../de/dhbwstuttgart/bytecode/Codegen.java | 6 +- .../bytecode/funN/FunNGenerator.java | 60 +++++++++---------- .../bytecode/funN/FunNUtilities.java | 14 ++--- .../target/generate/ASTToTargetAST.java | 4 +- .../target/tree/TargetMethod.java | 6 +- .../tree/type/TargetExtendsWildcard.java | 4 +- .../target/tree/type/TargetFunNType.java | 18 ++---- .../target/tree/type/TargetGenericType.java | 2 +- .../target/tree/type/TargetPrimitiveType.java | 2 +- .../tree/type/TargetSpecializedType.java | 4 +- .../target/tree/type/TargetSuperWildcard.java | 4 +- .../target/tree/type/TargetType.java | 2 +- 12 files changed, 55 insertions(+), 71 deletions(-) diff --git a/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java b/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java index dbd0fe45..9d196167 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java @@ -975,7 +975,7 @@ public class Codegen { } private void generateField(TargetField field) { - cw.visitField(field.access() | ACC_PUBLIC, field.name(), field.type().toSignature(), field.type().toGenericSignature(), null); + cw.visitField(field.access() | ACC_PUBLIC, field.name(), field.type().toSignature(), field.type().toDescriptor(), null); } private void generateConstructor(TargetConstructor constructor) { @@ -1018,10 +1018,10 @@ public class Codegen { private static String generateSignature(TargetClass clazz) { String ret = "<"; for (var generic : clazz.generics()) { - ret += generic.name() + ":" + generic.bound().toGenericSignature(); + ret += generic.name() + ":" + generic.bound().toDescriptor(); } ret += ">"; - ret += clazz.superType().toGenericSignature(); + ret += clazz.superType().toDescriptor(); return ret; } diff --git a/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNGenerator.java b/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNGenerator.java index d23cc524..d3917478 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNGenerator.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNGenerator.java @@ -3,8 +3,10 @@ package de.dhbwstuttgart.bytecode.funN; import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.RefType; -import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import de.dhbwstuttgart.target.tree.type.TargetGenericType; +import de.dhbwstuttgart.target.tree.type.TargetRefType; +import de.dhbwstuttgart.target.tree.type.TargetType; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Type; @@ -23,24 +25,23 @@ import static org.objectweb.asm.Opcodes.*; */ public class FunNGenerator implements FunNUtilities{ - private static FunNGenerator funNGenerator = new FunNGenerator(); + private static final FunNGenerator funNGenerator = new FunNGenerator(); public static FunNGenerator getInstance(){ return funNGenerator; } - private final String argumentGenericBase = "T"; - private final String returnGeneric = "R"; - private final String methodName = "apply"; + private static final String argumentGenericBase = "T"; + private static final String returnGeneric = "R"; + private static final String methodName = "apply"; private final int bytecodeVersion = V1_8; private final String objectSuperType = Type.getInternalName(Object.class).replace('.','/'); - private final RefType objectRefType = new RefType(new JavaClassName(objectSuperType), null); - private final String objectSignature = applySignature(objectRefType); + private final String objectSignature = applySignature(TargetType.Object); - private String applyDescriptor(RefTypeOrTPHOrWildcardOrGeneric a) { return a.acceptTV(new TypeToDescriptor(true)); } - private String applySignature(RefTypeOrTPHOrWildcardOrGeneric a) { return a.acceptTV(new TypeToSignature(true)); } - private String applyNameDescriptor(RefTypeOrTPHOrWildcardOrGeneric a){ return a instanceof TypePlaceholder ? "LTPH;" : String.format("L%s;", applyDescriptor(a)); } + private String applyDescriptor(TargetType a) { return a.toDescriptor(); } + private String applySignature(TargetType a) { return a.toSignature(); } + private String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("L%s;", applyDescriptor(a)); } @Override public byte[] generateSuperBytecode(int numberArguments) { @@ -50,11 +51,11 @@ public class FunNGenerator implements FunNUtilities{ for (int currentParameter = 1; currentParameter <= numberArguments; currentParameter++){ superFunNClassSignature.append(String.format("%s%d:%s",argumentGenericBase, currentParameter, objectSignature)); - superFunNMethodSignature.append(String.format("T%s;", applySignature( new GenericRefType(argumentGenericBase + currentParameter, null)))); + superFunNMethodSignature.append(String.format("T%s;", applySignature(new TargetRefType(argumentGenericBase + currentParameter)))); superFunNMethodDescriptor.append(objectSignature); } superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature)); - superFunNMethodSignature.append(String.format(")T%s;", applySignature(new GenericRefType(returnGeneric, null)))); + superFunNMethodSignature.append(String.format(")T%s;", applySignature(new TargetRefType(returnGeneric)))); superFunNMethodDescriptor.append(String.format(")%s", objectSignature)); ClassWriter classWriter = new ClassWriter(0); @@ -72,26 +73,19 @@ public class FunNGenerator implements FunNUtilities{ } @Override - public byte[] generateSpecializedBytecode(List argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType) { - List parameters = Stream + public byte[] generateSpecializedBytecode(List argumentTypes, TargetType returnType) { + List parameters = Stream .concat(argumentTypes.stream(), Stream.of(returnType)) .collect(Collectors.toList()); - RefType superFunN = new RefType(new JavaClassName(getSuperClassName(argumentTypes.size())), parameters , null); - StringBuilder funNClassSignature = new StringBuilder(objectSignature + (superFunN.acceptTV(new TypeToSignature(false)))); + StringBuilder funNClassSignature = new StringBuilder(objectSignature + applySignature(new TargetRefType(getSuperClassName(argumentTypes.size()), parameters))); boolean containsGeneric = false; String genericSignature = "<"; - for (RefTypeOrTPHOrWildcardOrGeneric typeArgument : parameters) { + for (TargetType typeArgument : parameters) { //ToDo Etienne: Refactor - if (typeArgument instanceof GenericRefType){ - GenericRefType generic = (GenericRefType) typeArgument; - if(genericSignature.contains(generic.getParsedName())) continue; - genericSignature += String.format("%s:%s", generic.getParsedName(), applyDescriptor(generic)); - containsGeneric = true; - } else if(typeArgument instanceof TypePlaceholder){ - TypePlaceholder placeholder = (TypePlaceholder) typeArgument; - if(genericSignature.contains(applySignature(placeholder).substring(1))) continue; - genericSignature += String.format("%s:%s", applySignature(placeholder).substring(1), objectSignature); + if (typeArgument instanceof TargetGenericType generic){ + if(genericSignature.contains(generic.name())) continue; + genericSignature += String.format("%s:%s", generic.name(), applyDescriptor(generic)); containsGeneric = true; } } @@ -105,7 +99,7 @@ public class FunNGenerator implements FunNUtilities{ } @Override - public String getSpecializedClassName(List argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType) { + public String getSpecializedClassName(List argumentTypes, TargetType returnType) { return String.format("Fun%d$$%s%s", argumentTypes.size(), argumentTypes @@ -118,17 +112,17 @@ public class FunNGenerator implements FunNUtilities{ } @Override - public String getSpecializedDescriptor(List argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType) { - return applyDescriptor(new RefType(new JavaClassName(getSpecializedClassName(argumentTypes, returnType)), null)); + public String getSpecializedDescriptor(List argumentTypes, TargetType returnType) { + return applyDescriptor(new TargetRefType(getSpecializedClassName(argumentTypes, returnType))); } @Override - public String getSpecializedSignature(List argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType) { - return applySignature(new RefType(new JavaClassName(getSpecializedClassName(argumentTypes, returnType)), null)); + public String getSpecializedSignature(List argumentTypes, TargetType returnType) { + return applySignature(new TargetRefType(getSpecializedClassName(argumentTypes, returnType))); } @Override - public List getArguments(List list) { + public List getArguments(List list) { return list .stream() .limit(Math.max(0, list.size() - 1)) @@ -136,7 +130,7 @@ public class FunNGenerator implements FunNUtilities{ } @Override - public RefTypeOrTPHOrWildcardOrGeneric getReturnType(List list) { + public TargetType getReturnType(List list) { if(list.size() == 0) throw new IndexOutOfBoundsException(); return list.get(list.size() - 1); diff --git a/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNUtilities.java b/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNUtilities.java index dceb0f18..b34b4e65 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNUtilities.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNUtilities.java @@ -1,6 +1,6 @@ package de.dhbwstuttgart.bytecode.funN; -import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.target.tree.type.TargetType; import java.io.File; import java.io.FileOutputStream; @@ -11,13 +11,13 @@ public interface FunNUtilities { byte[] generateSuperBytecode(int numberArguments); String getSuperClassName(int numberArguments); - byte[] generateSpecializedBytecode(List argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType); - String getSpecializedClassName(List argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType); - String getSpecializedDescriptor(List argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType); - String getSpecializedSignature(List argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType); + byte[] generateSpecializedBytecode(List argumentTypes, TargetType returnType); + String getSpecializedClassName(List argumentTypes, TargetType returnType); + String getSpecializedDescriptor(List argumentTypes, TargetType returnType); + String getSpecializedSignature(List argumentTypes, TargetType returnType); - List getArguments(List list); - RefTypeOrTPHOrWildcardOrGeneric getReturnType(List list); + List getArguments(List list); + TargetType getReturnType(List list); @Deprecated public static boolean writeClassFile(String className, byte[] bytecode, File directory) { diff --git a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java index 4aaee428..7229cb50 100644 --- a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java +++ b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java @@ -676,7 +676,7 @@ public class ASTToTargetAST { var params = refType.getParaList().stream().map(ASTToTargetAST.this::convert).toList(); if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea var gen = FunNGenerator.getInstance(); - var className = gen.getSpecializedClassName(gen.getArguments(refType.getParaList()), gen.getReturnType(refType.getParaList())); + var className = gen.getSpecializedClassName(gen.getArguments(params), gen.getReturnType(params)); if (!usedFunNSuperTypes.contains(params.size())) { usedFunNSuperTypes.add(params.size()); var code = gen.generateSuperBytecode(params.size() - 1); @@ -685,7 +685,7 @@ public class ASTToTargetAST { } if (!usedFunN.contains(className)) { usedFunN.add(className); - var code = gen.generateSpecializedBytecode(gen.getArguments(refType.getParaList()), gen.getReturnType(refType.getParaList())); + var code = gen.generateSpecializedBytecode(gen.getArguments(params), gen.getReturnType(params)); var clazz = classLoader.loadClass(code); auxiliaries.put(clazz.getName(), code); } diff --git a/src/main/java/de/dhbwstuttgart/target/tree/TargetMethod.java b/src/main/java/de/dhbwstuttgart/target/tree/TargetMethod.java index 2865603f..b3b45fd5 100644 --- a/src/main/java/de/dhbwstuttgart/target/tree/TargetMethod.java +++ b/src/main/java/de/dhbwstuttgart/target/tree/TargetMethod.java @@ -22,15 +22,15 @@ public record TargetMethod(int access, String name, Set generics, public static String getSignature(Set generics, List parameters, TargetType returnType) { String ret = "<"; for (var generic : generics) { - ret += generic.name() + ":" + generic.bound().toGenericSignature(); + ret += generic.name() + ":" + generic.bound().toDescriptor(); } ret += ">("; for (var param : parameters) { - ret += param.type().toGenericSignature(); + ret += param.type().toDescriptor(); } ret += ")"; if (returnType == null) ret += "V"; - else ret += returnType.toGenericSignature(); + else ret += returnType.toDescriptor(); return ret; } diff --git a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetExtendsWildcard.java b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetExtendsWildcard.java index a242dec9..db7c1eee 100644 --- a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetExtendsWildcard.java +++ b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetExtendsWildcard.java @@ -7,8 +7,8 @@ public record TargetExtendsWildcard(TargetType innerType) implements TargetType } @Override - public String toGenericSignature() { - return "+" + innerType.toGenericSignature(); + public String toDescriptor() { + return "+" + innerType.toDescriptor(); } @Override diff --git a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetFunNType.java b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetFunNType.java index 0b252d68..596bf773 100644 --- a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetFunNType.java +++ b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetFunNType.java @@ -1,26 +1,16 @@ package de.dhbwstuttgart.target.tree.type; +import de.dhbwstuttgart.bytecode.funN.FunNGenerator; + import java.util.List; import java.util.stream.Collectors; public record TargetFunNType(int N, List params) implements TargetSpecializedType { - private static String nameDescriptor(TargetType type) { - if (type instanceof TargetGenericType) return "LTPH;"; - return type.toSignature(); - } - @Override public String getInternalName() { - // TODO This is duplicate code from FunNGenerator, I think we should change it to accept TargetTypes and refactor. - var returnType = params.get(params.size() - 1); - var argumentTypes = params.subList(0, params.size() - 1); - return java.lang.String.format("Fun%d$$%s%s", - argumentTypes.size(), - argumentTypes.stream().map(TargetFunNType::nameDescriptor).collect(Collectors.joining()), - nameDescriptor(returnType)) - .replace('/', '$') - .replace(";", "$_$"); + var gen = FunNGenerator.getInstance(); + return gen.getSpecializedClassName(gen.getArguments(params), gen.getReturnType(params)); } @Override diff --git a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetGenericType.java b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetGenericType.java index 15900fb4..f3f49823 100644 --- a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetGenericType.java +++ b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetGenericType.java @@ -7,7 +7,7 @@ public record TargetGenericType(String name) implements TargetType { } @Override - public String toGenericSignature() { + public String toDescriptor() { return "T" + getInternalName() + ";"; } diff --git a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetPrimitiveType.java b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetPrimitiveType.java index 9d3bbf46..fe41a342 100644 --- a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetPrimitiveType.java +++ b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetPrimitiveType.java @@ -8,7 +8,7 @@ public record TargetPrimitiveType(String name) implements TargetType { } @Override - public String toGenericSignature() { + public String toDescriptor() { return toSignature(); } diff --git a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetSpecializedType.java b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetSpecializedType.java index 2a74307c..45e84fde 100644 --- a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetSpecializedType.java +++ b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetSpecializedType.java @@ -6,12 +6,12 @@ public sealed interface TargetSpecializedType extends TargetType permits TargetF List params(); @Override - default String toGenericSignature() { + default String toDescriptor() { String ret = "L" + getInternalName(); if (params().size() > 0) { ret += "<"; for (var param : params()) { - ret += param.toGenericSignature(); + ret += param.toDescriptor(); } ret += ">"; } diff --git a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetSuperWildcard.java b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetSuperWildcard.java index 52cc6dea..594ee2df 100644 --- a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetSuperWildcard.java +++ b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetSuperWildcard.java @@ -7,8 +7,8 @@ public record TargetSuperWildcard(TargetType innerType) implements TargetType { } @Override - public String toGenericSignature() { - return "-" + innerType.toGenericSignature(); + public String toDescriptor() { + return "-" + innerType.toDescriptor(); } @Override diff --git a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetType.java b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetType.java index 36d71af1..50ea6293 100644 --- a/src/main/java/de/dhbwstuttgart/target/tree/type/TargetType.java +++ b/src/main/java/de/dhbwstuttgart/target/tree/type/TargetType.java @@ -53,7 +53,7 @@ public sealed interface TargetType } String toSignature(); - String toGenericSignature(); + String toDescriptor(); String getInternalName(); String name(); }