From a0355896475d83615de2ecce6691be6900339418 Mon Sep 17 00:00:00 2001 From: Daniel Holle Date: Thu, 1 Feb 2024 11:58:08 +0100 Subject: [PATCH] Implement throw --- resources/bytecode/javFiles/Exceptions.jav | 7 ++++++- .../de/dhbwstuttgart/bytecode/Codegen.java | 5 +++++ .../StatementGenerator.java | 3 +-- .../syntaxtree/AbstractASTWalker.java | 5 +++++ .../syntaxtree/StatementVisitor.java | 2 ++ .../syntaxtree/statement/Throw.java | 21 +++++++++++++++++++ .../syntaxtree/visual/OutputGenerator.java | 5 +++++ .../generate/StatementToTargetExpression.java | 5 +++++ .../generate/TracingStatementVisitor.java | 5 +++++ .../tree/expression/TargetExpression.java | 2 +- .../target/tree/expression/TargetThrow.java | 4 ++++ .../typeinference/typeAlgo/TYPEStmt.java | 5 +++++ src/test/java/TestComplete.java | 19 ++++++++++++++++- 13 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 src/main/java/de/dhbwstuttgart/syntaxtree/statement/Throw.java create mode 100644 src/main/java/de/dhbwstuttgart/target/tree/expression/TargetThrow.java diff --git a/resources/bytecode/javFiles/Exceptions.jav b/resources/bytecode/javFiles/Exceptions.jav index 9903511c..7b804a6a 100644 --- a/resources/bytecode/javFiles/Exceptions.jav +++ b/resources/bytecode/javFiles/Exceptions.jav @@ -1,3 +1,8 @@ +import java.lang.String; +import java.lang.RuntimeException; + public class Exceptions { -// m(Integer i) throws + m() { + throw new RuntimeException("Some Exception"); + } } \ No newline at end of file diff --git a/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java b/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java index d7ced3bf..630982b2 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java @@ -1040,6 +1040,11 @@ public class Codegen { mv.visitMethodInsn(INVOKESPECIAL, _new.type().getInternalName(), "", _new.getDescriptor(), false); break; } + case TargetThrow _throw: { + generate(state, _throw.expr()); + mv.visitInsn(ATHROW); + break; + } default: throw new CodeGenException("Unexpected value: " + expr); } diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java index 39914f0d..64dad545 100644 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java +++ b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java @@ -611,8 +611,7 @@ public class StatementGenerator { } private Statement convert(Java17Parser.ThrowstmtContext stmt) { - // TODO - throw new NotImplementedException(); + return new Throw(convert(stmt.expression()), stmt.getStart()); } private Statement convert(Java17Parser.SynchronizedstmtContext stmt) { diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java b/src/main/java/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java index f8bf0502..fde26cb7 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java @@ -266,6 +266,11 @@ public abstract class AbstractASTWalker implements ASTVisitor { } + @Override + public void visit(Throw aThrow) { + + } + @Override public void visit(AssignToField assignLeftSide) { assignLeftSide.field.accept(this); diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/StatementVisitor.java b/src/main/java/de/dhbwstuttgart/syntaxtree/StatementVisitor.java index 3cc4e128..c7a6c2a7 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/StatementVisitor.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/StatementVisitor.java @@ -76,4 +76,6 @@ public interface StatementVisitor { void visit(UnaryExpr unaryExpr); void visit(Literal literal); + + void visit(Throw aThrow); } diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/statement/Throw.java b/src/main/java/de/dhbwstuttgart/syntaxtree/statement/Throw.java new file mode 100644 index 00000000..6d91389a --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/statement/Throw.java @@ -0,0 +1,21 @@ +package de.dhbwstuttgart.syntaxtree.statement; + +import de.dhbwstuttgart.syntaxtree.StatementVisitor; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.syntaxtree.type.Void; +import org.antlr.v4.runtime.Token; + +public class Throw extends Statement { + + public final Expression expr; + + public Throw(Expression expr, Token offset) { + super(new Void(offset), offset); + this.expr = expr; + } + + @Override + public void accept(StatementVisitor visitor) { + visitor.visit(this); + } +} diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java b/src/main/java/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java index 0e0b7081..e68adda6 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java @@ -407,6 +407,11 @@ public class OutputGenerator implements ASTVisitor { out.append(literal.value); } + @Override + public void visit(Throw aThrow) { + // TODO implement + } + @Override public void visit(Switch switchStmt) { out.append("switch("); diff --git a/src/main/java/de/dhbwstuttgart/target/generate/StatementToTargetExpression.java b/src/main/java/de/dhbwstuttgart/target/generate/StatementToTargetExpression.java index 6eeb784b..c79dd3bb 100644 --- a/src/main/java/de/dhbwstuttgart/target/generate/StatementToTargetExpression.java +++ b/src/main/java/de/dhbwstuttgart/target/generate/StatementToTargetExpression.java @@ -323,6 +323,11 @@ public class StatementToTargetExpression implements ASTVisitor { } } + @Override + public void visit(Throw aThrow) { + result = new TargetThrow(converter.convert(aThrow.expr)); + } + @Override public void visit(Switch switchStmt) { var cases = switchStmt.getBlocks().stream().filter(s -> !s.isDefault()).map(converter::convert).toList(); diff --git a/src/main/java/de/dhbwstuttgart/target/generate/TracingStatementVisitor.java b/src/main/java/de/dhbwstuttgart/target/generate/TracingStatementVisitor.java index a84d6322..7967f0c4 100644 --- a/src/main/java/de/dhbwstuttgart/target/generate/TracingStatementVisitor.java +++ b/src/main/java/de/dhbwstuttgart/target/generate/TracingStatementVisitor.java @@ -173,6 +173,11 @@ public abstract class TracingStatementVisitor implements StatementVisitor { } + @Override + public void visit(Throw aThrow) { + + } + @Override public void visit(Switch switchStmt) { 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 76d3976a..e0bbc523 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, TargetPattern, TargetTernary, TargetThis, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield { + permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetPattern, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetTernary, TargetThis, TargetThrow, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield { default TargetType type() { return null; diff --git a/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetThrow.java b/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetThrow.java new file mode 100644 index 00000000..080d06a8 --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/target/tree/expression/TargetThrow.java @@ -0,0 +1,4 @@ +package de.dhbwstuttgart.target.tree.expression; + +public record TargetThrow(TargetExpression expr) implements TargetExpression { +} diff --git a/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index a776f81c..5d6ce725 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -456,6 +456,11 @@ public class TYPEStmt implements StatementVisitor { } } + @Override + public void visit(Throw aThrow) { + aThrow.expr.accept(this); + } + @Override public void visit(Return returnExpr) { returnExpr.retexpr.accept(this); diff --git a/src/test/java/TestComplete.java b/src/test/java/TestComplete.java index 0ab8a7ec..784df1fc 100644 --- a/src/test/java/TestComplete.java +++ b/src/test/java/TestComplete.java @@ -1,9 +1,9 @@ import de.dhbwstuttgart.environment.ByteArrayClassLoader; -import de.dhbwstuttgart.syntaxtree.statement.Expression; import org.junit.Ignore; import org.junit.Test; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.util.Arrays; @@ -799,4 +799,21 @@ public class TestComplete { assertTrue((Boolean) clazz.getDeclaredMethod("test2").invoke(instance)); assertFalse((Boolean) clazz.getDeclaredMethod("test3").invoke(instance)); } + + @Test + public void testExceptions() throws Exception { + var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Exceptions.jav"); + var clazz = classFiles.get("Exceptions"); + var instance = clazz.getDeclaredConstructor().newInstance(); + + try { + clazz.getDeclaredMethod("m").invoke(instance); + fail("No exception thrown!"); + } catch (InvocationTargetException exception) { + var exc = exception.getTargetException(); + if (!(exc instanceof RuntimeException rexp) || !rexp.getMessage().equals("Some Exception")) { + fail("Wrong exception thrown!"); + } + } + } }