forked from JavaTX/JavaCompilerCore
Some fixes for the plugin
This commit is contained in:
parent
8e5a20e59e
commit
dce3ed8051
16
resources/javFiles/OL.jav
Normal file
16
resources/javFiles/OL.jav
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -1030,8 +1030,6 @@ public class Codegen {
|
|||||||
mv.visitAttribute(new JavaTXSignatureAttribute(method.getTXSignature()));
|
mv.visitAttribute(new JavaTXSignatureAttribute(method.getTXSignature()));
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println(method.getDescriptor());
|
|
||||||
System.out.println(method.getSignature());
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
var state = new State(method.signature().returnType(), mv, method.isStatic() ? 0 : 1);
|
var state = new State(method.signature().returnType(), mv, method.isStatic() ? 0 : 1);
|
||||||
for (var param: method.signature().parameters())
|
for (var param: method.signature().parameters())
|
||||||
|
@ -6,10 +6,7 @@ import org.objectweb.asm.ClassWriter;
|
|||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
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 objectSuperType = Type.getInternalName(Object.class).replace('.','/');
|
||||||
private static final String objectSignature = applySignature(TargetType.Object);
|
private static final String objectSignature = applySignature(TargetType.Object);
|
||||||
|
|
||||||
|
public static class GenericParameters {
|
||||||
|
int start;
|
||||||
|
public List<TargetType> parameters = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
private static String applyDescriptor(TargetType type, int[] start) {
|
private static String applyDescriptor(TargetType type, GenericParameters gep) {
|
||||||
var res = "L" + type.getInternalName();
|
var res = "L" + type.getInternalName();
|
||||||
if (type instanceof TargetSpecializedType a)
|
if (type instanceof TargetSpecializedType a) {
|
||||||
if (a.params().size() > 0) {
|
if (a.params().size() > 0) {
|
||||||
res += "<";
|
res += "<";
|
||||||
for (var param : a.params()) {
|
for (var param : a.params()) {
|
||||||
if (param instanceof TargetGenericType gp) {
|
if (param instanceof TargetGenericType gp) {
|
||||||
res += "TT" + start[0] + ";";
|
gep.parameters.add(param);
|
||||||
start[0] += 1;
|
res += "TT" + gep.start + ";";
|
||||||
|
gep.start += 1;
|
||||||
} else {
|
} else {
|
||||||
res += applyDescriptor(param, start);
|
res += applyDescriptor(param, gep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res += ">";
|
res += ">";
|
||||||
}
|
}
|
||||||
else return type.toDescriptor();
|
} else {
|
||||||
|
gep.parameters.add(null);
|
||||||
|
return type.toDescriptor();
|
||||||
|
}
|
||||||
res += ";";
|
res += ";";
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@ -85,17 +90,16 @@ public class FunNGenerator {
|
|||||||
return String.format("Fun%d$$", numberArguments);
|
return String.format("Fun%d$$", numberArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] generateSpecializedBytecode(List<TargetType> argumentTypes, TargetType returnType) {
|
public static byte[] generateSpecializedBytecode(List<TargetType> argumentTypes, TargetType returnType, GenericParameters gep) {
|
||||||
List<TargetType> parameters = Stream
|
List<TargetType> parameters = Stream
|
||||||
.concat(argumentTypes.stream(), Stream.of(returnType))
|
.concat(argumentTypes.stream(), Stream.of(returnType))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
var start = new int[]{0};
|
StringBuilder funNClassSignature = new StringBuilder(objectSignature + applyDescriptor(new TargetRefType(getSuperClassName(argumentTypes.size()), parameters), gep));
|
||||||
StringBuilder funNClassSignature = new StringBuilder(objectSignature + applyDescriptor(new TargetRefType(getSuperClassName(argumentTypes.size()), parameters), start));
|
|
||||||
boolean containsGeneric = false;
|
boolean containsGeneric = false;
|
||||||
|
|
||||||
String genericSignature = "<";
|
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);
|
genericSignature += String.format("T%d:%s", i, objectSignature);
|
||||||
containsGeneric = true;
|
containsGeneric = true;
|
||||||
}
|
}
|
||||||
|
@ -548,7 +548,17 @@ public class JavaTXCompiler {
|
|||||||
SourceFile sf = sourceFiles.get(f);
|
SourceFile sf = sourceFiles.get(f);
|
||||||
allClasses.addAll(getAvailableClasses(sf));
|
allClasses.addAll(getAvailableClasses(sf));
|
||||||
allClasses.addAll(sf.getClasses());
|
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<Pair> cons = getConstraints();
|
final ConstraintSet<Pair> cons = getConstraints();
|
||||||
@ -883,7 +893,7 @@ public class JavaTXCompiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<JavaClassName, byte[]> generateBytecode(SourceFile sf, List<ResultSet> typeInferenceResult) {
|
public synchronized Map<JavaClassName, byte[]> generateBytecode(SourceFile sf, List<ResultSet> typeInferenceResult) {
|
||||||
var converter = new ASTToTargetAST(typeInferenceResult, sf, classLoader);
|
var converter = new ASTToTargetAST(typeInferenceResult, sf, classLoader);
|
||||||
var generatedClasses = new HashMap<JavaClassName, byte[]>();
|
var generatedClasses = new HashMap<JavaClassName, byte[]>();
|
||||||
for (var clazz : sf.getClasses()) {
|
for (var clazz : sf.getClasses()) {
|
||||||
@ -898,7 +908,7 @@ public class JavaTXCompiler {
|
|||||||
return generatedClasses;
|
return generatedClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeClassFile(Map<JavaClassName, byte[]> classFiles, File path) throws IOException {
|
public synchronized void writeClassFile(Map<JavaClassName, byte[]> classFiles, File path) throws IOException {
|
||||||
FileOutputStream output;
|
FileOutputStream output;
|
||||||
for (JavaClassName name : classFiles.keySet()) {
|
for (JavaClassName name : classFiles.keySet()) {
|
||||||
byte[] bytecode = classFiles.get(name);
|
byte[] bytecode = classFiles.get(name);
|
||||||
|
@ -84,6 +84,7 @@ public class CompilationEnvironment {
|
|||||||
File [] files = dir.listFiles((dir1, name) -> name.endsWith(".class"));
|
File [] files = dir.listFiles((dir1, name) -> name.endsWith(".class"));
|
||||||
if(files != null)for (File classFile : files) {
|
if(files != null)for (File classFile : files) {
|
||||||
String className = classFile.getName().substring(0,classFile.getName().length()-6);
|
String className = classFile.getName().substring(0,classFile.getName().length()-6);
|
||||||
|
if (className.matches("Fun\\d+\\$\\$.*")) continue;
|
||||||
ret.add(classLoader.loadClass(packageName + className));
|
ret.add(classLoader.loadClass(packageName + className));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1111,7 +1111,6 @@ public class ASTToTargetAST {
|
|||||||
parameterSet.add(params);
|
parameterSet.add(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1133,7 +1132,7 @@ public class ASTToTargetAST {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Set<String> usedFunN = new HashSet<>();
|
private final Map<String, FunNGenerator.GenericParameters> usedFunN = new HashMap<>();
|
||||||
private final Set<Integer> usedFunNSuperTypes = new HashSet<>();
|
private final Set<Integer> usedFunNSuperTypes = new HashSet<>();
|
||||||
|
|
||||||
public Map<String, byte[]> auxiliaries = new HashMap<>();
|
public Map<String, byte[]> auxiliaries = new HashMap<>();
|
||||||
@ -1142,17 +1141,33 @@ public class ASTToTargetAST {
|
|||||||
return convert(input, generics.javaGenerics);
|
return convert(input, generics.javaGenerics);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TargetType flattenFunNType(List<TargetType> params) {
|
private static void collectArguments(TargetSpecializedType tspec, List<TargetType> newParams) {
|
||||||
var newParams = new ArrayList<TargetType>();
|
for (var i = 0; i < tspec.params().size(); i++) {
|
||||||
for (var i = 0; i < params.size(); i++) {
|
var param = tspec.params().get(i);
|
||||||
var param = params.get(i);
|
|
||||||
if (param instanceof TargetSpecializedType fn) {
|
if (param instanceof TargetSpecializedType fn) {
|
||||||
newParams.addAll(fn.params());
|
collectArguments(tspec, newParams);
|
||||||
} else {
|
} else {
|
||||||
newParams.add(param);
|
newParams.add(param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TargetFunNType.fromParams(params, newParams);
|
}
|
||||||
|
|
||||||
|
static TargetType flattenFunNType(List<TargetType> params, FunNGenerator.GenericParameters gep) {
|
||||||
|
var newParams = new ArrayList<TargetType>();
|
||||||
|
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<TargetType>();
|
||||||
|
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) {
|
protected TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics) {
|
||||||
@ -1168,16 +1183,18 @@ public class ASTToTargetAST {
|
|||||||
if (!usedFunNSuperTypes.contains(params.size())) {
|
if (!usedFunNSuperTypes.contains(params.size())) {
|
||||||
usedFunNSuperTypes.add(params.size());
|
usedFunNSuperTypes.add(params.size());
|
||||||
var code = FunNGenerator.generateSuperBytecode(params.size() - 1);
|
var code = FunNGenerator.generateSuperBytecode(params.size() - 1);
|
||||||
var clazz = classLoader.loadClass(code);
|
auxiliaries.put(FunNGenerator.getSuperClassName(params.size() - 1), code);
|
||||||
auxiliaries.put(clazz.getName(), code);
|
|
||||||
}
|
}
|
||||||
if (!usedFunN.contains(className)) {
|
FunNGenerator.GenericParameters gep = null;
|
||||||
usedFunN.add(className);
|
if (!usedFunN.containsKey(className)) {
|
||||||
var code = FunNGenerator.generateSpecializedBytecode(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
|
gep = new FunNGenerator.GenericParameters();
|
||||||
var clazz = classLoader.loadClass(code);
|
var code = FunNGenerator.generateSpecializedBytecode(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params), gep);
|
||||||
auxiliaries.put(clazz.getName(), code);
|
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);
|
return new TargetRefType(name, params);
|
||||||
}
|
}
|
||||||
|
@ -190,9 +190,10 @@ class TypeToInsertString implements ResultSetVisitor{
|
|||||||
if (constraints != null)
|
if (constraints != null)
|
||||||
resultPair = constraints.getResultPairFor(typePlaceholder).orElse(null);
|
resultPair = constraints.getResultPairFor(typePlaceholder).orElse(null);
|
||||||
if (resultPair == 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
|
@Override
|
||||||
|
@ -635,4 +635,10 @@ public class TestComplete {
|
|||||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Pair.jav");
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Pair.jav");
|
||||||
var instance = classFiles.get("Pair").getDeclaredConstructor().newInstance();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user