Compare commits

...

5 Commits

Author SHA1 Message Date
Ruben
94c359f7a1 test & feat: recursive Method-Call for nested Constraint-Generation Patterns in Records and added Linked-List Testcase.
All checks were successful
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 6m7s
2024-08-20 19:52:55 +02:00
Ruben
3be557a32b Merge branch 'targetBytecode' into patternMatching 2024-08-11 19:57:07 +02:00
9801f8a5ae Merge branch 'targetBytecode' of ssh://gitea.hb.dhbw-stuttgart.de:2221/JavaTX/JavaCompilerCore into targetBytecode
All checks were successful
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m39s
2024-08-07 13:34:03 +02:00
f0b9bea23e Fix #343 (le null check) 2024-08-07 13:33:40 +02:00
ce4347dd96 Fix Y Test #341
All checks were successful
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m20s
2024-08-06 12:42:09 +02:00
8 changed files with 118 additions and 56 deletions

View File

@ -0,0 +1,2 @@
public record Bug343() {
}

View File

@ -3,7 +3,7 @@ import java.lang.Object;
import java.lang.Float;
import java.lang.String;
public record Rec(Object a, Object b) {}
public record Rec(Object a, Object b) {}

View File

@ -0,0 +1,27 @@
import java.lang.Integer;
import java.lang.Object;
import java.lang.Float;
import java.lang.String;
sealed interface List permits LinkedElem {}
public record LinkedElem(Integer a,List l) implements List{} //Implementiert List und wird auch permittet
public record Elem(Integer c) implements List{} //Implementiert List, wird aber nicht permittet
public class SwitchCaseHeritageDetection {
public main(o) {
return switch(o) {
case LinkedElem(a, Elem(e)) -> a + e;
case LinkedElem(a, LinkedElem(e, Elem(f))) -> a + e + f;
default -> 0;
};
}
}

View File

@ -2,41 +2,21 @@ import java.lang.Integer;
public class Y {
y;
//factorial;
public Y() {
y = f -> t -> f.apply(y.apply(f)).apply(t);
//factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
}
/*
getY() {
return y;
}
*/
}
/*
class fac1 {
factorial;
fac1() {
var y;
y = new Y<Integer,Integer,Integer,Integer,Integer>().getY();
factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
y = f -> t -> f.apply(y.apply(f)).apply(t);
}
}
ergibt Parse-Error
class fac1 {
factorial;
fac1() {
public class Fac1 {
public factorial;
public Fac1() {
var y;
y = new Y<>().y;
var tmp = new Y<>(); // TODO Having new Y<>().y on one line doesn't work, see FIXME in StatementGenerator
y = tmp.y;
factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
}
public static void main(String args[]) {
System.out.println(new fac1().factorial.apply(3));
public fac(v) {
return factorial.apply(v);
}
}
*/
}

View File

@ -698,6 +698,7 @@ public class StatementGenerator {
if (!Objects.isNull(expr.methodCall())) {
return convert(expr.methodCall(), expr.expression(), offset);
} else if (!Objects.isNull(expr.identifier())) {
// FIXME This is not the right way of handling any of this
return generateLocalOrFieldVarOrClassName(expr.getText(), offset);
} else {
// Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite
@ -780,6 +781,7 @@ public class StatementGenerator {
* @return
*/
private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) {
// FIXME Why does this take a String argument???
String[] parts = expression.split("\\.");
if (parts.length < 2) {
// Check for localVar:

View File

@ -254,7 +254,10 @@ public class SyntaxTreeGenerator {
List<RefType> implementedInterfaces = new ArrayList<>();
List<Pattern> constructorParameters = new ArrayList<>();
List<Statement> constructorStatements = new ArrayList<>();
for (RecordComponentContext component : recordDeclaration.recordHeader().recordComponentList().recordComponent()) {
List<Java17Parser.RecordComponentContext> components = recordDeclaration.recordHeader().recordComponentList() != null ?
recordDeclaration.recordHeader().recordComponentList().recordComponent(): List.of();
for (RecordComponentContext component : components) {
int fieldmodifiers = allmodifiers.get("private") + allmodifiers.get("final");
String fieldname = component.identifier().getText();
Token fieldoffset = component.getStart();

View File

@ -863,26 +863,7 @@ public class TYPEStmt implements StatementVisitor {
if (el.getPattern() instanceof RecordPattern) {
var pattern = (RecordPattern) recType.getPattern();
var allClasses = info.getAvailableClasses();
var interestingClasses = allClasses.stream().filter(as -> as.getClassName().equals(((RefType) el.getType()).getName())).toList();
var test = "";
var constructors = interestingClasses.get(0).getConstructors();
for (int i = 0; i < pattern.getSubPattern().size(); i++) {
var supPattern = pattern.getSubPattern().get(i);
for (int j = 0; j < interestingClasses.size(); j++) {
var clazz = interestingClasses.get(j);
for (int k = 0; k < clazz.getConstructors().size(); k++) {
var constructor = clazz.getConstructors().get(k);
constraintsSet.addUndConstraint(new Pair(supPattern.getType(), constructor.getParameterList().getParameterAt(i).getType(), PairOperator.SMALLERDOT, loc(constructor.getParameterList().getParameterAt(i).getOffset())));
}
}
}
recursiveAddRecordConstraints(pattern);
}
@ -896,6 +877,37 @@ public class TYPEStmt implements StatementVisitor {
switchStack.pop();
}
public void recursiveAddRecordConstraints(RecordPattern el) {
var pattern = el;
var allClasses = info.getAvailableClasses();
var interestingClasses = allClasses.stream().filter(as -> as.getClassName().equals(((RefType) el.getType()).getName())).toList();
var test = "";
var constructors = interestingClasses.get(0).getConstructors();
for (int i = 0; i < pattern.getSubPattern().size(); i++) {
var supPattern = pattern.getSubPattern().get(i);
if (supPattern instanceof RecordPattern) {
recursiveAddRecordConstraints((RecordPattern) supPattern);
} else {
for (int j = 0; j < interestingClasses.size(); j++) {
var clazz = interestingClasses.get(j);
for (int k = 0; k < clazz.getConstructors().size(); k++) {
var constructor = clazz.getConstructors().get(k);
constraintsSet.addUndConstraint(new Pair(supPattern.getType(), constructor.getParameterList().getParameterAt(i).getType(), PairOperator.SMALLERDOT, loc(constructor.getParameterList().getParameterAt(i).getOffset())));
}
}
}
}
}
@Override
public void visit(SwitchBlock switchBlock) {
for (var stmt : switchBlock.statements) {

View File

@ -605,7 +605,11 @@ public class TestComplete {
@Test
public void yTest() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Y.jav");
var instance = classFiles.get("Y").getDeclaredConstructor().newInstance();
var fac1 = classFiles.get("Fac1");
var instance = fac1.getDeclaredConstructor().newInstance();
var fac = fac1.getDeclaredMethod("fac", Integer.class);
assertEquals(fac.invoke(instance, 10), 3628800);
}
@Test
@ -676,7 +680,6 @@ public class TestComplete {
assertEquals(swtch.invoke(instance, "Some string"), 0);
}
@Ignore("Not implemented")
@Test
public void testSwitchInfered() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchInfered.jav");
@ -693,9 +696,9 @@ public class TestComplete {
assertEquals(swtch.invoke(instance, r1), "asd");
}
@Ignore("Not implemented")
@Test
public void testRecordList() throws Exception {
public void testSwitchCaseHeritageDetection() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchCaseHeritageDetection.jav");
var clazz = classFiles.get("SwitchCaseHeritageDetection");
var clazzAbst = classFiles.get("NumberOrText");
@ -716,6 +719,32 @@ public class TestComplete {
assertEquals(swtch.invoke(instance, r1), "Second Element is a Text");
assertEquals(swtch.invoke(instance, r2), "Second Element is a Number");
}
@Ignore("Not implemented")
@Test
public void testSwitchListRecord() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchRecordList.jav");
var clazz = classFiles.get("SwitchCaseHeritageDetection");
var instance = clazz.getDeclaredConstructor().newInstance();
var swtch = clazz.getDeclaredMethod("main", Object.class);
var linkedElem = classFiles.get("LinkedElem");
var listInterface = classFiles.get("List");
var elem = classFiles.get("Elem");
var constructorLinkedElem = linkedElem.getDeclaredConstructor(Integer.class, listInterface);
var constructorElem = elem.getConstructor(Integer.class);
var listWithMoreThanOneElement = constructorLinkedElem.newInstance(5, constructorLinkedElem.newInstance(1, constructorElem.newInstance(5)));
assertEquals(swtch.invoke(instance, listWithMoreThanOneElement), 11);
var listWithOneElement = constructorLinkedElem.newInstance(5, constructorElem.newInstance(5));
assertEquals(swtch.invoke(instance, listWithOneElement), 10);
}
@Ignore("Not implemented")
@Test
@ -1192,4 +1221,11 @@ public class TestComplete {
var clazz = classFiles.get("Bug338");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testBug343() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug343.jav");
var clazz = classFiles.get("Bug343");
var instance = clazz.getDeclaredConstructor().newInstance();
}
}