TypeExpr angepasst bei method und fieldvar um den receiver This erkennen und verarbeiten zu koennen, Typen in Constraints werden mit den inferredTypes abgeleitet

This commit is contained in:
Aldaron7 2018-03-16 22:20:13 +01:00
parent 2eeb54e16a
commit 651c9ee68c
7 changed files with 93 additions and 29 deletions

View File

@ -6,6 +6,8 @@ import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.statement.Expression; import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.Return; import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class StrucTYPE extends DefaultASTVisitor { public class StrucTYPE extends DefaultASTVisitor {
@ -22,14 +24,13 @@ public class StrucTYPE extends DefaultASTVisitor {
for (ClassOrInterface cls : sourceFile.getClasses()) { for (ClassOrInterface cls : sourceFile.getClasses()) {
TYPEExpr typeExpr = new TYPEExpr(); TYPEExpr typeExpr = new TYPEExpr();
cls.accept(typeExpr); cls.accept(typeExpr);
this.evaluateTypeExpr(typeExpr);
cls.getMethods().forEach(m -> m.accept(this)); cls.getMethods().forEach(m -> m.accept(this));
this.evaluateTypeExpr(typeExpr);
} }
return this.constraintsSet; return this.constraintsSet;
} }
public InferredTypes getInferredTypes() { public InferredTypes getInferredTypes() {
this.inferredTypes.resolveTransitiveTypes();
return this.inferredTypes; return this.inferredTypes;
} }
@ -37,13 +38,25 @@ public class StrucTYPE extends DefaultASTVisitor {
public void visit(Method method) { public void visit(Method method) {
// Es gibt nur ein Return Statement // Es gibt nur ein Return Statement
Expression retexpr = ((Return) method.block.statements.get(0)).retexpr; 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)] // 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) { private void evaluateTypeExpr(TYPEExpr typeExpr) {
this.inferredTypes.putAll(typeExpr.getInferredTypes()); this.inferredTypes.putAll(typeExpr.getInferredTypes());
this.inferredTypes.resolveTransitiveTypes();
this.constraintsSet.addConstraintsSet(typeExpr.getConstraints()); this.constraintsSet.addConstraintsSet(typeExpr.getConstraints());
// TODO infer types in constraints
this.constraintsSet.inferTypes(inferredTypes);
} }
} }

View File

@ -61,18 +61,20 @@ public class TYPEExpr extends DefaultASTVisitor {
// Ermittelt den Typ ty von fieldVar.receiver und fields(f) // Ermittelt den Typ ty von fieldVar.receiver und fields(f)
TypeExtract fieldTypeVisitor = new TypeExtract(); 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( 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 } // keine neuen Constraints
else { else {
if (!receiverIsThis) { FieldConstraint fieldConstraint = new FieldConstraint(fieldVar.receiver.getType(), fieldVar.fieldVarName,
FieldConstraint fieldConstraint = new FieldConstraint(fieldVar.receiver.getType(), fieldVar.getType());
fieldVar.fieldVarName, fieldVar.getType()); this.constraints.addConstraint(fieldConstraint);
this.constraints.addConstraint(fieldConstraint);
}
} }
} }
@ -94,10 +96,16 @@ public class TYPEExpr extends DefaultASTVisitor {
// ermittelt den Typ ty0 von methodCall.receiver und mtype(m, ty0) // ermittelt den Typ ty0 von methodCall.receiver und mtype(m, ty0)
TypeExtract methodTypeVisitor = new TypeExtract(); 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<Expression> arguments = methodCall.getArgumentList().getArguments(); List<Expression> 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 -> { methodTypeVisitor.getMethod(methodCall.name, arguments.size()).ifPresent(m -> {
for (int i = 0; i < arguments.size(); i++) { for (int i = 0; i < arguments.size(); i++) {
this.constraints.addConstraint(new SubTypeConstraint(arguments.get(i).getType(), this.constraints.addConstraint(new SubTypeConstraint(arguments.get(i).getType(),

View File

@ -47,7 +47,8 @@ public class TypeExtract extends DefaultASTVisitor {
public Optional<Method> getMethod(String methodName, int parameterCount) { public Optional<Method> getMethod(String methodName, int parameterCount) {
return this.methods.stream() 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 // keine statische Polymorphie zugelassen
.findFirst(); .findFirst();
} }
@ -60,7 +61,10 @@ public class TypeExtract extends DefaultASTVisitor {
public void visit(ClassOrInterface classOrInterface) { public void visit(ClassOrInterface classOrInterface) {
classOrInterface.getFieldDecl().forEach(f -> f.accept(this)); classOrInterface.getFieldDecl().forEach(f -> f.accept(this));
classOrInterface.getMethods().forEach(m -> m.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; this.initialClass = false;
// superClass(Object) -> Object => unendliche Rekursionstiefe! // superClass(Object) -> Object => unendliche Rekursionstiefe!
if (!classOrInterface.getClassName().equals(new JavaClassName("java.lang.Object"))) { if (!classOrInterface.getClassName().equals(new JavaClassName("java.lang.Object"))) {
@ -77,12 +81,14 @@ public class TypeExtract extends DefaultASTVisitor {
@Override @Override
public void visit(Field field) { public void visit(Field field) {
this.fields.add(field); if (field.getType() instanceof RefType)
this.fields.add(field);
} }
@Override @Override
public void visit(Method method) { public void visit(Method method) {
this.methods.add(method); if (method.getReturnType() instanceof RefType)
this.methods.add(method);
} }
@Override @Override

View File

@ -3,6 +3,8 @@ package de.dhbwstuttgart.strucTypes.constraint;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.dhbwstuttgart.strucTypes.InferredTypes;
public class ConstraintsSet { public class ConstraintsSet {
private List<SubTypeConstraint> subTypeConstraints; private List<SubTypeConstraint> subTypeConstraints;
@ -27,24 +29,28 @@ public class ConstraintsSet {
return methodConstraints; return methodConstraints;
} }
public void addConstraint(SubTypeConstraint constraint){ public void addConstraint(SubTypeConstraint constraint) {
this.subTypeConstraints.add(constraint); this.subTypeConstraints.add(constraint);
} }
public void addConstraint(FieldConstraint constraint){ public void addConstraint(FieldConstraint constraint) {
this.fieldConstraints.add(constraint); this.fieldConstraints.add(constraint);
} }
public void addConstraint(MethodConstraint constraint){ public void addConstraint(MethodConstraint constraint) {
this.methodConstraints.add(constraint); this.methodConstraints.add(constraint);
} }
public void addConstraintsSet(ConstraintsSet constraintsSet){ public void addConstraintsSet(ConstraintsSet constraintsSet) {
constraintsSet.getSubTypeConstraints().forEach(this::addConstraint); constraintsSet.getSubTypeConstraints().forEach(this::addConstraint);
constraintsSet.getFieldConstraints().forEach(this::addConstraint); constraintsSet.getFieldConstraints().forEach(this::addConstraint);
constraintsSet.getMethodConstraints().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));
}
} }

View File

@ -1,5 +1,6 @@
package de.dhbwstuttgart.strucTypes.constraint; package de.dhbwstuttgart.strucTypes.constraint;
import de.dhbwstuttgart.strucTypes.InferredTypes;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
/** /**
@ -33,4 +34,13 @@ public class FieldConstraint {
return fieldName; 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);
}
}
} }

View File

@ -4,6 +4,7 @@ import java.util.List;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.strucTypes.InferredTypes;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; 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));
}
} }

View File

@ -1,5 +1,6 @@
package de.dhbwstuttgart.strucTypes.constraint; package de.dhbwstuttgart.strucTypes.constraint;
import de.dhbwstuttgart.strucTypes.InferredTypes;
import de.dhbwstuttgart.strucTypes.exception.ImpossibleSubTypeException; import de.dhbwstuttgart.strucTypes.exception.ImpossibleSubTypeException;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
@ -28,6 +29,15 @@ public class SubTypeConstraint {
return supertype; 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 { public boolean checkConstraintPossible() throws ImpossibleSubTypeException {
if (this.subtype instanceof RefType && this.supertype instanceof RefType) { if (this.subtype instanceof RefType && this.supertype instanceof RefType) {
Class<?> subClass = this.createClass(((RefType) this.subtype).getName().toString()); Class<?> subClass = this.createClass(((RefType) this.subtype).getName().toString());