Compare commits

..

4 Commits

20 changed files with 253 additions and 94 deletions

@ -15,7 +15,7 @@ jobs:
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '23' java-version: '22'
cache: 'maven' cache: 'maven'
- name: Compile project - name: Compile project
run: | run: |

@ -539,7 +539,7 @@ catchClause
; ;
catchType catchType
: qualifiedName ('|' qualifiedName)* : typeType ('|' typeType)*
; ;
finallyBlock finallyBlock

@ -10,6 +10,7 @@ import de.dhbwstuttgart.target.tree.expression.*;
import de.dhbwstuttgart.target.tree.type.*; import de.dhbwstuttgart.target.tree.type.*;
import org.objectweb.asm.*; import org.objectweb.asm.*;
import java.lang.annotation.Target;
import java.lang.invoke.*; import java.lang.invoke.*;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
@ -1158,11 +1159,48 @@ public class Codegen {
mv.visitLabel(end); mv.visitLabel(end);
break; break;
} }
default: case TargetPattern targetPattern:
throw new CodeGenException("Unexpected value: " + expr); break;
case TargetTryCatchFinally targetTryCatchFinally:
generateTryCatchFinally(targetTryCatchFinally, state);
} }
} }
private void generateTryCatchFinally(TargetTryCatchFinally tryCatchFinally, State state){
MethodVisitor mv = state.mv;
Label startTry = new Label();
Label endTry = new Label();
Label endOrFinally = new Label();
//Try
mv.visitLabel(startTry);
generate(state, tryCatchFinally.tryBlock());
mv.visitLabel(endTry);
mv.visitJumpInsn(GOTO, endOrFinally);
for (var catchClause : tryCatchFinally.catchClauses()){
Label startCatch = new Label();
Label endCatch = new Label();
mv.visitTryCatchBlock(startTry, endOrFinally, startCatch, "java/lang/Exception"); //ignore all exception types except the first
mv.visitLabel(startCatch);
if (!catchClause.identifier().isEmpty()) {
mv.visitFrame(F_SAME1, 0, null, 1, new Object[]{"java/lang/Exception"});
LocalVar excep = state.createVariable(catchClause.identifier(), catchClause.exceptionNames().getFirst());
mv.visitVarInsn(ASTORE, excep.index());
}
generate(state, catchClause.catchBlock());
mv.visitLabel(endCatch);
mv.visitJumpInsn(GOTO, endOrFinally);
}
if (tryCatchFinally.finallyBlock().isPresent()){
mv.visitLabel(endOrFinally);
generate(state, tryCatchFinally.finallyBlock().get());
}
else mv.visitLabel(endOrFinally);
}
private void generateForEach(TargetForEach forEach, State state) { private void generateForEach(TargetForEach forEach, State state) {
state.enterScope(); state.enterScope();
TargetVarDecl vd = (TargetVarDecl) forEach.vardecl(); TargetVarDecl vd = (TargetVarDecl) forEach.vardecl();

@ -97,7 +97,7 @@ public class JavaTXCompiler {
path.add(new File(System.getProperty("user.dir"))); path.add(new File(System.getProperty("user.dir")));
} }
if (outputPath != null) path.add(outputPath); if (outputPath != null) path.add(outputPath);
classLoader = new DirectoryClassLoader(path, ClassLoader.getSystemClassLoader()); classLoader = new DirectoryClassLoader(path, ClassLoader.getPlatformClassLoader());
environment = new CompilationEnvironment(sources, classLoader); environment = new CompilationEnvironment(sources, classLoader);
classPath = path; classPath = path;
this.outputPath = outputPath; this.outputPath = outputPath;

@ -16,7 +16,7 @@ public class DirectoryClassLoader extends URLClassLoader implements IByteArrayCl
// } // }
public DirectoryClassLoader(List<File> directory, java.lang.ClassLoader parent) { public DirectoryClassLoader(List<File> directory, java.lang.ClassLoader parent) {
super(directory.stream().map(DirectoryClassLoader::dirToURL).flatMap(List::stream).collect(Collectors.toList()).toArray(new URL[0]), parent.getParent()); super(directory.stream().map(DirectoryClassLoader::dirToURL).flatMap(List::stream).toArray(URL[]::new), parent);
} }
private static URL[] generateURLArray(URL url) { private static URL[] generateURLArray(URL url) {

@ -1,12 +1,7 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator; package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -16,6 +11,7 @@ import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.target.tree.expression.TargetUnaryOp; import de.dhbwstuttgart.target.tree.expression.TargetUnaryOp;
import de.dhbwstuttgart.target.generate.StatementToTargetExpression; import de.dhbwstuttgart.target.generate.StatementToTargetExpression;
import org.antlr.v4.runtime.RuleContext;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
@ -638,8 +634,16 @@ public class StatementGenerator {
} }
private Statement convert(Java17Parser.TrycatchblockContext stmt) { private Statement convert(Java17Parser.TrycatchblockContext stmt) {
// TODO Block tryBlock = convert(stmt.block(), false);
throw new NotImplementedException(); List<CatchClause> catchClauses = stmt.catchClause().stream().
map(x ->
new CatchClause(x.catchType().typeType().stream().map(y -> TypeGenerator.convert(y, reg, generics)).toList(),
x.identifier().getText(),
convert(x.block(), false)
)).toList();
Optional<Block> finallyBlock = stmt.finallyBlock() != null ? Optional.of(convert(stmt.finallyBlock().block(), false)) : Optional.empty();
return new TryCatchFinally(tryBlock, catchClauses, finallyBlock, stmt.getStart());
} }
private Statement convert(Java17Parser.TrycatchresourceContext stmt) { private Statement convert(Java17Parser.TrycatchresourceContext stmt) {

@ -39,6 +39,11 @@ public class SyntacticSugar {
public void visit(LambdaExpression le) { public void visit(LambdaExpression le) {
//PL 2024-04-09 Do nothing, as in a LambdaExpression a return could be //PL 2024-04-09 Do nothing, as in a LambdaExpression a return could be
} }
@Override
public void visit(TryCatchFinally tryCatchFinally) {
}
} }
private static boolean hasReturn(Block block) { private static boolean hasReturn(Block block) {

@ -1,5 +1,6 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.syntaxtree.statement.TryCatchFinally;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
public interface ASTVisitor extends StatementVisitor{ public interface ASTVisitor extends StatementVisitor{
@ -40,4 +41,6 @@ public interface ASTVisitor extends StatementVisitor{
void visit(GuardedPattern aGuardedPattern); void visit(GuardedPattern aGuardedPattern);
void visit(TryCatchFinally tryCatchFinally);
} }

@ -0,0 +1,19 @@
package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import java.util.List;
public class CatchClause {
public List<RefTypeOrTPHOrWildcardOrGeneric> exceptionTypes;
public String identifier;
public Block catchBlock;
public CatchClause(List<RefTypeOrTPHOrWildcardOrGeneric> exceptionTypes, String identifier, Block catchBlock){
this.exceptionTypes = exceptionTypes;
this.identifier = identifier;
this.catchBlock = catchBlock;
}
}

@ -85,4 +85,6 @@ public interface StatementVisitor {
void visit(Throw aThrow); void visit(Throw aThrow);
void visit(Ternary ternary); void visit(Ternary ternary);
void visit(TryCatchFinally tryCatchFinally);
} }

@ -0,0 +1,30 @@
package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.syntaxtree.CatchClause;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.type.Void;
import java.util.List;
import java.util.Optional;
public class TryCatchFinally extends Statement{
public Block tryBlock;
public List<CatchClause> catchClauses;
public Optional<Block> finallyBlock;
public TryCatchFinally(Block tryBlock, List<CatchClause> catchClauses, Optional<Block> finallyBlock, Token offset){
super(new Void(offset), offset);
this.tryBlock = tryBlock;
this.catchClauses = catchClauses;
this.finallyBlock = finallyBlock;
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
}
}

@ -530,4 +530,9 @@ public class OutputGenerator implements ASTVisitor {
out.append(" with "); out.append(" with ");
aGuardedPattern.getCondition().accept(this); aGuardedPattern.getCondition().accept(this);
} }
@Override
public void visit(TryCatchFinally tryCatchFinally) {
out.append("");
}
} }

@ -434,6 +434,11 @@ public abstract class GenerateGenerics {
whileStmt.loopBlock.accept(this); whileStmt.loopBlock.accept(this);
} }
@Override
public void visit(TryCatchFinally tryCatchFinally) {
}
@Override @Override
public void visit(ArgumentList arglist) { public void visit(ArgumentList arglist) {
for (int i = 0; i < arglist.getArguments().size(); i++) { for (int i = 0; i < arglist.getArguments().size(); i++) {
@ -536,6 +541,11 @@ public abstract class GenerateGenerics {
super.visit(methodCall); super.visit(methodCall);
typeVariables.addAll(findTypeVariables(methodCall.getType())); typeVariables.addAll(findTypeVariables(methodCall.getType()));
} }
@Override
public void visit(TryCatchFinally tryCatchFinally) {
}
}); });
} }

@ -76,6 +76,11 @@ public class StatementToTargetExpression implements ASTVisitor {
localVariables.add(varDecl.getName()); localVariables.add(varDecl.getName());
} }
@Override
public void visit(TryCatchFinally tryCatchFinally) {
}
@Override @Override
public void visit(LambdaExpression lambda) { public void visit(LambdaExpression lambda) {
} // Don't look at lambda expressions } // Don't look at lambda expressions
@ -591,4 +596,14 @@ public class StatementToTargetExpression implements ASTVisitor {
public void visit(GuardedPattern aGuardedPattern) { public void visit(GuardedPattern aGuardedPattern) {
result = new TargetGuard((TargetPattern) converter.convert(aGuardedPattern.getNestedPattern()), converter.convert(aGuardedPattern.getCondition())); result = new TargetGuard((TargetPattern) converter.convert(aGuardedPattern.getNestedPattern()), converter.convert(aGuardedPattern.getCondition()));
} }
@Override
public void visit(TryCatchFinally tryCatchFinally) {
result = new TargetTryCatchFinally(
converter.convert(tryCatchFinally.tryBlock),
tryCatchFinally.catchClauses.stream().map(x -> new TargetCatchClause(x.exceptionTypes.stream().map(converter::convert).toList(), x.identifier, converter.convert(x.catchBlock))).toList(),
tryCatchFinally.finallyBlock.map(converter::convert)
);
}
} }

@ -0,0 +1,8 @@
package de.dhbwstuttgart.target.tree.expression;
import de.dhbwstuttgart.target.tree.type.TargetType;
import java.util.List;
public record TargetCatchClause(List<TargetType> exceptionNames, String identifier, TargetBlock catchBlock) {
}

@ -3,7 +3,7 @@ package de.dhbwstuttgart.target.tree.expression;
import de.dhbwstuttgart.target.tree.type.*; import de.dhbwstuttgart.target.tree.type.*;
public sealed interface TargetExpression public sealed interface TargetExpression
permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetDo, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetPattern, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetTernary, TargetThis, TargetThrow, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield { permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetDo, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetPattern, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetTernary, TargetThis, TargetThrow, TargetTryCatchFinally, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield {
default TargetType type() { default TargetType type() {
return null; return null;

@ -0,0 +1,7 @@
package de.dhbwstuttgart.target.tree.expression;
import java.util.List;
import java.util.Optional;
public record TargetTryCatchFinally(TargetBlock tryBlock, List<TargetCatchClause> catchClauses, Optional<TargetBlock> finallyBlock) implements TargetExpression{
}

@ -2,6 +2,7 @@ package de.dhbwstuttgart.typedeployment;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.statement.TryCatchFinally;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.target.generate.GenericsResult; import de.dhbwstuttgart.target.generate.GenericsResult;
import de.dhbwstuttgart.target.generate.GenericsResultSet; import de.dhbwstuttgart.target.generate.GenericsResultSet;
@ -32,6 +33,11 @@ public class TypeInsertPlacer extends AbstractASTWalker {
TypeInsertPlacerClass cl = new TypeInsertPlacerClass(classOrInterface, withResults, genericsResult); TypeInsertPlacerClass cl = new TypeInsertPlacerClass(classOrInterface, withResults, genericsResult);
this.inserts.addAll(cl.inserts); this.inserts.addAll(cl.inserts);
} }
@Override
public void visit(TryCatchFinally tryCatchFinally) {
}
} }
class TypeInsertPlacerClass extends AbstractASTWalker{ class TypeInsertPlacerClass extends AbstractASTWalker{
@ -63,6 +69,11 @@ class TypeInsertPlacerClass extends AbstractASTWalker{
super.visit(method); super.visit(method);
} }
@Override
public void visit(TryCatchFinally tryCatchFinally) {
}
@Override @Override
public void visit(Field field) { public void visit(Field field) {
if(field.getType() instanceof TypePlaceholder){ if(field.getType() instanceof TypePlaceholder){

@ -500,6 +500,12 @@ public class TYPEStmt implements StatementVisitor {
constraintsSet.addUndConstraint(new Pair(ternary.iffalse.getType(), ternary.getType(), PairOperator.SMALLERDOT)); constraintsSet.addUndConstraint(new Pair(ternary.iffalse.getType(), ternary.getType(), PairOperator.SMALLERDOT));
} }
@Override
public void visit(TryCatchFinally tryCatchFinally) {
tryCatchFinally.tryBlock.accept(this);
tryCatchFinally.catchClauses.forEach(c -> c.catchBlock.accept(this));
}
@Override @Override
public void visit(Return returnExpr) { public void visit(Return returnExpr) {
returnExpr.retexpr.accept(this); returnExpr.retexpr.accept(this);

@ -303,7 +303,7 @@ public class TestComplete {
var result = mul.invoke(instanceOfClass_s1, instanceOfClass_s2); var result = mul.invoke(instanceOfClass_s1, instanceOfClass_s2);
System.out.println(instanceOfClass_s1.toString() + " * " + instanceOfClass_s2.toString() + " = " + result.toString()); System.out.println(instanceOfClass_s1.toString() + " * " + instanceOfClass_s2.toString() + " = " + result.toString());
assertEquals(8, result); assertEquals(result, 8);
} }
@Test @Test
@ -444,8 +444,8 @@ public class TestComplete {
var O = Arrays.stream(typeParaTypes).filter(t -> t.equals(paraTypes[0])).findFirst().get(); var O = Arrays.stream(typeParaTypes).filter(t -> t.equals(paraTypes[0])).findFirst().get();
var N2 = Arrays.stream(typeParaTypes).filter(t -> t.equals(paraTypes[1])).findFirst().get(); var N2 = Arrays.stream(typeParaTypes).filter(t -> t.equals(paraTypes[1])).findFirst().get();
assertEquals(N, N2); assertEquals(N, N2);
assertEquals(Object.class, N.getBounds()[0]); assertEquals(N.getBounds()[0], Object.class);
assertEquals(Object.class, O.getBounds()[0]); assertEquals(O.getBounds()[0], Object.class);
var m2 = tph4.getDeclaredMethod("m2", Object.class); var m2 = tph4.getDeclaredMethod("m2", Object.class);
@ -500,8 +500,8 @@ public class TestComplete {
var P = Arrays.stream(typeParaTypes).filter(t -> t.equals(paraTypes[0])).findFirst().get(); var P = Arrays.stream(typeParaTypes).filter(t -> t.equals(paraTypes[0])).findFirst().get();
var O = Arrays.stream(typeParaTypes).filter(t -> t.equals(paraTypes[1])).findFirst().get(); var O = Arrays.stream(typeParaTypes).filter(t -> t.equals(paraTypes[1])).findFirst().get();
assertEquals(Object.class, P.getBounds()[0]); assertEquals(P.getBounds()[0], Object.class);
assertEquals(Object.class, O.getBounds()[0]); assertEquals(O.getBounds()[0], Object.class);
var m2 = tph5.getDeclaredMethod("m2", Object.class); var m2 = tph5.getDeclaredMethod("m2", Object.class);
@ -605,7 +605,7 @@ public class TestComplete {
var fac1 = classFiles.get("Fac1"); var fac1 = classFiles.get("Fac1");
var instance = fac1.getDeclaredConstructor().newInstance(); var instance = fac1.getDeclaredConstructor().newInstance();
var fac = fac1.getDeclaredMethod("fac", Integer.class); var fac = fac1.getDeclaredMethod("fac", Integer.class);
assertEquals(3628800, fac.invoke(instance, 10)); assertEquals(fac.invoke(instance, 10), 3628800);
} }
@Test @Test
@ -676,16 +676,16 @@ public class TestComplete {
var r2 = ctor.newInstance(10, 20f); var r2 = ctor.newInstance(10, 20f);
var r3 = ctor.newInstance(10, r1); var r3 = ctor.newInstance(10, r1);
assertEquals(30, swtch.invoke(instance, r1)); assertEquals(swtch.invoke(instance, r1), 30);
assertEquals(20, swtch.invoke(instance, r2)); assertEquals(swtch.invoke(instance, r2), 20);
assertEquals(40, swtch.invoke(instance, r3)); assertEquals(swtch.invoke(instance, r3), 40);
assertEquals(50, swtch.invoke(instance, 50)); assertEquals(swtch.invoke(instance, 50), 50);
try { try {
assertEquals(0, swtch.invoke(instance, "Some string")); assertEquals(swtch.invoke(instance, "Some string"), 0);
fail("No assertion thrown!"); fail("No assertion thrown!");
} catch (InvocationTargetException exception) { } catch (InvocationTargetException exception) {
assertTrue(exception.getCause() instanceof IllegalArgumentException); assertTrue(exception.getCause() instanceof IllegalArgumentException);
assertEquals("Unhandled case value", exception.getCause().getMessage()); assertEquals(exception.getCause().getMessage(), "Unhandled case value");
} }
} }
@ -702,7 +702,7 @@ public class TestComplete {
var r1 = ctor.newInstance("asd", "asb"); var r1 = ctor.newInstance("asd", "asb");
assertEquals("asd", swtch.invoke(instance, r1)); assertEquals(swtch.invoke(instance, r1), "asd");
} }
@Test @Test
@ -753,8 +753,8 @@ public class TestComplete {
var r2 = ctor.newInstance(1, clazzNumber.getConstructor().newInstance()); var r2 = ctor.newInstance(1, clazzNumber.getConstructor().newInstance());
assertEquals("Second Element is a Text", swtch.invoke(instance, r1)); assertEquals(swtch.invoke(instance, r1), "Second Element is a Text");
assertEquals("Second Element is a Number", swtch.invoke(instance, r2)); assertEquals(swtch.invoke(instance, r2), "Second Element is a Number");
} }
@Test @Test
public void testSwitchListRecord() throws Exception { public void testSwitchListRecord() throws Exception {
@ -776,10 +776,10 @@ public class TestComplete {
var listWithMoreThanOneElement = constructorLinkedElem.newInstance(5, constructorLinkedElem.newInstance(1, constructorElem.newInstance(5))); var listWithMoreThanOneElement = constructorLinkedElem.newInstance(5, constructorLinkedElem.newInstance(1, constructorElem.newInstance(5)));
assertEquals(11, swtch.invoke(instance, listWithMoreThanOneElement)); assertEquals(swtch.invoke(instance, listWithMoreThanOneElement), 11);
var listWithOneElement = constructorLinkedElem.newInstance(5, constructorElem.newInstance(5)); var listWithOneElement = constructorLinkedElem.newInstance(5, constructorElem.newInstance(5));
assertEquals(10, swtch.invoke(instance, listWithOneElement)); assertEquals(swtch.invoke(instance, listWithOneElement), 10);
} }
@Test @Test
@ -795,9 +795,9 @@ public class TestComplete {
var r2 = ctor.newInstance(20); var r2 = ctor.newInstance(20);
var r3 = ctor.newInstance(30); var r3 = ctor.newInstance(30);
assertEquals(1, m.invoke(instance, r1)); assertEquals(m.invoke(instance, r1), 1);
assertEquals(2, m.invoke(instance, r2)); assertEquals(m.invoke(instance, r2), 2);
assertEquals(3, m.invoke(instance, r3)); assertEquals(m.invoke(instance, r3), 3);
} }
@Test @Test
@ -820,10 +820,10 @@ public class TestComplete {
var listWithMoreThanOneElement = constructorLinkedElem.newInstance(5, constructorLinkedElem.newInstance(1, constructorElem.newInstance(5))); var listWithMoreThanOneElement = constructorLinkedElem.newInstance(5, constructorLinkedElem.newInstance(1, constructorElem.newInstance(5)));
assertEquals(5, swtch.invoke(instance, listWithMoreThanOneElement)); assertEquals(swtch.invoke(instance, listWithMoreThanOneElement), 5);
var listWithOneElement = constructorLinkedElem.newInstance(5, constructorElem.newInstance(5)); var listWithOneElement = constructorLinkedElem.newInstance(5, constructorElem.newInstance(5));
assertEquals(5, swtch.invoke(instance, listWithOneElement)); assertEquals(swtch.invoke(instance, listWithOneElement), 5);
} }
@ -835,7 +835,6 @@ public class TestComplete {
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
} }
@Ignore("Not implemented")
@Test @Test
public void testStringSwitch() throws Exception { public void testStringSwitch() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchString.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchString.jav");
@ -843,11 +842,11 @@ public class TestComplete {
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
var main = clazz.getDeclaredMethod("main", String.class); var main = clazz.getDeclaredMethod("main", String.class);
assertEquals(1, main.invoke(instance, "AaAaAa")); assertEquals(main.invoke(instance, "AaAaAa"), 1);
assertEquals(2, main.invoke(instance, "AaAaBB")); assertEquals(main.invoke(instance, "AaAaBB"), 2);
assertEquals(3, main.invoke(instance, "test")); assertEquals(main.invoke(instance, "test"), 3);
assertEquals(3, main.invoke(instance, "TEST")); assertEquals(main.invoke(instance, "TEST"), 3);
assertEquals(4, main.invoke(instance, "awawa")); assertEquals(main.invoke(instance, "awawa"), 4);
} }
@Test @Test
@ -857,7 +856,6 @@ public class TestComplete {
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
} }
@Ignore("Not implemented")
@Test @Test
public void testOverloadPattern() throws Exception { public void testOverloadPattern() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OverloadPattern.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OverloadPattern.jav");
@ -872,18 +870,17 @@ public class TestComplete {
var ptInt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(1, 2); var ptInt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(1, 2);
var ptFlt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(1f, 2f); var ptFlt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(1f, 2f);
assertEquals(1, m1.invoke(instance, ptInt, ptFlt)); assertEquals(m1.invoke(instance, ptInt, ptFlt), 1);
assertEquals(2, m1.invoke(instance, ptInt, ptInt)); assertEquals(m1.invoke(instance, ptInt, ptInt), 2);
assertEquals(3, m1.invoke(instance, ptFlt, ptInt)); assertEquals(m1.invoke(instance, ptFlt, ptInt), 3);
assertEquals(4, m1.invoke(instance, ptFlt, ptFlt)); assertEquals(m1.invoke(instance, ptFlt, ptFlt), 4);
assertEquals(5, m2.invoke(instance, ptInt)); assertEquals(m2.invoke(instance, ptInt), 5);
assertEquals(6, m2.invoke(instance, ptFlt)); assertEquals(m2.invoke(instance, ptFlt), 6);
assertEquals(10, m3.invoke(instance, 10)); assertEquals(m3.invoke(instance, 10), 10);
} }
@Ignore("Not implemented")
@Test @Test
public void testOverloadNestedPattern() throws Exception { public void testOverloadNestedPattern() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OverloadNestedPattern.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OverloadNestedPattern.jav");
@ -896,16 +893,16 @@ public class TestComplete {
var r2 = ctor.newInstance(r1); var r2 = ctor.newInstance(r1);
var m = clazz.getDeclaredMethod("m", rec, rec); var m = clazz.getDeclaredMethod("m", rec, rec);
assertEquals(1, m.invoke(instance, r2, r1)); assertEquals(m.invoke(instance, r2, r1), 1);
var r3 = ctor.newInstance(2f); var r3 = ctor.newInstance(2f);
var r4 = ctor.newInstance(r3); var r4 = ctor.newInstance(r3);
assertEquals(2, m.invoke(instance, r4, r3)); assertEquals(m.invoke(instance, r4, r3), 2);
assertEquals(3, m.invoke(instance, r1, r1)); assertEquals(m.invoke(instance, r1, r1), 3);
} }
@Ignore("Not implemented") //@Ignore("Not implemented")
@Test @Test
public void testPatternMatchingHaskellStyle() throws Exception { public void testPatternMatchingHaskellStyle() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingHaskellStyle.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingHaskellStyle.jav");
@ -923,12 +920,11 @@ public class TestComplete {
var x = rctor.newInstance(rctor.newInstance(0, rctor.newInstance(0, r2ctor.newInstance(0))), r2ctor.newInstance(0)); var x = rctor.newInstance(rctor.newInstance(0, rctor.newInstance(0, r2ctor.newInstance(0))), r2ctor.newInstance(0));
var y = rctor.newInstance(r2ctor.newInstance(0), r2ctor.newInstance(0)); var y = rctor.newInstance(r2ctor.newInstance(0), r2ctor.newInstance(0));
assertNull(m.invoke(instance, x, y)); assertEquals(m.invoke(instance, x, y), null);
assertNull(m.invoke(instance, y, y)); assertEquals(m.invoke(instance, y, y), null);
} }
@Ignore("Not implemented")
@Test @Test
public void testPatternMatchingListAppend() throws Exception { public void testPatternMatchingListAppend() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingListAppend.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingListAppend.jav");
@ -963,8 +959,8 @@ public class TestComplete {
var x = rctor.newInstance(10); var x = rctor.newInstance(10);
var d = rctor.newInstance(20.0); var d = rctor.newInstance(20.0);
assertEquals(50, m.invoke(instance, x, 0)); assertEquals(m.invoke(instance, x, 0), 50);
assertEquals(40.0, m.invoke(instance, d, 0)); assertEquals(m.invoke(instance, d, 0), 40.0);
} }
@Test @Test
@ -979,7 +975,7 @@ public class TestComplete {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Static.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Static.jav");
var clazz = classFiles.get("Static"); var clazz = classFiles.get("Static");
var m = clazz.getDeclaredMethod("m"); var m = clazz.getDeclaredMethod("m");
assertEquals(50, m.invoke(null)); assertEquals(m.invoke(null), 50);
} }
@Test @Test
@ -988,7 +984,7 @@ public class TestComplete {
var clazz = classFiles.get("For"); var clazz = classFiles.get("For");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("m", Integer.class); var m = clazz.getDeclaredMethod("m", Integer.class);
assertEquals(60, m.invoke(instance, 10)); assertEquals(m.invoke(instance, 10), 60);
} }
@Test @Test
@ -997,7 +993,7 @@ public class TestComplete {
var clazz = classFiles.get("ForEach"); var clazz = classFiles.get("ForEach");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("m"); var m = clazz.getDeclaredMethod("m");
assertEquals(6, m.invoke(instance)); assertEquals(m.invoke(instance), 6);
} }
@Test @Test
@ -1015,7 +1011,7 @@ public class TestComplete {
var clazz = classFiles.get("FunctionalInterface"); var clazz = classFiles.get("FunctionalInterface");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("m"); var m = clazz.getDeclaredMethod("m");
assertEquals(200, m.invoke(instance)); assertEquals(m.invoke(instance), 200);
} }
@Test @Test
@ -1024,7 +1020,7 @@ public class TestComplete {
var clazz = classFiles.get("Chain"); var clazz = classFiles.get("Chain");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("m"); var m = clazz.getDeclaredMethod("m");
assertEquals(5, m.invoke(instance)); assertEquals(m.invoke(instance), 5);
} }
@Test @Test
@ -1077,9 +1073,9 @@ public class TestComplete {
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
assertNull(clazz.getDeclaredMethod("m").invoke(instance)); assertNull(clazz.getDeclaredMethod("m").invoke(instance));
assertEquals('C', clazz.getDeclaredMethod("m2").invoke(instance)); assertEquals(clazz.getDeclaredMethod("m2").invoke(instance), 'C');
assertEquals(10L, clazz.getDeclaredMethod("m3").invoke(instance)); assertEquals(clazz.getDeclaredMethod("m3").invoke(instance), 10L);
assertEquals(10.5F, clazz.getDeclaredMethod("m4").invoke(instance)); assertEquals(clazz.getDeclaredMethod("m4").invoke(instance), 10.5F);
} }
@Test @Test
@ -1087,7 +1083,7 @@ public class TestComplete {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OLConstructor.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OLConstructor.jav");
var clazz = classFiles.get("Child"); var clazz = classFiles.get("Child");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
assertEquals(3, clazz.getSuperclass().getDeclaredField("x").get(instance)); assertEquals(clazz.getSuperclass().getDeclaredField("x").get(instance), 3);
} }
@Test @Test
@ -1095,11 +1091,11 @@ public class TestComplete {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Op1.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Op1.jav");
var clazz = classFiles.get("Op1"); var clazz = classFiles.get("Op1");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
assertEquals(true, clazz.getDeclaredMethod("not").invoke(instance)); assertEquals(clazz.getDeclaredMethod("not").invoke(instance), true);
assertEquals(10 | 20, clazz.getDeclaredMethod("or").invoke(instance)); assertEquals(clazz.getDeclaredMethod("or").invoke(instance), 10 | 20);
assertEquals(10 & 20, clazz.getDeclaredMethod("and").invoke(instance)); assertEquals(clazz.getDeclaredMethod("and").invoke(instance), 10 & 20);
assertEquals(10 ^ 20, clazz.getDeclaredMethod("xor").invoke(instance)); assertEquals(clazz.getDeclaredMethod("xor").invoke(instance), 10 ^ 20);
assertEquals(10 % 2, clazz.getDeclaredMethod("mod").invoke(instance)); assertEquals(clazz.getDeclaredMethod("mod").invoke(instance), 10 % 2);
} }
@Ignore("Not implemented") @Ignore("Not implemented")
@ -1116,18 +1112,18 @@ public class TestComplete {
var clazzPublic = classFiles.get("Access"); var clazzPublic = classFiles.get("Access");
var clazzDefault = classFiles.get("AccessDefault"); var clazzDefault = classFiles.get("AccessDefault");
assertEquals(Modifier.PUBLIC, clazzPublic.getModifiers()); assertEquals(clazzPublic.getModifiers(), Modifier.PUBLIC);
assertEquals(0, clazzDefault.getModifiers()); assertEquals(clazzDefault.getModifiers(), 0);
assertEquals(Modifier.PUBLIC, clazzPublic.getDeclaredMethod("mPublic").getModifiers()); assertEquals(clazzPublic.getDeclaredMethod("mPublic").getModifiers(), Modifier.PUBLIC);
assertEquals(Modifier.PROTECTED, clazzPublic.getDeclaredMethod("mProtected").getModifiers()); assertEquals(clazzPublic.getDeclaredMethod("mProtected").getModifiers(), Modifier.PROTECTED);
assertEquals(0, clazzPublic.getDeclaredMethod("mDefault").getModifiers()); assertEquals(clazzPublic.getDeclaredMethod("mDefault").getModifiers(), 0);
assertEquals(Modifier.PRIVATE, clazzPublic.getDeclaredMethod("mPrivate").getModifiers()); assertEquals(clazzPublic.getDeclaredMethod("mPrivate").getModifiers(), Modifier.PRIVATE);
assertEquals(Modifier.PUBLIC, clazzPublic.getDeclaredField("fPublic").getModifiers()); assertEquals(clazzPublic.getDeclaredField("fPublic").getModifiers(), Modifier.PUBLIC);
assertEquals(Modifier.PROTECTED, clazzPublic.getDeclaredField("fProtected").getModifiers()); assertEquals(clazzPublic.getDeclaredField("fProtected").getModifiers(), Modifier.PROTECTED);
assertEquals(0, clazzPublic.getDeclaredField("fDefault").getModifiers()); assertEquals(clazzPublic.getDeclaredField("fDefault").getModifiers(), 0);
assertEquals(Modifier.PRIVATE, clazzPublic.getDeclaredField("fPrivate").getModifiers()); assertEquals(clazzPublic.getDeclaredField("fPrivate").getModifiers(), Modifier.PRIVATE);
} }
@Test @Test
@ -1165,7 +1161,7 @@ public class TestComplete {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Ternary.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Ternary.jav");
var clazz = classFiles.get("Ternary"); var clazz = classFiles.get("Ternary");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
assertEquals("small", clazz.getDeclaredMethod("main", Integer.class).invoke(instance, 5)); assertEquals(clazz.getDeclaredMethod("main", Integer.class).invoke(instance, 5), "small");
} }
@Test @Test
@ -1173,8 +1169,8 @@ public class TestComplete {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "While.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "While.jav");
var clazz = classFiles.get("While"); var clazz = classFiles.get("While");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
assertEquals(5, clazz.getDeclaredMethod("m", Integer.class).invoke(instance, 5)); assertEquals(clazz.getDeclaredMethod("m", Integer.class).invoke(instance, 5), 5);
assertEquals(10, clazz.getDeclaredMethod("m2").invoke(instance)); assertEquals(clazz.getDeclaredMethod("m2").invoke(instance), 10);
} }
@Test @Test
@ -1190,7 +1186,7 @@ public class TestComplete {
var clazz = classFiles.get("Assign"); var clazz = classFiles.get("Assign");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("m"); var m = clazz.getDeclaredMethod("m");
assertEquals(20, m.invoke(instance)); assertEquals(m.invoke(instance), 20);
} }
@Test @Test
@ -1247,9 +1243,9 @@ public class TestComplete {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug295.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug295.jav");
var clazz = classFiles.get("Bug295"); var clazz = classFiles.get("Bug295");
var instance = clazz.getDeclaredConstructor(Integer.class, Integer.class, Integer.class).newInstance(1, 2, 3); var instance = clazz.getDeclaredConstructor(Integer.class, Integer.class, Integer.class).newInstance(1, 2, 3);
assertEquals(1, clazz.getDeclaredField("a").get(instance)); assertEquals(clazz.getDeclaredField("a").get(instance), 1);
assertEquals(2, clazz.getDeclaredField("b").get(instance)); assertEquals(clazz.getDeclaredField("b").get(instance), 2);
assertEquals(3, clazz.getDeclaredField("c").get(instance)); assertEquals(clazz.getDeclaredField("c").get(instance), 3);
} }
@Test @Test
@ -1279,7 +1275,7 @@ public class TestComplete {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug300.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug300.jav");
var clazz = classFiles.get("Bug300"); var clazz = classFiles.get("Bug300");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
assertEquals("Base", clazz.getDeclaredMethod("m").invoke(instance)); assertEquals(clazz.getDeclaredMethod("m").invoke(instance), "Base");
} }
@Test @Test
@ -1324,7 +1320,7 @@ public class TestComplete {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug310.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug310.jav");
var clazz = classFiles.get("Bug310"); var clazz = classFiles.get("Bug310");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
assertEquals("3", clazz.getDeclaredMethod("toString").invoke(instance)); assertEquals(clazz.getDeclaredMethod("toString").invoke(instance), "3");
} }
@Test @Test