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.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);
}
}

View File

@ -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<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 -> {
for (int i = 0; i < arguments.size(); i++) {
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) {
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

View File

@ -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<SubTypeConstraint> subTypeConstraints;
private List<FieldConstraint> fieldConstraints;
private List<MethodConstraint> methodConstraints;
public ConstraintsSet() {
this.subTypeConstraints = new ArrayList<>();
this.fieldConstraints = new ArrayList<>();
@ -26,25 +28,29 @@ public class ConstraintsSet {
public List<MethodConstraint> 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));
}
}

View File

@ -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);
}
}
}

View File

@ -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));
}
}

View File

@ -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());