Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c19d4d74d5 |
No files matched your search
@@ -1,13 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
|
|
||||||
public class Bug409 {
|
|
||||||
public static m() {
|
|
||||||
var n = 0;
|
|
||||||
for (var i = 0; i < 5; i++) {
|
|
||||||
n = n + 1;
|
|
||||||
if (n > 100) { return -1; }
|
|
||||||
if (i == 2) { continue; }
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
|
|
||||||
public interface Bug411 {
|
|
||||||
default f() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
|
|
||||||
public class Bug412 {
|
|
||||||
public m(Integer i) {
|
|
||||||
var r = 0;
|
|
||||||
switch (i) {
|
|
||||||
case 1: r = 10; break;
|
|
||||||
default: r = 20;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
sealed interface L<T> permits Cons, Nil {}
|
|
||||||
public record Cons<T>(T head, L<T> tail) implements L<T> {}
|
|
||||||
public record Nil<T>() implements L<T> {}
|
|
||||||
|
|
||||||
public class Bug416 {
|
|
||||||
public static <T> len(Cons(h, t)) { return 1 + len(t); }
|
|
||||||
public static <T> len(Nil()) { return 0; }
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
import java.lang.String;
|
|
||||||
|
|
||||||
public class Bug417 {
|
|
||||||
public name(Integer i) {
|
|
||||||
return switch (i) {
|
|
||||||
case 1 -> "one";
|
|
||||||
default -> "many";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
public class Bug421 {
|
|
||||||
public m() { return 1 } // Missing semicolon
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
public class Bug422 {}
|
|
||||||
public class Bug422 {}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
|
|
||||||
interface Bug423I { Integer f(); }
|
|
||||||
|
|
||||||
public class Bug423 implements Bug423I { }
|
|
||||||
@@ -15,7 +15,6 @@ interface C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ClassX implements A {
|
class ClassX implements A {
|
||||||
void method1() {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
record ClassY(Integer myInt) implements C {}
|
record ClassY(Integer myInt) implements C {}
|
||||||
|
|||||||
@@ -13,15 +13,15 @@ public sealed interface LazyList permits Empty, Cons {
|
|||||||
public Integer fst();
|
public Integer fst();
|
||||||
public LazyList rest();
|
public LazyList rest();
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
public class Filter {
|
public class Filter {
|
||||||
public LazyList filter(Fun1$$<Integer, Boolean> p, LazyList l) {
|
/*public LazyList filter(Fun1$$<Integer, Boolean> p, LazyList l) {
|
||||||
return switch(l) {
|
return switch(l) {
|
||||||
case Empty e -> e;
|
case Empty e -> e;
|
||||||
case Cons(Integer x, Supplier<LazyList> l1) ->
|
case Cons(Integer x, Supplier<LazyList> l1) ->
|
||||||
p.apply(x) ? new Cons(x, () -> filter(p, l1.get())) : filter(p, l1.get());
|
p.apply(x) ? new Cons(x, () -> filter(p, l1.get())) : filter(p, l1.get());
|
||||||
};
|
};
|
||||||
}
|
}*/
|
||||||
public LazyList filter(Fun1$$<Integer, Boolean> p, Empty()@l) {
|
public LazyList filter(Fun1$$<Integer, Boolean> p, Empty()@l) {
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
@@ -31,8 +31,6 @@ public class Filter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
//Der Konstruktor Cons muss lazy sein, deshalb hier Supplier<...>
|
//Der Konstruktor Cons muss lazy sein, deshalb hier Supplier<...>
|
||||||
record Cons(Integer x, Fun0$$<LazyList> l) implements LazyList {
|
record Cons(Integer x, Fun0$$<LazyList> l) implements LazyList {
|
||||||
public Integer fst() { return this.x; }
|
public Integer fst() { return this.x; }
|
||||||
@@ -47,7 +45,7 @@ record Empty() implements LazyList {
|
|||||||
public LazyList rest() { return null; }
|
public LazyList rest() { return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
class Main {
|
class Main {
|
||||||
static LazyList Count(int i) { return new Cons(i, () -> Count(i+1)); }
|
static LazyList Count(int i) { return new Cons(i, () -> Count(i+1)); }
|
||||||
|
|
||||||
@@ -56,4 +54,3 @@ class Main {
|
|||||||
System.out.println(Count(1).rest().fst());
|
System.out.println(Count(1).rest().fst());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
@@ -5,8 +5,4 @@ public class Literal {
|
|||||||
public m2() { return 'C'; }
|
public m2() { return 'C'; }
|
||||||
public m3() { return 10L; }
|
public m3() { return 10L; }
|
||||||
public m4() { return 10.5F; }
|
public m4() { return 10.5F; }
|
||||||
public m5() { return 10.5D; }
|
|
||||||
public m6() { return 0xFF; }
|
|
||||||
public m7() { return 0b101010; }
|
|
||||||
public m8() { return 010; }
|
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@ sealed interface Interface permits A, B {}
|
|||||||
public record A() implements Interface {}
|
public record A() implements Interface {}
|
||||||
public record B() implements Interface {}
|
public record B() implements Interface {}
|
||||||
|
|
||||||
public interface Matcher {
|
public class Matcher {
|
||||||
default match(A()@a) { return 0; }
|
match(A()@a) { return 0; }
|
||||||
default match(B()@b) { return 1; }
|
match(B()@b) { return 1; }
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ import java.lang.Integer;
|
|||||||
import Matcher;
|
import Matcher;
|
||||||
import Interface;
|
import Interface;
|
||||||
|
|
||||||
public class M implements Matcher {}
|
public class M extends Matcher {}
|
||||||
|
|
||||||
public class PatternMatchingInterface {
|
public class PatternMatchingInterface {
|
||||||
public static match(matcher, v) {
|
public static match(matcher, v) {
|
||||||
|
|||||||
@@ -7,10 +7,9 @@ import java.io.PrintStream;
|
|||||||
import LazyList;
|
import LazyList;
|
||||||
import Cons;
|
import Cons;
|
||||||
import Empty;
|
import Empty;
|
||||||
//import Filter;
|
import Filter;
|
||||||
|
|
||||||
public class Primzahlen {
|
public class Primzahlen {
|
||||||
/*
|
|
||||||
static LazyList from(Integer i) { return new Cons(i, () -> from(i+1)); }
|
static LazyList from(Integer i) { return new Cons(i, () -> from(i+1)); }
|
||||||
|
|
||||||
/*LazyList filter(Fun1$$<Integer, Boolean> p, LazyList l) {
|
/*LazyList filter(Fun1$$<Integer, Boolean> p, LazyList l) {
|
||||||
@@ -19,7 +18,7 @@ public class Primzahlen {
|
|||||||
case Cons(Integer x, Fun0$$<LazyList> l1) ->
|
case Cons(Integer x, Fun0$$<LazyList> l1) ->
|
||||||
p.apply(x) ? new Cons(x, () -> filter(p, l1.apply())) : filter(p, l1.apply());
|
p.apply(x) ? new Cons(x, () -> filter(p, l1.apply())) : filter(p, l1.apply());
|
||||||
};
|
};
|
||||||
}
|
}*/
|
||||||
|
|
||||||
LazyList dropMul(Integer x, LazyList xs) {
|
LazyList dropMul(Integer x, LazyList xs) {
|
||||||
return new Filter().filter(y -> (y % x != 0), xs);
|
return new Filter().filter(y -> (y % x != 0), xs);
|
||||||
@@ -41,13 +40,13 @@ public class Primzahlen {
|
|||||||
new Cons(x, () -> take(n-1, l1.apply()));
|
new Cons(x, () -> take(n-1, l1.apply()));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
public static void main(args) {
|
public static void main(args) {
|
||||||
//System.out.println(new Cons(1, () -> new Cons(2, () -> new Empty())).fst());
|
System.out.println(new Cons(1, () -> new Cons(2, () -> new Empty())).fst());
|
||||||
var l = new Cons(1, () -> new Cons(2, () -> new Cons(2, () -> new Empty())));
|
var l = new Cons(1, () -> new Cons(2, () -> new Cons(2, () -> new Empty())));
|
||||||
//System.out.println(l);
|
System.out.println(l);
|
||||||
//var filtered = new Filter().filter(x -> x == 2, l);
|
var filtered = new Filter().filter(x -> x == 2, l);
|
||||||
//ystem.out.println(filtered);
|
System.out.println(filtered);
|
||||||
//System.out.println(from(1).rest().fst());
|
//System.out.println(from(1).rest().fst());
|
||||||
//Primzahlen pz = new Primzahlen();
|
//Primzahlen pz = new Primzahlen();
|
||||||
//System.out.println(pz.take(10, pz.from(2)));
|
//System.out.println(pz.take(10, pz.from(2)));
|
||||||
|
|||||||
@@ -1056,7 +1056,6 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Label start = new Label();
|
Label start = new Label();
|
||||||
Label skip = new Label();
|
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
mv.visitLabel(start);
|
mv.visitLabel(start);
|
||||||
if (_for.termination() != null) {
|
if (_for.termination() != null) {
|
||||||
@@ -1069,14 +1068,13 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var env = new BreakEnv();
|
var env = new BreakEnv();
|
||||||
env.startLabel = skip;
|
env.startLabel = start;
|
||||||
env.endLabel = end;
|
env.endLabel = end;
|
||||||
|
|
||||||
state.breakStack.push(env);
|
state.breakStack.push(env);
|
||||||
generate(state, _for.body());
|
generate(state, _for.body());
|
||||||
state.breakStack.pop();
|
state.breakStack.pop();
|
||||||
|
|
||||||
mv.visitLabel(skip);
|
|
||||||
if (_for.increment() != null) {
|
if (_for.increment() != null) {
|
||||||
_for.increment().forEach(e -> {
|
_for.increment().forEach(e -> {
|
||||||
generate(state, e);
|
generate(state, e);
|
||||||
@@ -1437,16 +1435,13 @@ public class Codegen {
|
|||||||
if (label instanceof TargetTypePattern || label instanceof TargetComplexPattern) {
|
if (label instanceof TargetTypePattern || label instanceof TargetComplexPattern) {
|
||||||
if (label.type() instanceof TargetGenericType) types.add(Type.getType(Object.class));
|
if (label.type() instanceof TargetGenericType) types.add(Type.getType(Object.class));
|
||||||
else types.add(Type.getObjectType(label.type().getInternalName()));
|
else types.add(Type.getObjectType(label.type().getInternalName()));
|
||||||
} else if (label instanceof TargetExpressionPattern expr) {
|
} else if (label instanceof TargetLiteral lit) {
|
||||||
if (expr.expression() instanceof TargetLiteral literal) {
|
types.add(lit.value());
|
||||||
types.add(Type.getObjectType(TargetType.toWrapper(literal.type()).getInternalName()));
|
|
||||||
} else {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
} else if (label instanceof TargetGuard guard) {
|
} else if (label instanceof TargetGuard guard) {
|
||||||
types.add(Type.getObjectType(guard.inner().type().getInternalName()));
|
types.add(Type.getObjectType(guard.inner().type().getInternalName()));
|
||||||
// TODO Same here we need to evaluate constant;
|
// TODO Same here we need to evaluate constant;
|
||||||
} else {
|
} else {
|
||||||
|
logger.info(label);
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1780,7 +1775,7 @@ public class Codegen {
|
|||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
state.scope.parent = parent.scope;
|
state.scope.parent = parent.scope;
|
||||||
}
|
}
|
||||||
var offset = method.isStatic() ? 0 : 1;
|
var offset = 1;
|
||||||
for (var param : method.signature().parameters()) {
|
for (var param : method.signature().parameters()) {
|
||||||
state.createVariable(param.pattern().name(), param.pattern().type());
|
state.createVariable(param.pattern().name(), param.pattern().type());
|
||||||
}
|
}
|
||||||
@@ -1851,35 +1846,6 @@ public class Codegen {
|
|||||||
clazz.constructors().forEach(this::generateConstructor);
|
clazz.constructors().forEach(this::generateConstructor);
|
||||||
clazz.methods().forEach(this::generateMethod);
|
clazz.methods().forEach(this::generateMethod);
|
||||||
|
|
||||||
// Check if non abstract class implements all interface methods
|
|
||||||
if ((access & ACC_ABSTRACT) == 0) {
|
|
||||||
for (var intf : clazz.implementingInterfaces()) {
|
|
||||||
var intfClass = compiler.getClass(new JavaClassName(intf.name()));
|
|
||||||
for (var method : intfClass.getMethods()) {
|
|
||||||
if ((method.modifier & ACC_ABSTRACT) != 0) {
|
|
||||||
// Check if the method is implemented in the current class
|
|
||||||
// TODO This is duplicate code, we should probably refactor instances of this pattern
|
|
||||||
var foundMethods = clazz.methods().stream().filter(m -> {
|
|
||||||
if (!m.name().equals(method.name)) return false;
|
|
||||||
if (m.signature().parameters().size() != method.getParameterList().getFormalparalist().size())
|
|
||||||
return false;
|
|
||||||
for (var i = 0; i < m.signature().parameters().size(); i++) {
|
|
||||||
var param1 = m.signature().parameters().get(i).pattern().type();
|
|
||||||
var param2 = converter.convert(
|
|
||||||
method.getParameterList().getParameterAt(i).getType(),
|
|
||||||
ASTToTargetAST.Generics.nullGenerics(compiler).javaGenerics());
|
|
||||||
if (!param1.equals(param2)) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}).toList();
|
|
||||||
if (foundMethods.size() != 1) {
|
|
||||||
throw new CodeGenException("Class " + clazz.qualifiedName() + " does not implement method " + method.name + " from interface " + intfClass.getClassName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clazz.staticConstructor() != null)
|
if (clazz.staticConstructor() != null)
|
||||||
generateStaticConstructor(clazz.staticConstructor());
|
generateStaticConstructor(clazz.staticConstructor());
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import de.dhbwstuttgart.bytecode.Codegen;
|
|||||||
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||||
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
||||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||||
import de.dhbwstuttgart.exceptions.CompilerException;
|
|
||||||
import de.dhbwstuttgart.exceptions.CompilerWarning;
|
import de.dhbwstuttgart.exceptions.CompilerWarning;
|
||||||
import de.dhbwstuttgart.exceptions.DebugException;
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
import de.dhbwstuttgart.exceptions.WarningsException;
|
import de.dhbwstuttgart.exceptions.WarningsException;
|
||||||
@@ -172,8 +171,6 @@ public class JavaTXCompiler {
|
|||||||
|
|
||||||
var numberOfGenerics = decl == null ? 0 : decl.genericTypeVar().size();
|
var numberOfGenerics = decl == null ? 0 : decl.genericTypeVar().size();
|
||||||
var className = pkgName + (!pkgName.isEmpty() ? "." : "") + name;
|
var className = pkgName + (!pkgName.isEmpty() ? "." : "") + name;
|
||||||
if (classRegistry.contains(className))
|
|
||||||
throw new CompilerException("Duplicate class definition: " + className);
|
|
||||||
classRegistry.addName(className, numberOfGenerics);
|
classRegistry.addName(className, numberOfGenerics);
|
||||||
input.add(classRegistry.getName(className));
|
input.add(classRegistry.getName(className));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
package de.dhbwstuttgart.exceptions;
|
|
||||||
|
|
||||||
public class CompilerException extends RuntimeException {
|
|
||||||
public CompilerException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,8 +2,9 @@ package de.dhbwstuttgart.exceptions;
|
|||||||
|
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
public class ParserError extends RuntimeException{
|
public class ParserError extends TypeinferenceException{
|
||||||
public ParserError(String message) {
|
|
||||||
super(message);
|
public ParserError(Token offset){
|
||||||
|
super("Fehler beim Parsen", offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package de.dhbwstuttgart.parser;
|
package de.dhbwstuttgart.parser;
|
||||||
|
|
||||||
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
||||||
import de.dhbwstuttgart.exceptions.ParserError;
|
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
|
||||||
import de.dhbwstuttgart.parser.antlr.Java17Lexer;
|
import de.dhbwstuttgart.parser.antlr.Java17Lexer;
|
||||||
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||||
@@ -9,7 +8,9 @@ import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
|||||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||||
|
|
||||||
import de.dhbwstuttgart.util.Logger;
|
import de.dhbwstuttgart.util.Logger;
|
||||||
import org.antlr.v4.runtime.*;
|
import org.antlr.v4.runtime.CharStream;
|
||||||
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
|
import org.antlr.v4.runtime.CommonTokenStream;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@@ -20,25 +21,13 @@ public class JavaTXParser {
|
|||||||
|
|
||||||
public static Logger logger = new Logger("Parser");
|
public static Logger logger = new Logger("Parser");
|
||||||
|
|
||||||
public static class ThrowingErrorListener extends BaseErrorListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol,
|
|
||||||
int line, int charPositionInLine, String msg, RecognitionException e) {
|
|
||||||
throw new ParserError("Syntax error at line " + line + ":" + charPositionInLine + " - " + msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Java17Parser.SourceFileContext parse(File source) throws IOException, java.lang.ClassNotFoundException {
|
public static Java17Parser.SourceFileContext parse(File source) throws IOException, java.lang.ClassNotFoundException {
|
||||||
InputStream stream = new FileInputStream(source);
|
InputStream stream = new FileInputStream(source);
|
||||||
// DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream);
|
// DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream);
|
||||||
var errorListener = new ThrowingErrorListener();
|
|
||||||
CharStream input = CharStreams.fromStream(stream);
|
CharStream input = CharStreams.fromStream(stream);
|
||||||
Java17Lexer lexer = new Java17Lexer(input);
|
Java17Lexer lexer = new Java17Lexer(input);
|
||||||
lexer.addErrorListener(errorListener);
|
|
||||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||||
Java17Parser parser = new Java17Parser(tokens);
|
Java17Parser parser = new Java17Parser(tokens);
|
||||||
parser.addErrorListener(errorListener);
|
|
||||||
return parser.sourceFile();
|
return parser.sourceFile();
|
||||||
/*
|
/*
|
||||||
* SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(source)); return generator.convert(tree);
|
* SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(source)); return generator.convert(tree);
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import de.dhbwstuttgart.typeinference.constraints.Pair;
|
|||||||
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.*;
|
import de.dhbwstuttgart.typeinference.unify.model.*;
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -55,8 +54,7 @@ public class FCGenerator {
|
|||||||
|
|
||||||
|
|
||||||
private static Boolean isFunctionalInterface(ClassOrInterface cly) {
|
private static Boolean isFunctionalInterface(ClassOrInterface cly) {
|
||||||
// TODO isFunctionalInterface should be set properly, we shouldn't need to check it again
|
return (cly.isInterface() && (cly.isFunctionalInterface() || cly.getMethods().size() == 1));
|
||||||
return (cly.isInterface() && (cly.isFunctionalInterface() || cly.getMethods().size() == 1 && Modifier.isAbstract(cly.getMethods().getFirst().modifier)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Pair genImplFunType(ClassOrInterface cly, RefTypeOrTPHOrWildcardOrGeneric fIType, HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs) {
|
private static Pair genImplFunType(ClassOrInterface cly, RefTypeOrTPHOrWildcardOrGeneric fIType, HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs) {
|
||||||
|
|||||||
@@ -405,16 +405,14 @@ public class StatementGenerator {
|
|||||||
|
|
||||||
private SwitchBlock convert(Java17Parser.SwitchBlockStatementGroupContext stmt) {
|
private SwitchBlock convert(Java17Parser.SwitchBlockStatementGroupContext stmt) {
|
||||||
List<SwitchLabel> labels = new ArrayList<>();
|
List<SwitchLabel> labels = new ArrayList<>();
|
||||||
var isDefault = false;
|
stmt.switchLabel().forEach((label) -> {
|
||||||
for (var label : stmt.switchLabel()) {
|
|
||||||
if (label instanceof SwitchLabelDefaultContext) isDefault = true;
|
|
||||||
labels.add(convert(label));
|
labels.add(convert(label));
|
||||||
}
|
});
|
||||||
List<Statement> block = new ArrayList<>();
|
List<Statement> block = new ArrayList<>();
|
||||||
stmt.blockStatement().stream().forEach((blockStmt) -> {
|
stmt.blockStatement().stream().forEach((blockStmt) -> {
|
||||||
block.addAll(convert(blockStmt));
|
block.addAll(convert(blockStmt));
|
||||||
});
|
});
|
||||||
return new SwitchBlock(labels, new Block(block, stmt.blockStatement(0).getStart()), isDefault,false, stmt.getStart());
|
return new SwitchBlock(labels, new Block(block, stmt.blockStatement(0).getStart()), false, stmt.getStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
private SwitchLabel convert(SwitchLabelContext switchLabel) {
|
private SwitchLabel convert(SwitchLabelContext switchLabel) {
|
||||||
@@ -1035,22 +1033,10 @@ public class StatementGenerator {
|
|||||||
private Expression convert(Java17Parser.LiteralContext literal) {
|
private Expression convert(Java17Parser.LiteralContext literal) {
|
||||||
switch (literal) {
|
switch (literal) {
|
||||||
case IntLiteralContext intliteral:
|
case IntLiteralContext intliteral:
|
||||||
var text = intliteral.getText();
|
|
||||||
var radix = 10;
|
|
||||||
if (text.startsWith("0x") || text.startsWith("0X")) {
|
|
||||||
radix = 16;
|
|
||||||
text = text.substring(2);
|
|
||||||
} else if (text.startsWith("0b") || text.startsWith("0B")) {
|
|
||||||
radix = 2;
|
|
||||||
text = text.substring(2);
|
|
||||||
} else if (text.startsWith("0") && text.length() > 1) {
|
|
||||||
radix = 8;
|
|
||||||
text = text.substring(1);
|
|
||||||
}
|
|
||||||
Number value;
|
Number value;
|
||||||
if (text.endsWith("l") || text.endsWith("L"))
|
if (intliteral.getText().endsWith("l") || intliteral.getText().endsWith("L"))
|
||||||
value = Long.parseLong(text.substring(0, text.length() - 1), radix);
|
value = Long.parseLong(intliteral.getText().substring(0, intliteral.getText().length() - 1));
|
||||||
else value = Integer.parseInt(text, radix);
|
else value = Integer.parseInt(intliteral.getText());
|
||||||
return new Literal(TypePlaceholder.fresh(literal.getStart()), value, intliteral.getStart());
|
return new Literal(TypePlaceholder.fresh(literal.getStart()), value, intliteral.getStart());
|
||||||
case FltLiteralContext floatliteral:
|
case FltLiteralContext floatliteral:
|
||||||
if (floatliteral.getText().endsWith("f") || floatliteral.getText().endsWith("F"))
|
if (floatliteral.getText().endsWith("f") || floatliteral.getText().endsWith("F"))
|
||||||
@@ -1111,7 +1097,7 @@ public class StatementGenerator {
|
|||||||
if (expression.lambdaBody().expression() != null) {
|
if (expression.lambdaBody().expression() != null) {
|
||||||
List<Statement> statements = new ArrayList<>();
|
List<Statement> statements = new ArrayList<>();
|
||||||
statements.add(new Return(lambdaGenerator.convert(expression.lambdaBody().expression()), expression.lambdaBody().expression().getStart()));
|
statements.add(new Return(lambdaGenerator.convert(expression.lambdaBody().expression()), expression.lambdaBody().expression().getStart()));
|
||||||
block = new Block(statements, expression.lambdaBody().getStart(), -1);
|
block = new Block(statements, expression.lambdaBody().getStart());
|
||||||
} else {
|
} else {
|
||||||
block = lambdaGenerator.convert(expression.lambdaBody().block(), true);
|
block = lambdaGenerator.convert(expression.lambdaBody().block(), true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -409,9 +409,8 @@ public class SyntaxTreeGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isFunctonalInterfce = methods.size() == 1 && Modifier.isAbstract(methods.getFirst().modifier);
|
|
||||||
var staticCtor = Optional.of(this.generateStaticConstructor(ctx.identifier().getText(), staticFieldInitializations, genericParams, ctx.getStart()));
|
var staticCtor = Optional.of(this.generateStaticConstructor(ctx.identifier().getText(), staticFieldInitializations, genericParams, ctx.getStart()));
|
||||||
return new ClassOrInterface(modifiers, name, fields, Optional.empty(), staticCtor, methods, new ArrayList<>(), genericParams, superClass, true, isFunctonalInterfce, extendedInterfaces, permittedSubtypes, ctx.getStart(), fileName);
|
return new ClassOrInterface(modifiers, name, fields, Optional.empty(), staticCtor, methods, new ArrayList<>(), genericParams, superClass, true, methods.size() == 1 ? true : false, extendedInterfaces, permittedSubtypes, ctx.getStart(), fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GenericDeclarationList createEmptyGenericDeclarationList(Token classNameIdentifier) {
|
private GenericDeclarationList createEmptyGenericDeclarationList(Token classNameIdentifier) {
|
||||||
|
|||||||
@@ -14,11 +14,6 @@ public class Block extends Statement {
|
|||||||
this.statements = statements;
|
this.statements = statements;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block(List<Statement> statements, Token offset, int variance) {
|
|
||||||
super(TypePlaceholder.fresh(offset, variance, true), offset);
|
|
||||||
this.statements = statements;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Statement> statements = new ArrayList<>();
|
public List<Statement> statements = new ArrayList<>();
|
||||||
|
|
||||||
public List<Statement> getStatements() {
|
public List<Statement> getStatements() {
|
||||||
|
|||||||
@@ -188,10 +188,8 @@ public class OutputGenerator implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LambdaExpression lambdaExpression) {
|
public void visit(LambdaExpression lambdaExpression) {
|
||||||
out.append("(");
|
lambdaExpression.params.accept(this);
|
||||||
lambdaExpression.params.accept(this);
|
|
||||||
out.append(" -> ");
|
out.append(" -> ");
|
||||||
out.append("(");
|
|
||||||
lambdaExpression.methodBody.accept(this);
|
lambdaExpression.methodBody.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import org.objectweb.asm.Opcodes;
|
|||||||
|
|
||||||
import java.lang.classfile.Opcode;
|
import java.lang.classfile.Opcode;
|
||||||
import java.lang.reflect.AccessFlag;
|
import java.lang.reflect.AccessFlag;
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -631,7 +630,7 @@ public class ASTToTargetAST {
|
|||||||
mParams,
|
mParams,
|
||||||
classType,
|
classType,
|
||||||
method.name(),
|
method.name(),
|
||||||
method.isStatic(), false, method.isPrivate()
|
false, false, method.isPrivate()
|
||||||
);
|
);
|
||||||
if (method.signature().returnType() != null) {
|
if (method.signature().returnType() != null) {
|
||||||
caseBody = new TargetReturn(caseBody);
|
caseBody = new TargetReturn(caseBody);
|
||||||
|
|||||||
@@ -476,7 +476,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
.map(this::extractAllPatterns)
|
.map(this::extractAllPatterns)
|
||||||
.flatMap(List::stream).toList();
|
.flatMap(List::stream).toList();
|
||||||
case FormalParameter param -> List.of(new TypeVariants(param.getType(), converter.findAllVariants(param.getType())));
|
case FormalParameter param -> List.of(new TypeVariants(param.getType(), converter.findAllVariants(param.getType())));
|
||||||
case null, default -> List.of();
|
default -> List.of();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -875,8 +875,8 @@ public class TYPEStmt implements StatementVisitor {
|
|||||||
if (caseExpressionType == null) {
|
if (caseExpressionType == null) {
|
||||||
for (var child : switchStmt.getBlocks()) {
|
for (var child : switchStmt.getBlocks()) {
|
||||||
for (var label : child.getLabels()) {
|
for (var label : child.getLabels()) {
|
||||||
if (label.getPattern() == null && switchStmt.getSwitch().getType() instanceof TypePlaceholder) {
|
if (label.getPattern() == null) {
|
||||||
constraintsSet.addUndConstraint(new Pair(new RefType(new JavaClassName("java.lang.Object"), new NullToken()), switchStmt.getSwitch().getType(), PairOperator.EQUALSDOT, loc(label.getOffset())));
|
constraintsSet.addUndConstraint(new Pair(new RefType(new JavaClassName("java.lang.Object"), new NullToken()), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT, loc(label.getOffset())));
|
||||||
}
|
}
|
||||||
if (label.getPattern() instanceof RecordPattern) {
|
if (label.getPattern() instanceof RecordPattern) {
|
||||||
RecordPattern recordPattern = (RecordPattern) label.getPattern();
|
RecordPattern recordPattern = (RecordPattern) label.getPattern();
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ public class distributeVariance extends visitUnifyTypeVisitor<Integer> {
|
|||||||
List<UnifyType> param = new ArrayList<>(funnty.getTypeParams().get().length);
|
List<UnifyType> param = new ArrayList<>(funnty.getTypeParams().get().length);
|
||||||
param.addAll(Arrays.asList(funnty.getTypeParams().get()));
|
param.addAll(Arrays.asList(funnty.getTypeParams().get()));
|
||||||
UnifyType resultType = param.remove(param.size()-1);
|
UnifyType resultType = param.remove(param.size()-1);
|
||||||
ht = (ht == 0)? 1 : 0; //bei ht = 0 wird ht auf die Standardwerte für Functionstypes gesetzt
|
|
||||||
int htInverse = inverseVariance(ht);
|
int htInverse = inverseVariance(ht);
|
||||||
param = param.stream()
|
param = param.stream()
|
||||||
.map(x -> x.accept(this, htInverse))
|
.map(x -> x.accept(this, htInverse))
|
||||||
|
|||||||
+212
-96
@@ -1,8 +1,6 @@
|
|||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.CodeGenException;
|
import de.dhbwstuttgart.bytecode.CodeGenException;
|
||||||
import de.dhbwstuttgart.core.ConsoleInterface;
|
import de.dhbwstuttgart.core.ConsoleInterface;
|
||||||
import de.dhbwstuttgart.exceptions.CompilerException;
|
|
||||||
import de.dhbwstuttgart.exceptions.ParserError;
|
|
||||||
import de.dhbwstuttgart.exceptions.WarningsException;
|
import de.dhbwstuttgart.exceptions.WarningsException;
|
||||||
import de.dhbwstuttgart.util.Logger;
|
import de.dhbwstuttgart.util.Logger;
|
||||||
import de.dhbwstuttgart.util.Logger.LogLevel;
|
import de.dhbwstuttgart.util.Logger.LogLevel;
|
||||||
@@ -43,6 +41,16 @@ public class TestComplete {
|
|||||||
var m = applyLambda.getDeclaredMethod("m");
|
var m = applyLambda.getDeclaredMethod("m");
|
||||||
var result = m.invoke(instance);
|
var result = m.invoke(instance);
|
||||||
|
|
||||||
|
assertEquals(Object.class, m.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[0], m.getParameterTypes());
|
||||||
|
|
||||||
|
var lambda = applyLambda.getDeclaredMethod("lambda$0", Object.class);
|
||||||
|
assertEquals(Object.class, lambda.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class}, lambda.getParameterTypes());
|
||||||
|
assertEquals(2, applyLambda.getDeclaredMethods().length);
|
||||||
|
|
||||||
|
var apply = classFiles.get("Apply");
|
||||||
|
assertEquals(0, apply.getDeclaredMethods().length);
|
||||||
assertEquals(result.getClass(), classFiles.get("Apply"));
|
assertEquals(result.getClass(), classFiles.get("Apply"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +62,23 @@ public class TestComplete {
|
|||||||
|
|
||||||
var m2 = binaryInMeth.getDeclaredMethod("m2", Integer.class, Integer.class);
|
var m2 = binaryInMeth.getDeclaredMethod("m2", Integer.class, Integer.class);
|
||||||
var m3 = binaryInMeth.getDeclaredMethod("m3", Integer.class);
|
var m3 = binaryInMeth.getDeclaredMethod("m3", Integer.class);
|
||||||
|
var mInteger = binaryInMeth.getDeclaredMethod("m", Integer.class);
|
||||||
|
var mDouble = binaryInMeth.getDeclaredMethod("m", Double.class);
|
||||||
|
var m2Double = binaryInMeth.getDeclaredMethod("m2", Double.class, Double.class);
|
||||||
|
var m3Double = binaryInMeth.getDeclaredMethod("m3", Double.class);
|
||||||
|
|
||||||
|
assertEquals(Integer.class, m2.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Integer.class, Integer.class}, m2.getParameterTypes());
|
||||||
|
assertEquals(Integer.class, m3.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Integer.class}, m3.getParameterTypes());
|
||||||
|
assertEquals(Integer.class, mInteger.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Integer.class}, mInteger.getParameterTypes());
|
||||||
|
assertEquals(Double.class, mDouble.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Double.class}, mDouble.getParameterTypes());
|
||||||
|
assertEquals(Double.class, m2Double.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Double.class, Double.class}, m2Double.getParameterTypes());
|
||||||
|
assertEquals(Double.class, m3Double.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Double.class}, m3Double.getParameterTypes());
|
||||||
|
|
||||||
assertEquals(6, m2.invoke(instance, 2, 3));
|
assertEquals(6, m2.invoke(instance, 2, 3));
|
||||||
assertEquals(4, m3.invoke(instance, 2));
|
assertEquals(4, m3.invoke(instance, 2));
|
||||||
@@ -62,7 +87,24 @@ public class TestComplete {
|
|||||||
@Test
|
@Test
|
||||||
public void classGenLamTest() throws Exception {
|
public void classGenLamTest() throws Exception {
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "ClassGenLam.jav");
|
var classFiles = generateClassFiles(createClassLoader(), "ClassGenLam.jav");
|
||||||
classFiles.get("ClassGenLam").getDeclaredConstructor().newInstance();
|
var classGenLam = classFiles.get("ClassGenLam");
|
||||||
|
classGenLam.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
assertEquals(1, classGenLam.getTypeParameters().length);
|
||||||
|
var typeParameter = classGenLam.getTypeParameters()[0];
|
||||||
|
|
||||||
|
var lam = classGenLam.getDeclaredField("lam");
|
||||||
|
assertEquals("lam", lam.getName());
|
||||||
|
assertEquals("Fun1$$LTPH$_$LTPH$_$", lam.getType().getName());
|
||||||
|
assertTrue(lam.getGenericType() instanceof ParameterizedType);
|
||||||
|
var lamType = (ParameterizedType) lam.getGenericType();
|
||||||
|
assertEquals(2, lamType.getActualTypeArguments().length);
|
||||||
|
assertEquals(typeParameter, lamType.getActualTypeArguments()[0]);
|
||||||
|
assertEquals(typeParameter, lamType.getActualTypeArguments()[1]);
|
||||||
|
|
||||||
|
var lambda = classGenLam.getDeclaredMethod("lambda$0", Object.class);
|
||||||
|
assertEquals(Object.class, lambda.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class}, lambda.getParameterTypes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -72,6 +114,13 @@ public class TestComplete {
|
|||||||
var instance = fac.getDeclaredConstructor().newInstance();
|
var instance = fac.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
var getFac = fac.getDeclaredMethod("getFac", Integer.class);
|
var getFac = fac.getDeclaredMethod("getFac", Integer.class);
|
||||||
|
var getFacDouble = fac.getDeclaredMethod("getFac", Double.class);
|
||||||
|
|
||||||
|
assertEquals(0, fac.getDeclaredFields().length);
|
||||||
|
assertEquals(Double.class, getFac.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Integer.class}, getFac.getParameterTypes());
|
||||||
|
assertEquals(Double.class, getFacDouble.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Double.class}, getFacDouble.getParameterTypes());
|
||||||
// assertEquals(6, getFac.invoke(instance, 3)); TODO This could be either an Integer or a Double so this simple test fails
|
// assertEquals(6, getFac.invoke(instance, 3)); TODO This could be either an Integer or a Double so this simple test fails
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +134,21 @@ public class TestComplete {
|
|||||||
var instance = constructor.newInstance();
|
var instance = constructor.newInstance();
|
||||||
|
|
||||||
var getFact = fac.getDeclaredMethod("getFact", Integer.class);
|
var getFact = fac.getDeclaredMethod("getFact", Integer.class);
|
||||||
|
var lambda = fac.getDeclaredMethod("lambda$0", Object.class);
|
||||||
|
var fact = fac.getDeclaredField("fact");
|
||||||
|
|
||||||
|
assertEquals(1, fac.getDeclaredFields().length);
|
||||||
|
assertEquals("Fun1$$Ljava$lang$Integer$_$Ljava$lang$Integer$_$", fact.getType().getName());
|
||||||
|
assertTrue(fact.getGenericType() instanceof ParameterizedType);
|
||||||
|
var factType = (ParameterizedType) fact.getGenericType();
|
||||||
|
assertEquals(2, factType.getActualTypeArguments().length);
|
||||||
|
assertEquals(Integer.class, factType.getActualTypeArguments()[0]);
|
||||||
|
assertEquals(Integer.class, factType.getActualTypeArguments()[1]);
|
||||||
|
assertEquals(Integer.class, getFact.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Integer.class}, getFact.getParameterTypes());
|
||||||
|
assertEquals(Integer.class, lambda.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class}, lambda.getParameterTypes());
|
||||||
|
|
||||||
assertEquals(6, getFact.invoke(instance, 3));
|
assertEquals(6, getFact.invoke(instance, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +157,14 @@ public class TestComplete {
|
|||||||
var classFiles = generateClassFiles(createClassLoader(), "Field.jav");
|
var classFiles = generateClassFiles(createClassLoader(), "Field.jav");
|
||||||
var field = classFiles.get("Field");
|
var field = classFiles.get("Field");
|
||||||
var instance = field.getDeclaredConstructor().newInstance();
|
var instance = field.getDeclaredConstructor().newInstance();
|
||||||
|
var x = field.getDeclaredField("x");
|
||||||
|
var m = field.getDeclaredMethod("m");
|
||||||
|
|
||||||
assertEquals(1, field.getFields().length);
|
assertEquals(1, field.getFields().length);
|
||||||
|
assertEquals(Integer.class, x.getType());
|
||||||
|
assertEquals(Integer.class, x.getGenericType());
|
||||||
|
assertEquals(Integer.class, m.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[0], m.getParameterTypes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -107,6 +178,24 @@ public class TestComplete {
|
|||||||
m2.invoke(instance, 1);
|
m2.invoke(instance, 1);
|
||||||
|
|
||||||
var m = fieldtph2.getDeclaredMethod("m", Object.class);
|
var m = fieldtph2.getDeclaredMethod("m", Object.class);
|
||||||
|
var typeParameters = fieldtph2.getTypeParameters();
|
||||||
|
assertEquals(2, typeParameters.length);
|
||||||
|
var p = typeParameters[0];
|
||||||
|
var t = typeParameters[1];
|
||||||
|
assertEquals("P", p.getName());
|
||||||
|
assertEquals("T", t.getName());
|
||||||
|
assertEquals(p, t.getBounds()[0]);
|
||||||
|
|
||||||
|
assertEquals(Object.class, a.getType());
|
||||||
|
assertEquals(t, a.getGenericType());
|
||||||
|
assertEquals(Object.class, m.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class}, m.getParameterTypes());
|
||||||
|
assertEquals(p, m.getGenericReturnType());
|
||||||
|
assertEquals(p, m.getGenericParameterTypes()[0]);
|
||||||
|
assertEquals(void.class, m2.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class}, m2.getParameterTypes());
|
||||||
|
assertEquals(t, m2.getGenericParameterTypes()[0]);
|
||||||
|
|
||||||
assertEquals(1, m.invoke(instance, 1));
|
assertEquals(1, m.invoke(instance, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,6 +208,35 @@ public class TestComplete {
|
|||||||
var instance = ctor.newInstance("C");
|
var instance = ctor.newInstance("C");
|
||||||
var a = fieldTphConsMeth.getDeclaredField("a");
|
var a = fieldTphConsMeth.getDeclaredField("a");
|
||||||
var id = fieldTphConsMeth.getDeclaredMethod("id", Object.class);
|
var id = fieldTphConsMeth.getDeclaredMethod("id", Object.class);
|
||||||
|
var typeParameter = fieldTphConsMeth.getTypeParameters()[0];
|
||||||
|
var setA = fieldTphConsMeth.getDeclaredMethod("setA", Object.class);
|
||||||
|
var m = fieldTphConsMeth.getDeclaredMethod("m", Object.class, Object.class);
|
||||||
|
|
||||||
|
assertEquals(1, fieldTphConsMeth.getTypeParameters().length);
|
||||||
|
assertEquals("AAB", typeParameter.getName());
|
||||||
|
assertEquals(Object.class, a.getType());
|
||||||
|
assertEquals(typeParameter, a.getGenericType());
|
||||||
|
assertEquals(Object.class, ctor.getParameterTypes()[0]);
|
||||||
|
assertEquals(1, ctor.getTypeParameters().length);
|
||||||
|
assertEquals(typeParameter, ctor.getTypeParameters()[0].getBounds()[0]);
|
||||||
|
assertEquals(ctor.getTypeParameters()[0], ctor.getGenericParameterTypes()[0]);
|
||||||
|
assertEquals(Object.class, setA.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class}, setA.getParameterTypes());
|
||||||
|
assertEquals(typeParameter, setA.getGenericReturnType());
|
||||||
|
assertEquals(setA.getTypeParameters()[0], setA.getGenericParameterTypes()[0]);
|
||||||
|
assertEquals(typeParameter, setA.getTypeParameters()[0].getBounds()[0]);
|
||||||
|
assertEquals(Object.class, id.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class}, id.getParameterTypes());
|
||||||
|
assertEquals(typeParameter, id.getGenericReturnType());
|
||||||
|
assertEquals(typeParameter, id.getGenericParameterTypes()[0]);
|
||||||
|
assertEquals(void.class, m.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class, Object.class}, m.getParameterTypes());
|
||||||
|
assertEquals(3, m.getTypeParameters().length);
|
||||||
|
assertEquals(Object.class, m.getTypeParameters()[0].getBounds()[0]);
|
||||||
|
assertEquals(m.getTypeParameters()[2], m.getTypeParameters()[1].getBounds()[0]);
|
||||||
|
assertEquals(m.getTypeParameters()[0], m.getTypeParameters()[2].getBounds()[0]);
|
||||||
|
assertEquals(m.getTypeParameters()[0], m.getGenericParameterTypes()[0]);
|
||||||
|
assertEquals(m.getTypeParameters()[1], m.getGenericParameterTypes()[1]);
|
||||||
|
|
||||||
assertEquals(42, id.invoke(instance, 42));
|
assertEquals(42, id.invoke(instance, 42));
|
||||||
assertEquals("C", a.get(instance));
|
assertEquals("C", a.get(instance));
|
||||||
@@ -134,9 +252,39 @@ public class TestComplete {
|
|||||||
var instance2 = ctor.newInstance("C", 42, false);
|
var instance2 = ctor.newInstance("C", 42, false);
|
||||||
|
|
||||||
var m = fieldTphMMeth.getDeclaredMethod("m", Object.class, Object.class, Boolean.class);
|
var m = fieldTphMMeth.getDeclaredMethod("m", Object.class, Object.class, Boolean.class);
|
||||||
|
var m2 = fieldTphMMeth.getDeclaredMethod("m2", Object.class);
|
||||||
|
var m3 = fieldTphMMeth.getDeclaredMethod("m3", Object.class);
|
||||||
|
var a = fieldTphMMeth.getDeclaredField("a");
|
||||||
|
var classTypeParameter = fieldTphMMeth.getTypeParameters()[0];
|
||||||
|
|
||||||
|
assertEquals(1, fieldTphMMeth.getTypeParameters().length);
|
||||||
|
assertEquals("AF", classTypeParameter.getName());
|
||||||
|
assertEquals(Object.class, a.getType());
|
||||||
|
assertEquals(classTypeParameter, a.getGenericType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class, Object.class, Boolean.class}, ctor.getParameterTypes());
|
||||||
|
assertEquals(2, ctor.getTypeParameters().length);
|
||||||
|
assertEquals(classTypeParameter, ctor.getTypeParameters()[0].getBounds()[0]);
|
||||||
|
assertEquals(classTypeParameter, ctor.getTypeParameters()[1].getBounds()[0]);
|
||||||
|
assertEquals(Object.class, m.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class, Object.class, Boolean.class}, m.getParameterTypes());
|
||||||
|
assertEquals(2, m.getTypeParameters().length);
|
||||||
|
assertEquals(Object.class, m.getTypeParameters()[0].getBounds()[0]);
|
||||||
|
assertEquals(m.getTypeParameters()[0], m.getTypeParameters()[1].getBounds()[0]);
|
||||||
|
assertEquals(m.getTypeParameters()[0], m.getGenericReturnType());
|
||||||
|
assertEquals(m.getTypeParameters()[0], m.getGenericParameterTypes()[0]);
|
||||||
|
assertEquals(m.getTypeParameters()[1], m.getGenericParameterTypes()[1]);
|
||||||
|
assertEquals(void.class, m2.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class}, m2.getParameterTypes());
|
||||||
|
assertEquals(classTypeParameter, m2.getTypeParameters()[0].getBounds()[0]);
|
||||||
|
assertEquals(m2.getTypeParameters()[0], m2.getGenericParameterTypes()[0]);
|
||||||
|
assertEquals(Object.class, m3.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class}, m3.getParameterTypes());
|
||||||
|
assertEquals(classTypeParameter, m3.getTypeParameters()[0].getBounds()[0]);
|
||||||
|
assertEquals(m3.getTypeParameters()[0], m3.getGenericReturnType());
|
||||||
|
assertEquals(m3.getTypeParameters()[0], m3.getGenericParameterTypes()[0]);
|
||||||
|
|
||||||
assertEquals(42, m.invoke(instance1, "C", 42, false));
|
assertEquals(42, m.invoke(instance1, "C", 42, false));
|
||||||
|
|
||||||
var a = fieldTphMMeth.getDeclaredField("a");
|
|
||||||
assertEquals("C", a.get(instance1));
|
assertEquals("C", a.get(instance1));
|
||||||
assertEquals(42, a.get(instance2));
|
assertEquals(42, a.get(instance2));
|
||||||
}
|
}
|
||||||
@@ -144,19 +292,74 @@ public class TestComplete {
|
|||||||
@Test
|
@Test
|
||||||
public void genTest() throws Exception {
|
public void genTest() throws Exception {
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Gen.jav");
|
var classFiles = generateClassFiles(createClassLoader(), "Gen.jav");
|
||||||
|
var gen = classFiles.get("Gen");
|
||||||
|
var m = gen.getDeclaredMethod("m", Vector.class);
|
||||||
|
|
||||||
|
assertEquals(0, gen.getDeclaredFields().length);
|
||||||
|
assertEquals(Vector.class, m.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Vector.class}, m.getParameterTypes());
|
||||||
|
assertTrue(m.getGenericReturnType() instanceof ParameterizedType);
|
||||||
|
var returnType = (ParameterizedType) m.getGenericReturnType();
|
||||||
|
assertEquals(Vector.class, returnType.getRawType());
|
||||||
|
assertArrayEquals(new Type[]{Integer.class}, returnType.getActualTypeArguments());
|
||||||
|
assertTrue(m.getGenericParameterTypes()[0] instanceof ParameterizedType);
|
||||||
|
var parameterType = (ParameterizedType) m.getGenericParameterTypes()[0];
|
||||||
|
assertEquals(Vector.class, parameterType.getRawType());
|
||||||
|
assertArrayEquals(new Type[]{Integer.class}, parameterType.getActualTypeArguments());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void idTest() throws Exception {
|
public void idTest() throws Exception {
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Id.jav");
|
var classFiles = generateClassFiles(createClassLoader(), "Id.jav");
|
||||||
var instance = classFiles.get("Id").getDeclaredConstructor().newInstance();
|
var id = classFiles.get("Id");
|
||||||
|
id.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
assertEquals(1, id.getTypeParameters().length);
|
||||||
|
assertEquals("FAU", id.getTypeParameters()[0].getName());
|
||||||
|
|
||||||
|
var id2 = id.getDeclaredField("id2");
|
||||||
|
assertEquals("Fun1$$LTPH$_$LTPH$_$", id2.getType().getName());
|
||||||
|
|
||||||
|
var lambda = id.getDeclaredMethod("lambda$0", Object.class);
|
||||||
|
assertEquals(Object.class, lambda.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class}, lambda.getParameterTypes());
|
||||||
|
|
||||||
|
var id3 = id.getDeclaredMethod("id3", Object.class);
|
||||||
|
assertEquals(Object.class, id3.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class}, id3.getParameterTypes());
|
||||||
|
assertEquals(1, id3.getTypeParameters().length);
|
||||||
|
assertEquals("V", id3.getTypeParameters()[0].getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void infTest() throws Exception {
|
public void infTest() throws Exception {
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Inf.jav");
|
var classFiles = generateClassFiles(createClassLoader(), "Inf.jav");
|
||||||
var instance = classFiles.get("Inf").getDeclaredConstructor().newInstance();
|
var inf = classFiles.get("Inf");
|
||||||
// TODO check generics
|
inf.getDeclaredConstructor().newInstance();
|
||||||
|
var m = inf.getDeclaredMethod("m", Object.class, Object.class, Object.class);
|
||||||
|
|
||||||
|
assertEquals(0, inf.getDeclaredFields().length);
|
||||||
|
assertEquals(void.class, m.getReturnType());
|
||||||
|
assertArrayEquals(new Class<?>[]{Object.class, Object.class, Object.class}, m.getParameterTypes());
|
||||||
|
assertEquals(5, m.getTypeParameters().length);
|
||||||
|
var zn = m.getTypeParameters()[0];
|
||||||
|
var zo = m.getTypeParameters()[1];
|
||||||
|
var q = m.getTypeParameters()[2];
|
||||||
|
var o = m.getTypeParameters()[3];
|
||||||
|
var zp = m.getTypeParameters()[4];
|
||||||
|
assertEquals("ZN", zn.getName());
|
||||||
|
assertEquals("ZO", zo.getName());
|
||||||
|
assertEquals("Q", q.getName());
|
||||||
|
assertEquals("O", o.getName());
|
||||||
|
assertEquals("ZP", zp.getName());
|
||||||
|
assertEquals(zo, zn.getBounds()[0]);
|
||||||
|
assertEquals(zp, zo.getBounds()[0]);
|
||||||
|
assertEquals(zn, q.getBounds()[0]);
|
||||||
|
assertEquals(zn, o.getBounds()[0]);
|
||||||
|
assertEquals(Object.class, zp.getBounds()[0]);
|
||||||
|
assertEquals(o, m.getGenericParameterTypes()[0]);
|
||||||
|
assertEquals(zn, m.getGenericParameterTypes()[1]);
|
||||||
|
assertEquals(q, m.getGenericParameterTypes()[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -257,7 +460,6 @@ public class TestComplete {
|
|||||||
@Test
|
@Test
|
||||||
//@Disabled("This is too complex")
|
//@Disabled("This is too complex")
|
||||||
public void matrixTest() throws Exception {
|
public void matrixTest() throws Exception {
|
||||||
//ConsoleInterface.logLevel = LogLevel.DEBUG;
|
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Matrix.jav");
|
var classFiles = generateClassFiles(createClassLoader(), "Matrix.jav");
|
||||||
var matrix = classFiles.get("Matrix");
|
var matrix = classFiles.get("Matrix");
|
||||||
|
|
||||||
@@ -1084,9 +1286,9 @@ public class TestComplete {
|
|||||||
assertEquals(40.0, m.invoke(instance, d, 0));
|
assertEquals(40.0, m.invoke(instance, d, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Disabled("Waiting for #407, skipping for now")
|
|
||||||
@Test
|
@Test
|
||||||
public void testPatternMatchingInterface() throws Exception {
|
public void testPatternMatchingInterface() throws Exception {
|
||||||
|
ConsoleInterface.logLevel = LogLevel.INFO;
|
||||||
var classFiles = generateClassFiles(createClassLoader(), false, "Matcher.jav", "PatternMatchingInterface.jav");
|
var classFiles = generateClassFiles(createClassLoader(), false, "Matcher.jav", "PatternMatchingInterface.jav");
|
||||||
var Intf = classFiles.get("Interface");
|
var Intf = classFiles.get("Interface");
|
||||||
var clazz = classFiles.get("PatternMatchingInterface");
|
var clazz = classFiles.get("PatternMatchingInterface");
|
||||||
@@ -1231,10 +1433,6 @@ public class TestComplete {
|
|||||||
assertEquals('C', clazz.getDeclaredMethod("m2").invoke(instance));
|
assertEquals('C', clazz.getDeclaredMethod("m2").invoke(instance));
|
||||||
assertEquals(10L, clazz.getDeclaredMethod("m3").invoke(instance));
|
assertEquals(10L, clazz.getDeclaredMethod("m3").invoke(instance));
|
||||||
assertEquals(10.5F, clazz.getDeclaredMethod("m4").invoke(instance));
|
assertEquals(10.5F, clazz.getDeclaredMethod("m4").invoke(instance));
|
||||||
assertEquals(10.5D, clazz.getDeclaredMethod("m5").invoke(instance));
|
|
||||||
assertEquals(0xFF, clazz.getDeclaredMethod("m6").invoke(instance));
|
|
||||||
assertEquals(0b101010, clazz.getDeclaredMethod("m7").invoke(instance));
|
|
||||||
assertEquals(010, clazz.getDeclaredMethod("m8").invoke(instance));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1360,7 +1558,6 @@ public class TestComplete {
|
|||||||
@Disabled("See #405")
|
@Disabled("See #405")
|
||||||
@Test
|
@Test
|
||||||
public void testLazy() throws Exception {
|
public void testLazy() throws Exception {
|
||||||
ConsoleInterface.logLevel = LogLevel.DEBUG;
|
|
||||||
var classFiles = generateClassFiles(createClassLoader(), false, "LazyList.jav", "Primzahlen.jav");
|
var classFiles = generateClassFiles(createClassLoader(), false, "LazyList.jav", "Primzahlen.jav");
|
||||||
var clazz = classFiles.get("Primzahlen");
|
var clazz = classFiles.get("Primzahlen");
|
||||||
var main = clazz.getDeclaredMethod("main", List.class);
|
var main = clazz.getDeclaredMethod("main", List.class);
|
||||||
@@ -1708,90 +1905,9 @@ public class TestComplete {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBug406() throws Exception {
|
public void testBug406() throws Exception {
|
||||||
|
ConsoleInterface.logLevel = LogLevel.INFO;
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Bug406.jav");
|
var classFiles = generateClassFiles(createClassLoader(), "Bug406.jav");
|
||||||
var clazz = classFiles.get("Bug406");
|
var clazz = classFiles.get("Bug406");
|
||||||
clazz.getDeclaredMethod("main", List.class).invoke(null, List.of());
|
clazz.getDeclaredMethod("main", List.class).invoke(null, List.of());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBug423() throws Exception {
|
|
||||||
try {
|
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Bug423.jav");
|
|
||||||
fail("No exception thrown!");
|
|
||||||
} catch (CodeGenException e) {
|
|
||||||
assertEquals("Class Bug423 does not implement method f from interface Bug423I", e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBug422() throws Exception {
|
|
||||||
try {
|
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Bug422.jav");
|
|
||||||
fail("Shouldn't compile!");
|
|
||||||
} catch (CompilerException e) {
|
|
||||||
assertEquals("Duplicate class definition: Bug422", e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBug421() throws Exception {
|
|
||||||
try {
|
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Bug421.jav");
|
|
||||||
fail("Shouldn't compile!");
|
|
||||||
} catch (ParserError e) {
|
|
||||||
assertEquals("Syntax error at line 2:26 - no viable alternative at input 'm() { return 1 }'", e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBug409() throws Exception {
|
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Bug409.jav");
|
|
||||||
var clazz = classFiles.get("Bug409");
|
|
||||||
var instance = clazz.getDeclaredConstructor().newInstance();
|
|
||||||
var m = clazz.getDeclaredMethod("m");
|
|
||||||
assertEquals(5, m.invoke(instance));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBug417() throws Exception {
|
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Bug417.jav");
|
|
||||||
var clazz = classFiles.get("Bug417");
|
|
||||||
var instance = clazz.getDeclaredConstructor().newInstance();
|
|
||||||
var name = clazz.getDeclaredMethod("name", Integer.class);
|
|
||||||
assertEquals("one", name.invoke(instance, 1));
|
|
||||||
assertEquals("many", name.invoke(instance, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBug411() throws Exception {
|
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Bug411.jav");
|
|
||||||
var clazz = classFiles.get("Bug411");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBug412() throws Exception {
|
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Bug412.jav");
|
|
||||||
var clazz = classFiles.get("Bug412");
|
|
||||||
var instance = clazz.getDeclaredConstructor().newInstance();
|
|
||||||
var m = clazz.getDeclaredMethod("m", Integer.class);
|
|
||||||
assertEquals(10, m.invoke(instance, 1));
|
|
||||||
assertEquals(20, m.invoke(instance, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBug416() throws Exception {
|
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Bug416.jav");
|
|
||||||
var clazz = classFiles.get("Bug416");
|
|
||||||
var L = classFiles.get("L");
|
|
||||||
var Cons = classFiles.get("Cons");
|
|
||||||
var Nil = classFiles.get("Nil");
|
|
||||||
|
|
||||||
var consCtor = Cons.getDeclaredConstructor(Object.class, L);
|
|
||||||
var nilCtor = Nil.getDeclaredConstructor();
|
|
||||||
|
|
||||||
var list = consCtor.newInstance(1, consCtor.newInstance(2, consCtor.newInstance(3, nilCtor.newInstance())));
|
|
||||||
|
|
||||||
var len = clazz.getDeclaredMethod("len", L);
|
|
||||||
assertEquals(3, len.invoke(null, list));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ import de.dhbwstuttgart.bytecode.Codegen;
|
|||||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||||
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
||||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||||
import de.dhbwstuttgart.target.tree.MethodParameter;
|
import de.dhbwstuttgart.target.tree.MethodParameter;
|
||||||
@@ -16,6 +17,7 @@ import de.dhbwstuttgart.target.tree.type.TargetFunNType;
|
|||||||
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@@ -202,20 +204,9 @@ public class TestCodegen {
|
|||||||
@Test
|
@Test
|
||||||
public void testFor() throws Exception {
|
public void testFor() throws Exception {
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("For"));
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("For"));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "forLoop", List.of(), TargetType.Integer,
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "forLoop", List.of(), TargetType.Integer, new TargetBlock(List.of(new TargetVarDecl(TargetType.Integer, "sum", new TargetLiteral.IntLiteral(0)), new TargetFor(List.of(new TargetVarDecl(TargetType.Integer, "i", new TargetLiteral.IntLiteral(0))), new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10)), List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(1)))), new TargetBlock(List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"), new TargetLocalVar(TargetType.Integer, "i")))))), new TargetReturn(new TargetLocalVar(TargetType.Integer, "sum")))));
|
||||||
new TargetBlock(List.of(new TargetVarDecl(TargetType.Integer, "sum", new TargetLiteral.IntLiteral(0)),
|
|
||||||
new TargetFor(List.of(new TargetVarDecl(TargetType.Integer, "i", new TargetLiteral.IntLiteral(0))),
|
|
||||||
new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"),
|
|
||||||
new TargetLiteral.IntLiteral(10)), List.of(new TargetAssign(TargetType.Integer,
|
|
||||||
new TargetLocalVar(TargetType.Integer, "i"),
|
|
||||||
new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(1)))),
|
|
||||||
new TargetBlock(List.of(
|
|
||||||
new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"),
|
|
||||||
new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"),
|
|
||||||
new TargetLocalVar(TargetType.Integer, "i")))))),
|
|
||||||
new TargetReturn(new TargetLocalVar(TargetType.Integer, "sum")))));
|
|
||||||
var clazz = generateClass(targetClass, createClassLoader());
|
var clazz = generateClass(targetClass, createClassLoader());
|
||||||
assertEquals(45, clazz.getDeclaredMethod("forLoop").invoke(null));
|
assertEquals(clazz.getDeclaredMethod("forLoop").invoke(null), 45);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in new issue
Block a user