Convert FunNGenerator to class with static methods instead of using a singleton
This commit is contained in:
parent
15e94111d4
commit
83b735716f
@ -23,28 +23,21 @@ import static org.objectweb.asm.Opcodes.*;
|
||||
* @since Studienarbeit Type Erasure
|
||||
* @author etiennezink
|
||||
*/
|
||||
public class FunNGenerator implements FunNUtilities{
|
||||
|
||||
private static final FunNGenerator funNGenerator = new FunNGenerator();
|
||||
|
||||
public static FunNGenerator getInstance(){
|
||||
return funNGenerator;
|
||||
}
|
||||
public class FunNGenerator {
|
||||
|
||||
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 static final int bytecodeVersion = V1_8;
|
||||
|
||||
private final String objectSuperType = Type.getInternalName(Object.class).replace('.','/');
|
||||
private final String objectSignature = applySignature(TargetType.Object);
|
||||
private static final String objectSuperType = Type.getInternalName(Object.class).replace('.','/');
|
||||
private static final String objectSignature = applySignature(TargetType.Object);
|
||||
|
||||
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)); }
|
||||
private static String applyDescriptor(TargetType a) { return a.toDescriptor(); }
|
||||
private static String applySignature(TargetType a) { return a.toSignature(); }
|
||||
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("L%s;", applyDescriptor(a)); }
|
||||
|
||||
@Override
|
||||
public byte[] generateSuperBytecode(int numberArguments) {
|
||||
public static byte[] generateSuperBytecode(int numberArguments) {
|
||||
StringBuilder superFunNClassSignature = new StringBuilder("<");
|
||||
StringBuilder superFunNMethodSignature = new StringBuilder("(");
|
||||
StringBuilder superFunNMethodDescriptor = new StringBuilder("(");
|
||||
@ -67,13 +60,11 @@ public class FunNGenerator implements FunNUtilities{
|
||||
return classWriter.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuperClassName(int numberArguments) {
|
||||
public static String getSuperClassName(int numberArguments) {
|
||||
return String.format("Fun%d$$", numberArguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] generateSpecializedBytecode(List<TargetType> argumentTypes, TargetType returnType) {
|
||||
public static byte[] generateSpecializedBytecode(List<TargetType> argumentTypes, TargetType returnType) {
|
||||
List<TargetType> parameters = Stream
|
||||
.concat(argumentTypes.stream(), Stream.of(returnType))
|
||||
.collect(Collectors.toList());
|
||||
@ -98,39 +89,34 @@ public class FunNGenerator implements FunNUtilities{
|
||||
return classWriter.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) {
|
||||
public static String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) {
|
||||
return String.format("Fun%d$$%s%s",
|
||||
argumentTypes.size(),
|
||||
argumentTypes
|
||||
.stream()
|
||||
.map(this::applyNameDescriptor)
|
||||
.map(FunNGenerator::applyNameDescriptor)
|
||||
.collect(Collectors.joining()),
|
||||
applyNameDescriptor(returnType))
|
||||
.replace('/', '$')
|
||||
.replace(";", "$_$");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpecializedDescriptor(List<TargetType> argumentTypes, TargetType returnType) {
|
||||
public static String getSpecializedDescriptor(List<TargetType> argumentTypes, TargetType returnType) {
|
||||
return applyDescriptor(new TargetRefType(getSpecializedClassName(argumentTypes, returnType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpecializedSignature(List<TargetType> argumentTypes, TargetType returnType) {
|
||||
public static String getSpecializedSignature(List<TargetType> argumentTypes, TargetType returnType) {
|
||||
return applySignature(new TargetRefType(getSpecializedClassName(argumentTypes, returnType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TargetType> getArguments(List<TargetType> list) {
|
||||
public static List<TargetType> getArguments(List<TargetType> list) {
|
||||
return list
|
||||
.stream()
|
||||
.limit(Math.max(0, list.size() - 1))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetType getReturnType(List<TargetType> list) {
|
||||
public static TargetType getReturnType(List<TargetType> list) {
|
||||
if(list.size() == 0)
|
||||
throw new IndexOutOfBoundsException();
|
||||
return list.get(list.size() - 1);
|
||||
|
@ -1,35 +0,0 @@
|
||||
package de.dhbwstuttgart.bytecode.funN;
|
||||
|
||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.List;
|
||||
|
||||
public interface FunNUtilities {
|
||||
|
||||
byte[] generateSuperBytecode(int numberArguments);
|
||||
String getSuperClassName(int numberArguments);
|
||||
|
||||
byte[] generateSpecializedBytecode(List<TargetType> argumentTypes, TargetType returnType);
|
||||
String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType);
|
||||
String getSpecializedDescriptor(List<TargetType> argumentTypes, TargetType returnType);
|
||||
String getSpecializedSignature(List<TargetType> argumentTypes, TargetType returnType);
|
||||
|
||||
List<TargetType> getArguments(List<TargetType> list);
|
||||
TargetType getReturnType(List<TargetType> list);
|
||||
|
||||
@Deprecated
|
||||
public static boolean writeClassFile(String className, byte[] bytecode, File directory) {
|
||||
try (FileOutputStream output = new FileOutputStream(new File(directory , className + ".class"))){
|
||||
output.write(bytecode);
|
||||
output.flush();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -675,17 +675,16 @@ 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(params), gen.getReturnType(params));
|
||||
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
|
||||
if (!usedFunNSuperTypes.contains(params.size())) {
|
||||
usedFunNSuperTypes.add(params.size());
|
||||
var code = gen.generateSuperBytecode(params.size() - 1);
|
||||
var code = FunNGenerator.generateSuperBytecode(params.size() - 1);
|
||||
var clazz = classLoader.loadClass(code);
|
||||
auxiliaries.put(clazz.getName(), code);
|
||||
}
|
||||
if (!usedFunN.contains(className)) {
|
||||
usedFunN.add(className);
|
||||
var code = gen.generateSpecializedBytecode(gen.getArguments(params), gen.getReturnType(params));
|
||||
var code = FunNGenerator.generateSpecializedBytecode(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
|
||||
var clazz = classLoader.loadClass(code);
|
||||
auxiliaries.put(clazz.getName(), code);
|
||||
}
|
||||
|
@ -9,8 +9,7 @@ public record TargetFunNType(int N, List<TargetType> params) implements TargetSp
|
||||
|
||||
@Override
|
||||
public String getInternalName() {
|
||||
var gen = FunNGenerator.getInstance();
|
||||
return gen.getSpecializedClassName(gen.getArguments(params), gen.getReturnType(params));
|
||||
return FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user