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:
parent
2eeb54e16a
commit
651c9ee68c
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user