From 94c359f7a11a919f81d5d409176ea780e8c6038a Mon Sep 17 00:00:00 2001 From: Ruben Date: Tue, 20 Aug 2024 19:52:55 +0200 Subject: [PATCH] test & feat: recursive Method-Call for nested Constraint-Generation Patterns in Records and added Linked-List Testcase. --- resources/bytecode/javFiles/SwitchInfered.jav | 2 +- .../bytecode/javFiles/SwitchRecordList.jav | 27 ++++++++++ .../typeinference/typeAlgo/TYPEStmt.java | 52 ++++++++++++------- src/test/java/TestComplete.java | 31 +++++++++-- 4 files changed, 88 insertions(+), 24 deletions(-) create mode 100644 resources/bytecode/javFiles/SwitchRecordList.jav diff --git a/resources/bytecode/javFiles/SwitchInfered.jav b/resources/bytecode/javFiles/SwitchInfered.jav index a222859b..13605ab6 100644 --- a/resources/bytecode/javFiles/SwitchInfered.jav +++ b/resources/bytecode/javFiles/SwitchInfered.jav @@ -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) {} diff --git a/resources/bytecode/javFiles/SwitchRecordList.jav b/resources/bytecode/javFiles/SwitchRecordList.jav new file mode 100644 index 00000000..27ca9217 --- /dev/null +++ b/resources/bytecode/javFiles/SwitchRecordList.jav @@ -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; + }; + } +} + + + + + + + diff --git a/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index 512a3294..1a9032f2 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -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) { diff --git a/src/test/java/TestComplete.java b/src/test/java/TestComplete.java index a8197daf..cdfc9d5e 100644 --- a/src/test/java/TestComplete.java +++ b/src/test/java/TestComplete.java @@ -680,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"); @@ -697,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"); @@ -720,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