diff --git a/resources/bytecode/javFiles/FieldTph2.jav b/resources/bytecode/javFiles/FieldTph2.jav index 7d60b683..ed0d4521 100644 --- a/resources/bytecode/javFiles/FieldTph2.jav +++ b/resources/bytecode/javFiles/FieldTph2.jav @@ -1,3 +1,5 @@ +import java.lang.String; + public class FieldTph2 { a; diff --git a/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java b/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java index 7f0bb0d5..25c1eca2 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java @@ -4,15 +4,12 @@ import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; -import de.dhbwstuttgart.syntaxtree.SourceFile; -import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.target.tree.*; import de.dhbwstuttgart.target.tree.expression.*; import de.dhbwstuttgart.target.tree.type.*; import org.objectweb.asm.*; -import java.io.File; import java.lang.invoke.*; import java.util.*; @@ -1113,11 +1110,11 @@ public class Codegen { for (var i = 0; i < types.length; i++) { var cse = aSwitch.cases().get(i); var label = cse.labels().get(0); - if (label instanceof TargetSwitch.SimplePattern || label instanceof TargetSwitch.ComplexPattern) + if (label instanceof SimplePattern || label instanceof ComplexPattern) types[i] = Type.getObjectType(label.type().getInternalName()); else if (label instanceof TargetLiteral lit) types[i] = lit.value(); - else if (label instanceof TargetSwitch.Guard guard) + else if (label instanceof Guard guard) types[i] = Type.getObjectType(guard.inner().type().getInternalName()); // TODO Same here we need to evaluate constant; else throw new NotImplementedException(); @@ -1151,15 +1148,15 @@ public class Codegen { if (cse.labels().size() == 1) { var label = cse.labels().get(0); - if (label instanceof TargetSwitch.Guard gd){ + if (label instanceof Guard gd){ state.mv.visitVarInsn(ALOAD, tmp); bindPattern(state, aSwitch.expr().type(), gd.inner(), start); - } else if (label instanceof TargetSwitch.Pattern pat) { + } else if (label instanceof TargetPattern pat) { state.mv.visitVarInsn(ALOAD, tmp); bindPattern(state, aSwitch.expr().type(), pat, start); } - if (label instanceof TargetSwitch.Guard gd) { + if (label instanceof Guard gd) { generate(state, gd.expression()); var next = new Label(); mv.visitJumpInsn(IFNE, next); @@ -1197,13 +1194,13 @@ public class Codegen { state.exitScope(); } - private void bindPattern(State state, TargetType type, TargetSwitch.Pattern pat, Label start) { - if (pat instanceof TargetSwitch.SimplePattern sp) { + private void bindPattern(State state, TargetType type, TargetPattern pat, Label start) { + if (pat instanceof SimplePattern sp) { var local = state.createVariable(sp.name(), sp.type()); convertTo(state, type, sp.type()); boxPrimitive(state, sp.type()); state.mv.visitVarInsn(ASTORE, local.index); - } else if (pat instanceof TargetSwitch.ComplexPattern cp) { + } else if (pat instanceof ComplexPattern cp) { convertTo(state, type, cp.type()); boxPrimitive(state, cp.type()); @@ -1232,7 +1229,7 @@ public class Codegen { return; } else for (var case_ : aSwitch.cases()) { - if (case_.labels().stream().anyMatch(c -> c instanceof TargetSwitch.Pattern)) { + if (case_.labels().stream().anyMatch(c -> c instanceof TargetPattern)) { generateEnhancedSwitch(state, aSwitch); return; } diff --git a/src/main/java/de/dhbwstuttgart/target/generate/GenerateGenerics.java b/src/main/java/de/dhbwstuttgart/target/generate/GenerateGenerics.java index 2f437d6e..cc209487 100644 --- a/src/main/java/de/dhbwstuttgart/target/generate/GenerateGenerics.java +++ b/src/main/java/de/dhbwstuttgart/target/generate/GenerateGenerics.java @@ -1,6 +1,5 @@ package de.dhbwstuttgart.target.generate; -import com.google.common.collect.Streams; import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.Constructor; @@ -15,12 +14,10 @@ import de.dhbwstuttgart.typeinference.result.PairTPHEqualTPH; import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType; import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH; import de.dhbwstuttgart.typeinference.result.ResultSet; -import de.dhbwstuttgart.util.Pair; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; -import java.util.stream.StreamSupport; public abstract class GenerateGenerics { @@ -106,6 +103,7 @@ public abstract class GenerateGenerics { this.right = right; } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; diff --git a/src/main/java/de/dhbwstuttgart/target/generate/StatementToTargetExpression.java b/src/main/java/de/dhbwstuttgart/target/generate/StatementToTargetExpression.java index a743da23..a800410a 100644 --- a/src/main/java/de/dhbwstuttgart/target/generate/StatementToTargetExpression.java +++ b/src/main/java/de/dhbwstuttgart/target/generate/StatementToTargetExpression.java @@ -3,10 +3,8 @@ package de.dhbwstuttgart.target.generate; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.scope.JavaClassName; -import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.statement.*; -import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.target.tree.MethodParameter; import de.dhbwstuttgart.target.tree.expression.*; import de.dhbwstuttgart.target.tree.type.*; @@ -369,20 +367,20 @@ public class StatementToTargetExpression implements StatementVisitor { @Override public void visit(Pattern aPattern) { - result = new TargetSwitch.SimplePattern(converter.convert(aPattern.getType()), aPattern.getName()); + result = new SimplePattern(converter.convert(aPattern.getType()), aPattern.getName()); } @Override public void visit(RecordPattern aRecordPattern) { - result = new TargetSwitch.ComplexPattern( + result = new ComplexPattern( converter.convert(aRecordPattern.getType()), aRecordPattern.getName(), - aRecordPattern.getSubPattern().stream().map(x -> (TargetSwitch.Pattern) converter.convert(x)).toList() + aRecordPattern.getSubPattern().stream().map(x -> (TargetPattern) converter.convert(x)).toList() ); } @Override public void visit(GuardedPattern aGuardedPattern) { - result = new TargetSwitch.Guard((TargetSwitch.Pattern) converter.convert(aGuardedPattern.getNestedPattern()), converter.convert(aGuardedPattern.getCondition())); + result = new Guard((TargetPattern) converter.convert(aGuardedPattern.getNestedPattern()), converter.convert(aGuardedPattern.getCondition())); } } diff --git a/src/main/java/de/dhbwstuttgart/target/tree/expression/ComplexPattern.java b/src/main/java/de/dhbwstuttgart/target/tree/expression/ComplexPattern.java new file mode 100644 index 00000000..92896ba3 --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/target/tree/expression/ComplexPattern.java @@ -0,0 +1,8 @@ +package de.dhbwstuttgart.target.tree.expression; + +import de.dhbwstuttgart.target.tree.type.TargetType; + +import java.util.List; + +public record ComplexPattern(TargetType type, String name, List subPatterns) implements TargetPattern { +} diff --git a/src/main/java/de/dhbwstuttgart/target/tree/expression/Guard.java b/src/main/java/de/dhbwstuttgart/target/tree/expression/Guard.java new file mode 100644 index 00000000..46594350 --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/target/tree/expression/Guard.java @@ -0,0 +1,4 @@ +package de.dhbwstuttgart.target.tree.expression; + +public record Guard(TargetPattern inner, TargetExpression expression) implements TargetPattern { +} diff --git a/src/main/java/de/dhbwstuttgart/target/tree/expression/SimplePattern.java b/src/main/java/de/dhbwstuttgart/target/tree/expression/SimplePattern.java new file mode 100644 index 00000000..1ed9bec6 --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/target/tree/expression/SimplePattern.java @@ -0,0 +1,6 @@ +package de.dhbwstuttgart.target.tree.expression; + +import de.dhbwstuttgart.target.tree.type.TargetType; + +public record SimplePattern(TargetType type, String name) implements TargetPattern { +} diff --git a/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetExpression.java b/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetExpression.java index bd1f1b07..76d3976a 100644 --- a/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetExpression.java +++ b/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetExpression.java @@ -3,7 +3,7 @@ package de.dhbwstuttgart.target.tree.expression; import de.dhbwstuttgart.target.tree.type.*; public sealed interface TargetExpression - permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetSwitch.Pattern, TargetTernary, TargetThis, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield { + permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetPattern, TargetTernary, TargetThis, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield { default TargetType type() { return null; diff --git a/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetPattern.java b/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetPattern.java new file mode 100644 index 00000000..9d9fd5ed --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetPattern.java @@ -0,0 +1,7 @@ +package de.dhbwstuttgart.target.tree.expression; + +public sealed interface TargetPattern extends TargetExpression permits ComplexPattern, Guard, SimplePattern { + default String name() { + return null; + } +} diff --git a/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetSwitch.java b/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetSwitch.java index ea3283ed..65dd5921 100644 --- a/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetSwitch.java +++ b/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetSwitch.java @@ -27,14 +27,4 @@ public record TargetSwitch(TargetExpression expr, List cases, Case default } } - public sealed interface Pattern extends TargetExpression { - default String name() { - return null; - } - } - - public record SimplePattern(TargetType type, String name) implements Pattern {} - public record ComplexPattern(TargetType type, String name, List subPatterns) implements Pattern {} - - public record Guard(Pattern inner, TargetExpression expression) implements Pattern {} } diff --git a/src/test/java/targetast/TestCodegen.java b/src/test/java/targetast/TestCodegen.java index 2f478c2d..f7292a4a 100644 --- a/src/test/java/targetast/TestCodegen.java +++ b/src/test/java/targetast/TestCodegen.java @@ -19,7 +19,6 @@ import static org.junit.Assert.*; import org.objectweb.asm.Opcodes; -import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -238,15 +237,15 @@ public class TestCodegen { var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "SwitchEnhanced"); targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "switchType", List.of(new MethodParameter(TargetType.Object, "obj")), TargetType.Integer, new TargetBlock(List.of( new TargetReturn(new TargetSwitch(new TargetLocalVar(TargetType.Object, "obj"), List.of( - new TargetSwitch.Case(List.of(new TargetSwitch.SimplePattern(TargetType.String, "aString")), new TargetBlock( + new TargetSwitch.Case(List.of(new SimplePattern(TargetType.String, "aString")), new TargetBlock( List.of(new TargetYield(new TargetLiteral.IntLiteral(0))) ), false), new TargetSwitch.Case(List.of( - new TargetSwitch.Guard(new TargetSwitch.SimplePattern(TargetType.Integer, "i"), new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10))) + new Guard(new SimplePattern(TargetType.Integer, "i"), new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10))) ), new TargetBlock( List.of(new TargetLiteral.IntLiteral(3)) ), true), - new TargetSwitch.Case(List.of(new TargetSwitch.SimplePattern(TargetType.Integer, "anInteger")), new TargetBlock( + new TargetSwitch.Case(List.of(new SimplePattern(TargetType.Integer, "anInteger")), new TargetBlock( List.of(new TargetLiteral.IntLiteral(1)) ), true) ), new TargetSwitch.Case(new TargetBlock(