Merge branch 'bigRefactoring' into strucTypesVollmer

This commit is contained in:
JanUlrich 2017-11-14 19:31:28 +01:00
commit b2825e2fa1
34 changed files with 308 additions and 262 deletions

View File

@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import de.dhbwstuttgart.syntaxtree.statement.*;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
@ -12,33 +13,6 @@ import org.objectweb.asm.Opcodes;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
import de.dhbwstuttgart.syntaxtree.statement.Assign;
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt;
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
import de.dhbwstuttgart.syntaxtree.statement.ForStmt;
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
import de.dhbwstuttgart.syntaxtree.statement.InstanceOf;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
import de.dhbwstuttgart.syntaxtree.statement.NewArray;
import de.dhbwstuttgart.syntaxtree.statement.NewClass;
import de.dhbwstuttgart.syntaxtree.statement.Receiver;
import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
import de.dhbwstuttgart.syntaxtree.statement.Super;
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
import de.dhbwstuttgart.syntaxtree.statement.This;
import de.dhbwstuttgart.syntaxtree.statement.UnaryPlus;
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
@ -281,12 +255,6 @@ public class BytecodeGen implements ASTVisitor {
} }
@Override
public void visit(Receiver receiver) {
// TODO Auto-generated method stub
}
@Override @Override
public void visit(Return aReturn) { public void visit(Return aReturn) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
@ -379,8 +347,13 @@ public class BytecodeGen implements ASTVisitor {
@Override @Override
public void visit(SuperCall superCall) { public void visit(SuperCall superCall) {
// TODO Auto-generated method stub
} }
@Override
public void visit(ExpressionReceiver expressionReceiver) {
// TODO Auto-generated method stub
}
} }

View File

@ -1,36 +1,10 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode;
import de.dhbwstuttgart.syntaxtree.statement.*;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
import de.dhbwstuttgart.syntaxtree.statement.Assign;
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt;
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
import de.dhbwstuttgart.syntaxtree.statement.ForStmt;
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
import de.dhbwstuttgart.syntaxtree.statement.InstanceOf;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
import de.dhbwstuttgart.syntaxtree.statement.NewArray;
import de.dhbwstuttgart.syntaxtree.statement.NewClass;
import de.dhbwstuttgart.syntaxtree.statement.Receiver;
import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
import de.dhbwstuttgart.syntaxtree.statement.Super;
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
import de.dhbwstuttgart.syntaxtree.statement.This;
import de.dhbwstuttgart.syntaxtree.statement.UnaryPlus;
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
@ -142,7 +116,7 @@ public class BytecodeGenLambda implements StatementVisitor{
} }
@Override @Override
public void visit(Receiver receiver) { public void visit(ExpressionReceiver receiver) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }

View File

@ -8,6 +8,7 @@ import java.lang.invoke.MethodType;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.HashMap; import java.util.HashMap;
import de.dhbwstuttgart.syntaxtree.statement.*;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Handle; import org.objectweb.asm.Handle;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
@ -17,35 +18,6 @@ import org.objectweb.asm.Type;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
import de.dhbwstuttgart.syntaxtree.statement.Assign;
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
import de.dhbwstuttgart.syntaxtree.statement.ForStmt;
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
import de.dhbwstuttgart.syntaxtree.statement.InstanceOf;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
import de.dhbwstuttgart.syntaxtree.statement.NewArray;
import de.dhbwstuttgart.syntaxtree.statement.NewClass;
import de.dhbwstuttgart.syntaxtree.statement.Receiver;
import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
import de.dhbwstuttgart.syntaxtree.statement.Super;
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
import de.dhbwstuttgart.syntaxtree.statement.This;
import de.dhbwstuttgart.syntaxtree.statement.UnaryPlus;
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
@ -230,14 +202,19 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override @Override
public void visit(MethodCall methodCall) { public void visit(MethodCall methodCall) {
System.out.println(" In Methodcall: (" +methodCall.name+")" ); System.out.println(" In Methodcall: (" +methodCall.name+")" );
System.out.println(" Method-Receiver: "+methodCall.receiver.expr); System.out.print(" Method-Receiver: ");
if(methodCall.receiver instanceof ExpressionReceiver){
System.out.print(((ExpressionReceiver) methodCall.receiver).expr + "\n");
}else{
System.out.print(((StaticClassName) methodCall.receiver).getType().toString() + "\n");
}
methodCall.receiver.accept(this); methodCall.receiver.accept(this);
methodCall.arglist.accept(this); methodCall.arglist.accept(this);
Descriptor mDesc = new Descriptor(methodCall.arglist, methodCall.getType()); Descriptor mDesc = new Descriptor(methodCall.arglist, methodCall.getType());
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, methodCall.receiver.expr.getType().toString(), mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, methodCall.receiver.getType().toString(),
methodCall.name, mDesc.getDesc(), false); methodCall.name, mDesc.getDesc(), false);
// test // test
if(!methodCall.getType().toString().equals("V")) { if(!methodCall.getType().toString().equals("V")) {
@ -270,7 +247,7 @@ public class BytecodeGenMethod implements StatementVisitor{
} }
@Override @Override
public void visit(Receiver receiver) { public void visit(ExpressionReceiver receiver) {
System.out.println(" in Receiver"); System.out.println(" in Receiver");
System.out.println(" expr : " + receiver.expr); System.out.println(" expr : " + receiver.expr);
receiver.expr.accept(this); receiver.expr.accept(this);

View File

@ -60,4 +60,13 @@ public class CompilationEnvironment {
allNames = GatherNames.getNames(tree, new PackageCrawler(librarys)); allNames = GatherNames.getNames(tree, new PackageCrawler(librarys));
return new JavaClassRegistry(allNames); return new JavaClassRegistry(allNames);
} }
public List<ClassOrInterface> getAllAvailableClasses() {
List<ClassOrInterface> ret = new ArrayList<>();
for(Class c : new PackageCrawler(librarys).getAllAvailableClasses()){
ret.add(ASTFactory.createClass(c));
}
return ret;
}
} }

View File

@ -3,6 +3,7 @@ package de.dhbwstuttgart.environment;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import org.reflections.Reflections; import org.reflections.Reflections;
@ -12,6 +13,7 @@ import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder; import org.reflections.util.FilterBuilder;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import org.reflections.vfs.SystemDir;
/** /**
* Hilft beim Durchsuchen von Packages * Hilft beim Durchsuchen von Packages
@ -54,9 +56,22 @@ public class PackageCrawler {
return classes; return classes;
} }
public Set<Class<?>> getAllAvailableClasses(){
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
.setUrls(urls));
Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);
return classes;
}
public List<String> getClassNames(String packageName){ public List<String> getClassNames(String packageName){
List<String> nameList = new ArrayList(); List<String> nameList = new ArrayList();
Set<Class<?>> classes = getClassesInPackage(packageName); Set<Class<?>> classes = getClassesInPackage(packageName);
if(packageName.equals("java.lang") && ! classes.contains(Object.class)) {
classes.add(Object.class);
}
for(Class c : classes){ for(Class c : classes){
nameList.add(c.getName()); nameList.add(c.getName());
} }

View File

@ -179,6 +179,14 @@ public class StatementGenerator {
}else throw new NotImplementedException(); }else throw new NotImplementedException();
} }
public Receiver getReceiver(Expression expr){
if(expr instanceof StaticClassName){
return (Receiver) expr;
}else {
return new ExpressionReceiver(expr);
}
}
private Statement convert(Java8Parser.MethodInvocationContext methodInvocationContext) { private Statement convert(Java8Parser.MethodInvocationContext methodInvocationContext) {
String name; String name;
if(methodInvocationContext.methodName()!=null){ if(methodInvocationContext.methodName()!=null){
@ -200,7 +208,7 @@ public class StatementGenerator {
}else throw new NotImplementedException(); }else throw new NotImplementedException();
ArgumentList argumentList = convert(methodInvocationContext.argumentList()); ArgumentList argumentList = convert(methodInvocationContext.argumentList());
MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()),new Receiver(receiver), name, argumentList, methodInvocationContext.getStart()); MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()), getReceiver(receiver), name, argumentList, methodInvocationContext.getStart());
return ret; return ret;
} }
@ -701,7 +709,7 @@ public class StatementGenerator {
}else { }else {
Java8Parser.MethodInvocation_lf_primaryContext ctxt = e.methodInvocation_lf_primary(); Java8Parser.MethodInvocation_lf_primaryContext ctxt = e.methodInvocation_lf_primary();
String methodName = ctxt.Identifier().toString(); String methodName = ctxt.Identifier().toString();
return new MethodCall(TypePlaceholder.fresh(e.getStart()), new Receiver(expr), methodName, convert(ctxt.argumentList()), e.getStart()); return new MethodCall(TypePlaceholder.fresh(e.getStart()), getReceiver(expr), methodName, convert(ctxt.argumentList()), e.getStart());
} }
} }
@ -809,7 +817,7 @@ public class StatementGenerator {
} }
ArgumentList argumentList = convert(methodInvocationContext.argumentList()); ArgumentList argumentList = convert(methodInvocationContext.argumentList());
MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()), new Receiver(receiver), name, argumentList, methodInvocationContext.getStart()); MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()), getReceiver(receiver), name, argumentList, methodInvocationContext.getStart());
return ret; return ret;
} }

View File

@ -3,6 +3,7 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import java.lang.ClassNotFoundException; import java.lang.ClassNotFoundException;
import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.antlr.Java8Parser; import de.dhbwstuttgart.parser.antlr.Java8Parser;
import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
@ -15,6 +16,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.sql.Ref;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -182,13 +184,13 @@ public class SyntaxTreeGenerator{
block = stmtGen.convert(body.block()); block = stmtGen.convert(body.block());
} }
if(parentClass.equals(new JavaClassName(name))){ if(parentClass.equals(new JavaClassName(name))){
return new Constructor(modifiers, name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations, superClass); return new Constructor(modifiers, name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations);
}else{ }else{
return new Method(modifiers, name, retType, modifiers, parameterList,block, gtvDeclarations, header.getStart()); return new Method(modifiers, name, retType, modifiers, parameterList,block, gtvDeclarations, header.getStart());
} }
} }
private ClassOrInterface convertClass(Java8Parser.ClassDeclarationContext ctx) { private ClassOrInterface convertClass(Java8Parser.ClassDeclarationContext ctx) {
ClassOrInterface newClass; ClassOrInterface newClass;
if(ctx.normalClassDeclaration() != null){ if(ctx.normalClassDeclaration() != null){
newClass = convertNormal(ctx.normalClassDeclaration()); newClass = convertNormal(ctx.normalClassDeclaration());
@ -199,7 +201,7 @@ public class SyntaxTreeGenerator{
return newClass; return newClass;
} }
private ClassOrInterface convertNormal(Java8Parser.NormalClassDeclarationContext ctx){ private ClassOrInterface convertNormal(Java8Parser.NormalClassDeclarationContext ctx) {
int modifiers = 0; int modifiers = 0;
if(ctx.classModifier() != null){ if(ctx.classModifier() != null){
for(Java8Parser.ClassModifierContext mod : ctx.classModifier()){ for(Java8Parser.ClassModifierContext mod : ctx.classModifier()){
@ -220,7 +222,7 @@ public class SyntaxTreeGenerator{
if(ctx.superclass() != null){ if(ctx.superclass() != null){
superClass = convert(ctx.superclass()); superClass = convert(ctx.superclass());
}else{ }else{
superClass = ASTFactory.createObjectClass().getType(); superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart());
} }
List<Field> fielddecl = convertFields(ctx.classBody(), generics); List<Field> fielddecl = convertFields(ctx.classBody(), generics);
List<Method> methods = convertMethods(ctx.classBody(), name, superClass, generics); List<Method> methods = convertMethods(ctx.classBody(), name, superClass, generics);
@ -267,11 +269,21 @@ public class SyntaxTreeGenerator{
int modifiers = 0; int modifiers = 0;
ParameterList params = new ParameterList(new ArrayList<>(), offset); ParameterList params = new ParameterList(new ArrayList<>(), offset);
Block block = new Block(new ArrayList<>(), offset); Block block = new Block(new ArrayList<>(), offset);
return new Constructor(Modifier.PUBLIC, className, classType, modifiers, params, block, classGenerics, offset, fieldInitializations, superClass); return new Constructor(Modifier.PUBLIC, className, classType, modifiers, params, block, classGenerics, offset, fieldInitializations);
} }
private RefType convert(Java8Parser.SuperclassContext superclass) { private RefType convert(Java8Parser.SuperclassContext superclass) {
throw new NotImplementedException(); if(superclass.classType().classOrInterfaceType() != null){
throw new NotImplementedException();
}else{
RefTypeOrTPHOrWildcardOrGeneric ret = TypeGenerator.convertTypeName(superclass.classType().Identifier().getText(), superclass.classType().typeArguments(),
superclass.getStart(), reg, globalGenerics);
if(ret instanceof RefType){
return (RefType) ret;
}else{
throw new TypeinferenceException(superclass.getText() + " ist kein gültiger Supertyp", superclass.getStart());
}
}
} }
private List<Method> convertMethods(Java8Parser.ClassBodyContext classBodyContext, private List<Method> convertMethods(Java8Parser.ClassBodyContext classBodyContext,
@ -422,7 +434,7 @@ public class SyntaxTreeGenerator{
}else{ }else{
genericParams = createEmptyGenericDeclarationList(ctx.Identifier()); genericParams = createEmptyGenericDeclarationList(ctx.Identifier());
} }
RefType superClass = ASTFactory.createObjectClass().getType(); RefType superClass = ASTFactory.createObjectType();
List<Field> fields = convertFields(ctx.interfaceBody()); List<Field> fields = convertFields(ctx.interfaceBody());
List<Method> methods = convertMethods(ctx.interfaceBody(), name, superClass, generics); List<Method> methods = convertMethods(ctx.interfaceBody(), name, superClass, generics);

View File

@ -77,7 +77,7 @@ public class TypeGenerator {
public static List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) { public static List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) {
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
if(typeBoundContext == null){ if(typeBoundContext == null){
ret.add(ASTFactory.createObjectClass().getType()); ret.add(ASTFactory.createObjectType());
return ret; return ret;
} }
if(typeBoundContext.typeVariable() != null){ if(typeBoundContext.typeVariable() != null){
@ -105,7 +105,16 @@ public class TypeGenerator {
} }
public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.ReferenceTypeContext referenceTypeContext, JavaClassRegistry reg, GenericsRegistry generics) { public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.ReferenceTypeContext referenceTypeContext, JavaClassRegistry reg, GenericsRegistry generics) {
return convertTypeName(referenceTypeContext.getText(), referenceTypeContext.getStart(), reg, generics); if(referenceTypeContext.classOrInterfaceType() != null){
if(referenceTypeContext.classOrInterfaceType().classType_lfno_classOrInterfaceType()!= null){
Java8Parser.ClassType_lfno_classOrInterfaceTypeContext ctx = referenceTypeContext.classOrInterfaceType().classType_lfno_classOrInterfaceType();
return convertTypeName(ctx.Identifier().toString(), ctx.typeArguments(),referenceTypeContext.getStart(), reg, generics);
}else{
throw new NotImplementedException();
}
}else{
throw new NotImplementedException();
}
} }
public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(String name, Token offset, JavaClassRegistry reg, GenericsRegistry generics){ public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(String name, Token offset, JavaClassRegistry reg, GenericsRegistry generics){

View File

@ -19,4 +19,8 @@ public class GenericTypeName extends JavaClassName {
+ DELIMITER + methodName + DELIMITER + methodName
+ DELIMITER + super.toString(); + DELIMITER + super.toString();
} }
public JavaClassName getParentClass() {
return parentClass;
}
} }

View File

@ -200,7 +200,7 @@ public abstract class AbstractASTWalker implements ASTVisitor{
} }
@Override @Override
public void visit(Receiver receiver) { public void visit(ExpressionReceiver receiver) {
receiver.expr.accept(this); receiver.expr.accept(this);
} }

View File

@ -60,10 +60,12 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
return this.methods; return this.methods;
} }
/*
public RefType getType() { public RefType getType() {
return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset()); return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset());
} }
*/
//TODO: Das hier ist ein Problem. Je nach Kontext wird hier ein anderer Typ benötigt
public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass ,Token offset){ public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass ,Token offset){
//Hier wird immer ein generischer Typ generiert, also mit Type placeholdern //Hier wird immer ein generischer Typ generiert, also mit Type placeholdern
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
@ -74,6 +76,10 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
return new RefType(name, params, offset); return new RefType(name, params, offset);
} }
/**
* Die Superklasse im Kontext dieser ClassOrInterface
* Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind
*/
public RefType getSuperClass() { public RefType getSuperClass() {
return superClass; return superClass;
} }

View File

@ -15,8 +15,8 @@ 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, int modifiers, ParameterList parameterList, Block codeInsideConstructor, public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor,
GenericDeclarationList gtvDeclarations, Token offset, List<Statement> fieldInitializations, RefType superClass) { GenericDeclarationList gtvDeclarations, Token offset, List<Statement> fieldInitializations) {
super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations, superClass), gtvDeclarations, offset); super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations), gtvDeclarations, offset);
} }
@ -25,7 +25,7 @@ public class Constructor extends Method {
* welche die Felder der zugehörigen Klasse dieses * welche die Felder der zugehörigen Klasse dieses
* Konstruktor initialisieren * Konstruktor initialisieren
*/ */
protected static Block prepareBlock(Block constructorBlock, List<Statement> fieldInitializations, RefType superClass){ protected static Block prepareBlock(Block constructorBlock, List<Statement> fieldInitializations){
List<Statement> statements = constructorBlock.getStatements(); List<Statement> statements = constructorBlock.getStatements();
statements.add(0, new SuperCall(constructorBlock.getOffset())); statements.add(0, new SuperCall(constructorBlock.getOffset()));
return new Block(statements, constructorBlock.getOffset()); return new Block(statements, constructorBlock.getOffset());

View File

@ -1,6 +1,7 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.parser.scope.GenericTypeName; import de.dhbwstuttgart.parser.scope.GenericTypeName;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
@ -53,6 +54,14 @@ public class GenericTypeVar extends SyntaxTreeNode
return name; return name;
} }
public String getParsedName(){
return name.toString();
}
public JavaClassName definingClass(){
return name.getParentClass();
}
@Override @Override
public void accept(ASTVisitor visitor) { public void accept(ASTVisitor visitor) {
visitor.visit(this); visitor.visit(this);

View File

@ -40,8 +40,6 @@ public interface StatementVisitor {
void visit(NewArray newArray); void visit(NewArray newArray);
void visit(Receiver receiver);
void visit(Return aReturn); void visit(Return aReturn);
void visit(ReturnVoid aReturn); void visit(ReturnVoid aReturn);
@ -67,4 +65,6 @@ public interface StatementVisitor {
void visit(AssignToLocal assignLeftSide); void visit(AssignToLocal assignLeftSide);
void visit(SuperCall superCall); void visit(SuperCall superCall);
void visit(ExpressionReceiver expressionReceiver);
} }

View File

@ -2,6 +2,8 @@ package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import java.util.Collection;
public interface TypeScope { public interface TypeScope {
Iterable<? extends GenericTypeVar> getGenerics(); Iterable<? extends GenericTypeVar> getGenerics();

View File

@ -5,6 +5,7 @@ import java.lang.reflect.Constructor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext;
import de.dhbwstuttgart.parser.scope.GenericTypeName; import de.dhbwstuttgart.parser.scope.GenericTypeName;
@ -45,7 +46,11 @@ public class ASTFactory {
java.lang.Class superjreClass = jreClass.getSuperclass(); java.lang.Class superjreClass = jreClass.getSuperclass();
RefType superClass; RefType superClass;
if(superjreClass != null){ if(superjreClass != null){
superClass = (RefType) createType(superjreClass, name, ""); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(TypeVariable tv : superjreClass.getTypeParameters()){
params.add(new RefType(new GenericTypeName(new GenericContext( name, null),tv.getName()), new NullToken()));
}
superClass = new RefType(new JavaClassName(superjreClass.getName()), params, new NullToken());
}else{//Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!) }else{//Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!)
superClass = (RefType) createType(java.lang.Object.class, name, ""); superClass = (RefType) createType(java.lang.Object.class, name, "");
} }
@ -83,13 +88,12 @@ public class ASTFactory {
return null; return null;
} }
return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>(), return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>());
createType(inClass.getSuperclass()));
} }
private static RefType createType(Class classType) { //private static RefType createType(Class classType) {
return createClass(classType).getType(); // return createClass(classType).getType();
} //}
public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){ public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){
String name = jreMethod.getName(); String name = jreMethod.getName();
@ -182,6 +186,9 @@ public class ASTFactory {
public static ClassOrInterface createObjectClass() { public static ClassOrInterface createObjectClass() {
return createClass(Object.class); return createClass(Object.class);
} }
public static RefType createObjectType() {
return new RefType(createClass(Object.class).getClassName(), new NullToken());
}
/* /*
public Constructor createEmptyConstructor(Class parent){ public Constructor createEmptyConstructor(Class parent){

View File

@ -3,11 +3,13 @@ package de.dhbwstuttgart.syntaxtree.factory;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken; 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.GenericTypeVar;
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.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
@ -26,19 +28,73 @@ import de.dhbwstuttgart.typeinference.unify.model.SuperType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
public class UnifyTypeFactory { public class UnifyTypeFactory {
public static FiniteClosure generateFC(List<ClassOrInterface> fromAvailableClasses){ public static FiniteClosure generateFC(List<ClassOrInterface> fromClasses) throws ClassNotFoundException {
/*
TODO: Generics werden zu TPHs
Die transitive Hülle muss funktionieren.
Man darf schreiben List<A> extends AL<A>
und Vector<B> extends List<B>
hier muss dann aber dennoch die Vererbung V < L < AL
hergestellt werden.
In einem solchen Vererbungsbaum dürfen die TPH auch die gleichen Namen haben.
Generell dürfen sie immer die gleichen Namen haben.
TODO: die transitive Hülle bilden
*/
HashSet<UnifyPair> pairs = new HashSet<>(); HashSet<UnifyPair> pairs = new HashSet<>();
for(ClassOrInterface cl : fromAvailableClasses){ for(ClassOrInterface cly : fromClasses){
UnifyType t1 = UnifyTypeFactory.convert(cl.getType()); pairs.addAll(getSuperTypes(cly, fromClasses));
UnifyType t2 = UnifyTypeFactory.convert(cl.getSuperClass());
pairs.add(generateSmallerPair(t1, t2));
} }
return new FiniteClosure(pairs); return new FiniteClosure(pairs);
} }
/**
* Bildet eine Kette vom übergebenen Typ bis hin zum höchsten bekannten Typ
* Als Generics werden TPHs benutzt, welche der Unifikationsalgorithmus korrekt interpretieren muss.
* Die verwendeten TPHs werden in der Kette nach oben gereicht, so erhält der selbe GTV immer den selben TPH
* @param forType
* @return
*/
private static List<UnifyPair> getSuperTypes(ClassOrInterface forType, List<ClassOrInterface> availableClasses) throws ClassNotFoundException {
return getSuperTypes(forType, availableClasses, new HashMap<>());
}
private static List<UnifyPair> getSuperTypes(ClassOrInterface forType, List<ClassOrInterface> availableClasses, HashMap<String, PlaceholderType> gtvs) throws ClassNotFoundException {
List<UnifyType> params = new ArrayList<>();
//Generics mit gleichem Namen müssen den selben TPH bekommen
for(GenericTypeVar gtv : forType.getGenerics()){
if(!gtvs.containsKey(gtv.getParsedName()))
gtvs.put(gtv.getParsedName(), PlaceholderType.freshPlaceholder());
params.add(gtvs.get(gtv.getParsedName()));
}
Optional<ClassOrInterface> hasSuperclass = availableClasses.stream().filter(cl -> forType.getSuperClass().getName().equals(cl.getClassName())).findAny();
ClassOrInterface superClass;
if(!hasSuperclass.isPresent()) //TODO: Wenn es die Object-Klasse ist, dann ist es in Ordnung, ansonsten Fehler ausgeben:
{
superClass = ASTFactory.createClass(ClassLoader.getSystemClassLoader().loadClass(forType.getSuperClass().getName().toString()));
}else{
superClass = hasSuperclass.get();
}
List<UnifyPair> superTypes;
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
superTypes = Arrays.asList(generateSmallerPair(convert(ASTFactory.createObjectType()), convert(ASTFactory.createObjectType())));
}else{
superTypes = getSuperTypes(superClass, availableClasses, gtvs);
}
TypeParams paramList = new TypeParams(params);
UnifyType t1 = new ReferenceType(forType.getClassName().toString(), paramList);
UnifyType t2 = superTypes.get(0).getLhsType();
UnifyPair ret = generateSmallerPair(t1, t2);
List<UnifyPair> retList = new ArrayList<>();
retList.add(ret);
retList.addAll(superTypes);
return retList;
}
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){ public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){
return new UnifyPair(tl, tr, PairOperator.SMALLER); return new UnifyPair(tl, tr, PairOperator.SMALLER);
} }

View File

@ -31,7 +31,7 @@ public class NewClass extends MethodCall
* @param start * @param start
*/ */
public NewClass(RefType newClass, ArgumentList args, Token start) { public NewClass(RefType newClass, ArgumentList args, Token start) {
super(newClass, new Receiver(new EmptyStmt(start)), newClass.getName().toString(), args, start); super(newClass, new ExpressionReceiver(new EmptyStmt(start)), newClass.getName().toString(), args, start);
} }
@Override @Override

View File

@ -1,26 +1,12 @@
package de.dhbwstuttgart.syntaxtree.statement; package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor; public abstract class Receiver extends Expression
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
public class Receiver extends Expression
{ {
public Expression expr; public Receiver(RefTypeOrTPHOrWildcardOrGeneric type, Token offset)
/**
* Autor: ¯Â¿Â½rg ¯Â¿Â½uerle
* @param expr
*/
public Receiver(Expression expr)
{ {
super(expr.getType(), expr.getOffset()); super(type, offset);
this.expr = expr;
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
} }
} }

View File

@ -8,7 +8,7 @@ import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
public class StaticClassName extends Expression { public class StaticClassName extends Receiver {
public StaticClassName(JavaClassName className, Token offset) { public StaticClassName(JavaClassName className, Token offset) {
super(new RefType(className, offset), offset); super(new RefType(className, offset), offset);
} }

View File

@ -17,7 +17,7 @@ public class SuperCall extends MethodCall
} }
public SuperCall(ArgumentList argumentList, Token offset){ public SuperCall(ArgumentList argumentList, Token offset){
super(new Void(offset), new Receiver(new This(offset)), "<init>", argumentList, offset); super(new Void(offset), new ExpressionReceiver(new This(offset)), "<init>", argumentList, offset);
} }

View File

@ -270,11 +270,6 @@ public class OutputGenerator implements ASTVisitor {
} }
@Override
public void visit(Receiver receiver) {
receiver.expr.accept(this);
}
@Override @Override
public void visit(Return aReturn) { public void visit(Return aReturn) {
out.append("return "); out.append("return ");
@ -349,4 +344,9 @@ public class OutputGenerator implements ASTVisitor {
superCall.arglist.accept(this); superCall.arglist.accept(this);
out.append(")"); out.append(")");
} }
@Override
public void visit(ExpressionReceiver receiver) {
receiver.expr.accept(this);
}
} }

View File

@ -181,7 +181,7 @@ public class TypeOutputGenerator extends OutputGenerator {
} }
@Override @Override
public void visit(Receiver receiver) { public void visit(ExpressionReceiver receiver) {
super.visit(receiver); super.visit(receiver);
} }

View File

@ -1,21 +1,22 @@
package de.dhbwstuttgart.typeinference.assumptions; package de.dhbwstuttgart.typeinference.assumptions;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class FieldAssumption extends Assumption{ public class FieldAssumption extends Assumption{
private RefTypeOrTPHOrWildcardOrGeneric receiverType; private ClassOrInterface receiverClass;
private RefTypeOrTPHOrWildcardOrGeneric type; private RefTypeOrTPHOrWildcardOrGeneric type;
public FieldAssumption(RefTypeOrTPHOrWildcardOrGeneric receiverType, public FieldAssumption(ClassOrInterface receiverType,
RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope){ RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope){
super(scope); super(scope);
this.type = type; this.type = type;
this.receiverType = receiverType; this.receiverClass = receiverType;
} }
public RefTypeOrTPHOrWildcardOrGeneric getReceiverType() { public ClassOrInterface getReceiverClass() {
return receiverType; return receiverClass;
} }
public RefTypeOrTPHOrWildcardOrGeneric getType() { public RefTypeOrTPHOrWildcardOrGeneric getType() {

View File

@ -1,5 +1,6 @@
package de.dhbwstuttgart.typeinference.assumptions; package de.dhbwstuttgart.typeinference.assumptions;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.statement.Assign; import de.dhbwstuttgart.syntaxtree.statement.Assign;
@ -10,11 +11,11 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class MethodAssumption extends Assumption{ public class MethodAssumption extends Assumption{
private RefType receiver; private ClassOrInterface receiver;
private RefTypeOrTPHOrWildcardOrGeneric retType; private RefTypeOrTPHOrWildcardOrGeneric retType;
List<RefTypeOrTPHOrWildcardOrGeneric> params; List<RefTypeOrTPHOrWildcardOrGeneric> params;
public MethodAssumption(RefType receiver, RefTypeOrTPHOrWildcardOrGeneric retType, public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType,
List<RefTypeOrTPHOrWildcardOrGeneric> params, TypeScope scope){ List<RefTypeOrTPHOrWildcardOrGeneric> params, TypeScope scope){
super(scope); super(scope);
this.receiver = receiver; this.receiver = receiver;
@ -22,7 +23,14 @@ public class MethodAssumption extends Assumption{
this.params = params; this.params = params;
} }
/*
public RefType getReceiverType() { public RefType getReceiverType() {
return receiver;
}
*/
public ClassOrInterface getReceiver(){
return receiver; return receiver;
} }

View File

@ -46,7 +46,8 @@ public class TypeInferenceInformation {
for(ClassOrInterface cl : classes){ for(ClassOrInterface cl : classes){
for(Field m : cl.getFieldDecl()){ for(Field m : cl.getFieldDecl()){
if(m.getName().equals(name)){ if(m.getName().equals(name)){
ret.add(new FieldAssumption(cl.getType(), checkGTV(m.getType()), new TypeScopeContainer(cl, m)));
ret.add(new FieldAssumption(cl, checkGTV(m.getType()), new TypeScopeContainer(cl, m)));
} }
} }
} }

View File

@ -1,58 +0,0 @@
package de.dhbwstuttgart.typeinference.constraints;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ConstraintsFactory {
public static Pair createPair(RefTypeOrTPHOrWildcardOrGeneric t1, RefTypeOrTPHOrWildcardOrGeneric t2,
PairOperator equalsdot, TypeScope currentScope, TypeScope additionalScope,
GenericsResolver resolver){
//Check whether Generics are in the same class and resolve all other generics:
return new Pair(checkGeneric(t1, currentScope, additionalScope,resolver),
checkGeneric(t2, currentScope,additionalScope, resolver), equalsdot);
}
public static Pair createPair(RefTypeOrTPHOrWildcardOrGeneric t1,
RefTypeOrTPHOrWildcardOrGeneric t2, TypeScope currentScope, TypeScope additionalScope,
GenericsResolver resolver){
return createPair(t1,t2,PairOperator.SMALLERDOT, currentScope, additionalScope, resolver);
}
private static RefTypeOrTPHOrWildcardOrGeneric checkGeneric(RefTypeOrTPHOrWildcardOrGeneric type,
TypeScope currentScope, TypeScope additionalScope,
GenericsResolver resolver){
if(type instanceof GenericRefType){
//TODO: Für Generics müssen auch noch Constraints generiert werden
for(GenericTypeVar genericTypeVar : currentScope.getGenerics()){
if(genericTypeVar.getName().toString().equals(((GenericRefType)type).getName().toString())){
return new RefType(((GenericRefType)type).getName(),type.getOffset());
}
}
//Nicht in den Generics in diesem Kontext enthalten:
TypePlaceholder ret = null;
for(GenericTypeVar genericTypeVar : additionalScope.getGenerics()){
if(genericTypeVar.getName().equals(((GenericRefType)type).getName())){
ret = resolver.resolve(genericTypeVar);
}
}
if(ret == null)
throw new DebugException("Der Generic " + ((GenericRefType) type).getName() + " kommt in keine TypeScope vor!");
return ret;
}else{
return type;
}
}
}

View File

@ -6,14 +6,12 @@ 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.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.parser.antlr.Java8Parser;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
import de.dhbwstuttgart.syntaxtree.type.FunN; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption; import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
@ -113,8 +111,10 @@ 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();
/*TODO Hier muss der Typ der Klasse ermittelt werden. In diesem müssen Generics mit TPHs ausgetauscht werden
constraint.add(ConstraintsFactory.createPair( constraint.add(ConstraintsFactory.createPair(
fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver));
*/
constraint.add(ConstraintsFactory.createPair( constraint.add(ConstraintsFactory.createPair(
fieldVar.getType(),fieldAssumption.getType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); fieldVar.getType(),fieldAssumption.getType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver));
oderConstraints.add(constraint); oderConstraints.add(constraint);
@ -122,6 +122,9 @@ public class TYPEStmt implements StatementVisitor{
if(oderConstraints.size() == 0) if(oderConstraints.size() == 0)
throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset()); throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints); constraintsSet.addOderConstraint(oderConstraints);
//Wegen dem Problem oben:
throw new NotImplementedException();
} }
@Override @Override
@ -184,7 +187,7 @@ public class TYPEStmt implements StatementVisitor{
} }
@Override @Override
public void visit(Receiver receiver) { public void visit(ExpressionReceiver receiver) {
receiver.expr.accept(this); receiver.expr.accept(this);
} }
@ -213,8 +216,15 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(This aThis) { public void visit(This aThis) {
//Im Falle von this, müssen die Generics in der Klasse als RefTypes behandelt werden.
ClassOrInterface currentClass = info.getCurrentClass();
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar gtv : currentClass.getGenerics()){
params.add(new GenericRefType(gtv.getName(), aThis.getOffset()));
}
RefType thisType = new RefType(currentClass.getClassName(), params, aThis.getOffset());
constraintsSet.addUndConstraint(ConstraintsFactory.createPair( constraintsSet.addUndConstraint(ConstraintsFactory.createPair(
aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info.getCurrentTypeScope(), aThis.getType(), thisType, PairOperator.EQUALSDOT, info.getCurrentTypeScope(),
createNullTypeScope(), getResolverInstance())); createNullTypeScope(), getResolverInstance()));
} }
@ -280,10 +290,21 @@ public class TYPEStmt implements StatementVisitor{
protected Constraint<Pair> generateConstraint(MethodCall forMethod, MethodAssumption assumption, protected Constraint<Pair> generateConstraint(MethodCall forMethod, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver){ TypeInferenceBlockInformation info, GenericsResolver resolver){
Constraint methodConstraint = new Constraint(); Constraint methodConstraint = new Constraint();
methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), assumption.getReceiverType(), ClassOrInterface receiverCl = assumption.getReceiver();
PairOperator.SMALLERDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(), for(GenericTypeVar gtv : receiverCl.getGenerics()){
PairOperator.EQUALSDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); //if(gtv.definingClass().equals(info.getCurrentClass().getClassName())){
// params.add(new GenericRefType(gtv.getName(), forMethod.getOffset()));
//}else{
//Die Generics werden alle zu TPHs umgewandelt.
params.add(TypePlaceholder.fresh(forMethod.getOffset()));
//}
}
RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
methodConstraint.add(new Pair(forMethod.receiver.getType(), receiverType,
PairOperator.SMALLERDOT);
methodConstraint.add(new Pair(assumption.getReturnType(), forMethod.getType(),
PairOperator.EQUALSDOT));
methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info, resolver)); methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info, resolver));
return methodConstraint; return methodConstraint;
} }
@ -302,6 +323,7 @@ public class TYPEStmt implements StatementVisitor{
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) { public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) {
List<MethodAssumption> ret = new ArrayList<>(); List<MethodAssumption> ret = new ArrayList<>();
/*
if(name.equals("apply")){ if(name.equals("apply")){
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
for(int i = 0; i< numArgs + 1 ; i++){ for(int i = 0; i< numArgs + 1 ; i++){
@ -320,13 +342,14 @@ public class TYPEStmt implements StatementVisitor{
} }
})); }));
} }
*/
for(ClassOrInterface cl : info.getAvailableClasses()){ for(ClassOrInterface cl : info.getAvailableClasses()){
for(Method m : cl.getMethods()){ for(Method m : cl.getMethods()){
if(m.getName().equals(name) && if(m.getName().equals(name) &&
m.getParameterList().getFormalparalist().size() == numArgs){ m.getParameterList().getFormalparalist().size() == numArgs){
RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getType()); RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getType());
ret.add(new MethodAssumption(cl.getType(), retType, convertParams(m.getParameterList(),info), ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(),info),
createTypeScope(cl, m))); createTypeScope(cl, m)));
} }
} }
@ -361,7 +384,7 @@ public class TYPEStmt implements StatementVisitor{
if(cl.getClassName().equals(ofType.getName())){ if(cl.getClassName().equals(ofType.getName())){
for(Method m : cl.getConstructors()){ for(Method m : cl.getConstructors()){
if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){ if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){
ret.add(new MethodAssumption(cl.getType(), ofType, convertParams(m.getParameterList(), ret.add(new MethodAssumption(cl, ofType, convertParams(m.getParameterList(),
info), createTypeScope(cl, m))); info), createTypeScope(cl, m)));
} }
} }

View File

@ -17,17 +17,18 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
* @author Florian Steurer * @author Florian Steurer
*/ */
public class FiniteClosure implements IFiniteClosure { public class FiniteClosure implements IFiniteClosure {
/** /**
* A map that maps every type to the node in the inheritance graph that contains that type. * A map that maps every type to the node in the inheritance graph that contains that type.
*/ */
private HashMap<UnifyType, Node<UnifyType>> inheritanceGraph; private HashMap<UnifyType, Node<UnifyType>> inheritanceGraph;
/** /**
* A map that maps every typename to the nodes of the inheritance graph that contain a type with that name. * A map that maps every typename to the nodes of the inheritance graph that contain a type with that name.
*/ */
private HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph; private HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph;
/** /**
* The initial pairs of that define the inheritance tree * The initial pairs of that define the inheritance tree
*/ */
@ -38,7 +39,7 @@ public class FiniteClosure implements IFiniteClosure {
*/ */
public FiniteClosure(Set<UnifyPair> pairs) { public FiniteClosure(Set<UnifyPair> pairs) {
this.pairs = new HashSet<>(pairs); this.pairs = new HashSet<>(pairs);
inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>(); inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>();
// Build the transitive closure of the inheritance tree // Build the transitive closure of the inheritance tree
for(UnifyPair pair : pairs) { for(UnifyPair pair : pairs) {
@ -46,7 +47,7 @@ public class FiniteClosure implements IFiniteClosure {
continue; continue;
// Add nodes if not already in the graph // Add nodes if not already in the graph
if(!inheritanceGraph.containsKey(pair.getLhsType())) if(!inheritanceGraph.containsKey(pair.getLhsType()))
inheritanceGraph.put(pair.getLhsType(), new Node<UnifyType>(pair.getLhsType())); inheritanceGraph.put(pair.getLhsType(), new Node<UnifyType>(pair.getLhsType()));
if(!inheritanceGraph.containsKey(pair.getRhsType())) if(!inheritanceGraph.containsKey(pair.getRhsType()))
inheritanceGraph.put(pair.getRhsType(), new Node<UnifyType>(pair.getRhsType())); inheritanceGraph.put(pair.getRhsType(), new Node<UnifyType>(pair.getRhsType()));
@ -61,7 +62,7 @@ public class FiniteClosure implements IFiniteClosure {
parentNode.getPredecessors().stream().forEach(x -> x.addDescendant(childNode)); parentNode.getPredecessors().stream().forEach(x -> x.addDescendant(childNode));
childNode.getDescendants().stream().forEach(x -> x.addPredecessor(parentNode)); childNode.getDescendants().stream().forEach(x -> x.addPredecessor(parentNode));
} }
// Build the alternative representation with strings as keys // Build the alternative representation with strings as keys
strInheritanceGraph = new HashMap<>(); strInheritanceGraph = new HashMap<>();
for(UnifyType key : inheritanceGraph.keySet()) { for(UnifyType key : inheritanceGraph.keySet()) {
@ -75,7 +76,7 @@ public class FiniteClosure implements 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.
*/ */
@Override @Override
public Set<UnifyType> smaller(UnifyType type) { public Set<UnifyType> smaller(UnifyType type) {
if(type instanceof FunNType) if(type instanceof FunNType)
@ -156,7 +157,7 @@ public class FiniteClosure implements IFiniteClosure {
/** /**
* 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.
*/ */
@Override @Override
public Set<UnifyType> greater(UnifyType type) { public Set<UnifyType> greater(UnifyType type) {
if(type instanceof FunNType) if(type instanceof FunNType)
@ -240,7 +241,7 @@ public class FiniteClosure implements IFiniteClosure {
return type.grArg(this); return type.grArg(this);
} }
@Override @Override
public Set<UnifyType> grArg(ReferenceType type) { public Set<UnifyType> grArg(ReferenceType type) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
@ -249,7 +250,7 @@ public class FiniteClosure implements IFiniteClosure {
return result; return result;
} }
@Override @Override
public Set<UnifyType> grArg(FunNType type) { public Set<UnifyType> grArg(FunNType type) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
@ -267,7 +268,7 @@ public class FiniteClosure implements IFiniteClosure {
return result; return result;
} }
@Override @Override
public Set<UnifyType> grArg(SuperType type) { public Set<UnifyType> grArg(SuperType type) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
@ -276,11 +277,11 @@ public class FiniteClosure implements IFiniteClosure {
return result; return result;
} }
@Override @Override
public Set<UnifyType> grArg(PlaceholderType type) { public Set<UnifyType> grArg(PlaceholderType type) {
HashSet<UnifyType> result = new HashSet<>(); HashSet<UnifyType> result = new HashSet<>();
result.add(type); result.add(type);
return result; return result;
} }
@Override @Override
@ -288,12 +289,12 @@ public class FiniteClosure implements IFiniteClosure {
return type.smArg(this); return type.smArg(this);
} }
@Override @Override
public Set<UnifyType> smArg(ReferenceType type) { public Set<UnifyType> smArg(ReferenceType type) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
return result; return result;
} }
@Override @Override
public Set<UnifyType> smArg(FunNType type) { public Set<UnifyType> smArg(FunNType type) {
@ -316,7 +317,7 @@ public class FiniteClosure implements IFiniteClosure {
} }
@Override @Override
public Set<UnifyType> smArg(SuperType type) { public Set<UnifyType> smArg(SuperType type) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
@ -329,20 +330,20 @@ public class FiniteClosure implements IFiniteClosure {
return result; return result;
} }
@Override @Override
public Set<UnifyType> smArg(PlaceholderType type) { public Set<UnifyType> smArg(PlaceholderType type) {
HashSet<UnifyType> result = new HashSet<>(); HashSet<UnifyType> result = new HashSet<>();
result.add(type); result.add(type);
return result; return result;
} }
@Override @Override
public Set<UnifyType> getAllTypesByName(String typeName) { public Set<UnifyType> getAllTypesByName(String typeName) {
if(!strInheritanceGraph.containsKey(typeName)) if(!strInheritanceGraph.containsKey(typeName))
return new HashSet<>(); return new HashSet<>();
return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new)); return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new));
} }
@Override @Override
public Optional<UnifyType> getLeftHandedType(String typeName) { public Optional<UnifyType> getLeftHandedType(String typeName) {
if(!strInheritanceGraph.containsKey(typeName)) if(!strInheritanceGraph.containsKey(typeName))
@ -392,7 +393,7 @@ public class FiniteClosure implements IFiniteClosure {
* @param result Set of all permutations found so far * @param result Set of all permutations found so far
* @param current The permutation of type params that is currently explored * @param current The permutation of type params that is currently explored
*/ */
protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) { protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
if(candidates.size() == idx) { if(candidates.size() == idx) {
result.add(new TypeParams(Arrays.copyOf(current, current.length))); result.add(new TypeParams(Arrays.copyOf(current, current.length)));
return; return;

View File

@ -24,8 +24,10 @@ public final class TypeParams implements Iterable<UnifyType>{
*/ */
public TypeParams(List<UnifyType> types){ public TypeParams(List<UnifyType> types){
typeParams = new UnifyType[types.size()]; typeParams = new UnifyType[types.size()];
for(int i=0;i<types.size();i++) for(int i=0;i<types.size();i++){
typeParams[i] = types.get(i); typeParams[i] = types.get(i);
if(types.get(i)==null)throw new NullPointerException();
}
// Hashcode calculation is expensive and must be cached. // Hashcode calculation is expensive and must be cached.
hashCode = Arrays.deepHashCode(typeParams); hashCode = Arrays.deepHashCode(typeParams);
@ -149,7 +151,11 @@ public final class TypeParams implements Iterable<UnifyType>{
if(other.size() != this.size()) if(other.size() != this.size())
return false; return false;
for(int i = 0; i < this.size(); i++){
if(this.get(i) == null)
System.out.print("s");
}
for(int i = 0; i < this.size(); i++) for(int i = 0; i < this.size(); i++)
if(!(this.get(i).equals(other.get(i)))) if(!(this.get(i).equals(other.get(i))))
return false; return false;

View File

@ -1,5 +1,16 @@
import java.util.Vector; import java.util.Vector;
class Matrix extends Vector<Vector<Integer>> {
methode(Matrix m) {
Vector<Vector<Integer>> i;
methode(i);
}
}
/*
import java.util.Vector;
class Matrix extends Vector<Vector<Integer>> { class Matrix extends Vector<Vector<Integer>> {
Matrix mul_rec(Matrix m) { Matrix mul_rec(Matrix m) {
@ -39,4 +50,5 @@ class Matrix extends Vector<Vector<Integer>> {
} }
return ret; return ret;
} }
} }
*/

View File

@ -0,0 +1,4 @@
class C1 extends Object
{
m(para) { return para; }
}

View File

@ -5,7 +5,9 @@ import static org.junit.Assert.*;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.parser.JavaTXParser; import de.dhbwstuttgart.parser.JavaTXParser;
import org.junit.Test; import org.junit.Test;
@ -25,6 +27,7 @@ public class GeneralParserTest{
List<String> filenames = new ArrayList<String>(); List<String> filenames = new ArrayList<String>();
/*
filenames.add("NewTest.jav"); filenames.add("NewTest.jav");
filenames.add("FieldInitializationTest.jav"); filenames.add("FieldInitializationTest.jav");
filenames.add("ImportTest.jav"); filenames.add("ImportTest.jav");
@ -37,13 +40,10 @@ public class GeneralParserTest{
//filenames.add("GenericFieldVarTest.jav"); //filenames.add("GenericFieldVarTest.jav");
filenames.add("FieldVarTest.jav"); filenames.add("FieldVarTest.jav");
filenames.add("StructuralTypes.jav"); filenames.add("StructuralTypes.jav");
JavaTXParser parser = new JavaTXParser(); */
filenames.add("ExtendsTest.jav");
try{ try{
for(String filename : filenames) { new JavaTXCompiler(filenames.stream().map(s -> new File(rootDirectory + s)).collect(Collectors.toList()));
System.out.println("Teste: "+filename);
parser.parse(new File(rootDirectory + filename));
//TODO: Test ANTLR Parser
}
}catch(Exception exc){ }catch(Exception exc){
exc.printStackTrace(); exc.printStackTrace();
fail(); fail();

View File

@ -37,6 +37,7 @@ public class JavaTXCompilerTest {
//filesToTest.add(new File(rootDirectory+"mathStruc.jav")); //filesToTest.add(new File(rootDirectory+"mathStruc.jav"));
//filesToTest.add(new File(rootDirectory+"test.jav")); //filesToTest.add(new File(rootDirectory+"test.jav"));
filesToTest.add(new File(rootDirectory+"EmptyMethod.jav")); filesToTest.add(new File(rootDirectory+"EmptyMethod.jav"));
//filesToTest.add(new File(rootDirectory+"fc.jav"));
//filesToTest.add(new File(rootDirectory+"Lambda.jav")); //filesToTest.add(new File(rootDirectory+"Lambda.jav"));
//filesToTest.add(new File(rootDirectory+"Lambda2.jav")); //filesToTest.add(new File(rootDirectory+"Lambda2.jav"));
//filesToTest.add(new File(rootDirectory+"Lambda3.jav")); //filesToTest.add(new File(rootDirectory+"Lambda3.jav"));