From dce3ed8051e14320dbe9353b8d08609696f693e4 Mon Sep 17 00:00:00 2001 From: Daniel Holle Date: Thu, 1 Jun 2023 16:13:03 +0200 Subject: [PATCH] Some fixes for the plugin --- resources/javFiles/OL.jav | 16 ++++++ .../de/dhbwstuttgart/bytecode/Codegen.java | 2 - .../dhbwstuttgart/bytecode/FunNGenerator.java | 32 ++++++------ .../de/dhbwstuttgart/core/JavaTXCompiler.java | 16 ++++-- .../environment/CompilationEnvironment.java | 1 + .../target/generate/ASTToTargetAST.java | 49 +++++++++++++------ .../typedeployment/TypeInsertFactory.java | 5 +- src/test/java/targetast/TestComplete.java | 6 +++ 8 files changed, 90 insertions(+), 37 deletions(-) create mode 100644 resources/javFiles/OL.jav diff --git a/resources/javFiles/OL.jav b/resources/javFiles/OL.jav new file mode 100644 index 00000000..66c72d53 --- /dev/null +++ b/resources/javFiles/OL.jav @@ -0,0 +1,16 @@ +import java.lang.Integer; +import java.lang.Double; +import java.lang.String; +import java.lang.Long; + +class OL { + m (x) { return x + x; } +} + +class OLMain { + main(x) { + var ol; + ol = new OL(); + return ol.m(x); + } +} \ No newline at end of file diff --git a/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java b/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java index 34dcd929..156a10d7 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java @@ -1030,8 +1030,6 @@ public class Codegen { mv.visitAttribute(new JavaTXSignatureAttribute(method.getTXSignature())); } - System.out.println(method.getDescriptor()); - System.out.println(method.getSignature()); mv.visitCode(); var state = new State(method.signature().returnType(), mv, method.isStatic() ? 0 : 1); for (var param: method.signature().parameters()) diff --git a/src/main/java/de/dhbwstuttgart/bytecode/FunNGenerator.java b/src/main/java/de/dhbwstuttgart/bytecode/FunNGenerator.java index bf4c6730..ac1dbd84 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/FunNGenerator.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/FunNGenerator.java @@ -6,10 +6,7 @@ import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -31,23 +28,31 @@ public class FunNGenerator { private static final String objectSuperType = Type.getInternalName(Object.class).replace('.','/'); private static final String objectSignature = applySignature(TargetType.Object); + public static class GenericParameters { + int start; + public List parameters = new ArrayList<>(); + } - private static String applyDescriptor(TargetType type, int[] start) { + private static String applyDescriptor(TargetType type, GenericParameters gep) { var res = "L" + type.getInternalName(); - if (type instanceof TargetSpecializedType a) + if (type instanceof TargetSpecializedType a) { if (a.params().size() > 0) { res += "<"; for (var param : a.params()) { if (param instanceof TargetGenericType gp) { - res += "TT" + start[0] + ";"; - start[0] += 1; + gep.parameters.add(param); + res += "TT" + gep.start + ";"; + gep.start += 1; } else { - res += applyDescriptor(param, start); + res += applyDescriptor(param, gep); } } res += ">"; } - else return type.toDescriptor(); + } else { + gep.parameters.add(null); + return type.toDescriptor(); + } res += ";"; return res; @@ -85,17 +90,16 @@ public class FunNGenerator { return String.format("Fun%d$$", numberArguments); } - public static byte[] generateSpecializedBytecode(List argumentTypes, TargetType returnType) { + public static byte[] generateSpecializedBytecode(List argumentTypes, TargetType returnType, GenericParameters gep) { List parameters = Stream .concat(argumentTypes.stream(), Stream.of(returnType)) .toList(); - var start = new int[]{0}; - StringBuilder funNClassSignature = new StringBuilder(objectSignature + applyDescriptor(new TargetRefType(getSuperClassName(argumentTypes.size()), parameters), start)); + StringBuilder funNClassSignature = new StringBuilder(objectSignature + applyDescriptor(new TargetRefType(getSuperClassName(argumentTypes.size()), parameters), gep)); boolean containsGeneric = false; String genericSignature = "<"; - for (var i = 0; i < start[0]; i++) { + for (var i = 0; i < gep.start; i++) { genericSignature += String.format("T%d:%s", i, objectSignature); containsGeneric = true; } diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index 7e802569..19d32cc5 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -548,7 +548,17 @@ public class JavaTXCompiler { SourceFile sf = sourceFiles.get(f); allClasses.addAll(getAvailableClasses(sf)); allClasses.addAll(sf.getClasses()); - allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(f,classLoader).stream().map(ASTFactory::createClass).collect(Collectors.toList())); + var newClasses = CompilationEnvironment.loadDefaultPackageClasses(f,classLoader).stream().map(ASTFactory::createClass).collect(Collectors.toList()); + for (var clazz : newClasses) { + var found = false; + for (var old : allClasses) { + if (clazz.getClassName().equals(old.getClassName())) { + found = true; + break; + } + } + if (!found) newClasses.add(clazz); + } } final ConstraintSet cons = getConstraints(); @@ -883,7 +893,7 @@ public class JavaTXCompiler { } } - public Map generateBytecode(SourceFile sf, List typeInferenceResult) { + public synchronized Map generateBytecode(SourceFile sf, List typeInferenceResult) { var converter = new ASTToTargetAST(typeInferenceResult, sf, classLoader); var generatedClasses = new HashMap(); for (var clazz : sf.getClasses()) { @@ -898,7 +908,7 @@ public class JavaTXCompiler { return generatedClasses; } - public void writeClassFile(Map classFiles, File path) throws IOException { + public synchronized void writeClassFile(Map classFiles, File path) throws IOException { FileOutputStream output; for (JavaClassName name : classFiles.keySet()) { byte[] bytecode = classFiles.get(name); diff --git a/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java b/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java index 746d1e85..9ca471cb 100644 --- a/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java +++ b/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java @@ -84,6 +84,7 @@ public class CompilationEnvironment { File [] files = dir.listFiles((dir1, name) -> name.endsWith(".class")); if(files != null)for (File classFile : files) { String className = classFile.getName().substring(0,classFile.getName().length()-6); + if (className.matches("Fun\\d+\\$\\$.*")) continue; ret.add(classLoader.loadClass(packageName + className)); } return ret; diff --git a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java index 7fb10f76..7be48f1d 100644 --- a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java +++ b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java @@ -1111,7 +1111,6 @@ public class ASTToTargetAST { parameterSet.add(params); } } - return result; } @@ -1133,7 +1132,7 @@ public class ASTToTargetAST { ); } - private final Set usedFunN = new HashSet<>(); + private final Map usedFunN = new HashMap<>(); private final Set usedFunNSuperTypes = new HashSet<>(); public Map auxiliaries = new HashMap<>(); @@ -1142,17 +1141,33 @@ public class ASTToTargetAST { return convert(input, generics.javaGenerics); } - static TargetType flattenFunNType(List params) { - var newParams = new ArrayList(); - for (var i = 0; i < params.size(); i++) { - var param = params.get(i); + private static void collectArguments(TargetSpecializedType tspec, List newParams) { + for (var i = 0; i < tspec.params().size(); i++) { + var param = tspec.params().get(i); if (param instanceof TargetSpecializedType fn) { - newParams.addAll(fn.params()); + collectArguments(tspec, newParams); } else { newParams.add(param); } } - return TargetFunNType.fromParams(params, newParams); + } + + static TargetType flattenFunNType(List params, FunNGenerator.GenericParameters gep) { + var newParams = new ArrayList(); + for (var i = 0; i < params.size(); i++) { + var param = params.get(i); + if (param instanceof TargetSpecializedType fn) { + collectArguments(fn, newParams); + } else { + newParams.add(param); + } + } + var filteredParams = new ArrayList(); + for (var i = 0; i < newParams.size(); i++) { + if (gep.parameters.get(i) != null) + filteredParams.add(newParams.get(i)); + } + return TargetFunNType.fromParams(params, filteredParams); } protected TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics) { @@ -1168,16 +1183,18 @@ public class ASTToTargetAST { if (!usedFunNSuperTypes.contains(params.size())) { usedFunNSuperTypes.add(params.size()); var code = FunNGenerator.generateSuperBytecode(params.size() - 1); - var clazz = classLoader.loadClass(code); - auxiliaries.put(clazz.getName(), code); + auxiliaries.put(FunNGenerator.getSuperClassName(params.size() - 1), code); } - if (!usedFunN.contains(className)) { - usedFunN.add(className); - var code = FunNGenerator.generateSpecializedBytecode(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params)); - var clazz = classLoader.loadClass(code); - auxiliaries.put(clazz.getName(), code); + FunNGenerator.GenericParameters gep = null; + if (!usedFunN.containsKey(className)) { + gep = new FunNGenerator.GenericParameters(); + var code = FunNGenerator.generateSpecializedBytecode(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params), gep); + usedFunN.put(className, gep); + auxiliaries.put(className, code); + } else { + gep = usedFunN.get(className); } - return flattenFunNType(params); + return flattenFunNType(params, gep); } return new TargetRefType(name, params); } diff --git a/src/main/java/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java b/src/main/java/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java index be49fde2..660fc494 100644 --- a/src/main/java/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java +++ b/src/main/java/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java @@ -190,9 +190,10 @@ class TypeToInsertString implements ResultSetVisitor{ if (constraints != null) resultPair = constraints.getResultPairFor(typePlaceholder).orElse(null); if (resultPair == null) - resultPair = classConstraints.getResultPairFor(typePlaceholder).get(); + resultPair = classConstraints.getResultPairFor(typePlaceholder).orElse(null); - insert += ((TypePlaceholder)resultPair.getLeft()).getName(); + if (resultPair != null) + insert += ((TypePlaceholder)resultPair.getLeft()).getName(); } @Override diff --git a/src/test/java/targetast/TestComplete.java b/src/test/java/targetast/TestComplete.java index a5c56828..d5f6d455 100644 --- a/src/test/java/targetast/TestComplete.java +++ b/src/test/java/targetast/TestComplete.java @@ -635,4 +635,10 @@ public class TestComplete { var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Pair.jav"); var instance = classFiles.get("Pair").getDeclaredConstructor().newInstance(); } + + @Test + public void olTest() throws Exception { + var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OL.jav"); + var instance = classFiles.get("OL").getDeclaredConstructor().newInstance(); + } }