Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de:/bahome/projekt/git/JavaCompilerCore into targetBytecode
This commit is contained in:
commit
f10e7e6d72
14165
doc/Studienarbeiten_Bachelorarbeiten/S2023_Luca_Trumpfheller.pdf
Normal file
14165
doc/Studienarbeiten_Bachelorarbeiten/S2023_Luca_Trumpfheller.pdf
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
import java.lang.Integer;
|
import java.lang.Integer;
|
||||||
import java.lang.Float;
|
|
||||||
import java.lang.Number;
|
import java.lang.Number;
|
||||||
|
import java.lang.Float;
|
||||||
|
|
||||||
record Point(Number x, Number y) {}
|
record Point(Number x, Number y) {}
|
||||||
|
|
||||||
@ -17,3 +17,34 @@ public class OverloadPattern {
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public class OverloadPattern {
|
||||||
|
Integer m$Point$_$java$lang$Integer$_$java$lang$Integer$_$(Point point) {
|
||||||
|
var x = point.x();
|
||||||
|
var y = point.y();
|
||||||
|
return x + y;
|
||||||
|
}
|
||||||
|
|
||||||
|
Float m$Point$_$java$lang$Float$_$java$lang$Float$_$(Point point) {
|
||||||
|
var x = point.x();
|
||||||
|
var y = point.y();
|
||||||
|
return x * y;
|
||||||
|
}
|
||||||
|
|
||||||
|
Number m(Point point) {
|
||||||
|
return switch(point) {
|
||||||
|
case Point(Integer x, Integer y) ->
|
||||||
|
m$Point$_$java$lang$Integer$_$java$lang$Integer$_$(point);
|
||||||
|
case Point(Float x, Float y) ->
|
||||||
|
m$Point$_$java$lang$Float$_$java$lang$Float$_$(point);
|
||||||
|
default -> throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer m(Integer x) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
@ -59,7 +59,11 @@ public class FunNGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String applySignature(TargetType a) { return a.toSignature(); }
|
private static String applySignature(TargetType a) { return a.toSignature(); }
|
||||||
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s;", applySignature(a)); }
|
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", applySignature(a)); }
|
||||||
|
|
||||||
|
public static String encodeType(TargetType type) {
|
||||||
|
return applyNameDescriptor(type).replace("/", "$").replace(";", "$_$");
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] generateSuperBytecode(int numberArguments) {
|
public static byte[] generateSuperBytecode(int numberArguments) {
|
||||||
StringBuilder superFunNClassSignature = new StringBuilder("<");
|
StringBuilder superFunNClassSignature = new StringBuilder("<");
|
||||||
@ -130,11 +134,9 @@ public class FunNGenerator {
|
|||||||
argumentTypes.size(),
|
argumentTypes.size(),
|
||||||
argumentTypes
|
argumentTypes
|
||||||
.stream()
|
.stream()
|
||||||
.map(FunNGenerator::applyNameDescriptor)
|
.map(FunNGenerator::encodeType)
|
||||||
.collect(Collectors.joining()),
|
.collect(Collectors.joining()),
|
||||||
applyNameDescriptor(returnType))
|
encodeType(returnType));
|
||||||
.replace('/', '$')
|
|
||||||
.replace(";", "$_$");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<TargetType> getArguments(List<TargetType> list) {
|
public static List<TargetType> getArguments(List<TargetType> list) {
|
||||||
|
@ -67,7 +67,7 @@ public class Method extends SyntaxTreeNode implements IItemWithOffset, TypeScope
|
|||||||
return parameterlist;
|
return parameterlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<? extends GenericTypeVar> getGenerics() {
|
public GenericDeclarationList getGenerics() {
|
||||||
return generics;
|
return generics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import de.dhbwstuttgart.bytecode.FunNGenerator;
|
|||||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.Record;
|
import de.dhbwstuttgart.syntaxtree.Record;
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||||
@ -141,7 +142,7 @@ public class ASTToTargetAST {
|
|||||||
var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics)).toList();
|
var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics)).toList();
|
||||||
var constructors = input.getConstructors().stream().map(constructor -> this.convert(constructor, finalFieldInitializer)).flatMap(List::stream).toList();
|
var constructors = input.getConstructors().stream().map(constructor -> this.convert(constructor, finalFieldInitializer)).flatMap(List::stream).toList();
|
||||||
var fields = input.getFieldDecl().stream().map(this::convert).toList();
|
var fields = input.getFieldDecl().stream().map(this::convert).toList();
|
||||||
var methods = input.getMethods().stream().map(this::convert).flatMap(List::stream).toList();
|
var methods = groupOverloads(input.getMethods()).stream().map(this::convert).flatMap(List::stream).toList();
|
||||||
|
|
||||||
if (input instanceof Record)
|
if (input instanceof Record)
|
||||||
return new TargetRecord(input.getModifiers(), input.getClassName().toString(), javaGenerics, txGenerics, superInterfaces, constructors, fields, methods);
|
return new TargetRecord(input.getModifiers(), input.getClassName().toString(), javaGenerics, txGenerics, superInterfaces, constructors, fields, methods);
|
||||||
@ -199,23 +200,151 @@ public class ASTToTargetAST {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TargetMethod> convert(Method input) {
|
/**
|
||||||
|
* This only considers type patterns, all other methods aren't grouped together
|
||||||
|
* @param a
|
||||||
|
* @param b
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean signatureEquals(Method a, Method b) {
|
||||||
|
if (!a.name.equals(b.name)) return false;
|
||||||
|
var para = a.getParameterList().getFormalparalist();
|
||||||
|
var parb = b.getParameterList().getFormalparalist();
|
||||||
|
if (para.size() != parb.size()) return false;
|
||||||
|
|
||||||
|
for (var i = 0; i < para.size(); i++) {
|
||||||
|
var pa = para.get(i);
|
||||||
|
var pb = parb.get(i);
|
||||||
|
|
||||||
|
if (pa instanceof RecordPattern rpa) {
|
||||||
|
if (pb instanceof RecordPattern rpb) {
|
||||||
|
if (rpa.getType().equals(rpb.getType())) continue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else if (pa.getType().equals(pb.getType())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Nested patterns
|
||||||
|
private List<List<Method>> groupOverloads(List<Method> input) {
|
||||||
|
var done = new HashSet<Method>();
|
||||||
|
var res = new ArrayList<List<Method>>();
|
||||||
|
for (var method : input) {
|
||||||
|
if (done.contains(method)) continue;
|
||||||
|
var overloads = new ArrayList<Method>();
|
||||||
|
overloads.add(method);
|
||||||
|
done.add(method);
|
||||||
|
for (var method2 : input) {
|
||||||
|
if (!done.contains(method2) && signatureEquals(method, method2)) {
|
||||||
|
done.add(method2);
|
||||||
|
overloads.add(method2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.add(overloads);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String encodeName(String name, ParameterList params) {
|
||||||
|
var res = new StringBuilder();
|
||||||
|
res.append(name);
|
||||||
|
res.append('$');
|
||||||
|
for (var param : params.getFormalparalist()) {
|
||||||
|
if (param instanceof RecordPattern rp) {
|
||||||
|
res.append(FunNGenerator.encodeType(convert(param.getType())));
|
||||||
|
for (var pattern : rp.getSubPattern()) {
|
||||||
|
res.append(FunNGenerator.encodeType(convert(pattern.getType())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TargetMethod> convert(List<Method> overloadedMethods) {
|
||||||
|
if (overloadedMethods.size() == 1) {
|
||||||
|
return convert(overloadedMethods.get(0));
|
||||||
|
}
|
||||||
|
var res = new ArrayList<Method>();
|
||||||
|
for (var method : overloadedMethods) {
|
||||||
|
var newMethod = new Method(
|
||||||
|
method.modifier,
|
||||||
|
encodeName(method.name, method.getParameterList()),
|
||||||
|
method.getReturnType(),
|
||||||
|
method.getParameterList(),
|
||||||
|
method.block,
|
||||||
|
method.getGenerics(),
|
||||||
|
method.getOffset()
|
||||||
|
);
|
||||||
|
res.add(newMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
var template = overloadedMethods.get(0);
|
||||||
|
|
||||||
|
var pParams = new ArrayList<Pattern>();
|
||||||
|
var i = 0;
|
||||||
|
for (var par : template.getParameterList()) {
|
||||||
|
pParams.add(switch (par) {
|
||||||
|
case RecordPattern rp -> new RecordPattern(rp.getSubPattern(), "par" + i, rp.getType(), new NullToken());
|
||||||
|
default -> par;
|
||||||
|
});
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
var params = new ParameterList(pParams, new NullToken());
|
||||||
|
|
||||||
|
var statements = new ArrayList<Statement>();
|
||||||
|
statements.add(new Return(makeRecordSwitch(template.getReturnType(), params, res), new NullToken()));
|
||||||
|
var block = new Block(statements, new NullToken());
|
||||||
|
var entryPoint = new Method(template.modifier, template.name, template.getReturnType(), params, block, template.getGenerics(), new NullToken());
|
||||||
|
|
||||||
|
res.add(entryPoint); // TODO
|
||||||
|
return res.stream().map(this::convert).flatMap(List::stream).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Expression makeRecordSwitch(RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList params, List<Method> overloadedMethods) {
|
||||||
|
var param = params.getFormalparalist().get(0);
|
||||||
|
assert param instanceof RecordPattern; // TODO
|
||||||
|
|
||||||
|
var cases = new ArrayList<SwitchBlock>();
|
||||||
|
for (var method : overloadedMethods) {
|
||||||
|
var statements = new ArrayList<Statement>();
|
||||||
|
/*statements.add(new MethodCall(
|
||||||
|
method.getReturnType(), new ExpressionReceiver(new This(new NullToken())), method.name,
|
||||||
|
params,
|
||||||
|
));*/
|
||||||
|
|
||||||
|
var block = new Block(statements, new NullToken());
|
||||||
|
var labels = new ArrayList<SwitchLabel>();
|
||||||
|
cases.add(new SwitchBlock(labels, block, true, new NullToken()));
|
||||||
|
}
|
||||||
|
var swtch = new Switch(new LocalVar("par0", param.getType(), new NullToken()), cases, returnType, false, new NullToken());
|
||||||
|
|
||||||
|
return swtch;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TargetMethod> convert(Method method) {
|
||||||
generics = all.get(0);
|
generics = all.get(0);
|
||||||
List<TargetMethod> result = new ArrayList<>();
|
List<TargetMethod> result = new ArrayList<>();
|
||||||
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
||||||
|
|
||||||
for (var s : all) {
|
for (var s : all) {
|
||||||
generics = s;
|
generics = s;
|
||||||
var javaGenerics = this.generics.javaGenerics.generics(currentClass, input);
|
var javaGenerics = this.generics.javaGenerics.generics(currentClass, method);
|
||||||
var txGenerics = this.generics.txGenerics.generics(currentClass, input);
|
var txGenerics = this.generics.txGenerics.generics(currentClass, method);
|
||||||
List<MethodParameter> params = convert(input.getParameterList(), this.generics.javaGenerics);
|
List<MethodParameter> params = convert(method.getParameterList(), this.generics.javaGenerics);
|
||||||
if (parameterSet.stream().noneMatch(p -> p.equals(params))) {
|
if (parameterSet.stream().noneMatch(p -> p.equals(params))) {
|
||||||
List<MethodParameter> txParams = convert(input.getParameterList(), this.generics.txGenerics);
|
List<MethodParameter> txParams = convert(method.getParameterList(), this.generics.txGenerics);
|
||||||
|
|
||||||
var javaMethodGenerics = collectMethodGenerics(generics.javaGenerics(), javaGenerics, input);
|
var javaMethodGenerics = collectMethodGenerics(generics.javaGenerics(), javaGenerics, method);
|
||||||
var txMethodGenerics = collectMethodGenerics(generics.txGenerics(), txGenerics, input);
|
var txMethodGenerics = collectMethodGenerics(generics.txGenerics(), txGenerics, method);
|
||||||
|
|
||||||
result.add(new TargetMethod(input.modifier, input.name, convert(input.block), new TargetMethod.Signature(javaMethodGenerics, params, convert(input.getReturnType(), this.generics.javaGenerics)), new TargetMethod.Signature(txMethodGenerics, txParams, convert(input.getReturnType(), this.generics.txGenerics))));
|
var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, convert(method.getReturnType(), this.generics.javaGenerics));
|
||||||
|
var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), this.generics.txGenerics));
|
||||||
|
result.add(new TargetMethod(method.modifier, method.name, convert(method.block), javaSignature, txSignature));
|
||||||
parameterSet.add(params);
|
parameterSet.add(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,6 +371,23 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
|||||||
do {
|
do {
|
||||||
eq0Prime = eqSubst.get();
|
eq0Prime = eqSubst.get();
|
||||||
eq0 = applyTypeUnificationRules(eq0Prime, fc);
|
eq0 = applyTypeUnificationRules(eq0Prime, fc);
|
||||||
|
/* In commit dfd91b5f8b7fca1cb5f302eec4b0ba3330271c9b eingefuegt ANFANG */
|
||||||
|
Set<UnifyPair> occurcheck = new HashSet<>(eq0);
|
||||||
|
occurcheck.removeAll(eq0Prime);
|
||||||
|
ocurrPairs = occurcheck.stream().filter(x -> {
|
||||||
|
UnifyType lhs, rhs;
|
||||||
|
return (lhs = x.getLhsType()) instanceof PlaceholderType
|
||||||
|
&& !((rhs = x.getRhsType()) instanceof PlaceholderType)
|
||||||
|
&& rhs.getTypeParams().occurs((PlaceholderType)lhs);})
|
||||||
|
.map(x -> { x.setUndefinedPair(); return x;})
|
||||||
|
.collect(Collectors.toCollection(HashSet::new));
|
||||||
|
writeLog("ocurrPairs: " + ocurrPairs);
|
||||||
|
if (ocurrPairs.size() > 0) {
|
||||||
|
Set<Set<UnifyPair>> ret = new HashSet<>();
|
||||||
|
ret.add(ocurrPairs);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* In commit dfd91b5f8b7fca1cb5f302eec4b0ba3330271c9b eingefuegt ENDE */
|
||||||
eqSubst = rules.subst(eq0, oderConstraints);
|
eqSubst = rules.subst(eq0, oderConstraints);
|
||||||
} while (eqSubst.isPresent());
|
} while (eqSubst.isPresent());
|
||||||
|
|
||||||
|
@ -58,8 +58,9 @@ public class AllgemeinTest {
|
|||||||
//String className = "Assign";
|
//String className = "Assign";
|
||||||
//String className = "StreamTest";
|
//String className = "StreamTest";
|
||||||
//String className = "Iteration";
|
//String className = "Iteration";
|
||||||
String className = "Test";
|
|
||||||
|
|
||||||
|
//String className = "Cycle";
|
||||||
|
String className = "TripleTest";
|
||||||
//PL 2019-10-24: genutzt fuer unterschiedliche Tests
|
//PL 2019-10-24: genutzt fuer unterschiedliche Tests
|
||||||
path = System.getProperty("user.dir")+"/resources/AllgemeinTest/" + className + ".jav";
|
path = System.getProperty("user.dir")+"/resources/AllgemeinTest/" + className + ".jav";
|
||||||
//path = System.getProperty("user.dir")+"/src/test/resources/AllgemeinTest/Overloading_Generics.jav";
|
//path = System.getProperty("user.dir")+"/src/test/resources/AllgemeinTest/Overloading_Generics.jav";
|
||||||
|
Loading…
Reference in New Issue
Block a user