diff --git a/src/de/dhbwstuttgart/strucTypes/StrucTYPE.java b/src/de/dhbwstuttgart/strucTypes/StrucTYPE.java index 86984efb..dbca1113 100644 --- a/src/de/dhbwstuttgart/strucTypes/StrucTYPE.java +++ b/src/de/dhbwstuttgart/strucTypes/StrucTYPE.java @@ -6,6 +6,8 @@ import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.statement.Expression; import de.dhbwstuttgart.syntaxtree.statement.Return; +import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; public class StrucTYPE extends DefaultASTVisitor { @@ -22,14 +24,13 @@ public class StrucTYPE extends DefaultASTVisitor { for (ClassOrInterface cls : sourceFile.getClasses()) { TYPEExpr typeExpr = new TYPEExpr(); cls.accept(typeExpr); - this.evaluateTypeExpr(typeExpr); cls.getMethods().forEach(m -> m.accept(this)); + this.evaluateTypeExpr(typeExpr); } return this.constraintsSet; } public InferredTypes getInferredTypes() { - this.inferredTypes.resolveTransitiveTypes(); return this.inferredTypes; } @@ -37,13 +38,25 @@ public class StrucTYPE extends DefaultASTVisitor { public void visit(Method method) { // Es gibt nur ein Return Statement Expression retexpr = ((Return) method.block.statements.get(0)).retexpr; + + RefTypeOrTPHOrWildcardOrGeneric methodReturnType = method.getReturnType(); + RefTypeOrTPHOrWildcardOrGeneric retExprType = retexpr.getType(); + // ordnet dem Methodentyp den Returntyp zu [sigma(Mt)] - this.inferredTypes.put((TypePlaceholder) method.getReturnType(), retexpr.getType()); + if (methodReturnType instanceof TypePlaceholder) { + this.inferredTypes.put((TypePlaceholder) methodReturnType, retExprType); + } + if (methodReturnType instanceof RefType && retExprType instanceof TypePlaceholder) { + this.inferredTypes.put((TypePlaceholder) retExprType, methodReturnType); + } } private void evaluateTypeExpr(TYPEExpr typeExpr) { this.inferredTypes.putAll(typeExpr.getInferredTypes()); + this.inferredTypes.resolveTransitiveTypes(); this.constraintsSet.addConstraintsSet(typeExpr.getConstraints()); + // TODO infer types in constraints + this.constraintsSet.inferTypes(inferredTypes); } } diff --git a/src/de/dhbwstuttgart/strucTypes/TYPEExpr.java b/src/de/dhbwstuttgart/strucTypes/TYPEExpr.java index 89a39dae..2048ea88 100644 --- a/src/de/dhbwstuttgart/strucTypes/TYPEExpr.java +++ b/src/de/dhbwstuttgart/strucTypes/TYPEExpr.java @@ -61,18 +61,20 @@ public class TYPEExpr extends DefaultASTVisitor { // Ermittelt den Typ ty von fieldVar.receiver und fields(f) TypeExtract fieldTypeVisitor = new TypeExtract(); - fieldVar.receiver.getType().accept(fieldTypeVisitor); + if (receiverIsThis) { + this.aThis.accept(fieldTypeVisitor); + } else { + fieldVar.receiver.getType().accept(fieldTypeVisitor); + } - if (!fieldTypeVisitor.isTypeVariable()) { + if (!fieldTypeVisitor.isTypeVariable() && fieldTypeVisitor.getField(fieldVar.fieldVarName).isPresent()) { fieldTypeVisitor.getField(fieldVar.fieldVarName).ifPresent( - f -> this.inferredTypes.put((TypePlaceholder) fieldVar.receiver.getType(), (RefType) f.getType())); + f -> this.inferredTypes.put((TypePlaceholder) fieldVar.getType(), (RefType) f.getType())); } // keine neuen Constraints else { - if (!receiverIsThis) { - FieldConstraint fieldConstraint = new FieldConstraint(fieldVar.receiver.getType(), - fieldVar.fieldVarName, fieldVar.getType()); - this.constraints.addConstraint(fieldConstraint); - } + FieldConstraint fieldConstraint = new FieldConstraint(fieldVar.receiver.getType(), fieldVar.fieldVarName, + fieldVar.getType()); + this.constraints.addConstraint(fieldConstraint); } } @@ -94,10 +96,16 @@ public class TYPEExpr extends DefaultASTVisitor { // ermittelt den Typ ty0 von methodCall.receiver und mtype(m, ty0) TypeExtract methodTypeVisitor = new TypeExtract(); - methodCall.receiver.getType().accept(methodTypeVisitor); + if (methodCall.receiver instanceof ExpressionReceiver + && ((ExpressionReceiver) methodCall.receiver).expr instanceof This) { + this.aThis.accept(methodTypeVisitor); + } else { + methodCall.receiver.getType().accept(methodTypeVisitor); + } List arguments = methodCall.getArgumentList().getArguments(); - if (!methodTypeVisitor.isTypeVariable()) { + if (!methodTypeVisitor.isTypeVariable() + && methodTypeVisitor.getMethod(methodCall.name, arguments.size()).isPresent()) { methodTypeVisitor.getMethod(methodCall.name, arguments.size()).ifPresent(m -> { for (int i = 0; i < arguments.size(); i++) { this.constraints.addConstraint(new SubTypeConstraint(arguments.get(i).getType(), diff --git a/src/de/dhbwstuttgart/strucTypes/TypeExtract.java b/src/de/dhbwstuttgart/strucTypes/TypeExtract.java index 47fbc5ec..0dc7956c 100644 --- a/src/de/dhbwstuttgart/strucTypes/TypeExtract.java +++ b/src/de/dhbwstuttgart/strucTypes/TypeExtract.java @@ -47,7 +47,8 @@ public class TypeExtract extends DefaultASTVisitor { public Optional getMethod(String methodName, int parameterCount) { return this.methods.stream() - .filter(m -> m.getName().equals(methodName) && m.getParameterList().getFormalparalist().size() == parameterCount) + .filter(m -> m.getName().equals(methodName) + && m.getParameterList().getFormalparalist().size() == parameterCount) // keine statische Polymorphie zugelassen .findFirst(); } @@ -60,7 +61,10 @@ public class TypeExtract extends DefaultASTVisitor { public void visit(ClassOrInterface classOrInterface) { classOrInterface.getFieldDecl().forEach(f -> f.accept(this)); classOrInterface.getMethods().forEach(m -> m.accept(this)); - classOrInterface.getConstructors().forEach(c -> {if(c != null && this.initialClass) c.accept(this);}); + classOrInterface.getConstructors().forEach(c -> { + if (c != null && this.initialClass) + c.accept(this); + }); this.initialClass = false; // superClass(Object) -> Object => unendliche Rekursionstiefe! if (!classOrInterface.getClassName().equals(new JavaClassName("java.lang.Object"))) { @@ -77,12 +81,14 @@ public class TypeExtract extends DefaultASTVisitor { @Override public void visit(Field field) { - this.fields.add(field); + if (field.getType() instanceof RefType) + this.fields.add(field); } @Override public void visit(Method method) { - this.methods.add(method); + if (method.getReturnType() instanceof RefType) + this.methods.add(method); } @Override diff --git a/src/de/dhbwstuttgart/strucTypes/constraint/ConstraintsSet.java b/src/de/dhbwstuttgart/strucTypes/constraint/ConstraintsSet.java index 6024e674..c9347627 100644 --- a/src/de/dhbwstuttgart/strucTypes/constraint/ConstraintsSet.java +++ b/src/de/dhbwstuttgart/strucTypes/constraint/ConstraintsSet.java @@ -3,12 +3,14 @@ package de.dhbwstuttgart.strucTypes.constraint; import java.util.ArrayList; import java.util.List; +import de.dhbwstuttgart.strucTypes.InferredTypes; + public class ConstraintsSet { private List subTypeConstraints; private List fieldConstraints; private List methodConstraints; - + public ConstraintsSet() { this.subTypeConstraints = new ArrayList<>(); this.fieldConstraints = new ArrayList<>(); @@ -26,25 +28,29 @@ public class ConstraintsSet { public List getMethodConstraints() { return methodConstraints; } - - public void addConstraint(SubTypeConstraint constraint){ + + public void addConstraint(SubTypeConstraint constraint) { this.subTypeConstraints.add(constraint); } - - public void addConstraint(FieldConstraint constraint){ + + public void addConstraint(FieldConstraint constraint) { this.fieldConstraints.add(constraint); } - - public void addConstraint(MethodConstraint constraint){ + + public void addConstraint(MethodConstraint constraint) { this.methodConstraints.add(constraint); } - - public void addConstraintsSet(ConstraintsSet constraintsSet){ + + public void addConstraintsSet(ConstraintsSet constraintsSet) { constraintsSet.getSubTypeConstraints().forEach(this::addConstraint); constraintsSet.getFieldConstraints().forEach(this::addConstraint); constraintsSet.getMethodConstraints().forEach(this::addConstraint); } - - - + + public void inferTypes(InferredTypes inferredTypes) { + this.subTypeConstraints.forEach(c -> c.inferTypes(inferredTypes)); + this.fieldConstraints.forEach(c -> c.inferTypes(inferredTypes)); + this.methodConstraints.forEach(c -> c.inferTypes(inferredTypes)); + } + } diff --git a/src/de/dhbwstuttgart/strucTypes/constraint/FieldConstraint.java b/src/de/dhbwstuttgart/strucTypes/constraint/FieldConstraint.java index 014491af..abe2b119 100644 --- a/src/de/dhbwstuttgart/strucTypes/constraint/FieldConstraint.java +++ b/src/de/dhbwstuttgart/strucTypes/constraint/FieldConstraint.java @@ -1,5 +1,6 @@ package de.dhbwstuttgart.strucTypes.constraint; +import de.dhbwstuttgart.strucTypes.InferredTypes; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; /** @@ -33,4 +34,13 @@ public class FieldConstraint { return fieldName; } + public void inferTypes(InferredTypes inferredTypes) { + if (inferredTypes.containsKey(classType)) { + this.classType = inferredTypes.get(classType); + } + if (inferredTypes.containsKey(fieldType)) { + this.fieldType = inferredTypes.get(fieldType); + } + } + } diff --git a/src/de/dhbwstuttgart/strucTypes/constraint/MethodConstraint.java b/src/de/dhbwstuttgart/strucTypes/constraint/MethodConstraint.java index 0aa6846f..285698ef 100644 --- a/src/de/dhbwstuttgart/strucTypes/constraint/MethodConstraint.java +++ b/src/de/dhbwstuttgart/strucTypes/constraint/MethodConstraint.java @@ -4,6 +4,7 @@ import java.util.List; import org.antlr.v4.runtime.Token; +import de.dhbwstuttgart.strucTypes.InferredTypes; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; @@ -60,4 +61,14 @@ public class MethodConstraint { } } + public void inferTypes(InferredTypes inferredTypes) { + if (inferredTypes.containsKey(classType)) { + this.classType = inferredTypes.get(classType); + } + if (inferredTypes.containsKey(returnType)) { + this.returnType = inferredTypes.get(returnType); + } + arguments.forEach(c -> c.inferTypes(inferredTypes)); + } + } diff --git a/src/de/dhbwstuttgart/strucTypes/constraint/SubTypeConstraint.java b/src/de/dhbwstuttgart/strucTypes/constraint/SubTypeConstraint.java index 733c2ddb..1e4248e4 100644 --- a/src/de/dhbwstuttgart/strucTypes/constraint/SubTypeConstraint.java +++ b/src/de/dhbwstuttgart/strucTypes/constraint/SubTypeConstraint.java @@ -1,5 +1,6 @@ package de.dhbwstuttgart.strucTypes.constraint; +import de.dhbwstuttgart.strucTypes.InferredTypes; import de.dhbwstuttgart.strucTypes.exception.ImpossibleSubTypeException; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; @@ -28,6 +29,15 @@ public class SubTypeConstraint { return supertype; } + public void inferTypes(InferredTypes inferredTypes) { + if (inferredTypes.containsKey(subtype)) { + this.subtype = inferredTypes.get(subtype); + } + if (inferredTypes.containsKey(supertype)) { + this.supertype = inferredTypes.get(supertype); + } + } + public boolean checkConstraintPossible() throws ImpossibleSubTypeException { if (this.subtype instanceof RefType && this.supertype instanceof RefType) { Class subClass = this.createClass(((RefType) this.subtype).getName().toString());