Fix bugs and add new example
All checks were successful
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m13s
All checks were successful
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m13s
This commit is contained in:
parent
94c359f7a1
commit
fbc9f1e755
6
SwitchAppend.java
Normal file
6
SwitchAppend.java
Normal file
@ -0,0 +1,6 @@
|
||||
sealed interface List<T> permits LinkedElem, Elem {}
|
||||
|
||||
record LinkedElem<T>(T a, List<T> l) implements List<T> {}
|
||||
record Elem<T>(T a) implements List<T> {}
|
||||
|
||||
public class SwitchAppend {}
|
1
resources/bytecode/javFiles/GenericRecord.jav
Normal file
1
resources/bytecode/javFiles/GenericRecord.jav
Normal file
@ -0,0 +1 @@
|
||||
public record GenericRecord<T>(T a) {}
|
16
resources/bytecode/javFiles/SwitchAppend.jav
Normal file
16
resources/bytecode/javFiles/SwitchAppend.jav
Normal file
@ -0,0 +1,16 @@
|
||||
sealed interface List<T> permits LinkedElem, Elem {}
|
||||
|
||||
public record LinkedElem<T>(T a, List<T> l) implements List<T> {}
|
||||
public record Elem<T>(T a) implements List<T> {}
|
||||
|
||||
public class SwitchAppend {
|
||||
public append(l1, l2) {
|
||||
return switch(l1) {
|
||||
case LinkedElem(a, Elem(e)) -> new LinkedElem<>(a, new LinkedElem<>(e, l2));
|
||||
case LinkedElem(a, r) -> new LinkedElem<>(a, append(r, l2));
|
||||
//Alternativ:
|
||||
//case LinkedElem(a, LinkedElem(e, r)) -> new LinkedElem<>(a, append(new LinkedElem(e, r), l2));
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
}
|
@ -1402,32 +1402,32 @@ public class Codegen {
|
||||
if (i >= clazz.getFieldDecl().size())
|
||||
throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'");
|
||||
var field = clazz.getFieldDecl().get(i);
|
||||
var fieldType = new TargetRefType(((RefType) field.getType()).getName().toString());
|
||||
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toDescriptor(), false);
|
||||
var fieldType = converter.convert(field.getType());
|
||||
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toSignature(), false);
|
||||
}
|
||||
|
||||
private void bindPattern(State state, TargetType type, TargetPattern pat, Label start, int index, int depth) {
|
||||
if (pat.type() instanceof TargetPrimitiveType)
|
||||
boxPrimitive(state, pat.type());
|
||||
|
||||
state.mv.visitInsn(DUP);
|
||||
state.mv.visitTypeInsn(INSTANCEOF, pat.type().getInternalName());
|
||||
if (pat.type() instanceof TargetRefType) {
|
||||
state.mv.visitInsn(DUP);
|
||||
state.mv.visitTypeInsn(INSTANCEOF, pat.type().getInternalName());
|
||||
|
||||
var cont = new Label();
|
||||
state.mv.visitJumpInsn(IFNE, cont);
|
||||
for (var i = 0; i < depth; i++) {
|
||||
state.mv.visitInsn(POP);
|
||||
var cont = new Label();
|
||||
state.mv.visitJumpInsn(IFNE, cont);
|
||||
for (var i = 0; i < depth; i++) {
|
||||
state.mv.visitInsn(POP);
|
||||
}
|
||||
|
||||
state.mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
||||
state.mv.visitLdcInsn(index + 1);
|
||||
state.mv.visitJumpInsn(GOTO, start);
|
||||
state.mv.visitLabel(cont);
|
||||
|
||||
state.mv.visitTypeInsn(CHECKCAST, pat.type().getInternalName());
|
||||
}
|
||||
|
||||
|
||||
|
||||
state.mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
||||
state.mv.visitLdcInsn(index + 1);
|
||||
state.mv.visitJumpInsn(GOTO, start);
|
||||
state.mv.visitLabel(cont);
|
||||
|
||||
state.mv.visitTypeInsn(CHECKCAST, pat.type().getInternalName());
|
||||
|
||||
if (pat instanceof TargetTypePattern sp) {
|
||||
var local = state.createVariable(sp.name(), sp.type());
|
||||
state.mv.visitVarInsn(ASTORE, local.index);
|
||||
@ -1601,8 +1601,11 @@ public class Codegen {
|
||||
var superType = clazz.superType() != null ? clazz.superType().getInternalName() : "java/lang/Object";
|
||||
|
||||
cw.visit(V1_8, access, clazz.qualifiedName().toString().replaceAll("\\.", "/"), signature, superType, interfaces);
|
||||
if (clazz.txGenerics() != null && signature != null)
|
||||
cw.visitAttribute(new JavaTXSignatureAttribute(generateSignature(clazz, clazz.txGenerics())));
|
||||
if (clazz.txGenerics() != null && signature != null) {
|
||||
var txSignature = generateSignature(clazz, clazz.txGenerics());
|
||||
if (txSignature != null)
|
||||
cw.visitAttribute(new JavaTXSignatureAttribute(txSignature));
|
||||
}
|
||||
|
||||
clazz.fields().forEach(this::generateField);
|
||||
clazz.constructors().forEach(this::generateConstructor);
|
||||
@ -1723,7 +1726,7 @@ public class Codegen {
|
||||
bootstrapArgs[1] = String.join(";", clazz.fields().stream().map(TargetField::name).toArray(String[]::new));
|
||||
for (var i = 0; i < clazz.fields().size(); i++) {
|
||||
var field = clazz.fields().get(i);
|
||||
var fieldRef = new Handle(H_GETFIELD, clazz.getName(), field.name(), field.type().toDescriptor(), false);
|
||||
var fieldRef = new Handle(H_GETFIELD, clazz.getName(), field.name(), field.type().toSignature(), false);
|
||||
bootstrapArgs[i + 2] = fieldRef;
|
||||
}
|
||||
|
||||
|
@ -660,6 +660,13 @@ public class TestComplete {
|
||||
System.out.println(clazz.getDeclaredMethod("toString").invoke(instance));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericRecordTest() throws Exception {
|
||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "GenericRecord.jav");
|
||||
var clazz = classFiles.get("GenericRecord");
|
||||
var instance = clazz.getDeclaredConstructor(Object.class).newInstance((Object) null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwitch() throws Exception {
|
||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Switch.jav");
|
||||
@ -696,6 +703,29 @@ public class TestComplete {
|
||||
assertEquals(swtch.invoke(instance, r1), "asd");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwitchAppend() throws Exception {
|
||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchAppend.jav");
|
||||
var clazz = classFiles.get("SwitchAppend");
|
||||
|
||||
var listClass = classFiles.get("List");
|
||||
var elemClass = classFiles.get("Elem");
|
||||
var linkedElemClass = classFiles.get("LinkedElem");
|
||||
|
||||
var elemCtor = elemClass.getDeclaredConstructor(Object.class);
|
||||
var listCtor = linkedElemClass.getDeclaredConstructor(Object.class, listClass);
|
||||
|
||||
var list1 = listCtor.newInstance("A", listCtor.newInstance("B", elemCtor.newInstance("C")));
|
||||
var list2 = listCtor.newInstance("D", listCtor.newInstance("E", elemCtor.newInstance("F")));
|
||||
|
||||
var instance = clazz.getDeclaredConstructor().newInstance();
|
||||
var appendMethod = clazz.getDeclaredMethod("append", Object.class, listClass);
|
||||
|
||||
var res = appendMethod.invoke(instance, list2, list1);
|
||||
var expected = listCtor.newInstance("D", listCtor.newInstance("E", listCtor.newInstance("F", listCtor.newInstance("A", listCtor.newInstance("B", elemCtor.newInstance("C"))))));
|
||||
|
||||
assertEquals(res, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwitchCaseHeritageDetection() throws Exception {
|
||||
|
Loading…
Reference in New Issue
Block a user