Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode

This commit is contained in:
pl@gohorb.ba-horb.de 2024-03-04 19:37:40 +01:00
commit 1c1f5ae29f
50 changed files with 722 additions and 210 deletions

View File

@ -0,0 +1,7 @@
public class Bug112 {
m(x) {
var y;
x = y;
return y;
}
}

View File

@ -0,0 +1,12 @@
import java.lang.Integer;
import java.lang.Boolean;
class Bug122 {
void main() {
if (true) {
for (Integer i = 0; i < 10; i++) {
}
}
}
}

View File

@ -0,0 +1,13 @@
import java.lang.Boolean;
import java.lang.Integer;
class Bug123 {
Boolean works(){
if(true) return true;
else return false;
}
void fails(){
Boolean a = true;
if(true) a = false;
}
}

View File

@ -0,0 +1,16 @@
import java.lang.Boolean;
import java.lang.Integer;
import java.lang.String;
import java.util.List;
import java.util.LinkedList;
import java.util.ArrayList;
class Bug125 {
static ArrayList<String> works = new ArrayList<>();
static List<String> fails = new ArrayList<>();
void main() {
works.toString();
fails.toString();
}
}

View File

@ -1,3 +1,8 @@
import java.lang.String;
import java.lang.RuntimeException;
public class Exceptions { public class Exceptions {
// m(Integer i) throws m() {
throw new RuntimeException("Some Exception");
}
} }

View File

@ -0,0 +1,15 @@
import java.util.ArrayList;
import java.lang.Integer;
public class ForEach {
m() {
var list = new ArrayList<>();
list.add(1); list.add(2); list.add(3);
var sum = 0;
for (var i : list) {
sum = sum + i;
}
return sum;
}
}

View File

@ -1,18 +1,18 @@
import java.lang.Number; import java.lang.Object;
import java.lang.Integer; import java.lang.Integer;
import java.lang.Double; import java.lang.Boolean;
import java.lang.String;
interface Interface {}
class Test implements Interface {
}
class Test2 {
}
public class InstanceOf { public class InstanceOf {
main(n) { a = new Test();
if (n instanceof Integer i) {
takes(i);
return "Integer";
} else if (n instanceof Double d) {
takes(d);
return "Double";
}
}
takes(i) {} // Should be overloaded test1() { return this.a instanceof Test; }
test2() { return this.a instanceof Interface; }
test3() { return this.a instanceof Integer; }
} }

View File

@ -1,8 +1,15 @@
public class LamRunnable{ import java.lang.Runnable;
import java.lang.System;
import java.lang.String;
import java.io.PrintStream;
public class LamRunnable {
public LamRunnable() {
Runnable lam = () -> {
System.out.println("lambda");
};
public LamRunnable(){
Runnable lam = () -> {System.out.println("lambda");};
lam.run(); lam.run();
} }
} }

View File

@ -0,0 +1,6 @@
import java.lang.Character;
public class Literal {
m() { return null; }
m2() { return 'C'; }
}

View File

@ -0,0 +1,17 @@
import java.lang.Integer;
public class Parent {
public Integer x;
public Parent(Integer a) {
this.x = a;
}
public Parent() {}
}
class Child extends Parent {
Child() {
super(3);
}
}

View File

@ -1,11 +1,17 @@
import java.lang.Integer; import java.lang.Integer;
import java.lang.Double;
import java.lang.String; import java.lang.String;
public class Op2 { public class Op2 {
m(){ m(){
var x = ""; //var x = "";
var a = 5+x; //var a = 5+x;
Integer x = 10;
Double y = 10.5;
var a = x - y;
return a; return a;
} }
} }

View File

@ -0,0 +1,11 @@
import java.lang.Integer;
class Parent {
public Parent(Integer x) {}
}
public class SuperCall extends Parent {
public SuperCall() {
super(20);
}
}

View File

@ -2,6 +2,7 @@ package de.dhbwstuttgart.bytecode;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
@ -135,7 +136,7 @@ public class Codegen {
} else if (type.equals(TargetType.Short) || type.equals(TargetType.short_)) { } else if (type.equals(TargetType.Short) || type.equals(TargetType.short_)) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
} else if (type.equals(TargetType.Char) || type.equals(TargetType.char_)) { } else if (type.equals(TargetType.Char) || type.equals(TargetType.char_)) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Char", "valueOf", "(C)Ljava/lang/Char;", false); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
} }
} }
@ -156,7 +157,7 @@ public class Codegen {
} else if (type.equals(TargetType.Short)) { } else if (type.equals(TargetType.Short)) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
} else if (type.equals(TargetType.Char)) { } else if (type.equals(TargetType.Char)) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Char", "charValue", "()C", false); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
} }
} }
@ -805,6 +806,7 @@ public class Codegen {
case StringLiteral stringLiteral -> mv.visitLdcInsn(stringLiteral.value()); case StringLiteral stringLiteral -> mv.visitLdcInsn(stringLiteral.value());
case CharLiteral charLiteral -> mv.visitIntInsn(BIPUSH, charLiteral.value()); case CharLiteral charLiteral -> mv.visitIntInsn(BIPUSH, charLiteral.value());
case DoubleLiteral doubleLiteral -> mv.visitLdcInsn(doubleLiteral.value()); case DoubleLiteral doubleLiteral -> mv.visitLdcInsn(doubleLiteral.value());
case Null ignored -> mv.visitInsn(ACONST_NULL);
case BooleanLiteral booleanLiteral -> { case BooleanLiteral booleanLiteral -> {
if (booleanLiteral.value()) { if (booleanLiteral.value()) {
mv.visitInsn(ICONST_1); mv.visitInsn(ICONST_1);
@ -884,8 +886,12 @@ public class Codegen {
case TargetFor _for: { case TargetFor _for: {
state.enterScope(); state.enterScope();
var localCounter = state.localCounter; var localCounter = state.localCounter;
if (_for.init() != null) if (_for.init() != null) {
_for.init().forEach(e -> generate(state, e)); for (var e : _for.init()) {
generate(state, e);
if (e instanceof TargetAssign) mv.visitInsn(POP);
}
}
Label start = new Label(); Label start = new Label();
Label end = new Label(); Label end = new Label();
@ -918,6 +924,9 @@ public class Codegen {
state.localCounter = localCounter; state.localCounter = localCounter;
break; break;
} }
case TargetForEach forEach:
generateForEach(forEach, state);
break;
case TargetWhile _while: { case TargetWhile _while: {
Label start = new Label(); Label start = new Label();
Label end = new Label(); Label end = new Label();
@ -1036,15 +1045,50 @@ public class Codegen {
mv.visitMethodInsn(INVOKESPECIAL, _new.type().getInternalName(), "<init>", _new.getDescriptor(), false); mv.visitMethodInsn(INVOKESPECIAL, _new.type().getInternalName(), "<init>", _new.getDescriptor(), false);
break; break;
} }
case TargetThrow _throw: {
generate(state, _throw.expr());
mv.visitInsn(ATHROW);
break;
}
default: default:
throw new CodeGenException("Unexpected value: " + expr); throw new CodeGenException("Unexpected value: " + expr);
} }
} }
private void generateForEach(TargetForEach forEach, State state) {
state.enterScope();
TargetVarDecl vd = (TargetVarDecl) forEach.vardecl();
var localVar = state.createVariable(vd.name(), vd.varType());
var expr = forEach.expression();
// TODO Check for arrays
var mv = state.mv;
generate(state, expr);
mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/Iterable", "iterator", "()Ljava/util/Iterator;", true);
var start = new Label();
var end = new Label();
mv.visitLabel(start);
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true);
mv.visitJumpInsn(IFEQ, end);
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true);
mv.visitVarInsn(ASTORE, localVar.index);
generate(state, forEach.body());
mv.visitJumpInsn(GOTO, start);
mv.visitLabel(end);
mv.visitInsn(POP);
state.exitScope();
}
private void generateInstanceOf(State state, TargetInstanceOf instanceOf) { private void generateInstanceOf(State state, TargetInstanceOf instanceOf) {
var mv = state.mv; var mv = state.mv;
if (instanceOf.right() instanceof TargetTypePattern right && right.name() == null) { if (instanceOf.right() instanceof TargetTypePattern right && right.name() == null) {
generate(state, instanceOf.left());
mv.visitTypeInsn(INSTANCEOF, right.type().getInternalName()); mv.visitTypeInsn(INSTANCEOF, right.type().getInternalName());
return; return;
} }
@ -1349,8 +1393,8 @@ public class Codegen {
generate(state, stmts.get(0)); generate(state, stmts.get(0));
if (constructor.fieldInitializer() != null) { if (constructor.fieldInitializer() != null) {
var stmts2 = constructor.fieldInitializer().statements(); var stmts2 = constructor.fieldInitializer().statements();
for (var i = 1; i < stmts2.size(); i++) { for (TargetExpression expression : stmts2) {
generate(state, stmts2.get(i)); generate(state, expression);
} }
} }
for (var i = 1; i < stmts.size(); i++) for (var i = 1; i < stmts.size(); i++)

View File

@ -651,7 +651,7 @@ public class JavaTXCompiler {
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException { private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
SourceFileContext tree = JavaTXParser.parse(sourceFile); SourceFileContext tree = JavaTXParser.parse(sourceFile);
environment.addClassesToRegistry(classRegistry, tree, sourceFile, this); environment.addClassesToRegistry(classRegistry, tree, sourceFile, this);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null)); SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null), sourceFile.getName());
var classes = new ArrayList<ClassOrInterface>(); var classes = new ArrayList<ClassOrInterface>();
var sf = new SourceFile(generator.pkgName, classes, generator.imports); var sf = new SourceFile(generator.pkgName, classes, generator.imports);
addSourceFile(sourceFile, sf); addSourceFile(sourceFile, sf);
@ -672,7 +672,7 @@ public class JavaTXCompiler {
var tree = JavaTXParser.parse(file); var tree = JavaTXParser.parse(file);
classRegistry.addName(name.toString(), 0); // TODO This gets overwritten later, is it bad if we don't know this right away? classRegistry.addName(name.toString(), 0); // TODO This gets overwritten later, is it bad if we don't know this right away?
environment.addClassesToRegistry(classRegistry, tree, file, this); environment.addClassesToRegistry(classRegistry, tree, file, this);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null)); SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null), file.getName());
var classes = new ArrayList<ClassOrInterface>(); var classes = new ArrayList<ClassOrInterface>();
var sf = new SourceFile(generator.pkgName, classes, generator.imports); var sf = new SourceFile(generator.pkgName, classes, generator.imports);
addSourceFile(file, sf); addSourceFile(file, sf);

View File

@ -0,0 +1,4 @@
package de.dhbwstuttgart.parser;
public record SourceLoc(String file, int line) {
}

View File

@ -60,7 +60,7 @@ public class FCGenerator {
.collect(Collectors.toList())); .collect(Collectors.toList()));
tl.add(m.getReturnType().acceptTV(new TypeExchanger(gtvs))); tl.add(m.getReturnType().acceptTV(new TypeExchanger(gtvs)));
return new Pair(new RefType(new JavaClassName("Fun" + (tl.size()-1) + "$$"), tl, new NullToken()), return new Pair(new RefType(new JavaClassName("Fun" + (tl.size()-1) + "$$"), tl, new NullToken()),
fIType); fIType, PairOperator.SMALLER);
} }
return null; //kann nicht passieren, da die Methode nur aufgerufen wird wenn cl Functional Interface ist return null; //kann nicht passieren, da die Methode nur aufgerufen wird wenn cl Functional Interface ist
} }

View File

@ -490,15 +490,33 @@ public class StatementGenerator {
private Statement convert(Java17Parser.ForloopContext stmt) { private Statement convert(Java17Parser.ForloopContext stmt) {
var control = stmt.forControl(); var control = stmt.forControl();
var block = convert(stmt.statement()); if (control.enhancedForControl() != null) {
if (control.enhancedForControl() != null) var forCtrl = control.enhancedForControl();
throw new NotImplementedException(); var name = forCtrl.variableDeclaratorId().identifier();
else {
RefTypeOrTPHOrWildcardOrGeneric type;
if (Objects.isNull(forCtrl.typeType()) || !Objects.isNull(forCtrl.VAR())) {
type = TypePlaceholder.fresh(forCtrl.getStart());
} else {
type = TypeGenerator.convert(forCtrl.typeType(), reg, generics);
}
var vardecl = new LocalVarDecl(name.getText(), type, name.getStart());
this.localVars.put(name.getText(), type);
return new ForEachStmt(
stmt.getStart(),
vardecl,
convert(forCtrl.expression()),
convert(stmt.statement())
);
} else {
return new ForStmt( return new ForStmt(
stmt.getStart(), stmt.getStart(),
convert(control.forInit().localVariableDeclaration()), control.forInit() != null ? convert(control.forInit().localVariableDeclaration()) : List.of(),
convert(control.expression()), control.forUpdate.expression().stream().map(this::convert).toList(), control.expression() != null ? convert(control.expression()) : null,
block control.forUpdate != null ? control.forUpdate.expression().stream().map(this::convert).toList() : List.of(),
convert(stmt.statement())
); );
} }
} }
@ -594,8 +612,7 @@ public class StatementGenerator {
} }
private Statement convert(Java17Parser.ThrowstmtContext stmt) { private Statement convert(Java17Parser.ThrowstmtContext stmt) {
// TODO return new Throw(convert(stmt.expression()), stmt.getStart());
throw new NotImplementedException();
} }
private Statement convert(Java17Parser.SynchronizedstmtContext stmt) { private Statement convert(Java17Parser.SynchronizedstmtContext stmt) {
@ -616,7 +633,6 @@ public class StatementGenerator {
/* /*
*************** + Expression Conversions: *************** + Expression Conversions:
*/ */
private Expression convert(Java17Parser.ExpressionContext expression) { private Expression convert(Java17Parser.ExpressionContext expression) {
switch (expression) { switch (expression) {
case PrimaryExpression2Context primary: case PrimaryExpression2Context primary:
@ -690,13 +706,19 @@ public class StatementGenerator {
} else if (!Objects.isNull(expr.SUPER())) { } else if (!Objects.isNull(expr.SUPER())) {
// if(methodInvocationContext.Identifier() != null){ // if(methodInvocationContext.Identifier() != null){
name = expr.SUPER().getText(); name = expr.SUPER().getText();
receiver = new Super(offset);
} }
ArgumentList argumentList = convertArguments(expr.expressionList()); ArgumentList argumentList = convertArguments(expr.expressionList());
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> signature = argumentList.getArguments().stream().map(x -> (RefTypeOrTPHOrWildcardOrGeneric) TypePlaceholder.fresh(offset)).collect(Collectors.toCollection(ArrayList::new)); ArrayList<RefTypeOrTPHOrWildcardOrGeneric> signature = argumentList.getArguments().stream().map(x -> (RefTypeOrTPHOrWildcardOrGeneric) TypePlaceholder.fresh(offset)).collect(Collectors.toCollection(ArrayList::new));
signature.add(TypePlaceholder.fresh(offset)); // return type signature.add(TypePlaceholder.fresh(offset)); // return type
MethodCall ret = new MethodCall(TypePlaceholder.fresh(offset), getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(offset), signature, offset);
MethodCall ret;
if (expr.SUPER() != null) {
ret = new SuperCall(argumentList, TypePlaceholder.fresh(offset), signature, offset);
} else {
ret = new MethodCall(TypePlaceholder.fresh(offset), getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(offset), signature, offset);
}
ret.setStatement(); ret.setStatement();
return ret; return ret;
} }
@ -779,7 +801,7 @@ public class StatementGenerator {
receiver = new This(offset); receiver = new This(offset);
isStatic = Modifier.isStatic(fields.get(fieldName).modifiers()); isStatic = Modifier.isStatic(fields.get(fieldName).modifiers());
} else if (parts[0].contentEquals("super")) { } else if (parts[0].contentEquals("super")) {
receiver = new Super(offset); receiver = new Super(TypePlaceholder.fresh(offset), offset);
isStatic = Modifier.isStatic(compiler.getClass(new JavaClassName(superClass.getName().toString())).getField(fieldName).orElseThrow().modifier); isStatic = Modifier.isStatic(compiler.getClass(new JavaClassName(superClass.getName().toString())).getField(fieldName).orElseThrow().modifier);
} else if (receiver == null) { // Handelt es sich um keinen Statischen Klassennamen: } else if (receiver == null) { // Handelt es sich um keinen Statischen Klassennamen:
String part = expression.substring(0, expression.length() - (1 + parts[parts.length - 1].length())); String part = expression.substring(0, expression.length() - (1 + parts[parts.length - 1].length()));

View File

@ -16,6 +16,7 @@ import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.Record; import de.dhbwstuttgart.syntaxtree.Record;
import de.dhbwstuttgart.syntaxtree.statement.*;
import org.antlr.v4.runtime.CommonToken; import org.antlr.v4.runtime.CommonToken;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
@ -66,15 +67,6 @@ import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry; import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.statement.Assign;
import de.dhbwstuttgart.syntaxtree.statement.AssignLeftSide;
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.statement.This;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
@ -100,7 +92,9 @@ public class SyntaxTreeGenerator {
private final JavaTXCompiler compiler; private final JavaTXCompiler compiler;
private RefType superClass; private RefType superClass;
public SyntaxTreeGenerator(JavaTXCompiler compiler, JavaClassRegistry reg, GenericsRegistry globalGenerics) { public final String fileName;
public SyntaxTreeGenerator(JavaTXCompiler compiler, JavaClassRegistry reg, GenericsRegistry globalGenerics, String fileName) {
// Die Generics müssen während des Bauens des AST erstellt werden, // Die Generics müssen während des Bauens des AST erstellt werden,
// da diese mit der Methode oder Klasse, in welcher sie deklariert werden // da diese mit der Methode oder Klasse, in welcher sie deklariert werden
// verknüpft sein müssen. Dennoch werden die Namen aller Generics in einer // verknüpft sein müssen. Dennoch werden die Namen aller Generics in einer
@ -125,6 +119,7 @@ public class SyntaxTreeGenerator {
this.allmodifiers.put("strictfp", 32768); this.allmodifiers.put("strictfp", 32768);
this.compiler = compiler; this.compiler = compiler;
this.fileName = fileName;
} }
public JavaClassRegistry getReg() { public JavaClassRegistry getReg() {
@ -234,7 +229,7 @@ public class SyntaxTreeGenerator {
} }
var ctor = Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), fieldInitializations, genericClassParameters, offset)); var ctor = Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), fieldInitializations, genericClassParameters, offset));
var staticCtor = Optional.of(this.generateStaticConstructor(ctx.identifier().getText(), staticFieldInitializations, genericClassParameters, offset)); var staticCtor = Optional.of(this.generateStaticConstructor(ctx.identifier().getText(), staticFieldInitializations, genericClassParameters, offset));
return new ClassOrInterface(modifiers, name, fielddecl, ctor, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, isFunctionalInterface, implementedInterfaces, permittedSubtypes, offset); return new ClassOrInterface(modifiers, name, fielddecl, ctor, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, isFunctionalInterface, implementedInterfaces, permittedSubtypes, offset, fileName);
} }
@ -280,8 +275,8 @@ public class SyntaxTreeGenerator {
methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset)); methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset));
} }
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), genericClassParameters, offset); RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), genericClassParameters, offset);
Constructor implicitConstructor = new Constructor(allmodifiers.get("public"), identifier, classType, new ParameterList(constructorParameters, offset), new Block(constructorStatements, offset), genericClassParameters, offset); Constructor implicitConstructor = new Constructor(allmodifiers.get("public"), identifier, classType, new ParameterList(constructorParameters, offset), prepareBlock(new Block(constructorStatements, offset), superClass), genericClassParameters, offset);
Optional<Constructor> initializations = Optional.of(implicitConstructor); //Optional<Constructor> initializations = Optional.of(implicitConstructor);
constructors.add(implicitConstructor); constructors.add(implicitConstructor);
for (ClassBodyDeclarationContext bodyDeclaration : recordDeclaration.recordBody().classBodyDeclaration()) { for (ClassBodyDeclarationContext bodyDeclaration : recordDeclaration.recordBody().classBodyDeclaration()) {
convert(bodyDeclaration, fielddecl, constructors, methods, name, superClass, generics); convert(bodyDeclaration, fielddecl, constructors, methods, name, superClass, generics);
@ -290,7 +285,7 @@ public class SyntaxTreeGenerator {
implementedInterfaces.addAll(convert(recordDeclaration.typeList(), generics)); implementedInterfaces.addAll(convert(recordDeclaration.typeList(), generics));
} }
var staticCtor = Optional.of(this.generateStaticConstructor(recordDeclaration.identifier().getText(), staticFieldInitializations, genericClassParameters, offset)); var staticCtor = Optional.of(this.generateStaticConstructor(recordDeclaration.identifier().getText(), staticFieldInitializations, genericClassParameters, offset));
return new Record(modifiers, name, fielddecl, initializations, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset); return new Record(modifiers, name, fielddecl, Optional.empty(), staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset, fileName);
} }
private void convert(ClassBodyDeclarationContext classBody, List<Field> fields, List<Constructor> constructors, List<Method> methods, JavaClassName name, RefType superClass, GenericsRegistry generics) { private void convert(ClassBodyDeclarationContext classBody, List<Field> fields, List<Constructor> constructors, List<Method> methods, JavaClassName name, RefType superClass, GenericsRegistry generics) {
@ -409,7 +404,7 @@ public class SyntaxTreeGenerator {
} }
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, methods.size() == 1 ? true : false, extendedInterfaces, permittedSubtypes, ctx.getStart()); 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) {
@ -451,18 +446,24 @@ public class SyntaxTreeGenerator {
return new Method(modifiers, name, retType, paramlist, block, gtvDeclarations, bodydeclaration.getStart()); return new Method(modifiers, name, retType, paramlist, block, gtvDeclarations, bodydeclaration.getStart());
} }
protected static Block prepareBlock(Block constructorBlock, RefType superClass) {
List<Statement> statements = constructorBlock.getStatements();
if (statements.isEmpty() || !(statements.get(0) instanceof SuperCall)) {
var signature = new ArrayList<RefTypeOrTPHOrWildcardOrGeneric>();
signature.add(new Void(new NullToken()));
statements.add(0, new SuperCall(superClass, signature, constructorBlock.getOffset()));
}
/* statements.addAll(fieldInitializations); geloescht PL 2018-11-24 */
return new Block(statements, constructorBlock.getOffset());
}
/** /**
* http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.9 * http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.9
*/ */
private Constructor generateStandardConstructor(String className, JavaClassName parentClass, RefType superClass, GenericDeclarationList classGenerics, Token offset) { private Constructor generateStandardConstructor(String className, JavaClassName parentClass, RefType superClass, GenericDeclarationList classGenerics, Token offset) {
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset); RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
ParameterList params = new ParameterList(new ArrayList<>(), offset); ParameterList params = new ParameterList(new ArrayList<>(), offset);
Block block = new Block(new ArrayList<>(), offset); return new Constructor(Modifier.PUBLIC, className, classType, params, prepareBlock(new Block(new ArrayList<>(), offset), superClass), classGenerics, offset); // fieldInitializations // 2018-11-24
//
//
return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset); // fieldInitializations
// geloescht PL
// 2018-11-24
} }
/* /*
@ -471,10 +472,7 @@ public class SyntaxTreeGenerator {
private Constructor generatePseudoConstructor(String className, List<Statement> initializations, GenericDeclarationList classGenerics, Token offset) { private Constructor generatePseudoConstructor(String className, List<Statement> initializations, GenericDeclarationList classGenerics, Token offset) {
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset); RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
ParameterList params = new ParameterList(new ArrayList<>(), offset); ParameterList params = new ParameterList(new ArrayList<>(), offset);
Block block = new Block(new ArrayList<>(initializations), offset); return new Constructor(Modifier.PUBLIC, className, classType, params, new Block(new ArrayList<>(initializations), offset), classGenerics, offset);
return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /*
* fieldInitializations geloescht PL 2018-11-24
*/);
} }
private Method generateStaticConstructor(String className, List<Statement> initializations, GenericDeclarationList classGenerics, Token offset) { private Method generateStaticConstructor(String className, List<Statement> initializations, GenericDeclarationList classGenerics, Token offset) {
@ -553,7 +551,7 @@ public class SyntaxTreeGenerator {
block = stmtgen.convert(methodblock.block(), true); block = stmtgen.convert(methodblock.block(), true);
} }
if (name.equals(parentClass.getClassName())) { if (name.equals(parentClass.getClassName())) {
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, methoddeclaration.getStart()); return new Constructor(modifiers, name, retType, paramlist, prepareBlock(block, superClass), gtvDeclarations, methoddeclaration.getStart());
} else { } else {
return new Method(modifiers, name, retType, paramlist, block, gtvDeclarations, methoddeclaration.getStart()); return new Method(modifiers, name, retType, paramlist, block, gtvDeclarations, methoddeclaration.getStart());
} }
@ -582,7 +580,7 @@ public class SyntaxTreeGenerator {
RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics); RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics);
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>()); StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList()); ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList());
Block block = stmtgen.convert(constructordeclaration.constructorBody, true); Block block = prepareBlock(stmtgen.convert(constructordeclaration.constructorBody, true), superClass);
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart()); return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart());
} }

View File

@ -31,7 +31,7 @@ public class JavaClassRegistry {
if (name.equals(new JavaClassName(className))) if (name.equals(new JavaClassName(className)))
return name; return name;
} }
throw new NotImplementedException(); throw new RuntimeException("Class " + className + " not found!");
} }
@Override @Override

View File

@ -166,6 +166,11 @@ public abstract class AbstractASTWalker implements ASTVisitor {
forStmt.block.accept(this); forStmt.block.accept(this);
} }
@Override
public void visit(ForEachStmt forEachStmt) {
forEachStmt.block.accept(this);
}
@Override @Override
public void visit(IfStmt ifStmt) { public void visit(IfStmt ifStmt) {
ifStmt.then_block.accept(this); ifStmt.then_block.accept(this);
@ -261,6 +266,11 @@ public abstract class AbstractASTWalker implements ASTVisitor {
} }
@Override
public void visit(Throw aThrow) {
}
@Override @Override
public void visit(AssignToField assignLeftSide) { public void visit(AssignToField assignLeftSide) {
assignLeftSide.field.accept(this); assignLeftSide.field.accept(this);

View File

@ -21,6 +21,8 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
private Boolean methodAdded = false; // wird benoetigt bei in JavaTXCompiler.getConstraints() private Boolean methodAdded = false; // wird benoetigt bei in JavaTXCompiler.getConstraints()
protected int modifiers; protected int modifiers;
protected JavaClassName name; protected JavaClassName name;
private final String fileName;
private List<Field> fields = new ArrayList<>(); private List<Field> fields = new ArrayList<>();
private Optional<Constructor> fieldInitializations; // PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen private Optional<Constructor> fieldInitializations; // PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen
private Optional<Method> staticInitializer; private Optional<Method> staticInitializer;
@ -33,7 +35,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
private List<RefType> permittedSubtypes; private List<RefType> permittedSubtypes;
private List<Constructor> constructors; private List<Constructor> constructors;
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, Boolean isFunctionalInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset) { public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, Boolean isFunctionalInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset, String fileName) {
super(offset); super(offset);
if (isInterface) { if (isInterface) {
modifiers |= Modifier.INTERFACE | Modifier.ABSTRACT; modifiers |= Modifier.INTERFACE | Modifier.ABSTRACT;
@ -51,6 +53,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
this.permittedSubtypes = permittedSubtypes; this.permittedSubtypes = permittedSubtypes;
this.methods = methods; this.methods = methods;
this.constructors = constructors; this.constructors = constructors;
this.fileName = fileName;
} }
/* /*
@ -70,6 +73,11 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
this.implementedInterfaces = cl.implementedInterfaces; this.implementedInterfaces = cl.implementedInterfaces;
this.methods = new ArrayList<>(cl.methods); this.methods = new ArrayList<>(cl.methods);
this.constructors = new ArrayList<>(cl.constructors); this.constructors = new ArrayList<>(cl.constructors);
this.fileName = cl.fileName;
}
public String getFileName() {
return fileName;
} }
public Optional<Field> getField(String name) { public Optional<Field> getField(String name) {

View File

@ -1,31 +1,25 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.statement.Statement; import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.statement.Super;
import de.dhbwstuttgart.syntaxtree.statement.SuperCall; import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.Void;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.statement.Block; import de.dhbwstuttgart.syntaxtree.statement.Block;
import java.sql.Ref;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class Constructor extends Method { public class Constructor extends Method {
// TODO: Constructor braucht ein super-Statement // TODO: Constructor braucht ein super-Statement
public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList parameterList, Block codeInsideConstructor, GenericDeclarationList gtvDeclarations, Token offset /* , List<Statement> fieldInitializations geloescht PL 2018-11-24 */) { public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList parameterList, Block codeInsideConstructor, GenericDeclarationList gtvDeclarations, Token offset) {
super(modifier, name, returnType, parameterList, /* codeInsideConstructor, */ prepareBlock(codeInsideConstructor) /* ,fieldInitializations )geloescht PL 2018-11-24 ) */, gtvDeclarations, offset); super(modifier, name, returnType, parameterList, codeInsideConstructor, gtvDeclarations, offset);
}
/**
* @param fieldInitializations - Das sind die Statements, welche die Felder der zugehörigen Klasse dieses Konstruktor initialisieren
*/
protected static Block prepareBlock(Block constructorBlock /* , List<Statement> fieldInitializations new ArrayList<>() geloescht PL 2018-11-24 */) {
List<Statement> statements = constructorBlock.getStatements();
statements.add(0, new SuperCall(null, null, constructorBlock.getOffset()));
/* statements.addAll(fieldInitializations); geloescht PL 2018-11-24 */
return new Block(statements, constructorBlock.getOffset());
} }
@Override @Override

View File

@ -13,7 +13,7 @@ import javax.swing.text.html.Option;
public class Record extends ClassOrInterface { public class Record extends ClassOrInterface {
public Record(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset) { public Record(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset, String fileName) {
super(modifiers, name, fielddecl, fieldInitializations, staticInitializer, methods, constructors, genericClassParameters, superClass, isInterface, methods.size() == 1 ? true : false, implementedInterfaces, new ArrayList<>(), offset); super(modifiers, name, fielddecl, fieldInitializations, staticInitializer, methods, constructors, genericClassParameters, superClass, isInterface, methods.size() == 1 ? true : false, implementedInterfaces, new ArrayList<>(), offset, fileName);
} }
} }

View File

@ -25,6 +25,8 @@ public interface StatementVisitor {
void visit(ForStmt forStmt); void visit(ForStmt forStmt);
void visit(ForEachStmt forEachStmt);
void visit(IfStmt ifStmt); void visit(IfStmt ifStmt);
void visit(InstanceOf instanceOf); void visit(InstanceOf instanceOf);
@ -74,4 +76,6 @@ public interface StatementVisitor {
void visit(UnaryExpr unaryExpr); void visit(UnaryExpr unaryExpr);
void visit(Literal literal); void visit(Literal literal);
void visit(Throw aThrow);
} }

View File

@ -148,7 +148,7 @@ public class ASTFactory {
Token offset = new NullToken(); // Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde Token offset = new NullToken(); // Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
var cinf = new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */, Optional.empty(), methoden, konstruktoren, genericDeclarationList, superClass, isInterface, isFunctionalInterface, implementedInterfaces, permittedSubtypes, offset); var cinf = new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */, Optional.empty(), methoden, konstruktoren, genericDeclarationList, superClass, isInterface, isFunctionalInterface, implementedInterfaces, permittedSubtypes, offset, null);
cache.put(jreClass, cinf); cache.put(jreClass, cinf);
return cinf; return cinf;
} }
@ -361,7 +361,7 @@ public class ASTFactory {
} else if (type.getTypeName().equals("boolean")) { } else if (type.getTypeName().equals("boolean")) {
return new RefType(new JavaClassName("java.lang.Boolean"), new ArrayList<>(), new NullToken(), true); return new RefType(new JavaClassName("java.lang.Boolean"), new ArrayList<>(), new NullToken(), true);
} else if (type.getTypeName().equals("char")) { } else if (type.getTypeName().equals("char")) {
return new RefType(new JavaClassName("java.lang.Char"), new ArrayList<>(), new NullToken(), true); return new RefType(new JavaClassName("java.lang.Character"), new ArrayList<>(), new NullToken(), true);
} else if (type.getTypeName().equals("short")) { } else if (type.getTypeName().equals("short")) {
return new RefType(new JavaClassName("java.lang.Short"), new ArrayList<>(), new NullToken(), true); return new RefType(new JavaClassName("java.lang.Short"), new ArrayList<>(), new NullToken(), true);
} else if (type.getTypeName().equals("double")) { } else if (type.getTypeName().equals("double")) {

View File

@ -1,6 +1,5 @@
package de.dhbwstuttgart.syntaxtree.factory; package de.dhbwstuttgart.syntaxtree.factory;
import java.io.FileWriter;
import java.io.Writer; import java.io.Writer;
import java.util.*; import java.util.*;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -9,13 +8,13 @@ import java.util.stream.Collectors;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SourceLoc;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.syntaxtree.type.WildcardType; import de.dhbwstuttgart.syntaxtree.type.WildcardType;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.PairNoResult; import de.dhbwstuttgart.typeinference.result.PairNoResult;
@ -24,6 +23,7 @@ import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType;
import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH; import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH;
import de.dhbwstuttgart.typeinference.result.ResultPair; import de.dhbwstuttgart.typeinference.result.ResultPair;
import de.dhbwstuttgart.typeinference.unify.model.*; import de.dhbwstuttgart.typeinference.unify.model.*;
import org.antlr.v4.runtime.Token;
public class UnifyTypeFactory { public class UnifyTypeFactory {
@ -43,20 +43,20 @@ public class UnifyTypeFactory {
return new FiniteClosure(FCGenerator.toUnifyFC(fromClasses, classLoader), logFile); return new FiniteClosure(FCGenerator.toUnifyFC(fromClasses, classLoader), logFile);
} }
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){ public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr, SourceLoc location){
return new UnifyPair(tl, tr, PairOperator.SMALLER); return new UnifyPair(tl, tr, PairOperator.SMALLER, location);
} }
public static UnifyPair generateSmallerDotPair(UnifyType tl, UnifyType tr){ public static UnifyPair generateSmallerDotPair(UnifyType tl, UnifyType tr, SourceLoc location){
return new UnifyPair(tl, tr, PairOperator.SMALLERDOT); return new UnifyPair(tl, tr, PairOperator.SMALLERDOT, location);
} }
public static UnifyPair generateSmallNotEqualDotPair(UnifyType tl, UnifyType tr){ public static UnifyPair generateSmallNotEqualDotPair(UnifyType tl, UnifyType tr, SourceLoc location){
return new UnifyPair(tl, tr, PairOperator.SMALLERNEQDOT); return new UnifyPair(tl, tr, PairOperator.SMALLERNEQDOT, location);
} }
public static UnifyPair generateEqualDotPair(UnifyType tl, UnifyType tr){ public static UnifyPair generateEqualDotPair(UnifyType tl, UnifyType tr, SourceLoc location){
return new UnifyPair(tl, tr, PairOperator.EQUALSDOT); return new UnifyPair(tl, tr, PairOperator.EQUALSDOT, location);
} }
/** /**
@ -164,19 +164,19 @@ public class UnifyTypeFactory {
UnifyPair ret = null; UnifyPair ret = null;
if(p.GetOperator().equals(PairOperator.SMALLERDOT)) { if(p.GetOperator().equals(PairOperator.SMALLERDOT)) {
ret = generateSmallerDotPair(UnifyTypeFactory.convert(p.TA1, false) ret = generateSmallerDotPair(UnifyTypeFactory.convert(p.TA1, false)
, UnifyTypeFactory.convert(p.TA2, false)); , UnifyTypeFactory.convert(p.TA2, false), p.getLocation());
//return ret; //return ret;
}else if(p.GetOperator().equals(PairOperator.SMALLERNEQDOT)) { }else if(p.GetOperator().equals(PairOperator.SMALLERNEQDOT)) {
ret = generateSmallNotEqualDotPair(UnifyTypeFactory.convert(p.TA1, false) ret = generateSmallNotEqualDotPair(UnifyTypeFactory.convert(p.TA1, false)
, UnifyTypeFactory.convert(p.TA2, false)); , UnifyTypeFactory.convert(p.TA2, false), p.getLocation());
//return ret; //return ret;
}else if(p.GetOperator().equals(PairOperator.EQUALSDOT)) { }else if(p.GetOperator().equals(PairOperator.EQUALSDOT)) {
ret = generateEqualDotPair(UnifyTypeFactory.convert(p.TA1, false) ret = generateEqualDotPair(UnifyTypeFactory.convert(p.TA1, false)
, UnifyTypeFactory.convert(p.TA2, false)); , UnifyTypeFactory.convert(p.TA2, false), p.getLocation());
//return ret; //return ret;
}else if(p.GetOperator().equals(PairOperator.SMALLER)){ }else if(p.GetOperator().equals(PairOperator.SMALLER)){
ret = generateSmallerPair(UnifyTypeFactory.convert(p.TA1, false), ret = generateSmallerPair(UnifyTypeFactory.convert(p.TA1, false),
UnifyTypeFactory.convert(p.TA2, false)); UnifyTypeFactory.convert(p.TA2, false), p.getLocation());
}else throw new NotImplementedException(); }else throw new NotImplementedException();
UnifyType lhs, rhs; UnifyType lhs, rhs;
if (((lhs = ret.getLhsType()) instanceof PlaceholderType) if (((lhs = ret.getLhsType()) instanceof PlaceholderType)

View File

@ -0,0 +1,26 @@
package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.Void;
import org.antlr.v4.runtime.Token;
public class ForEachStmt extends Statement {
public final Statement statement;
public final Expression expression;
public final Statement block;
public ForEachStmt(Token offset, Statement stmt, Expression expression, Statement block) {
super(new Void(new NullToken()), offset);
this.statement = stmt;
this.expression = expression;
this.block = block;
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -37,6 +37,7 @@ public class MethodCall extends Statement
this.receiver = receiver; this.receiver = receiver;
this.receiverType = receiverType; this.receiverType = receiverType;
this.signature = signature; this.signature = signature;
if (signature == null) throw new NullPointerException();
} }
public List<RefTypeOrTPHOrWildcardOrGeneric> signatureArguments() { public List<RefTypeOrTPHOrWildcardOrGeneric> signatureArguments() {

View File

@ -1,6 +1,9 @@
package de.dhbwstuttgart.syntaxtree.statement; package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
@ -9,9 +12,9 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
public class Super extends Expression public class Super extends Expression
{ {
public Super(Token offset) public Super(RefTypeOrTPHOrWildcardOrGeneric type, Token offset)
{ {
super(null,null); super(type, offset);
} }
@Override @Override

View File

@ -1,5 +1,6 @@
package de.dhbwstuttgart.syntaxtree.statement; package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
@ -9,6 +10,7 @@ import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public class SuperCall extends MethodCall public class SuperCall extends MethodCall
@ -20,7 +22,7 @@ public class SuperCall extends MethodCall
public SuperCall(ArgumentList argumentList, RefTypeOrTPHOrWildcardOrGeneric receiverType, public SuperCall(ArgumentList argumentList, RefTypeOrTPHOrWildcardOrGeneric receiverType,
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes, Token offset){ ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes, Token offset){
super(new Void(offset), new ExpressionReceiver(new This(offset)), "<init>", argumentList, receiverType, argTypes, offset); super(new Void(offset), new ExpressionReceiver(new Super(receiverType, offset)), "<init>", argumentList, receiverType, argTypes, offset);
} }

View File

@ -0,0 +1,21 @@
package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.Void;
import org.antlr.v4.runtime.Token;
public class Throw extends Statement {
public final Expression expr;
public Throw(Expression expr, Token offset) {
super(new Void(offset), offset);
this.expr = expr;
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -244,6 +244,11 @@ public class OutputGenerator implements ASTVisitor {
} }
@Override
public void visit(ForEachStmt forEachStmt) {
}
@Override @Override
public void visit(IfStmt ifStmt) { public void visit(IfStmt ifStmt) {
out.append("if("); out.append("if(");
@ -402,6 +407,11 @@ public class OutputGenerator implements ASTVisitor {
out.append(literal.value); out.append(literal.value);
} }
@Override
public void visit(Throw aThrow) {
// TODO implement
}
@Override @Override
public void visit(Switch switchStmt) { public void visit(Switch switchStmt) {
out.append("switch("); out.append("switch(");

View File

@ -380,6 +380,13 @@ public class ASTToTargetAST {
return new TargetBlock(block.statements.stream().map(this::convert).toList()); return new TargetBlock(block.statements.stream().map(this::convert).toList());
} }
protected TargetBlock convertWrapInBlock(Expression expression) {
var res = convert(expression);
if (!(res instanceof TargetBlock))
return new TargetBlock(List.of(res));
return (TargetBlock) res;
}
protected TargetExpression convert(Expression expr) { protected TargetExpression convert(Expression expr) {
var converter = new StatementToTargetExpression(this); var converter = new StatementToTargetExpression(this);
expr.accept(converter); expr.accept(converter);

View File

@ -141,12 +141,22 @@ public class StatementToTargetExpression implements ASTVisitor {
@Override @Override
public void visit(ForStmt forStmt) { public void visit(ForStmt forStmt) {
result = new TargetFor(forStmt.initializer.stream().map(converter::convert).toList(), converter.convert(forStmt.condition), forStmt.loopExpr.stream().map(converter::convert).toList(), converter.convert(forStmt.block)); result = new TargetFor(
forStmt.initializer.stream().map(converter::convert).toList(),
forStmt.condition != null ? converter.convert(forStmt.condition) : null,
forStmt.loopExpr.stream().map(converter::convert).toList(),
converter.convertWrapInBlock(forStmt.block)
);
}
@Override
public void visit(ForEachStmt forEachStmt) {
result = new TargetForEach(converter.convert(forEachStmt.statement), converter.convert(forEachStmt.expression), converter.convertWrapInBlock(forEachStmt.block));
} }
@Override @Override
public void visit(IfStmt ifStmt) { public void visit(IfStmt ifStmt) {
result = new TargetIf(converter.convert(ifStmt.expr), converter.convert(ifStmt.then_block), ifStmt.else_block != null ? converter.convert(ifStmt.else_block) : null); result = new TargetIf(converter.convert(ifStmt.expr), converter.convertWrapInBlock(ifStmt.then_block), ifStmt.else_block != null ? converter.convertWrapInBlock(ifStmt.else_block) : null);
} }
@Override @Override
@ -315,9 +325,16 @@ public class StatementToTargetExpression implements ASTVisitor {
result = new TargetLiteral.StringLiteral((String) literal.value); result = new TargetLiteral.StringLiteral((String) literal.value);
} else if (literal.value instanceof Boolean) { } else if (literal.value instanceof Boolean) {
result = new TargetLiteral.BooleanLiteral((boolean) literal.value); result = new TargetLiteral.BooleanLiteral((boolean) literal.value);
} else if (literal.value == null) {
result = new TargetLiteral.Null();
} }
} }
@Override
public void visit(Throw aThrow) {
result = new TargetThrow(converter.convert(aThrow.expr));
}
@Override @Override
public void visit(Switch switchStmt) { public void visit(Switch switchStmt) {
var cases = switchStmt.getBlocks().stream().filter(s -> !s.isDefault()).map(converter::convert).toList(); var cases = switchStmt.getBlocks().stream().filter(s -> !s.isDefault()).map(converter::convert).toList();

View File

@ -66,6 +66,11 @@ public abstract class TracingStatementVisitor implements StatementVisitor {
forStmt.block.accept(this); forStmt.block.accept(this);
} }
@Override
public void visit(ForEachStmt forEachStmt) {
forEachStmt.block.accept(this);
}
@Override @Override
public void visit(IfStmt ifStmt) { public void visit(IfStmt ifStmt) {
ifStmt.then_block.accept(this); ifStmt.then_block.accept(this);
@ -168,6 +173,11 @@ public abstract class TracingStatementVisitor implements StatementVisitor {
} }
@Override
public void visit(Throw aThrow) {
}
@Override @Override
public void visit(Switch switchStmt) { public void visit(Switch switchStmt) {

View File

@ -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, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetPattern, TargetTernary, TargetThis, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield { permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetPattern, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetTernary, TargetThis, TargetThrow, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield {
default TargetType type() { default TargetType type() {
return null; return null;

View File

@ -1,4 +1,4 @@
package de.dhbwstuttgart.target.tree.expression; package de.dhbwstuttgart.target.tree.expression;
public record TargetForEach(TargetExpression vardecl, TargetExpression list) implements TargetExpression { public record TargetForEach(TargetExpression vardecl, TargetExpression expression, TargetExpression body) implements TargetExpression {
} }

View File

@ -53,4 +53,16 @@ public sealed interface TargetLiteral extends TargetExpression {
return TargetType.String; return TargetType.String;
} }
} }
record Null() implements TargetLiteral {
@Override
public TargetType type() {
return TargetType.Object;
}
@Override
public Object value() {
return null;
}
}
} }

View File

@ -0,0 +1,4 @@
package de.dhbwstuttgart.target.tree.expression;
public record TargetThrow(TargetExpression expr) implements TargetExpression {
}

View File

@ -22,7 +22,7 @@ import java.util.Optional;
public class FunNClass extends ClassOrInterface { public class FunNClass extends ClassOrInterface {
public FunNClass(List<GenericRefType> funNParams) { public FunNClass(List<GenericRefType> funNParams) {
super(0, new JavaClassName("Fun" + (funNParams.size() - 1)), new ArrayList<>(), Optional.empty(), Optional.empty() /* eingefuegt PL 2018-11-24 */, createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams), ASTFactory.createObjectType(), true, false, new ArrayList<>(), new ArrayList<>(), new NullToken()); super(0, new JavaClassName("Fun" + (funNParams.size() - 1)), new ArrayList<>(), Optional.empty(), Optional.empty() /* eingefuegt PL 2018-11-24 */, createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams), ASTFactory.createObjectType(), true, false, new ArrayList<>(), new ArrayList<>(), new NullToken(), null);
} }

View File

@ -8,6 +8,7 @@ import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.constraints.GenericsResolver; import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
import java.util.ArrayList; import java.util.ArrayList;
@ -66,6 +67,7 @@ public class MethodAssumption extends Assumption{
* @return * @return
*/ */
public RefTypeOrTPHOrWildcardOrGeneric getReceiverType(GenericsResolver resolver) { public RefTypeOrTPHOrWildcardOrGeneric getReceiverType(GenericsResolver resolver) {
if (receiver == null) return null;
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar gtv : receiver.getGenerics()){ for(GenericTypeVar gtv : receiver.getGenerics()){
//Die Generics werden alle zu TPHs umgewandelt. //Die Generics werden alle zu TPHs umgewandelt.

View File

@ -3,9 +3,12 @@ import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SourceLoc;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import org.antlr.v4.runtime.Token;
public class Pair implements Serializable public class Pair implements Serializable
@ -13,11 +16,13 @@ public class Pair implements Serializable
public final RefTypeOrTPHOrWildcardOrGeneric TA1; public final RefTypeOrTPHOrWildcardOrGeneric TA1;
public final RefTypeOrTPHOrWildcardOrGeneric TA2; public final RefTypeOrTPHOrWildcardOrGeneric TA2;
private SourceLoc location;
private PairOperator eOperator = PairOperator.SMALLER; private PairOperator eOperator = PairOperator.SMALLER;
private Boolean noUnification = false; private Boolean noUnification = false;
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2 ) private Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2 )
{ {
this.TA1 = TA1; this.TA1 = TA1;
this.TA2 = TA2; this.TA2 = TA2;
@ -32,7 +37,11 @@ public class Pair implements Serializable
this(TA1,TA2); this(TA1,TA2);
this.eOperator = eOp; this.eOperator = eOp;
} }
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator e0p, SourceLoc location) {
this(TA1, TA2, e0p);
this.location = location;
}
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, Boolean noUnification) public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, Boolean noUnification)
{ {
@ -41,6 +50,10 @@ public class Pair implements Serializable
this.eOperator = eOp; this.eOperator = eOp;
this.noUnification = noUnification; this.noUnification = noUnification;
} }
public SourceLoc getLocation() {
return this.location;
}
public String toString() public String toString()
{ {

View File

@ -7,6 +7,7 @@ import java.util.stream.Collectors;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SourceLoc;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
@ -28,6 +29,7 @@ import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.GenericsResolver; import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import org.antlr.v4.runtime.Token;
public class TYPEStmt implements StatementVisitor { public class TYPEStmt implements StatementVisitor {
@ -43,6 +45,10 @@ public class TYPEStmt implements StatementVisitor {
return constraintsSet; return constraintsSet;
} }
private SourceLoc loc(Token token) {
return new SourceLoc(info.getCurrentClass().getFileName(), token.getLine());
};
/** /**
* Erstellt einen neuen GenericResolver Die Idee dieser Datenstruktur ist es, GTVs einen eindeutigen TPH zuzuweisen. Bei Methodenaufrufen oder anderen Zugriffen, bei denen alle benutzten GTVs jeweils einen einheitlichen TPH bekommen müssen kann diese Klasse eingesetzt werden. Wichtig ist, dass hierfür jeweils eine frische Instanz benutzt wird. * Erstellt einen neuen GenericResolver Die Idee dieser Datenstruktur ist es, GTVs einen eindeutigen TPH zuzuweisen. Bei Methodenaufrufen oder anderen Zugriffen, bei denen alle benutzten GTVs jeweils einen einheitlichen TPH bekommen müssen kann diese Klasse eingesetzt werden. Wichtig ist, dass hierfür jeweils eine frische Instanz benutzt wird.
* *
@ -71,8 +77,8 @@ public class TYPEStmt implements StatementVisitor {
// lambdaParams.add(0,tphRetType); // lambdaParams.add(0,tphRetType);
constraintsSet.addUndConstraint(new Pair(lambdaExpression.getType(), new RefType(new JavaClassName("Fun" + (lambdaParams.size() - 1) + "$$"), lambdaParams, new NullToken()), constraintsSet.addUndConstraint(new Pair(lambdaExpression.getType(), new RefType(new JavaClassName("Fun" + (lambdaParams.size() - 1) + "$$"), lambdaParams, new NullToken()),
// new FunN(lambdaParams), // new FunN(lambdaParams),
PairOperator.EQUALSDOT)); PairOperator.EQUALSDOT, loc(lambdaExpression.getOffset())));
constraintsSet.addUndConstraint(new Pair(lambdaExpression.getReturnType(), tphRetType, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(lambdaExpression.getReturnType(), tphRetType, PairOperator.EQUALSDOT, loc(lambdaExpression.getOffset())));
// Constraints des Bodys generieren: // Constraints des Bodys generieren:
TYPEStmt lambdaScope = new TYPEStmt(new TypeInferenceBlockInformation(info, lambdaExpression)); TYPEStmt lambdaScope = new TYPEStmt(new TypeInferenceBlockInformation(info, lambdaExpression));
@ -84,7 +90,7 @@ public class TYPEStmt implements StatementVisitor {
public void visit(Assign assign) { public void visit(Assign assign) {
assign.lefSide.accept(this); assign.lefSide.accept(this);
assign.rightSide.accept(this); assign.rightSide.accept(this);
constraintsSet.addUndConstraint(new Pair(assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT)); constraintsSet.addUndConstraint(new Pair(assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT, loc(assign.getOffset())));
} }
@Override @Override
@ -111,8 +117,8 @@ public class TYPEStmt implements StatementVisitor {
for (FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)) { for (FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)) {
Constraint constraint = new Constraint(); Constraint constraint = new Constraint();
GenericsResolver resolver = getResolverInstance(); GenericsResolver resolver = getResolverInstance();
constraint.add(new Pair(fieldVar.receiver.getType(), fieldAssumption.getReceiverType(resolver), PairOperator.SMALLERDOT)); // PL 2019-12-09: SMALLERDOT eingefuegt, EQUALSDOT entfernt, wenn ds Field privat ist muesste es EQUALSDOT lauten constraint.add(new Pair(fieldVar.receiver.getType(), fieldAssumption.getReceiverType(resolver), PairOperator.SMALLERDOT, loc(fieldVar.getOffset()))); // PL 2019-12-09: SMALLERDOT eingefuegt, EQUALSDOT entfernt, wenn ds Field privat ist muesste es EQUALSDOT lauten
constraint.add(new Pair(fieldVar.getType(), fieldAssumption.getType(resolver), PairOperator.EQUALSDOT)); constraint.add(new Pair(fieldVar.getType(), fieldAssumption.getType(resolver), PairOperator.EQUALSDOT, loc(fieldVar.getOffset())));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (oderConstraints.size() == 0) if (oderConstraints.size() == 0)
@ -123,32 +129,42 @@ public class TYPEStmt implements StatementVisitor {
@Override @Override
public void visit(ForStmt forStmt) { public void visit(ForStmt forStmt) {
forStmt.initializer.forEach(s -> s.accept(this)); forStmt.initializer.forEach(s -> s.accept(this));
forStmt.condition.accept(this); if (forStmt.condition != null)
forStmt.condition.accept(this);
forStmt.loopExpr.forEach(e -> e.accept(this)); forStmt.loopExpr.forEach(e -> e.accept(this));
forStmt.block.accept(this); forStmt.block.accept(this);
} }
@Override
public void visit(ForEachStmt forEachStmt) {
var iterableType = new RefType(ASTFactory.createClass(java.lang.Iterable.class).getClassName(), Arrays.asList(forEachStmt.statement.getType()), new NullToken());
constraintsSet.addUndConstraint(new Pair(forEachStmt.expression.getType(), iterableType, PairOperator.SMALLERDOT, loc(forEachStmt.getOffset())));
forEachStmt.statement.accept(this);
forEachStmt.expression.accept(this);
forEachStmt.block.accept(this);
}
@Override @Override
public void visit(IfStmt ifStmt) { public void visit(IfStmt ifStmt) {
RefType booleanType = new RefType(ASTFactory.createClass(java.lang.Boolean.class).getClassName(), new NullToken()); RefType booleanType = new RefType(ASTFactory.createClass(java.lang.Boolean.class).getClassName(), new NullToken());
// Expression inferieren: // Expression inferieren:
ifStmt.expr.accept(this); ifStmt.expr.accept(this);
// Expression muss boolean sein: // Expression muss boolean sein:
constraintsSet.addUndConstraint(new Pair(ifStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(ifStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT, loc(ifStmt.getOffset())));
// Blöcke inferieren: // Blöcke inferieren:
ifStmt.then_block.accept(this); ifStmt.then_block.accept(this);
// Beide Blöcke müssen den gleichen Supertyp haben, welcher den Rückgabetyp des If-Stmts darstellt // Beide Blöcke müssen den gleichen Supertyp haben, welcher den Rückgabetyp des If-Stmts darstellt
//constraintsSet.addUndConstraint(new Pair(ifStmt.else_block.getType(), ifStmt.getType(), PairOperator.SMALLERDOT)); //constraintsSet.addUndConstraint(new Pair(ifStmt.else_block.getType(), ifStmt.getType(), PairOperator.SMALLERDOT));
if (ifStmt.else_block != null) { if (ifStmt.else_block != null) {
ifStmt.else_block.accept(this); ifStmt.else_block.accept(this);
constraintsSet.addUndConstraint(new Pair(ifStmt.else_block.getType(), ifStmt.getType(), PairOperator.SMALLERDOT)); constraintsSet.addUndConstraint(new Pair(ifStmt.else_block.getType(), ifStmt.getType(), PairOperator.SMALLERDOT, loc(ifStmt.getOffset())));
} }
} }
@Override @Override
public void visit(InstanceOf instanceOf) { public void visit(InstanceOf instanceOf) {
//throw new NotImplementedException(); instanceOf.getExpression().accept(this);
} }
@Override @Override
@ -217,15 +233,17 @@ public class TYPEStmt implements StatementVisitor {
private final RefType doublee = new RefType(ASTFactory.createClass(Double.class).getClassName(), new NullToken()); private final RefType doublee = new RefType(ASTFactory.createClass(Double.class).getClassName(), new NullToken());
private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken()); private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken());
private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken()); private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken());
private final RefType charr = new RefType(ASTFactory.createClass(Character.class).getClassName(), new NullToken());
@Override @Override
public void visit(UnaryExpr unaryExpr) { public void visit(UnaryExpr unaryExpr) {
if (unaryExpr.operation == UnaryExpr.Operation.POSTDECREMENT || unaryExpr.operation == UnaryExpr.Operation.POSTINCREMENT || unaryExpr.operation == UnaryExpr.Operation.PREDECREMENT || unaryExpr.operation == UnaryExpr.Operation.PREINCREMENT) { if (unaryExpr.operation == UnaryExpr.Operation.POSTDECREMENT || unaryExpr.operation == UnaryExpr.Operation.POSTINCREMENT || unaryExpr.operation == UnaryExpr.Operation.PREDECREMENT || unaryExpr.operation == UnaryExpr.Operation.PREINCREMENT) {
// @see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2 // @see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2
// Expression muss zu Numeric Convertierbar sein. also von Numeric erben // Expression muss zu Numeric Convertierbar sein. also von Numeric erben
constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), number, PairOperator.SMALLERNEQDOT)); constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), number, PairOperator.SMALLERNEQDOT, loc(unaryExpr.getOffset())));
// The type of the postfix increment expression is the type of the variable // The type of the postfix increment expression is the type of the variable
constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), unaryExpr.getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), unaryExpr.getType(), PairOperator.EQUALSDOT, loc(unaryExpr.getOffset())));
} else { } else {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -252,49 +270,49 @@ public class TYPEStmt implements StatementVisitor {
// PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(bytee.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(bytee.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT)); numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT, loc(binary.getOffset())));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
// PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(shortt.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(shortt.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT)); numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT, loc(binary.getOffset())));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
// PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(integer.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(integer.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(integer, binary.getType(), PairOperator.EQUALSDOT)); numeric.add(new Pair(integer, binary.getType(), PairOperator.EQUALSDOT, loc(binary.getOffset())));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
// PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(longg.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(longg.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(longg, binary.getType(), PairOperator.EQUALSDOT)); numeric.add(new Pair(longg, binary.getType(), PairOperator.EQUALSDOT, loc(binary.getOffset())));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
// PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(floatt.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(floatt.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(floatt, binary.getType(), PairOperator.EQUALSDOT)); numeric.add(new Pair(floatt, binary.getType(), PairOperator.EQUALSDOT, loc(binary.getOffset())));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
// PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(doublee.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(doublee.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(doublee, binary.getType(), PairOperator.EQUALSDOT)); numeric.add(new Pair(doublee, binary.getType(), PairOperator.EQUALSDOT, loc(binary.getOffset())));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
/* /*
@ -307,9 +325,9 @@ public class TYPEStmt implements StatementVisitor {
// Dann kann der Ausdruck auch das aneinanderfügen zweier Strings sein: ("a" + "b") oder (1 + 2) // Dann kann der Ausdruck auch das aneinanderfügen zweier Strings sein: ("a" + "b") oder (1 + 2)
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(string.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(string.getName())) {
Constraint<Pair> stringConcat = new Constraint<>(); Constraint<Pair> stringConcat = new Constraint<>();
stringConcat.add(new Pair(binary.lexpr.getType(), string, PairOperator.EQUALSDOT)); stringConcat.add(new Pair(binary.lexpr.getType(), string, PairOperator.EQUALSDOT, loc(binary.getOffset())));
stringConcat.add(new Pair(binary.rexpr.getType(), string, PairOperator.EQUALSDOT)); stringConcat.add(new Pair(binary.rexpr.getType(), string, PairOperator.EQUALSDOT, loc(binary.getOffset())));
stringConcat.add(new Pair(string, binary.getType(), PairOperator.EQUALSDOT)); stringConcat.add(new Pair(string, binary.getType(), PairOperator.EQUALSDOT, loc(binary.getOffset())));
numericAdditionOrStringConcatenation.add(stringConcat); numericAdditionOrStringConcatenation.add(stringConcat);
} }
} }
@ -328,10 +346,10 @@ public class TYPEStmt implements StatementVisitor {
*/ */
// Testeise eingefuegt PL 2018-05-24 // Testeise eingefuegt PL 2018-05-24
// Hier sollte evtl. noch importe angefragt werden PL 2019-05-07 // Hier sollte evtl. noch importe angefragt werden PL 2019-05-07
constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERNEQDOT)); constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERNEQDOT, loc(binary.getOffset())));
constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERNEQDOT)); constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERNEQDOT, loc(binary.getOffset())));
// Rückgabetyp ist Boolean // Rückgabetyp ist Boolean
constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT, loc(binary.getOffset())));
// auskommentiert PL 2018-05-24 // auskommentiert PL 2018-05-24
// constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERDOT)); // constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERDOT));
@ -343,7 +361,7 @@ public class TYPEStmt implements StatementVisitor {
* Auszug aus https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.21 The equality operators may be used to compare two operands that are convertible (§5.1.8) to numeric type, or two operands of type boolean or Boolean, or two operands that are each of either reference type or the null type. All other cases result in a compile-time error. * Auszug aus https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.21 The equality operators may be used to compare two operands that are convertible (§5.1.8) to numeric type, or two operands of type boolean or Boolean, or two operands that are each of either reference type or the null type. All other cases result in a compile-time error.
*/ */
// Der Equals Operator geht mit fast allen Typen, daher werden hier keine Constraints gesetzt // Der Equals Operator geht mit fast allen Typen, daher werden hier keine Constraints gesetzt
constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT, loc(binary.getOffset())));
} else { } else {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -352,9 +370,9 @@ public class TYPEStmt implements StatementVisitor {
@Override @Override
public void visit(BoolExpression expr) { public void visit(BoolExpression expr) {
constraintsSet.addUndConstraint(new Pair(bool, expr.getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(bool, expr.getType(), PairOperator.EQUALSDOT, loc(expr.getOffset())));
constraintsSet.addUndConstraint(new Pair(bool, expr.lexpr.getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(bool, expr.lexpr.getType(), PairOperator.EQUALSDOT, loc(expr.getOffset())));
constraintsSet.addUndConstraint(new Pair(bool, expr.rexpr.getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(bool, expr.rexpr.getType(), PairOperator.EQUALSDOT, loc(expr.getOffset())));
// TODO // TODO
return; return;
@ -367,23 +385,23 @@ public class TYPEStmt implements StatementVisitor {
// wie hier fuer double gezeigt. Im Momment auskommentiert, weil zu wenige Literaltypen // wie hier fuer double gezeigt. Im Momment auskommentiert, weil zu wenige Literaltypen
// funktionieren // funktionieren
if (literal.value instanceof Short) { if (literal.value instanceof Short) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT, loc(literal.getOffset())));
return; return;
} }
if (literal.value instanceof Byte) { if (literal.value instanceof Byte) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT, loc(literal.getOffset())));
return; return;
} }
if (literal.value instanceof Float) { if (literal.value instanceof Float) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT, loc(literal.getOffset())));
return; return;
} }
if (literal.value instanceof Double) { if (literal.value instanceof Double) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT, loc(literal.getOffset())));
return; return;
} }
if (literal.value instanceof Long) { if (literal.value instanceof Long) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT, loc(literal.getOffset())));
return; return;
} }
if (literal.value instanceof Integer) { if (literal.value instanceof Integer) {
@ -392,31 +410,31 @@ public class TYPEStmt implements StatementVisitor {
HashSet<JavaClassName> clNames = info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)); HashSet<JavaClassName> clNames = info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new));
Set<Constraint> oderConstraints = new HashSet<>(); Set<Constraint> oderConstraints = new HashSet<>();
Constraint constraint = new Constraint(); Constraint constraint = new Constraint();
constraint.add(new Pair(literal.getType(), integer, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), integer, PairOperator.EQUALSDOT, loc(literal.getOffset())));
oderConstraints.add(constraint); oderConstraints.add(constraint);
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Double")).findAny().isPresent()) { if (clNames.stream().filter(x -> x.toString().equals("java.lang.Double")).findAny().isPresent()) {
constraint = new Constraint(); constraint = new Constraint();
constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT, loc(literal.getOffset())));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Long")).findAny().isPresent()) { if (clNames.stream().filter(x -> x.toString().equals("java.lang.Long")).findAny().isPresent()) {
constraint = new Constraint(); constraint = new Constraint();
constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT, loc(literal.getOffset())));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Float")).findAny().isPresent()) { if (clNames.stream().filter(x -> x.toString().equals("java.lang.Float")).findAny().isPresent()) {
constraint = new Constraint(); constraint = new Constraint();
constraint.add(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT, loc(literal.getOffset())));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Short")).findAny().isPresent()) { if (clNames.stream().filter(x -> x.toString().equals("java.lang.Short")).findAny().isPresent()) {
constraint = new Constraint(); constraint = new Constraint();
constraint.add(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT, loc(literal.getOffset())));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Byte")).findAny().isPresent()) { if (clNames.stream().filter(x -> x.toString().equals("java.lang.Byte")).findAny().isPresent()) {
constraint = new Constraint(); constraint = new Constraint();
constraint.add(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT, loc(literal.getOffset())));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
constraintsSet.addOderConstraint(oderConstraints); constraintsSet.addOderConstraint(oderConstraints);
@ -424,33 +442,43 @@ public class TYPEStmt implements StatementVisitor {
return; return;
} }
if (literal.value instanceof Short) { if (literal.value instanceof Short) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT, loc(literal.getOffset())));
return; return;
} }
if (literal.value instanceof Byte) { if (literal.value instanceof Byte) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT, loc(literal.getOffset())));
return; return;
} }
if (literal.value instanceof Float) { if (literal.value instanceof Float) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT, loc(literal.getOffset())));
return; return;
} }
if (literal.value instanceof String) { if (literal.value instanceof String) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), string, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), string, PairOperator.EQUALSDOT, loc(literal.getOffset())));
return; return;
} }
if (literal.value instanceof Boolean) { if (literal.value instanceof Boolean) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), bool, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), bool, PairOperator.EQUALSDOT, loc(literal.getOffset())));
return; return;
} else { }
if (literal.value instanceof Character) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), charr, PairOperator.EQUALSDOT, loc(literal.getOffset())));
return;
}
if (literal.value != null) {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
@Override
public void visit(Throw aThrow) {
aThrow.expr.accept(this);
}
@Override @Override
public void visit(Return returnExpr) { public void visit(Return returnExpr) {
returnExpr.retexpr.accept(this); returnExpr.retexpr.accept(this);
constraintsSet.addUndConstraint(new Pair(returnExpr.getType(), info.getCurrentTypeScope().getReturnType(), PairOperator.SMALLERDOT)); constraintsSet.addUndConstraint(new Pair(returnExpr.getType(), info.getCurrentTypeScope().getReturnType(), PairOperator.SMALLERDOT, loc(returnExpr.getOffset())));
} }
@Override @Override
@ -482,7 +510,7 @@ public class TYPEStmt implements StatementVisitor {
params.add(new GenericRefType(gtv.getName(), aThis.getOffset())); params.add(new GenericRefType(gtv.getName(), aThis.getOffset()));
} }
RefType thisType = new RefType(currentClass.getClassName(), params, aThis.getOffset()); RefType thisType = new RefType(currentClass.getClassName(), params, aThis.getOffset());
constraintsSet.addUndConstraint(new Pair(aThis.getType(), thisType, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(aThis.getType(), thisType, PairOperator.EQUALSDOT, loc(aThis.getOffset())));
} }
private static TypeScope createNullTypeScope() { private static TypeScope createNullTypeScope() {
@ -505,7 +533,7 @@ public class TYPEStmt implements StatementVisitor {
// Expression inferieren: // Expression inferieren:
whileStmt.expr.accept(this); whileStmt.expr.accept(this);
// Expression muss boolean sein: // Expression muss boolean sein:
constraintsSet.addUndConstraint(new Pair(whileStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(whileStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT, loc(whileStmt.expr.getOffset())));
// LoopBlock inferieren: // LoopBlock inferieren:
whileStmt.loopBlock.accept(this); whileStmt.loopBlock.accept(this);
} }
@ -529,7 +557,22 @@ public class TYPEStmt implements StatementVisitor {
@Override @Override
public void visit(SuperCall superCall) { public void visit(SuperCall superCall) {
// TODO: Für einen super-Call werden keine Constraints erzeugt bisher Set<Constraint<Pair>> methodConstraints = new HashSet<>();
for (var clazz : info.getAvailableClasses()) {
if (clazz.getClassName().equals(info.getCurrentClass().getSuperClass().getName())) {
for (var ctor : clazz.getConstructors()) {
var params = convertParams(ctor.getParameterList(), info);
if (params.size() != superCall.arglist.getArguments().size()) continue;
var assumption = new MethodAssumption(null, new Void(new NullToken()), params, createTypeScope(clazz, ctor), ctor.isInherited);
GenericsResolver resolver = getResolverInstance();
Set<Constraint<Pair>> oneMethodConstraints = generateConstraint(superCall, assumption, info, resolver);
methodConstraints.addAll(oneMethodConstraints);
}
break;
}
}
constraintsSet.addOderConstraint(methodConstraints);
} }
/* /*
@ -549,10 +592,12 @@ public class TYPEStmt implements StatementVisitor {
*/ */
RefTypeOrTPHOrWildcardOrGeneric receiverType = assumption.getReceiverType(resolver); RefTypeOrTPHOrWildcardOrGeneric receiverType = assumption.getReceiverType(resolver);
methodConstraint.add(new Pair(forMethod.receiver.getType(), receiverType, PairOperator.EQUALSDOT));// PL 2020-03-17 SMALLERDOT in EQUALSDOT umgewandelt, weil alle geerbten Methoden in den jeweilen Klassen enthalten sind. if (receiverType != null) {
methodConstraint.add(new Pair(forMethod.receiver.getType(), receiverType, PairOperator.EQUALSDOT, loc(forMethod.getOffset())));// PL 2020-03-17 SMALLERDOT in EQUALSDOT umgewandelt, weil alle geerbten Methoden in den jeweilen Klassen enthalten sind.
// PL 2023-01-24: dafuer ? extends receiverType noch ergaenzt // PL 2023-01-24: dafuer ? extends receiverType noch ergaenzt
extendsMethodConstraint.add(new Pair(forMethod.receiver.getType(), new ExtendsWildcardType(receiverType, receiverType.getOffset()), PairOperator.EQUALSDOT)); extendsMethodConstraint.add(new Pair(forMethod.receiver.getType(), new ExtendsWildcardType(receiverType, receiverType.getOffset()), PairOperator.EQUALSDOT, loc(forMethod.getOffset())));
}
// gegenseite Verschraenkung der beiden Mengen von Typannahmen // gegenseite Verschraenkung der beiden Mengen von Typannahmen
methodConstraint.setExtendConstraint(extendsMethodConstraint); methodConstraint.setExtendConstraint(extendsMethodConstraint);
@ -563,13 +608,14 @@ public class TYPEStmt implements StatementVisitor {
// PairOperator.EQUALSDOT)); // PairOperator.EQUALSDOT));
// Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE // Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.SMALLERDOT)); methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.SMALLERDOT, loc(forMethod.getOffset())));
extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.SMALLERDOT)); extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.SMALLERDOT, loc(forMethod.getOffset())));
// methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); // methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
// extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); // extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
((TypePlaceholder) forMethod.getType()).setOrCons((byte) -1);// fuer Maximums-Bestimmung if (forMethod.getType() instanceof TypePlaceholder tph)
tph.setOrCons((byte) -1);// fuer Maximums-Bestimmung
Set<Pair> parameterContraints = generateParameterConstraints(forMethod, assumption, info, resolver); Set<Pair> parameterContraints = generateParameterConstraints(forMethod, assumption, info, resolver);
@ -596,7 +642,7 @@ public class TYPEStmt implements StatementVisitor {
RefTypeOrTPHOrWildcardOrGeneric argType = foMethod.arglist.getArguments().get(i).getType(); RefTypeOrTPHOrWildcardOrGeneric argType = foMethod.arglist.getArguments().get(i).getType();
RefTypeOrTPHOrWildcardOrGeneric assType = assumption.getArgTypes(resolver).get(i); RefTypeOrTPHOrWildcardOrGeneric assType = assumption.getArgTypes(resolver).get(i);
ret.add(new Pair(argType, assType, PairOperator.SMALLERDOT)); ret.add(new Pair(argType, assType, PairOperator.SMALLERDOT, loc(foMethod.getOffset())));
// Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG // Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG
// ret.add(new Pair(foMethod.argTypes.get(i), assType, PairOperator.EQUALSDOT)); // ret.add(new Pair(foMethod.argTypes.get(i), assType, PairOperator.EQUALSDOT));
@ -616,7 +662,6 @@ public class TYPEStmt implements StatementVisitor {
} }
// Zuordnung von MethodCall.signature(ReturnType) zu dem ReturnType der ausgewaehlten Methode (assumption.returnType) // Zuordnung von MethodCall.signature(ReturnType) zu dem ReturnType der ausgewaehlten Methode (assumption.returnType)
System.out.println(foMethod.name);
ret.add(new Pair(foMethod.signature.get(foMethod.signature.size() - 1), assumption.getReturnType(), PairOperator.EQUALSDOT)); ret.add(new Pair(foMethod.signature.get(foMethod.signature.size() - 1), assumption.getReturnType(), PairOperator.EQUALSDOT));
return ret; return ret;
} }
@ -691,7 +736,7 @@ public class TYPEStmt implements StatementVisitor {
Constraint methodConstraint = new Constraint(); Constraint methodConstraint = new Constraint();
// WELCHEN SINN MACHT DIESER CONSTRAINT??? // WELCHEN SINN MACHT DIESER CONSTRAINT???
// Ist er nicht immer classname <. classname und damit redundant? // Ist er nicht immer classname <. classname und damit redundant?
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forConstructor.getType(), PairOperator.SMALLERDOT)); methodConstraint.add(new Pair(assumption.getReturnType(resolver), forConstructor.getType(), PairOperator.SMALLERDOT, loc(forConstructor.getOffset())));
// WELCHEN SINN MACHT DIESER CONSTRAINT??? // WELCHEN SINN MACHT DIESER CONSTRAINT???
methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info, resolver)); methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info, resolver));
return methodConstraint; return methodConstraint;
@ -715,17 +760,17 @@ public class TYPEStmt implements StatementVisitor {
for (var child : switchStmt.getBlocks()) { for (var child : switchStmt.getBlocks()) {
for (var label : child.getLabels()) { for (var label : child.getLabels()) {
if (label.getPattern() instanceof FormalParameter) { if (label.getPattern() instanceof FormalParameter) {
constraintsSet.addUndConstraint(new Pair(label.getPattern().getType(), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT)); constraintsSet.addUndConstraint(new Pair(label.getPattern().getType(), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT, loc(label.getOffset())));
} }
} }
} }
} else { } else {
constraintsSet.addUndConstraint(new Pair(caseExpressionType, switchStmt.getSwitch().getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(caseExpressionType, switchStmt.getSwitch().getType(), PairOperator.EQUALSDOT, loc(switchStmt.getSwitch().getOffset())));
} }
for (var child : switchStmt.getBlocks()) { for (var child : switchStmt.getBlocks()) {
child.accept(this); child.accept(this);
constraintsSet.addUndConstraint(new Pair(child.getType(), switchStmt.getType(), PairOperator.SMALLERDOT)); constraintsSet.addUndConstraint(new Pair(child.getType(), switchStmt.getType(), PairOperator.SMALLERDOT, loc(switchStmt.getOffset())));
} }
switchStack.pop(); switchStack.pop();
@ -746,7 +791,7 @@ public class TYPEStmt implements StatementVisitor {
@Override @Override
public void visit(Yield aYield) { public void visit(Yield aYield) {
aYield.retexpr.accept(this); aYield.retexpr.accept(this);
constraintsSet.addUndConstraint(new Pair(aYield.getType(), switchStack.peek().getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(aYield.getType(), switchStack.peek().getType(), PairOperator.EQUALSDOT, loc(aYield.getOffset())));
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
} }

View File

@ -439,7 +439,7 @@ public class RuleSet implements IRuleSet{
if(!(rhsType instanceof ReferenceType) && !(rhsType instanceof PlaceholderType)) if(!(rhsType instanceof ReferenceType) && !(rhsType instanceof PlaceholderType))
return false; return false;
return fc.greater(lhsType, new HashSet<>()).contains(rhsType); return fc.greater(lhsType, new HashSet<>(), pair.getLocation()).contains(rhsType);
} }
@Override @Override

View File

@ -3,6 +3,7 @@ package de.dhbwstuttgart.typeinference.unify.interfaces;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.parser.SourceLoc;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.unify.model.FunNType; import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
@ -10,6 +11,7 @@ import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType; import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.SuperType; import de.dhbwstuttgart.typeinference.unify.model.SuperType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import org.antlr.v4.runtime.Token;
/** /**
* *
@ -22,13 +24,19 @@ public interface IFiniteClosure {
* Returns all types of the finite closure that are subtypes of the argument. * Returns all types of the finite closure that are subtypes of the argument.
* @return The set of subtypes of the argument. * @return The set of subtypes of the argument.
*/ */
public Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded); public Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded, Token position);
public default Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded) {
return this.smaller(type, fBounded, null);
}
/** /**
* Returns all types of the finite closure that are supertypes of the argument. * Returns all types of the finite closure that are supertypes of the argument.
* @return The set of supertypes of the argument. * @return The set of supertypes of the argument.
*/ */
public Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded); public Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded, SourceLoc position);
public default Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded) {
return this.greater(type, fBounded, null);
}
/** /**
* Wo passt Type rein? * Wo passt Type rein?

View File

@ -20,6 +20,7 @@ import com.google.common.collect.Ordering;
//PL 18-02-05/18-04-05 Unifier durch Matcher ersetzt //PL 18-02-05/18-04-05 Unifier durch Matcher ersetzt
//muss greater noch ersetzt werden ja erledigt 18--04-05 //muss greater noch ersetzt werden ja erledigt 18--04-05
import de.dhbwstuttgart.parser.SourceLoc;
import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify; import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify;
import de.dhbwstuttgart.typeinference.unify.Match; import de.dhbwstuttgart.typeinference.unify.Match;
@ -27,6 +28,7 @@ import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
import de.dhbwstuttgart.util.Pair; import de.dhbwstuttgart.util.Pair;
import org.antlr.v4.runtime.Token;
/** /**
* The finite closure for the type unification * The finite closure for the type unification
@ -145,7 +147,7 @@ implements IFiniteClosure {
* @return The set of subtypes of the argument. * @return The set of subtypes of the argument.
*/ */
@Override @Override
public Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded) { public Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded, Token position) {
Set<UnifyType> ret; Set<UnifyType> ret;
if ((ret = smallerHash.get(new hashKeyType(type))) != null) { if ((ret = smallerHash.get(new hashKeyType(type))) != null) {
@ -260,8 +262,7 @@ implements IFiniteClosure {
*/ */
@Override @Override
//Eingefuegt PL 2018-05-24 F-Bounded Problematik //Eingefuegt PL 2018-05-24 F-Bounded Problematik
public Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded) { public Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded, SourceLoc location) {
Set<UnifyType> ret; Set<UnifyType> ret;
if ((ret = greaterHash.get(new hashKeyType(type))) != null) { if ((ret = greaterHash.get(new hashKeyType(type))) != null) {
//System.out.println(greaterHash); //System.out.println(greaterHash);
@ -302,7 +303,7 @@ implements IFiniteClosure {
//PL 18-04-05 Unifier durch Matcher ersetzt ANFANG //PL 18-04-05 Unifier durch Matcher ersetzt ANFANG
ArrayList<UnifyPair> termList= new ArrayList<UnifyPair>(); ArrayList<UnifyPair> termList= new ArrayList<UnifyPair>();
termList.add(new UnifyPair(theta1,type, PairOperator.EQUALSDOT)); termList.add(new UnifyPair(theta1,type, PairOperator.EQUALSDOT, location));
Optional<Unifier> optSigma = match.match(termList); Optional<Unifier> optSigma = match.match(termList);
//PL 18-04-05 Unifier durch Matcher ersetzt ENDE //PL 18-04-05 Unifier durch Matcher ersetzt ENDE
if(!optSigma.isPresent()) { if(!optSigma.isPresent()) {
@ -344,7 +345,7 @@ implements IFiniteClosure {
BiFunction<Boolean,UnifyType,Boolean> f = (x,y) -> BiFunction<Boolean,UnifyType,Boolean> f = (x,y) ->
{ {
ArrayList<UnifyPair> termList = new ArrayList<UnifyPair>(); ArrayList<UnifyPair> termList = new ArrayList<UnifyPair>();
termList.add(new UnifyPair(y,t.getTypeParams().get(i_ef), PairOperator.EQUALSDOT)); termList.add(new UnifyPair(y,t.getTypeParams().get(i_ef), PairOperator.EQUALSDOT, location));
return ((match.match(termList).isPresent()) || x); return ((match.match(termList).isPresent()) || x);
}; };
//if (parai.getName().equals("java.lang.Integer")) { //if (parai.getName().equals("java.lang.Integer")) {

View File

@ -102,7 +102,7 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
} }
return new UnifyPair(newLhs, newRhs, p.getPairOp(), suniUnifyPair, p); return new UnifyPair(newLhs, newRhs, p.getPairOp(), suniUnifyPair, p);
} }
return new UnifyPair(newLhs, newRhs, p.getPairOp(), p.getSubstitution(), p.getBasePair(), p.getfBounded()); return new UnifyPair(newLhs, newRhs, p.getPairOp(), p.getSubstitution(), p.getBasePair(), p.getfBounded(), p.getLocation());
} }
/** /**

View File

@ -1,5 +1,10 @@
package de.dhbwstuttgart.typeinference.unify.model; package de.dhbwstuttgart.typeinference.unify.model;
import com.google.common.collect.ObjectArrays;
import de.dhbwstuttgart.parser.SourceLoc;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import org.antlr.v4.runtime.Token;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
@ -13,7 +18,9 @@ import java.util.Set;
* @author Florian Steurer * @author Florian Steurer
*/ */
public class UnifyPair { public class UnifyPair {
private SourceLoc location;
/** /**
* The type on the left hand side of the pair. * The type on the left hand side of the pair.
*/ */
@ -63,27 +70,41 @@ public class UnifyPair {
this.rhs = rhs; this.rhs = rhs;
pairOp = op; pairOp = op;
substitution = new HashSet<>(); substitution = new HashSet<>();
// Caching hashcode // Caching hashcode
hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode(); hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode();
} }
public UnifyPair(UnifyType lhs, UnifyType rhs, PairOperator op, SourceLoc location) {
this(lhs, rhs, op);
this.location = location;
}
public UnifyPair(UnifyType lhs, UnifyType rhs, PairOperator op, Set<UnifyPair> uni, UnifyPair base) { public UnifyPair(UnifyType lhs, UnifyType rhs, PairOperator op, Set<UnifyPair> uni, UnifyPair base) {
this(lhs, rhs, op, uni, base, null);
}
public UnifyPair(UnifyType lhs, UnifyType rhs, PairOperator op, Set<UnifyPair> uni, UnifyPair base, Set<UnifyType> fBounded) {
this(lhs, rhs, op, uni, base, fBounded, null);
}
public UnifyPair(UnifyType lhs, UnifyType rhs, PairOperator op, Set<UnifyPair> uni, UnifyPair base, Set<UnifyType> fBounded, SourceLoc location) {
this.lhs = lhs; this.lhs = lhs;
this.rhs = rhs; this.rhs = rhs;
pairOp = op; pairOp = op;
substitution = uni; substitution = uni;
basePair = base; basePair = base;
this.location = location;
//this.fBounded = fBounded; // what?
// Caching hashcode // Caching hashcode
hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode(); hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode();
} }
public UnifyPair(UnifyType lhs, UnifyType rhs, PairOperator op, Set<UnifyPair> uni, UnifyPair base, Set<UnifyType> fBounded) { public SourceLoc getLocation() {
this(lhs, rhs, op, uni, base); if (location != null) return location;
else if (basePair != null) return basePair.getLocation();
this.fBounded = fBounded; return null;
} }
/** /**
@ -231,7 +252,13 @@ public class UnifyPair {
+ "WC: " + ((PlaceholderType)rhs).isWildcardable() + "WC: " + ((PlaceholderType)rhs).isWildcardable()
+ ", IT: " + ((PlaceholderType)rhs).isInnerType(); + ", IT: " + ((PlaceholderType)rhs).isInnerType();
} }
return "(" + lhs + " " + pairOp + " " + rhs + ", " + ret + ")"; //+ ", [" + getfBounded().toString()+ "])"; var res = "(" + lhs + " " + pairOp + " " + rhs + ", " + ret + ")"; //+ ", [" + getfBounded().toString()+ "])";
var location = this.getLocation();
if (location != null) {
res += "@" + location.line() + " in " + location.file();
}
return res;
} }
/* /*

View File

@ -1,9 +1,9 @@
import de.dhbwstuttgart.environment.ByteArrayClassLoader; import de.dhbwstuttgart.environment.ByteArrayClassLoader;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.util.Arrays; import java.util.Arrays;
@ -234,7 +234,7 @@ public class TestComplete {
} }
@Test @Test
//@Ignore("This is to complex") //@Ignore("This is too complex")
public void matrixTest() throws Exception { public void matrixTest() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Matrix.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Matrix.jav");
var matrix = classFiles.get("Matrix"); var matrix = classFiles.get("Matrix");
@ -737,6 +737,15 @@ public class TestComplete {
var m = clazz.getDeclaredMethod("m", Integer.class); var m = clazz.getDeclaredMethod("m", Integer.class);
assertEquals(m.invoke(instance, 10), 60); assertEquals(m.invoke(instance, 10), 60);
} }
@Test
public void testForEach() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "ForEach.jav");
var clazz = classFiles.get("ForEach");
var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("m");
assertEquals(m.invoke(instance), 6);
}
@Test @Test
public void testLambdaRunnable() throws Exception { public void testLambdaRunnable() throws Exception {
@ -772,4 +781,99 @@ public class TestComplete {
var hello = clazz.getDeclaredMethod("hello"); var hello = clazz.getDeclaredMethod("hello");
hello.invoke(null); hello.invoke(null);
} }
@Test
public void testSuperCall() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SuperCall.jav");
var clazz = classFiles.get("SuperCall");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testInstanceOf() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "InstanceOf.jav");
var clazz = classFiles.get("InstanceOf");
var instance = clazz.getDeclaredConstructor().newInstance();
assertTrue((Boolean) clazz.getDeclaredMethod("test1").invoke(instance));
assertTrue((Boolean) clazz.getDeclaredMethod("test2").invoke(instance));
assertFalse((Boolean) clazz.getDeclaredMethod("test3").invoke(instance));
}
@Test
public void testExceptions() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Exceptions.jav");
var clazz = classFiles.get("Exceptions");
var instance = clazz.getDeclaredConstructor().newInstance();
try {
clazz.getDeclaredMethod("m").invoke(instance);
fail("No exception thrown!");
} catch (InvocationTargetException exception) {
var exc = exception.getTargetException();
if (!(exc instanceof RuntimeException rexp) || !rexp.getMessage().equals("Some Exception")) {
fail("Wrong exception thrown!");
}
}
}
@Test
public void testLiteral() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Literal.jav");
var clazz = classFiles.get("Literal");
var instance = clazz.getDeclaredConstructor().newInstance();
assertNull(clazz.getDeclaredMethod("m").invoke(instance));
assertEquals(clazz.getDeclaredMethod("m2").invoke(instance), 'C');
}
@Test
public void testOLConstructor() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OLConstructor.jav");
var clazz = classFiles.get("Child");
var instance = clazz.getDeclaredConstructor().newInstance();
assertEquals(clazz.getSuperclass().getDeclaredField("x").get(instance), 3);
}
@Test
public void testStringConcat() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Op2.jav");
var clazz = classFiles.get("Op2");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testLamRunnable() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "LamRunnable.jav");
var clazz = classFiles.get("LamRunnable");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testBug122() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug122.jav");
var clazz = classFiles.get("Bug122");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testBug123() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug123.jav");
var clazz = classFiles.get("Bug123");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testBug125() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug125.jav");
var clazz = classFiles.get("Bug125");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testBug112() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug112.jav");
var clazz = classFiles.get("Bug112");
var instance = clazz.getDeclaredConstructor().newInstance();
}
} }

View File

@ -22,7 +22,7 @@ public class ASTToTypedTargetAST {
@Test @Test
public void emptyClass() { public void emptyClass() {
ClassOrInterface emptyClass = new ClassOrInterface(0, new JavaClassName("EmptyClass"), new ArrayList<>(), Optional.empty(), Optional.empty(), new ArrayList<>(), new ArrayList<>(), new GenericDeclarationList(new ArrayList<>(), new NullToken()), new RefType(new JavaClassName("Object"), new NullToken()), false, false, new ArrayList<>(), new ArrayList<>(), new NullToken()); ClassOrInterface emptyClass = new ClassOrInterface(0, new JavaClassName("EmptyClass"), new ArrayList<>(), Optional.empty(), Optional.empty(), new ArrayList<>(), new ArrayList<>(), new GenericDeclarationList(new ArrayList<>(), new NullToken()), new RefType(new JavaClassName("Object"), new NullToken()), false, false, new ArrayList<>(), new ArrayList<>(), new NullToken(), null);
ResultSet emptyResultSet = new ResultSet(new HashSet<>()); ResultSet emptyResultSet = new ResultSet(new HashSet<>());
TargetStructure emptyTargetClass = new ASTToTargetAST(List.of(emptyResultSet)).convert(emptyClass); TargetStructure emptyTargetClass = new ASTToTargetAST(List.of(emptyResultSet)).convert(emptyClass);
assert emptyTargetClass.getName().equals("EmptyClass"); assert emptyTargetClass.getName().equals("EmptyClass");