Compare commits
5 Commits
96eb504174
...
94c359f7a1
Author | SHA1 | Date | |
---|---|---|---|
|
94c359f7a1 | ||
|
3be557a32b | ||
9801f8a5ae | |||
f0b9bea23e | |||
ce4347dd96 |
2
resources/bytecode/javFiles/Bug343.jav
Normal file
2
resources/bytecode/javFiles/Bug343.jav
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
public record Bug343() {
|
||||||
|
}
|
@ -3,7 +3,7 @@ import java.lang.Object;
|
|||||||
import java.lang.Float;
|
import java.lang.Float;
|
||||||
import java.lang.String;
|
import java.lang.String;
|
||||||
|
|
||||||
public record Rec(Object a, Object b) {}
|
public record Rec(Object a, Object b) {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
27
resources/bytecode/javFiles/SwitchRecordList.jav
Normal file
27
resources/bytecode/javFiles/SwitchRecordList.jav
Normal 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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2,41 +2,21 @@ import java.lang.Integer;
|
|||||||
|
|
||||||
public class Y {
|
public class Y {
|
||||||
y;
|
y;
|
||||||
//factorial;
|
|
||||||
|
|
||||||
public Y() {
|
public Y() {
|
||||||
y = f -> t -> f.apply(y.apply(f)).apply(t);
|
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); });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ergibt Parse-Error
|
public class Fac1 {
|
||||||
class fac1 {
|
public factorial;
|
||||||
factorial;
|
public Fac1() {
|
||||||
|
|
||||||
fac1() {
|
|
||||||
var y;
|
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); });
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
@ -698,6 +698,7 @@ public class StatementGenerator {
|
|||||||
if (!Objects.isNull(expr.methodCall())) {
|
if (!Objects.isNull(expr.methodCall())) {
|
||||||
return convert(expr.methodCall(), expr.expression(), offset);
|
return convert(expr.methodCall(), expr.expression(), offset);
|
||||||
} else if (!Objects.isNull(expr.identifier())) {
|
} else if (!Objects.isNull(expr.identifier())) {
|
||||||
|
// FIXME This is not the right way of handling any of this
|
||||||
return generateLocalOrFieldVarOrClassName(expr.getText(), offset);
|
return generateLocalOrFieldVarOrClassName(expr.getText(), offset);
|
||||||
} else {
|
} else {
|
||||||
// Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite
|
// Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite
|
||||||
@ -780,6 +781,7 @@ public class StatementGenerator {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) {
|
private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) {
|
||||||
|
// FIXME Why does this take a String argument???
|
||||||
String[] parts = expression.split("\\.");
|
String[] parts = expression.split("\\.");
|
||||||
if (parts.length < 2) {
|
if (parts.length < 2) {
|
||||||
// Check for localVar:
|
// Check for localVar:
|
||||||
|
@ -254,7 +254,10 @@ public class SyntaxTreeGenerator {
|
|||||||
List<RefType> implementedInterfaces = new ArrayList<>();
|
List<RefType> implementedInterfaces = new ArrayList<>();
|
||||||
List<Pattern> constructorParameters = new ArrayList<>();
|
List<Pattern> constructorParameters = new ArrayList<>();
|
||||||
List<Statement> constructorStatements = 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");
|
int fieldmodifiers = allmodifiers.get("private") + allmodifiers.get("final");
|
||||||
String fieldname = component.identifier().getText();
|
String fieldname = component.identifier().getText();
|
||||||
Token fieldoffset = component.getStart();
|
Token fieldoffset = component.getStart();
|
||||||
|
@ -863,26 +863,7 @@ public class TYPEStmt implements StatementVisitor {
|
|||||||
|
|
||||||
if (el.getPattern() instanceof RecordPattern) {
|
if (el.getPattern() instanceof RecordPattern) {
|
||||||
var pattern = (RecordPattern) recType.getPattern();
|
var pattern = (RecordPattern) recType.getPattern();
|
||||||
|
recursiveAddRecordConstraints(pattern);
|
||||||
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())));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -896,6 +877,37 @@ public class TYPEStmt implements StatementVisitor {
|
|||||||
switchStack.pop();
|
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
|
@Override
|
||||||
public void visit(SwitchBlock switchBlock) {
|
public void visit(SwitchBlock switchBlock) {
|
||||||
for (var stmt : switchBlock.statements) {
|
for (var stmt : switchBlock.statements) {
|
||||||
|
@ -605,7 +605,11 @@ public class TestComplete {
|
|||||||
@Test
|
@Test
|
||||||
public void yTest() throws Exception {
|
public void yTest() throws Exception {
|
||||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Y.jav");
|
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
|
@Test
|
||||||
@ -676,7 +680,6 @@ public class TestComplete {
|
|||||||
assertEquals(swtch.invoke(instance, "Some string"), 0);
|
assertEquals(swtch.invoke(instance, "Some string"), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Not implemented")
|
|
||||||
@Test
|
@Test
|
||||||
public void testSwitchInfered() throws Exception {
|
public void testSwitchInfered() throws Exception {
|
||||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchInfered.jav");
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchInfered.jav");
|
||||||
@ -693,9 +696,9 @@ public class TestComplete {
|
|||||||
assertEquals(swtch.invoke(instance, r1), "asd");
|
assertEquals(swtch.invoke(instance, r1), "asd");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Not implemented")
|
|
||||||
@Test
|
@Test
|
||||||
public void testRecordList() throws Exception {
|
public void testSwitchCaseHeritageDetection() throws Exception {
|
||||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchCaseHeritageDetection.jav");
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchCaseHeritageDetection.jav");
|
||||||
var clazz = classFiles.get("SwitchCaseHeritageDetection");
|
var clazz = classFiles.get("SwitchCaseHeritageDetection");
|
||||||
var clazzAbst = classFiles.get("NumberOrText");
|
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, r1), "Second Element is a Text");
|
||||||
assertEquals(swtch.invoke(instance, r2), "Second Element is a Number");
|
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")
|
@Ignore("Not implemented")
|
||||||
@Test
|
@Test
|
||||||
@ -1192,4 +1221,11 @@ public class TestComplete {
|
|||||||
var clazz = classFiles.get("Bug338");
|
var clazz = classFiles.get("Bug338");
|
||||||
var instance = clazz.getDeclaredConstructor().newInstance();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user