diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index 6f0ac91e..425582ad 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import de.dhbwstuttgart.syntaxtree.statement.*; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.MethodVisitor; @@ -12,33 +13,6 @@ import org.objectweb.asm.Opcodes; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; 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.Null; 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 public void visit(Return aReturn) { // TODO Auto-generated method stub @@ -379,8 +347,13 @@ public class BytecodeGen implements ASTVisitor { @Override public void visit(SuperCall superCall) { - // TODO Auto-generated method stub } + @Override + public void visit(ExpressionReceiver expressionReceiver) { + // TODO Auto-generated method stub + + } + } diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenLambda.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenLambda.java index 4b1557b0..679a1365 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenLambda.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenLambda.java @@ -1,36 +1,10 @@ package de.dhbwstuttgart.bytecode; +import de.dhbwstuttgart.syntaxtree.statement.*; import org.objectweb.asm.MethodVisitor; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; 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.Null; @@ -142,7 +116,7 @@ public class BytecodeGenLambda implements StatementVisitor{ } @Override - public void visit(Receiver receiver) { + public void visit(ExpressionReceiver receiver) { // TODO Auto-generated method stub } diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index c65e691c..d92ebfc3 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -8,6 +8,7 @@ import java.lang.invoke.MethodType; import java.security.GeneralSecurityException; import java.util.HashMap; +import de.dhbwstuttgart.syntaxtree.statement.*; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Handle; import org.objectweb.asm.MethodVisitor; @@ -17,35 +18,6 @@ import org.objectweb.asm.Type; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.syntaxtree.Method; 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.Null; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; @@ -230,14 +202,19 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(MethodCall methodCall) { 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.arglist.accept(this); 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); // test if(!methodCall.getType().toString().equals("V")) { @@ -270,7 +247,7 @@ public class BytecodeGenMethod implements StatementVisitor{ } @Override - public void visit(Receiver receiver) { + public void visit(ExpressionReceiver receiver) { System.out.println(" in Receiver"); System.out.println(" expr : " + receiver.expr); receiver.expr.accept(this); diff --git a/src/de/dhbwstuttgart/environment/CompilationEnvironment.java b/src/de/dhbwstuttgart/environment/CompilationEnvironment.java index 46a60139..9a632674 100644 --- a/src/de/dhbwstuttgart/environment/CompilationEnvironment.java +++ b/src/de/dhbwstuttgart/environment/CompilationEnvironment.java @@ -60,4 +60,13 @@ public class CompilationEnvironment { allNames = GatherNames.getNames(tree, new PackageCrawler(librarys)); return new JavaClassRegistry(allNames); } + + public List getAllAvailableClasses() { + List ret = new ArrayList<>(); + for(Class c : new PackageCrawler(librarys).getAllAvailableClasses()){ + ret.add(ASTFactory.createClass(c)); + } + return ret; + } + } diff --git a/src/de/dhbwstuttgart/environment/PackageCrawler.java b/src/de/dhbwstuttgart/environment/PackageCrawler.java index e1e4b70c..cec63562 100644 --- a/src/de/dhbwstuttgart/environment/PackageCrawler.java +++ b/src/de/dhbwstuttgart/environment/PackageCrawler.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.environment; import java.net.URL; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Set; import org.reflections.Reflections; @@ -12,6 +13,7 @@ import org.reflections.util.ConfigurationBuilder; import org.reflections.util.FilterBuilder; import de.dhbwstuttgart.parser.scope.JavaClassName; +import org.reflections.vfs.SystemDir; /** * Hilft beim Durchsuchen von Packages @@ -54,9 +56,22 @@ public class PackageCrawler { return classes; } + public Set> getAllAvailableClasses(){ + Reflections reflections = new Reflections(new ConfigurationBuilder() + .setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner()) + .setUrls(urls)); + + Set> classes = reflections.getSubTypesOf(Object.class); + + return classes; + } + public List getClassNames(String packageName){ List nameList = new ArrayList(); Set> classes = getClassesInPackage(packageName); + if(packageName.equals("java.lang") && ! classes.contains(Object.class)) { + classes.add(Object.class); + } for(Class c : classes){ nameList.add(c.getName()); } diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java index 9da5777d..f4ada6b2 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java @@ -179,6 +179,14 @@ public class StatementGenerator { }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) { String name; if(methodInvocationContext.methodName()!=null){ @@ -200,7 +208,7 @@ public class StatementGenerator { }else throw new NotImplementedException(); 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; } @@ -701,7 +709,7 @@ public class StatementGenerator { }else { Java8Parser.MethodInvocation_lf_primaryContext ctxt = e.methodInvocation_lf_primary(); 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()); - 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; } diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index e51972ab..ed9d82e2 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator; import de.dhbwstuttgart.exceptions.NotImplementedException; import java.lang.ClassNotFoundException; +import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.parser.antlr.Java8Parser; import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.JavaClassName; @@ -15,6 +16,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import java.lang.reflect.Modifier; +import java.sql.Ref; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -182,13 +184,13 @@ public class SyntaxTreeGenerator{ block = stmtGen.convert(body.block()); } 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{ 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; if(ctx.normalClassDeclaration() != null){ newClass = convertNormal(ctx.normalClassDeclaration()); @@ -199,7 +201,7 @@ public class SyntaxTreeGenerator{ return newClass; } - private ClassOrInterface convertNormal(Java8Parser.NormalClassDeclarationContext ctx){ + private ClassOrInterface convertNormal(Java8Parser.NormalClassDeclarationContext ctx) { int modifiers = 0; if(ctx.classModifier() != null){ for(Java8Parser.ClassModifierContext mod : ctx.classModifier()){ @@ -220,7 +222,7 @@ public class SyntaxTreeGenerator{ if(ctx.superclass() != null){ superClass = convert(ctx.superclass()); }else{ - superClass = ASTFactory.createObjectClass().getType(); + superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart()); } List fielddecl = convertFields(ctx.classBody(), generics); List methods = convertMethods(ctx.classBody(), name, superClass, generics); @@ -267,11 +269,21 @@ public class SyntaxTreeGenerator{ int modifiers = 0; ParameterList params = new ParameterList(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) { - 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 convertMethods(Java8Parser.ClassBodyContext classBodyContext, @@ -422,7 +434,7 @@ public class SyntaxTreeGenerator{ }else{ genericParams = createEmptyGenericDeclarationList(ctx.Identifier()); } - RefType superClass = ASTFactory.createObjectClass().getType(); + RefType superClass = ASTFactory.createObjectType(); List fields = convertFields(ctx.interfaceBody()); List methods = convertMethods(ctx.interfaceBody(), name, superClass, generics); diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java index ed0f06af..b5042fba 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java @@ -77,7 +77,7 @@ public class TypeGenerator { public static List convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) { List ret = new ArrayList<>(); if(typeBoundContext == null){ - ret.add(ASTFactory.createObjectClass().getType()); + ret.add(ASTFactory.createObjectType()); return ret; } if(typeBoundContext.typeVariable() != null){ @@ -105,7 +105,16 @@ public class TypeGenerator { } 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){ diff --git a/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java b/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java index 0cee932f..c5355ebd 100644 --- a/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java +++ b/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java @@ -19,4 +19,8 @@ public class GenericTypeName extends JavaClassName { + DELIMITER + methodName + DELIMITER + super.toString(); } + + public JavaClassName getParentClass() { + return parentClass; + } } diff --git a/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java b/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java index cd3027f5..50b4b470 100644 --- a/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java +++ b/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java @@ -200,7 +200,7 @@ public abstract class AbstractASTWalker implements ASTVisitor{ } @Override - public void visit(Receiver receiver) { + public void visit(ExpressionReceiver receiver) { receiver.expr.accept(this); } diff --git a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java index 540bc993..5d5fc3e2 100644 --- a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java +++ b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java @@ -60,10 +60,12 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{ return this.methods; } + /* public RefType getType() { 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){ //Hier wird immer ein generischer Typ generiert, also mit Type placeholdern List params = new ArrayList<>(); @@ -74,6 +76,10 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{ return new RefType(name, params, offset); } + /** + * Die Superklasse im Kontext dieser ClassOrInterface + * Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind + */ public RefType getSuperClass() { return superClass; } diff --git a/src/de/dhbwstuttgart/syntaxtree/Constructor.java b/src/de/dhbwstuttgart/syntaxtree/Constructor.java index 2fdfb04e..bb48be40 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Constructor.java +++ b/src/de/dhbwstuttgart/syntaxtree/Constructor.java @@ -15,8 +15,8 @@ public class Constructor extends Method { //TODO: Constructor braucht ein super-Statement public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor, - GenericDeclarationList gtvDeclarations, Token offset, List fieldInitializations, RefType superClass) { - super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations, superClass), gtvDeclarations, offset); + GenericDeclarationList gtvDeclarations, Token offset, List fieldInitializations) { + 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 * Konstruktor initialisieren */ - protected static Block prepareBlock(Block constructorBlock, List fieldInitializations, RefType superClass){ + protected static Block prepareBlock(Block constructorBlock, List fieldInitializations){ List statements = constructorBlock.getStatements(); statements.add(0, new SuperCall(constructorBlock.getOffset())); return new Block(statements, constructorBlock.getOffset()); diff --git a/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java b/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java index c43fe068..02042ca3 100644 --- a/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java +++ b/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.syntaxtree; import de.dhbwstuttgart.parser.scope.GenericTypeName; +import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import org.antlr.v4.runtime.Token; @@ -53,6 +54,14 @@ public class GenericTypeVar extends SyntaxTreeNode return name; } + public String getParsedName(){ + return name.toString(); + } + + public JavaClassName definingClass(){ + return name.getParentClass(); + } + @Override public void accept(ASTVisitor visitor) { visitor.visit(this); diff --git a/src/de/dhbwstuttgart/syntaxtree/StatementVisitor.java b/src/de/dhbwstuttgart/syntaxtree/StatementVisitor.java index b63e0438..195db230 100644 --- a/src/de/dhbwstuttgart/syntaxtree/StatementVisitor.java +++ b/src/de/dhbwstuttgart/syntaxtree/StatementVisitor.java @@ -40,8 +40,6 @@ public interface StatementVisitor { void visit(NewArray newArray); - void visit(Receiver receiver); - void visit(Return aReturn); void visit(ReturnVoid aReturn); @@ -67,4 +65,6 @@ public interface StatementVisitor { void visit(AssignToLocal assignLeftSide); void visit(SuperCall superCall); + + void visit(ExpressionReceiver expressionReceiver); } diff --git a/src/de/dhbwstuttgart/syntaxtree/TypeScope.java b/src/de/dhbwstuttgart/syntaxtree/TypeScope.java index 3631eb2e..f651648b 100644 --- a/src/de/dhbwstuttgart/syntaxtree/TypeScope.java +++ b/src/de/dhbwstuttgart/syntaxtree/TypeScope.java @@ -2,6 +2,8 @@ package de.dhbwstuttgart.syntaxtree; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import java.util.Collection; + public interface TypeScope { Iterable getGenerics(); diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java index b3f628a7..046b97b8 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java @@ -5,6 +5,7 @@ import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; +import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext; import de.dhbwstuttgart.parser.scope.GenericTypeName; @@ -45,7 +46,11 @@ public class ASTFactory { java.lang.Class superjreClass = jreClass.getSuperclass(); RefType superClass; if(superjreClass != null){ - superClass = (RefType) createType(superjreClass, name, ""); + List 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!) superClass = (RefType) createType(java.lang.Object.class, name, ""); } @@ -83,13 +88,12 @@ public class ASTFactory { return null; } - return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>(), - createType(inClass.getSuperclass())); + return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>()); } - private static RefType createType(Class classType) { - return createClass(classType).getType(); - } + //private static RefType createType(Class classType) { + // return createClass(classType).getType(); + //} public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){ String name = jreMethod.getName(); @@ -182,6 +186,9 @@ public class ASTFactory { public static ClassOrInterface createObjectClass() { return createClass(Object.class); } + public static RefType createObjectType() { + return new RefType(createClass(Object.class).getClassName(), new NullToken()); + } /* public Constructor createEmptyConstructor(Class parent){ diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index c154e86f..7ad15acc 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -3,11 +3,13 @@ package de.dhbwstuttgart.syntaxtree.factory; import java.util.*; import java.util.stream.Collectors; +import de.dhbwstuttgart.environment.CompilationEnvironment; import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.Void; 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.UnifyType; - public class UnifyTypeFactory { - public static FiniteClosure generateFC(List fromAvailableClasses){ + public static FiniteClosure generateFC(List fromClasses) throws ClassNotFoundException { + /* + TODO: Generics werden zu TPHs + Die transitive Hülle muss funktionieren. + Man darf schreiben List extends AL + und Vector extends List + 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 pairs = new HashSet<>(); - for(ClassOrInterface cl : fromAvailableClasses){ - UnifyType t1 = UnifyTypeFactory.convert(cl.getType()); - UnifyType t2 = UnifyTypeFactory.convert(cl.getSuperClass()); - pairs.add(generateSmallerPair(t1, t2)); + for(ClassOrInterface cly : fromClasses){ + pairs.addAll(getSuperTypes(cly, fromClasses)); } 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 getSuperTypes(ClassOrInterface forType, List availableClasses) throws ClassNotFoundException { + return getSuperTypes(forType, availableClasses, new HashMap<>()); + } + + private static List getSuperTypes(ClassOrInterface forType, List availableClasses, HashMap gtvs) throws ClassNotFoundException { + List 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 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 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 retList = new ArrayList<>(); + retList.add(ret); + retList.addAll(superTypes); + + return retList; + } + public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){ return new UnifyPair(tl, tr, PairOperator.SMALLER); } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java b/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java index b6f2a795..258da2e5 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java @@ -31,7 +31,7 @@ public class NewClass extends MethodCall * @param 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 diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Receiver.java b/src/de/dhbwstuttgart/syntaxtree/statement/Receiver.java index 09bc191c..93ee36a0 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Receiver.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Receiver.java @@ -1,26 +1,12 @@ package de.dhbwstuttgart.syntaxtree.statement; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import org.antlr.v4.runtime.Token; -import de.dhbwstuttgart.syntaxtree.StatementVisitor; -import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; -import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; -import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; - -public class Receiver extends Expression +public abstract class Receiver extends Expression { - public Expression expr; - /** - * Autor: J�rg B�uerle - * @param expr - */ - public Receiver(Expression expr) + public Receiver(RefTypeOrTPHOrWildcardOrGeneric type, Token offset) { - super(expr.getType(), expr.getOffset()); - this.expr = expr; - } - - @Override - public void accept(StatementVisitor visitor) { - visitor.visit(this); + super(type, offset); } } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/StaticClassName.java b/src/de/dhbwstuttgart/syntaxtree/statement/StaticClassName.java index d0ddb31c..a7089d8c 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/StaticClassName.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/StaticClassName.java @@ -8,7 +8,7 @@ import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import org.antlr.v4.runtime.Token; -public class StaticClassName extends Expression { +public class StaticClassName extends Receiver { public StaticClassName(JavaClassName className, Token offset) { super(new RefType(className, offset), offset); } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java index 572f1b11..42cfb8ee 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java @@ -17,7 +17,7 @@ public class SuperCall extends MethodCall } public SuperCall(ArgumentList argumentList, Token offset){ - super(new Void(offset), new Receiver(new This(offset)), "", argumentList, offset); + super(new Void(offset), new ExpressionReceiver(new This(offset)), "", argumentList, offset); } diff --git a/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java b/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java index 0befcb2b..4b4ac7dc 100644 --- a/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java +++ b/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java @@ -270,11 +270,6 @@ public class OutputGenerator implements ASTVisitor { } - @Override - public void visit(Receiver receiver) { - receiver.expr.accept(this); - } - @Override public void visit(Return aReturn) { out.append("return "); @@ -349,4 +344,9 @@ public class OutputGenerator implements ASTVisitor { superCall.arglist.accept(this); out.append(")"); } + + @Override + public void visit(ExpressionReceiver receiver) { + receiver.expr.accept(this); + } } \ No newline at end of file diff --git a/src/de/dhbwstuttgart/syntaxtree/visual/TypeOutputGenerator.java b/src/de/dhbwstuttgart/syntaxtree/visual/TypeOutputGenerator.java index c0628ef9..dcefafa4 100644 --- a/src/de/dhbwstuttgart/syntaxtree/visual/TypeOutputGenerator.java +++ b/src/de/dhbwstuttgart/syntaxtree/visual/TypeOutputGenerator.java @@ -181,7 +181,7 @@ public class TypeOutputGenerator extends OutputGenerator { } @Override - public void visit(Receiver receiver) { + public void visit(ExpressionReceiver receiver) { super.visit(receiver); } diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java b/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java index 88b2bd4a..2e568e48 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java @@ -1,21 +1,22 @@ package de.dhbwstuttgart.typeinference.assumptions; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; public class FieldAssumption extends Assumption{ - private RefTypeOrTPHOrWildcardOrGeneric receiverType; + private ClassOrInterface receiverClass; private RefTypeOrTPHOrWildcardOrGeneric type; - public FieldAssumption(RefTypeOrTPHOrWildcardOrGeneric receiverType, + public FieldAssumption(ClassOrInterface receiverType, RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope){ super(scope); this.type = type; - this.receiverType = receiverType; + this.receiverClass = receiverType; } - public RefTypeOrTPHOrWildcardOrGeneric getReceiverType() { - return receiverType; + public ClassOrInterface getReceiverClass() { + return receiverClass; } public RefTypeOrTPHOrWildcardOrGeneric getType() { diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java index bbeff0d7..af8d6fb7 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java @@ -1,5 +1,6 @@ package de.dhbwstuttgart.typeinference.assumptions; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.statement.Assign; @@ -10,11 +11,11 @@ import java.util.List; import java.util.stream.Collectors; public class MethodAssumption extends Assumption{ - private RefType receiver; + private ClassOrInterface receiver; private RefTypeOrTPHOrWildcardOrGeneric retType; List params; - public MethodAssumption(RefType receiver, RefTypeOrTPHOrWildcardOrGeneric retType, + public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType, List params, TypeScope scope){ super(scope); this.receiver = receiver; @@ -22,7 +23,14 @@ public class MethodAssumption extends Assumption{ this.params = params; } + /* public RefType getReceiverType() { + + return receiver; + } + */ + + public ClassOrInterface getReceiver(){ return receiver; } diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java b/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java index 90548e6d..737cd0c4 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java @@ -46,7 +46,8 @@ public class TypeInferenceInformation { for(ClassOrInterface cl : classes){ for(Field m : cl.getFieldDecl()){ 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))); } } } diff --git a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java b/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java deleted file mode 100644 index 3d1058da..00000000 --- a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java +++ /dev/null @@ -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; - } - } - -} diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index e50a8b1e..e45f7326 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -6,14 +6,12 @@ import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; +import de.dhbwstuttgart.parser.antlr.Java8Parser; import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Null; -import de.dhbwstuttgart.syntaxtree.type.FunN; -import de.dhbwstuttgart.syntaxtree.type.RefType; -import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; -import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; @@ -113,8 +111,10 @@ public class TYPEStmt implements StatementVisitor{ for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){ Constraint constraint = new Constraint(); 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( fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); + */ constraint.add(ConstraintsFactory.createPair( fieldVar.getType(),fieldAssumption.getType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); oderConstraints.add(constraint); @@ -122,6 +122,9 @@ public class TYPEStmt implements StatementVisitor{ if(oderConstraints.size() == 0) throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset()); constraintsSet.addOderConstraint(oderConstraints); + + //Wegen dem Problem oben: + throw new NotImplementedException(); } @Override @@ -184,7 +187,7 @@ public class TYPEStmt implements StatementVisitor{ } @Override - public void visit(Receiver receiver) { + public void visit(ExpressionReceiver receiver) { receiver.expr.accept(this); } @@ -213,8 +216,15 @@ public class TYPEStmt implements StatementVisitor{ @Override 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 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( - aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info.getCurrentTypeScope(), + aThis.getType(), thisType, PairOperator.EQUALSDOT, info.getCurrentTypeScope(), createNullTypeScope(), getResolverInstance())); } @@ -280,10 +290,21 @@ public class TYPEStmt implements StatementVisitor{ protected Constraint generateConstraint(MethodCall forMethod, MethodAssumption assumption, TypeInferenceBlockInformation info, GenericsResolver resolver){ Constraint methodConstraint = new Constraint(); - methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), assumption.getReceiverType(), - PairOperator.SMALLERDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); - methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(), - PairOperator.EQUALSDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); + ClassOrInterface receiverCl = assumption.getReceiver(); + List params = new ArrayList<>(); + for(GenericTypeVar gtv : receiverCl.getGenerics()){ + //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)); return methodConstraint; } @@ -302,6 +323,7 @@ public class TYPEStmt implements StatementVisitor{ public static List getMethods(String name, int numArgs, TypeInferenceBlockInformation info) { List ret = new ArrayList<>(); + /* if(name.equals("apply")){ List funNParams = new ArrayList<>(); for(int i = 0; i< numArgs + 1 ; i++){ @@ -320,13 +342,14 @@ public class TYPEStmt implements StatementVisitor{ } })); } + */ for(ClassOrInterface cl : info.getAvailableClasses()){ for(Method m : cl.getMethods()){ if(m.getName().equals(name) && m.getParameterList().getFormalparalist().size() == numArgs){ 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))); } } @@ -361,7 +384,7 @@ public class TYPEStmt implements StatementVisitor{ if(cl.getClassName().equals(ofType.getName())){ for(Method m : cl.getConstructors()){ 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))); } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 9ace0e51..aba3d3f6 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -17,17 +17,18 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; * @author Florian Steurer */ public class FiniteClosure implements IFiniteClosure { - + /** * A map that maps every type to the node in the inheritance graph that contains that type. - */ + */ private HashMap> inheritanceGraph; /** * A map that maps every typename to the nodes of the inheritance graph that contain a type with that name. */ private HashMap>> strInheritanceGraph; - + + /** * The initial pairs of that define the inheritance tree */ @@ -38,7 +39,7 @@ public class FiniteClosure implements IFiniteClosure { */ public FiniteClosure(Set pairs) { this.pairs = new HashSet<>(pairs); - inheritanceGraph = new HashMap>(); + inheritanceGraph = new HashMap>(); // Build the transitive closure of the inheritance tree for(UnifyPair pair : pairs) { @@ -46,7 +47,7 @@ public class FiniteClosure implements IFiniteClosure { continue; // Add nodes if not already in the graph - if(!inheritanceGraph.containsKey(pair.getLhsType())) + if(!inheritanceGraph.containsKey(pair.getLhsType())) inheritanceGraph.put(pair.getLhsType(), new Node(pair.getLhsType())); if(!inheritanceGraph.containsKey(pair.getRhsType())) inheritanceGraph.put(pair.getRhsType(), new Node(pair.getRhsType())); @@ -61,7 +62,7 @@ public class FiniteClosure implements IFiniteClosure { parentNode.getPredecessors().stream().forEach(x -> x.addDescendant(childNode)); childNode.getDescendants().stream().forEach(x -> x.addPredecessor(parentNode)); } - + // Build the alternative representation with strings as keys strInheritanceGraph = new HashMap<>(); 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. * @return The set of subtypes of the argument. - */ + */ @Override public Set smaller(UnifyType type) { 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. * @return The set of supertypes of the argument. - */ + */ @Override public Set greater(UnifyType type) { if(type instanceof FunNType) @@ -240,7 +241,7 @@ public class FiniteClosure implements IFiniteClosure { return type.grArg(this); } - @Override + @Override public Set grArg(ReferenceType type) { Set result = new HashSet(); result.add(type); @@ -249,7 +250,7 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set grArg(FunNType type) { Set result = new HashSet(); result.add(type); @@ -267,7 +268,7 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set grArg(SuperType type) { Set result = new HashSet(); result.add(type); @@ -276,11 +277,11 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set grArg(PlaceholderType type) { HashSet result = new HashSet<>(); result.add(type); - return result; + return result; } @Override @@ -288,12 +289,12 @@ public class FiniteClosure implements IFiniteClosure { return type.smArg(this); } - @Override + @Override public Set smArg(ReferenceType type) { Set result = new HashSet(); result.add(type); return result; - } + } @Override public Set smArg(FunNType type) { @@ -316,7 +317,7 @@ public class FiniteClosure implements IFiniteClosure { } - @Override + @Override public Set smArg(SuperType type) { Set result = new HashSet(); result.add(type); @@ -329,20 +330,20 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set smArg(PlaceholderType type) { HashSet result = new HashSet<>(); - result.add(type); + result.add(type); return result; } - @Override - public Set getAllTypesByName(String typeName) { + @Override + public Set getAllTypesByName(String typeName) { if(!strInheritanceGraph.containsKey(typeName)) return new HashSet<>(); return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new)); } - + @Override public Optional getLeftHandedType(String typeName) { if(!strInheritanceGraph.containsKey(typeName)) @@ -392,7 +393,7 @@ public class FiniteClosure implements IFiniteClosure { * @param result Set of all permutations found so far * @param current The permutation of type params that is currently explored */ - protected void permuteParams(ArrayList> candidates, int idx, Set result, UnifyType[] current) { + protected void permuteParams(ArrayList> candidates, int idx, Set result, UnifyType[] current) { if(candidates.size() == idx) { result.add(new TypeParams(Arrays.copyOf(current, current.length))); return; diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java index fd87eecc..f40ecb2f 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java @@ -24,8 +24,10 @@ public final class TypeParams implements Iterable{ */ public TypeParams(List types){ typeParams = new UnifyType[types.size()]; - for(int i=0;i{ if(other.size() != this.size()) 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++) if(!(this.get(i).equals(other.get(i)))) return false; diff --git a/test/javFiles/Matrix.jav b/test/javFiles/Matrix.jav index 65dc465a..e6aa84cd 100644 --- a/test/javFiles/Matrix.jav +++ b/test/javFiles/Matrix.jav @@ -1,5 +1,16 @@ import java.util.Vector; +class Matrix extends Vector> { + + methode(Matrix m) { + Vector> i; + methode(i); + } + } + +/* +import java.util.Vector; + class Matrix extends Vector> { Matrix mul_rec(Matrix m) { @@ -39,4 +50,5 @@ class Matrix extends Vector> { } return ret; } -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/test/parser/ExtendsTest.jav b/test/parser/ExtendsTest.jav new file mode 100644 index 00000000..9103f463 --- /dev/null +++ b/test/parser/ExtendsTest.jav @@ -0,0 +1,4 @@ +class C1 extends Object +{ + m(para) { return para; } +} \ No newline at end of file diff --git a/test/parser/GeneralParserTest.java b/test/parser/GeneralParserTest.java index 53cb6f7b..c48e1320 100644 --- a/test/parser/GeneralParserTest.java +++ b/test/parser/GeneralParserTest.java @@ -5,7 +5,9 @@ import static org.junit.Assert.*; import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; +import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.parser.JavaTXParser; import org.junit.Test; @@ -25,6 +27,7 @@ public class GeneralParserTest{ List filenames = new ArrayList(); + /* filenames.add("NewTest.jav"); filenames.add("FieldInitializationTest.jav"); filenames.add("ImportTest.jav"); @@ -37,13 +40,10 @@ public class GeneralParserTest{ //filenames.add("GenericFieldVarTest.jav"); filenames.add("FieldVarTest.jav"); filenames.add("StructuralTypes.jav"); - JavaTXParser parser = new JavaTXParser(); + */ + filenames.add("ExtendsTest.jav"); try{ - for(String filename : filenames) { - System.out.println("Teste: "+filename); - parser.parse(new File(rootDirectory + filename)); - //TODO: Test ANTLR Parser - } + new JavaTXCompiler(filenames.stream().map(s -> new File(rootDirectory + s)).collect(Collectors.toList())); }catch(Exception exc){ exc.printStackTrace(); fail(); diff --git a/test/typeinference/JavaTXCompilerTest.java b/test/typeinference/JavaTXCompilerTest.java index 4b79b8c5..8e60c803 100644 --- a/test/typeinference/JavaTXCompilerTest.java +++ b/test/typeinference/JavaTXCompilerTest.java @@ -37,6 +37,7 @@ public class JavaTXCompilerTest { //filesToTest.add(new File(rootDirectory+"mathStruc.jav")); //filesToTest.add(new File(rootDirectory+"test.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+"Lambda2.jav")); //filesToTest.add(new File(rootDirectory+"Lambda3.jav"));