Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5c0d653d2 | ||
|
|
f7e5a1f8a2 | ||
|
|
8f6e6e1980 | ||
|
|
912f3d381e | ||
|
|
7e24bbd552 | ||
|
|
50f2572644 | ||
|
|
e1518c8b37 | ||
|
|
f7a85db191 | ||
|
|
41d5f661e1 | ||
|
|
b7f46c428f |
@@ -1,11 +1,9 @@
|
|||||||
import java.lang.String;
|
import java.lang.String;
|
||||||
import java.lang.Integer;
|
import java.lang.Integer;
|
||||||
|
|
||||||
sealed interface List permits LinkedElem, Elem {}
|
sealed interface List<T> permits LinkedElem, Elem {}
|
||||||
|
public record LinkedElem<T>(T a, List<T> l) implements List<T>{}
|
||||||
|
public record Elem<T>(T c) implements List<T>{}
|
||||||
public record LinkedElem<T>(T a,List l) implements List{}
|
|
||||||
public record Elem<T>(T c) implements List{}
|
|
||||||
|
|
||||||
public class GenericRecordSwitchCase {
|
public class GenericRecordSwitchCase {
|
||||||
public main(o) {
|
public main(o) {
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import java.lang.Object;
|
|||||||
|
|
||||||
public class HelloWorld {
|
public class HelloWorld {
|
||||||
public static hello() {
|
public static hello() {
|
||||||
System.out.println((Object)"Hello World!");
|
System.out.println("Hello World!");
|
||||||
|
System.out.println("Bye World!");
|
||||||
|
System.out.println("The end!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,25 @@
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.lang.String;
|
import java.lang.Integer;
|
||||||
|
|
||||||
public class Sorting{
|
public class Sorting {
|
||||||
merge(a, b){
|
List<Integer> merge(List<Integer> a, List<Integer> b) {
|
||||||
a.addAll(b);
|
var r = new ArrayList<>();
|
||||||
return a;
|
for (var i = 0, j = 0; i < a.size() || j < b.size();)
|
||||||
|
if (j == b.size() || (i < a.size() && a.get(i) <= b.get(j)))
|
||||||
|
r.add(a.get(i++));
|
||||||
|
else r.add(b.get(j++));
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
sort(in){
|
split(list) {
|
||||||
var firstHalf = in;
|
var mid = list.size() / 2;
|
||||||
var secondHalf = in;
|
return List.of(list.subList(0, mid), list.subList(mid, list.size()));
|
||||||
return merge(sort(firstHalf), sort(secondHalf));
|
}
|
||||||
}
|
|
||||||
|
public sort(in) {
|
||||||
|
if (in.size() <= 1) return in;
|
||||||
/*
|
var halves = split(in);
|
||||||
void sort(a){
|
return merge(sort(halves.get(0)), sort(halves.get(1)));
|
||||||
a = merge(a,a);
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -350,6 +350,8 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private TargetType largerType(TargetType left, TargetType right) {
|
private TargetType largerType(TargetType left, TargetType right) {
|
||||||
|
if (left instanceof TargetExtendsWildcard wc) left = wc.innerType();
|
||||||
|
if (right instanceof TargetExtendsWildcard wc) right = wc.innerType();
|
||||||
if (left.equals(TargetType.String) || right.equals(TargetType.String)) {
|
if (left.equals(TargetType.String) || right.equals(TargetType.String)) {
|
||||||
return TargetType.String;
|
return TargetType.String;
|
||||||
} else if (left.equals(TargetType.Double) || right.equals(TargetType.Double)) {
|
} else if (left.equals(TargetType.Double) || right.equals(TargetType.Double)) {
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ package de.dhbwstuttgart.exceptions;
|
|||||||
public class DebugException extends RuntimeException {
|
public class DebugException extends RuntimeException {
|
||||||
|
|
||||||
public DebugException(String message) {
|
public DebugException(String message) {
|
||||||
System.err.print(message);
|
super(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -482,8 +482,8 @@ public class StatementGenerator {
|
|||||||
IdentifierContext identifierCtx = recordPatternCtx.identifier();
|
IdentifierContext identifierCtx = recordPatternCtx.identifier();
|
||||||
var text = (identifierCtx != null) ? identifierCtx.getText() : null;
|
var text = (identifierCtx != null) ? identifierCtx.getText() : null;
|
||||||
//Hier evtl. Typ anpassen -> wenn kein Typ bekannt ist push neuen Typ auf Hashtable
|
//Hier evtl. Typ anpassen -> wenn kein Typ bekannt ist push neuen Typ auf Hashtable
|
||||||
var type = recordPatternCtx.type == null ? TypePlaceholder.fresh(recordPatternCtx.getStart()) : TypeGenerator.convert(recordPatternCtx.type, reg, generics);
|
|
||||||
var ctor = TypeGenerator.convert(recordPatternCtx.ctor, reg, generics);
|
var ctor = TypeGenerator.convert(recordPatternCtx.ctor, reg, generics);
|
||||||
|
var type = recordPatternCtx.type == null ? ctor : TypeGenerator.convert(recordPatternCtx.type, reg, generics);
|
||||||
if (text != null) localVars.put(text, type);
|
if (text != null) localVars.put(text, type);
|
||||||
var ret = new RecordPattern(subPattern, text, type, (RefType)ctor, recordPatternCtx.getStart());
|
var ret = new RecordPattern(subPattern, text, type, (RefType)ctor, recordPatternCtx.getStart());
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -115,8 +115,10 @@ public class ASTToTargetAST {
|
|||||||
public static Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList, IGenerics generics, JavaTXCompiler compiler) {
|
public static Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList, IGenerics generics, JavaTXCompiler compiler) {
|
||||||
Optional<Method> method = Optional.empty();
|
Optional<Method> method = Optional.empty();
|
||||||
while (method.isEmpty()) {
|
while (method.isEmpty()) {
|
||||||
method = owner.getMethods().stream().filter(m -> m.name.equals(name) &&
|
method = owner.getMethods().stream().filter(m -> {
|
||||||
parameterEquals(m.getParameterList().getFormalparalist().stream().map(p -> generics.getTargetType(p.getType())).toList(), argumentList)).findFirst();
|
return m.name.equals(name) &&
|
||||||
|
parameterEquals(m.getParameterList().getFormalparalist().stream().map(p -> generics.getTargetType(p.getType())).toList(), argumentList);
|
||||||
|
}).findFirst();
|
||||||
if (owner.getClassName().toString().equals("java.lang.Object")) break;
|
if (owner.getClassName().toString().equals("java.lang.Object")) break;
|
||||||
owner = compiler.getClass(owner.getSuperClass().getName());
|
owner = compiler.getClass(owner.getSuperClass().getName());
|
||||||
}
|
}
|
||||||
@@ -331,15 +333,16 @@ public class ASTToTargetAST {
|
|||||||
var u_opt = unify(m, m1);
|
var u_opt = unify(m, m1);
|
||||||
if (u_opt.isPresent()) {
|
if (u_opt.isPresent()) {
|
||||||
var u = u_opt.get();
|
var u = u_opt.get();
|
||||||
//Target.logger.info("Unified " + m + " AND " + m1 + "\n\t" + u);
|
//System.out.println("Unified " + m + " AND " + m1 + "\n\t" + u);
|
||||||
i.remove(m1);
|
i.remove(m1);
|
||||||
R.remove(m);
|
R.remove(m);
|
||||||
R.remove(m1);
|
R.remove(m1);
|
||||||
R.add(u);
|
R.add(u);
|
||||||
a.add(u);
|
a.add(u);
|
||||||
} /*else {
|
m = u;
|
||||||
Target.logger.info("Couldn't unify " + m + " AND " + m1);
|
} else {
|
||||||
}*/
|
//System.out.println("Couldn't unify " + m + " AND " + m1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -381,8 +384,21 @@ public class ASTToTargetAST {
|
|||||||
TargetBlock finalFieldInitializer = fieldInitializer;
|
TargetBlock finalFieldInitializer = fieldInitializer;
|
||||||
|
|
||||||
var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics, compiler)).toList();
|
var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics, compiler)).toList();
|
||||||
var constructors = input.getConstructors().stream().map(constructor -> this.convert(input, constructor, finalFieldInitializer, generics)).flatMap(List::stream).toList();
|
var constructors = input.getConstructors().stream().map(constructor -> {
|
||||||
var fields = input.getFieldDecl().stream().map(f -> convert(f, generics.javaGenerics)).toList();
|
try {
|
||||||
|
return this.convert(input, constructor, finalFieldInitializer, generics);
|
||||||
|
} catch (DiscardResultSet discard) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).filter(Objects::nonNull).flatMap(List::stream).toList();
|
||||||
|
var fields = input.getFieldDecl().stream().map(f -> {
|
||||||
|
var possibleTypes = new HashSet<TargetType>();
|
||||||
|
for (var g : all) possibleTypes.add(convert(f.getType(), g.javaGenerics(), compiler));
|
||||||
|
if (possibleTypes.size() > 1)
|
||||||
|
compiler.warn(new CompilerWarning(f.getOffset(), "Multiple possible types for field " + f.getName() + ": " + possibleTypes + " please select one"));
|
||||||
|
return convert(f, generics.javaGenerics);
|
||||||
|
}).toList();
|
||||||
var m0 = groupMethods(input, input.getMethods());
|
var m0 = groupMethods(input, input.getMethods());
|
||||||
|
|
||||||
var m1 = new ArrayList<TargetMethod>();
|
var m1 = new ArrayList<TargetMethod>();
|
||||||
@@ -851,7 +867,13 @@ public class ASTToTargetAST {
|
|||||||
for (var tph : tphs) {
|
for (var tph : tphs) {
|
||||||
var left = a.getTargetType(tph);
|
var left = a.getTargetType(tph);
|
||||||
var right = b.getTargetType(tph);
|
var right = b.getTargetType(tph);
|
||||||
if (!Objects.equals(left, right)) return true;
|
if (left instanceof TargetExtendsWildcard wc) left = wc.innerType();
|
||||||
|
if (right instanceof TargetExtendsWildcard wc) right = wc.innerType();
|
||||||
|
|
||||||
|
if (!Objects.equals(left, right)) {
|
||||||
|
System.out.println(tph + " " + left + " " + right);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -889,10 +911,13 @@ public class ASTToTargetAST {
|
|||||||
signatures.add(new Signature(javaSignature, txSignature, generics));
|
signatures.add(new Signature(javaSignature, txSignature, generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!signatures.isEmpty()) {
|
for (var signature : new ArrayList<>(signatures)) {
|
||||||
var signature = signatures.getFirst();
|
try {
|
||||||
// We need to convert once to find out what TPHs are existing in the given method
|
|
||||||
convert(new MethodWithTphs(method, signature.generics, signature));
|
convert(new MethodWithTphs(method, signature.generics, signature));
|
||||||
|
} catch (DiscardResultSet discard) {
|
||||||
|
// If a result set is discarded we skip it from now on
|
||||||
|
signatures.removeIf(s -> s == signature);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var signature : signatures) {
|
for (var signature : signatures) {
|
||||||
@@ -980,7 +1005,7 @@ public class ASTToTargetAST {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSubtype(TargetType test, TargetType other) {
|
public boolean isSubtype(TargetType test, TargetType other) {
|
||||||
if (other.equals(TargetType.Object)) return true;
|
if (other.equals(TargetType.Object)) return true;
|
||||||
if (test instanceof TargetFunNType tfun && other instanceof TargetFunNType ofun)
|
if (test instanceof TargetFunNType tfun && other instanceof TargetFunNType ofun)
|
||||||
return isSubtype(new FunNGenerator.GenericParameters(tfun), new FunNGenerator.GenericParameters(ofun));
|
return isSubtype(new FunNGenerator.GenericParameters(tfun), new FunNGenerator.GenericParameters(ofun));
|
||||||
@@ -989,6 +1014,12 @@ public class ASTToTargetAST {
|
|||||||
var otherClass = compiler.getClass(new JavaClassName(other.name()));
|
var otherClass = compiler.getClass(new JavaClassName(other.name()));
|
||||||
if (testClass == null) return false;
|
if (testClass == null) return false;
|
||||||
while (testClass != null) {
|
while (testClass != null) {
|
||||||
|
if (otherClass.isInterface()) {
|
||||||
|
for (var superInterface : testClass.getSuperInterfaces()) {
|
||||||
|
if (superInterface.getName().equals(otherClass.getClassName())) return true;
|
||||||
|
if (isSubtype(new TargetRefType(superInterface.getName().toString()), other)) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (testClass.equals(otherClass)) return true;
|
if (testClass.equals(otherClass)) return true;
|
||||||
if (testClass.getClassName().equals(new JavaClassName("java.lang.Object"))) break;
|
if (testClass.getClassName().equals(new JavaClassName("java.lang.Object"))) break;
|
||||||
testClass = compiler.getClass(testClass.getSuperClass().getName());
|
testClass = compiler.getClass(testClass.getSuperClass().getName());
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DiscardResultSet extends RuntimeException {
|
||||||
|
public DiscardResultSet() {}
|
||||||
|
}
|
||||||
@@ -1008,7 +1008,9 @@ public abstract class GenerateGenerics implements IGenerics {
|
|||||||
public TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in) {
|
public TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in) {
|
||||||
if (in instanceof TypePlaceholder tph) {
|
if (in instanceof TypePlaceholder tph) {
|
||||||
if (equality.containsKey(tph)) {
|
if (equality.containsKey(tph)) {
|
||||||
return getTargetType(equality.get(tph));
|
var tph2 = equality.get(tph);
|
||||||
|
// Sanity check, they should not be equal!
|
||||||
|
if (!Objects.equals(in, tph2)) return getTargetType(tph2);
|
||||||
}
|
}
|
||||||
var type = concreteTypes.get(new TPH(tph));
|
var type = concreteTypes.get(new TPH(tph));
|
||||||
if (type == null) return new TargetGenericType(tph.getName());
|
if (type == null) return new TargetGenericType(tph.getName());
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package de.dhbwstuttgart.target.generate;
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.exceptions.DebugException;
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
@@ -222,6 +223,19 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
|
|
||||||
|
// Look at the signature in all result sets and check if a more specific insertion exists.
|
||||||
|
// If so, discard this result set by throwing an exception
|
||||||
|
for (var tph : Iterables.concat(List.of(methodCall.receiver.getType()), methodCall.signatureArguments())) {
|
||||||
|
var currentType = converter.convert(tph, generics);
|
||||||
|
for (var g2 : converter.all) if (g2.javaGenerics() != generics) {
|
||||||
|
var type = g2.javaGenerics().getTargetType(tph);
|
||||||
|
if (!Objects.equals(type, currentType) && converter.isSubtype(type, currentType)) {
|
||||||
|
throw new DiscardResultSet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var receiverType = converter.convert(methodCall.receiver.getType(), generics);
|
var receiverType = converter.convert(methodCall.receiver.getType(), generics);
|
||||||
var isFunNType = receiverType instanceof TargetFunNType;
|
var isFunNType = receiverType instanceof TargetFunNType;
|
||||||
|
|
||||||
@@ -250,18 +264,20 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
} else if (!isFunNType) {
|
} else if (!isFunNType) {
|
||||||
receiverClass = converter.compiler.getClass(receiverName);
|
receiverClass = converter.compiler.getClass(receiverName);
|
||||||
if (receiverClass == null) throw new DebugException("Class " + receiverName + " does not exist!");
|
if (receiverClass == null) throw new DebugException("Class " + receiverName + " does not exist!");
|
||||||
foundMethod = findMethod(receiverName, methodCall.name, signature, converter.compiler).orElseThrow();
|
foundMethod = findMethod(receiverName, methodCall.name, signature, converter.compiler).orElseThrow(
|
||||||
|
() -> new DebugException("Method " + methodCall.name + " not found (" + signature + ") on class " + receiverName)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isFunNType) {
|
if (!isFunNType) {
|
||||||
returnType = converter.convert(foundMethod.getReturnType(), generics);
|
// NOTE Not using the direct conversion method on converter to bypass adding the TPH to the used TPH list
|
||||||
|
returnType = ASTToTargetAST.convert(foundMethod.getReturnType(), generics, converter.compiler);
|
||||||
argList = foundMethod.getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType(), generics)).toList();
|
argList = foundMethod.getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType(), generics)).toList();
|
||||||
isStatic = Modifier.isStatic(foundMethod.modifier);
|
isStatic = Modifier.isStatic(foundMethod.modifier);
|
||||||
isPrivate = Modifier.isPrivate(foundMethod.modifier);
|
isPrivate = Modifier.isPrivate(foundMethod.modifier);
|
||||||
isInterface = receiverClass.isInterface();
|
isInterface = receiverClass.isInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
//System.out.println(argList);
|
|
||||||
result = new TargetMethodCall(
|
result = new TargetMethodCall(
|
||||||
converter.convert(methodCall.getType(), generics), returnType, argList,
|
converter.convert(methodCall.getType(), generics), returnType, argList,
|
||||||
converter.convert(methodCall.receiver, generics),
|
converter.convert(methodCall.receiver, generics),
|
||||||
|
|||||||
@@ -392,6 +392,8 @@ public class TYPEStmt implements StatementVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(BoolExpression expr) {
|
public void visit(BoolExpression expr) {
|
||||||
|
expr.lexpr.accept(this);
|
||||||
|
expr.rexpr.accept(this);
|
||||||
|
|
||||||
constraintsSet.addUndConstraint(new Pair(bool, expr.getType(), PairOperator.EQUALSDOT, loc(expr.getOffset())));
|
constraintsSet.addUndConstraint(new Pair(bool, expr.getType(), PairOperator.EQUALSDOT, loc(expr.getOffset())));
|
||||||
constraintsSet.addUndConstraint(new Pair(bool, expr.lexpr.getType(), PairOperator.EQUALSDOT, loc(expr.getOffset())));
|
constraintsSet.addUndConstraint(new Pair(bool, expr.lexpr.getType(), PairOperator.EQUALSDOT, loc(expr.getOffset())));
|
||||||
|
|||||||
@@ -32,14 +32,12 @@ public class Logger {
|
|||||||
private static Writer defaultWriter;
|
private static Writer defaultWriter;
|
||||||
private static void initLogger() {
|
private static void initLogger() {
|
||||||
if (defaultWriter != null) return;
|
if (defaultWriter != null) return;
|
||||||
if (ConsoleInterface.writeLogFiles) {
|
if (!ConsoleInterface.writeLogFiles) return;
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(logFolder.toPath());
|
Files.createDirectories(logFolder.toPath());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Could not create directory for log files: " + logFolder, e);
|
throw new RuntimeException("Could not create directory for log files: " + logFolder, e);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");
|
var formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");
|
||||||
var currentTimestamp = LocalDateTime.now().format(formatter);
|
var currentTimestamp = LocalDateTime.now().format(formatter);
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -320,9 +320,17 @@ public class TestComplete {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void overloadingSortingTest() throws Exception {
|
public void sortingTest() throws Exception {
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Sorting.jav");
|
var classFiles = generateClassFiles(createClassLoader(), "Sorting.jav");
|
||||||
var instance = classFiles.get("Sorting").getDeclaredConstructor().newInstance();
|
var Sorting = classFiles.get("Sorting");
|
||||||
|
var instance = Sorting.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
var unsorted = List.of(10, 2, 1, 20, -1, 5);
|
||||||
|
var sorted = List.of(-1, 1, 2, 5, 10, 20);
|
||||||
|
var sort = Sorting.getDeclaredMethod("sort", List.class);
|
||||||
|
|
||||||
|
var result = sort.invoke(instance, unsorted);
|
||||||
|
assertEquals(sorted, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user