Type refactoring

This commit is contained in:
JanUlrich 2017-08-28 15:42:51 +02:00
parent ff59b585bd
commit 45c85b7686
9 changed files with 390 additions and 361 deletions

View File

@ -14,6 +14,7 @@ import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.unify.TypeUnify; import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
@ -29,15 +30,13 @@ public class JavaTXCompiler {
protected List<SourceFile> sourceFiles = new ArrayList<>(); protected List<SourceFile> sourceFiles = new ArrayList<>();
public ResultSet typeInference(){ public ResultSet typeInference(){
ConstraintSet<Pair> cons = new ConstraintSet<>();
List<ClassOrInterface> allClasses = new ArrayList<>(); List<ClassOrInterface> allClasses = new ArrayList<>();
for(SourceFile sf : sourceFiles){ for(SourceFile sf : sourceFiles){
allClasses.addAll(sf.getClasses()); allClasses.addAll(sf.getClasses());
} }
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses); FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses);
for(SourceFile sf : sourceFiles){ ConstraintSet<Pair> cons = new ConstraintSet<>();
cons.addAll(sf.getConstraints(sf.getTypeInferenceInformation(sourceFiles))); cons = new TYPE(sourceFiles).getConstraints();
}
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons); ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
TypeUnify unify = new TypeUnify(); TypeUnify unify = new TypeUnify();

View File

@ -58,14 +58,6 @@ public class ClassOrInterface extends SyntaxTreeNode {
return this.methods; return this.methods;
} }
public ConstraintSet getConstraints(TypeInferenceInformation info) {
ConstraintSet ret = new ConstraintSet();
for(Method m : this.getMethods()){
ret.addAll(m.getConstraints(info, this));
}
return ret;
}
public RefType getType() { public RefType getType() {
return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset()); return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset());
} }

View File

@ -6,6 +6,7 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPEStmt;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.statement.Block; import de.dhbwstuttgart.syntaxtree.statement.Block;
@ -19,7 +20,7 @@ public class Constructor extends Method {
/** /**
* Das sind die Statements, welche die Felder der zugehörigen Klasse dieses Konstruktor initialisieren * Das sind die Statements, welche die Felder der zugehörigen Klasse dieses Konstruktor initialisieren
*/ */
private final List<Statement> fieldInitializations; public final List<Statement> fieldInitializations;
public Constructor(String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor, GenericDeclarationList gtvDeclarations, Token offset, List<Statement> fieldInitializations) { public Constructor(String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor, GenericDeclarationList gtvDeclarations, Token offset, List<Statement> fieldInitializations) {
super(name, returnType, modifiers, parameterList, codeInsideConstructor, gtvDeclarations, offset); super(name, returnType, modifiers, parameterList, codeInsideConstructor, gtvDeclarations, offset);
@ -27,15 +28,6 @@ public class Constructor extends Method {
this.fieldInitializations = fieldInitializations; this.fieldInitializations = fieldInitializations;
} }
public ConstraintSet getConstraints(TypeInferenceInformation info, ClassOrInterface currentClass) {
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, null);
TYPE methodScope = new TYPE(blockInfo);
for(Statement stmt : fieldInitializations)stmt.accept(methodScope);
ConstraintSet ret = super.getConstraints(info, currentClass);
ret.addAll(methodScope.getConstraints());
return ret;
}
@Override @Override
public void accept(ASTVisitor visitor) { public void accept(ASTVisitor visitor) {
visitor.visit(this); visitor.visit(this);

View File

@ -8,6 +8,7 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPEStmt;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.core.IItemWithOffset;
@ -36,14 +37,6 @@ public class Method extends Field implements IItemWithOffset, TypeScope
this.generics = gtvDeclarations; this.generics = gtvDeclarations;
} }
public ConstraintSet getConstraints(TypeInferenceInformation info, ClassOrInterface currentClass) {
if(block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, this);
TYPE methodScope = new TYPE(blockInfo);
block.accept(methodScope);
return methodScope.getConstraints();
}
public ParameterList getParameterList() { public ParameterList getParameterList() {
return parameterlist; return parameterlist;
} }

View File

@ -13,8 +13,8 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
public class SourceFile extends SyntaxTreeNode{ public class SourceFile extends SyntaxTreeNode{
private String pkgName; private String pkgName;
private final List<ClassOrInterface> KlassenVektor; public final List<ClassOrInterface> KlassenVektor;
private final List<JavaClassName> imports; public final List<JavaClassName> imports;
/** /**
* Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei. * Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei.
@ -36,23 +36,6 @@ public class SourceFile extends SyntaxTreeNode{
return this.imports; return this.imports;
} }
public ConstraintSet getConstraints(TypeInferenceInformation info) {
ConstraintSet ret = new ConstraintSet();
for (ClassOrInterface cl : this.KlassenVektor) {
ret.addAll(cl.getConstraints(info));
}
return ret;
}
public TypeInferenceInformation getTypeInferenceInformation(List<SourceFile> sourceFiles){
Set<ClassOrInterface> classes = new HashSet<>();
for(SourceFile sourceFile : sourceFiles){
classes.addAll(sourceFile.KlassenVektor);
}
return new TypeInferenceInformation(classes);
}
public List<ClassOrInterface> getClasses() { public List<ClassOrInterface> getClasses() {
return KlassenVektor; return KlassenVektor;
} }

View File

@ -1,318 +1,66 @@
package de.dhbwstuttgart.typeinference.typeAlgo; package de.dhbwstuttgart.typeinference.typeAlgo;
//import com.sun.org.apache.xpath.internal.Arg;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.typecheck.JavaClassName;
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.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
public class TYPE implements StatementVisitor{ public class TYPE {
private final TypeInferenceBlockInformation info; private final List<SourceFile> sfs;
private final ConstraintSet constraintsSet = new ConstraintSet();
public TYPE(TypeInferenceBlockInformation info){ public TYPE(List<SourceFile> sourceFiles){
this.info = info; sfs = sourceFiles;
} }
public ConstraintSet getConstraints() { public ConstraintSet getConstraints() {
return constraintsSet; ConstraintSet ret = new ConstraintSet();
} TypeInferenceInformation info = getTypeInferenceInformation();
for(SourceFile sf : sfs)
@Override for (ClassOrInterface cl : sf.KlassenVektor) {
public void visit(LambdaExpression lambdaExpression) { ret.addAll(getConstraintsClass(cl ,info));
TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken());
List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList());
//lambdaParams.add(tphRetType);
lambdaParams.add(0,tphRetType);
constraintsSet.addUndConstraint(
ConstraintsFactory.createPair(lambdaExpression.getType(),
new FunN(lambdaParams),PairOperator.EQUALSDOT,info));
constraintsSet.addUndConstraint(
ConstraintsFactory.createPair(lambdaExpression.getReturnType(),
tphRetType,info));
//Constraints des Bodys generieren:
TYPE lambdaScope = new TYPE(new TypeInferenceBlockInformation(info, lambdaExpression));
lambdaExpression.methodBody.accept(lambdaScope);
constraintsSet.addAll(lambdaScope.getConstraints());
}
@Override
public void visit(Assign assign) {
assign.lefSide.accept(this);
assign.rightSide.accept(this);
constraintsSet.addUndConstraint(ConstraintsFactory.createPair(
assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT, info));
}
@Override
public void visit(Binary binary) {
throw new NotImplementedException();
}
@Override
public void visit(Block block) {
for(Statement stmt : block.getStatements()){
stmt.accept(this);
}
}
@Override
public void visit(CastExpr castExpr) {
throw new NotImplementedException();
}
@Override
public void visit(EmptyStmt emptyStmt) {
//Nothing :)
}
@Override
public void visit(FieldVar fieldVar) {
fieldVar.receiver.accept(this);
Set<Constraint> oderConstraints = new HashSet<>();
for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){
Constraint constraint = new Constraint();
constraint.add(ConstraintsFactory.createPair(
fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info));
constraint.add(ConstraintsFactory.createPair(
fieldVar.getType(),fieldAssumption.getType(), info));
oderConstraints.add(constraint);
}
if(oderConstraints.size() == 0)
throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints);
}
@Override
public void visit(ForStmt forStmt) {
throw new NotImplementedException();
}
@Override
public void visit(IfStmt ifStmt) {
throw new NotImplementedException();
}
@Override
public void visit(InstanceOf instanceOf) {
throw new NotImplementedException();
}
@Override
public void visit(LocalVar localVar) {
// Es werden nur bei Feldvariablen Constraints generiert. Lokale Variablen sind eindeutig
}
@Override
public void visit(LocalVarDecl localVarDecl) {
//Hier ist nichts zu tun. Allen lokalen Variablen bekommen beim parsen schon den korrekten Typ
}
@Override
public void visit(MethodCall methodCall) {
methodCall.receiver.accept(this);
constraintsSet.addAll(this.getArgumentListConstraints(methodCall, info));
//Overloading:
Set<Constraint> methodConstraints = new HashSet<>();
for(MethodAssumption m : this.getMethods(methodCall.name, methodCall.arglist, info)){
methodConstraints.add(generateConstraint(methodCall, m, info));
}
if(methodConstraints.size()<1){
throw new TypeinferenceException("Methode "+methodCall.name+" ist nicht vorhanden!",methodCall.getOffset());
}
constraintsSet.addOderConstraint(methodConstraints);
}
@Override
public void visit(NewClass methodCall) {
constraintsSet.addAll(this.getArgumentListConstraints(methodCall, info));
//Overloading:
Set<Constraint> methodConstraints = new HashSet<>();
for(MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())){
methodConstraints.add(generateConstructorConstraint(methodCall, m, info));
}
if(methodConstraints.size()<1){
throw new TypeinferenceException("Konstruktor in Klasse "+methodCall.getType().toString()+" ist nicht vorhanden!",methodCall.getOffset());
}
constraintsSet.addOderConstraint(methodConstraints);
}
@Override
public void visit(NewArray newArray) {
throw new NotImplementedException();
}
@Override
public void visit(Receiver receiver) {
receiver.expr.accept(this);
}
@Override
public void visit(Return returnExpr) {
returnExpr.retexpr.accept(this);
constraintsSet.addUndConstraint(ConstraintsFactory.createPair(
returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT, info));
}
@Override
public void visit(ReturnVoid aReturn) {
visit((Return) aReturn);
}
@Override
public void visit(StaticClassName staticClassName) {
throw new NotImplementedException();
}
@Override
public void visit(Super aSuper) {
throw new NotImplementedException();
}
@Override
public void visit(This aThis) {
constraintsSet.addUndConstraint(ConstraintsFactory.createPair( aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info));
}
@Override
public void visit(UnaryPlus unaryPlus) {
throw new NotImplementedException();
}
@Override
public void visit(WhileStmt whileStmt) {
throw new NotImplementedException();
}
@Override
public void visit(DoStmt whileStmt) {
throw new NotImplementedException();
}
@Override
public void visit(Null aNull) {
throw new NotImplementedException();
}
@Override
public void visit(Literal literal) {
throw new NotImplementedException();
}
@Override
public void visit(AssignToField assignLeftSide) {
//Hier ist kein Code nötig. Es werden keine extra Constraints generiert
}
@Override
public void visit(AssignToLocal assignLeftSide) {
//Hier ist kein Code nötig. Es werden keine extra Constraints generiert
}
/*
METHOD CALL Section:
*/
protected Constraint<Pair> generateConstraint(MethodCall forMethod, MethodAssumption assumption, TypeInferenceBlockInformation info){
Constraint methodConstraint = new Constraint();
methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), assumption.getReceiverType(), PairOperator.SMALLERDOT, info));
methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(), PairOperator.EQUALSDOT, info));
methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info));
return methodConstraint;
}
protected Set<Pair> generateParameterConstraints(MethodCall foMethod, MethodAssumption assumption, TypeInferenceBlockInformation info) {
Set<Pair> ret = new HashSet<>();
for(int i = 0;i<foMethod.arglist.getArguments().size();i++){
ret.add(ConstraintsFactory.createPair(foMethod.arglist.getArguments().get(i).getType(),
assumption.getArgTypes().get(i), PairOperator.SMALLERDOT, info));
} }
return ret; return ret;
} }
private ConstraintSet getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) {
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) { ConstraintSet ret = new ConstraintSet();
List<MethodAssumption> ret = new ArrayList<>();
if(name.equals("apply")){
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
for(int i = 0; i< numArgs + 1 ; i++){
funNParams.add(TypePlaceholder.fresh(new NullToken()));
}
ret.add(new MethodAssumption(new FunN(funNParams), funNParams.get(0), funNParams.subList(1, funNParams.size())));
}
for(ClassOrInterface cl : info.getAvailableClasses()){
for(Method m : cl.getMethods()){ for(Method m : cl.getMethods()){
if(m.getName().equals(name) && ret.addAll(getConstraintsMethod(m,info, cl));
m.getParameterList().getFormalparalist().size() == numArgs){
RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getType());
ret.add(new MethodAssumption(cl.getType(), retType, convertParams(m.getParameterList(),info)));
}
}
} }
return ret; return ret;
} }
public static List<MethodAssumption> getMethods(String name, ArgumentList arglist, TypeInferenceBlockInformation info) { private TypeInferenceInformation getTypeInferenceInformation(){
return getMethods(name, arglist.getArguments().size(), info); Set<ClassOrInterface> classes = new HashSet<>();
for(SourceFile sourceFile : sfs){
for(JavaClassName importName : sourceFile.imports){
System.out.println(importName);
}
classes.addAll(sourceFile.KlassenVektor);
} }
protected static List<RefTypeOrTPHOrWildcardOrGeneric> convertParams(ParameterList parameterList, TypeInferenceBlockInformation info){ return new TypeInferenceInformation(classes);
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(FormalParameter fp : parameterList.getFormalparalist()){
params.add(info.checkGTV(fp.getType()));
}
return params;
} }
public ConstraintSet getArgumentListConstraints(MethodCall forMethod, TypeInferenceBlockInformation info) { private ConstraintSet getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) {
TYPE ret = new TYPE(info); if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints
for(int i = 0;i<forMethod.arglist.getArguments().size();i++){ TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
forMethod.arglist.getArguments().get(i).accept(ret); TYPEStmt methodScope = new TYPEStmt(blockInfo);
} m.block.accept(methodScope);
return ret.constraintsSet; return methodScope.getConstraints();
} }
public List<MethodAssumption> getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList){ private ConstraintSet getConstraintsConstructor(Constructor m, TypeInferenceInformation info, ClassOrInterface currentClass) {
List<MethodAssumption> ret = new ArrayList<>(); TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, null);
for(ClassOrInterface cl : info.getAvailableClasses()){ TYPEStmt methodScope = new TYPEStmt(blockInfo);
if(cl.getClassName().equals(ofType.getName())){ for(Statement stmt : m.fieldInitializations)stmt.accept(methodScope);
for(Method m : cl.getConstructors()){ ConstraintSet ret = this.getConstraintsMethod(m, info, currentClass);
if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){ ret.addAll(methodScope.getConstraints());
ret.add(new MethodAssumption(ofType, ofType, convertParams(m.getParameterList(), info)));
}
}
}
}
return ret; return ret;
} }
protected Constraint<Pair> generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption, TypeInferenceBlockInformation info){
Constraint methodConstraint = new Constraint();
methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forConstructor.getType(), PairOperator.SMALLERDOT, info));
methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info));
return methodConstraint;
}
} }

View File

@ -0,0 +1,322 @@
package de.dhbwstuttgart.typeinference.typeAlgo;
//import com.sun.org.apache.xpath.internal.Arg;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
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.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class TYPEStmt implements StatementVisitor{
private final TypeInferenceBlockInformation info;
private final ConstraintSet constraintsSet = new ConstraintSet();
public TYPEStmt(TypeInferenceBlockInformation info){
this.info = info;
}
public ConstraintSet getConstraints() {
return constraintsSet;
}
@Override
public void visit(LambdaExpression lambdaExpression) {
TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken());
List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList());
//lambdaParams.add(tphRetType);
lambdaParams.add(0,tphRetType);
constraintsSet.addUndConstraint(
ConstraintsFactory.createPair(lambdaExpression.getType(),
new FunN(lambdaParams),PairOperator.EQUALSDOT,info));
constraintsSet.addUndConstraint(
ConstraintsFactory.createPair(lambdaExpression.getReturnType(),
tphRetType,info));
//Constraints des Bodys generieren:
TYPEStmt lambdaScope = new TYPEStmt(new TypeInferenceBlockInformation(info, lambdaExpression));
lambdaExpression.methodBody.accept(lambdaScope);
constraintsSet.addAll(lambdaScope.getConstraints());
}
@Override
public void visit(Assign assign) {
assign.lefSide.accept(this);
assign.rightSide.accept(this);
constraintsSet.addUndConstraint(ConstraintsFactory.createPair(
assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT, info));
}
@Override
public void visit(Binary binary) {
throw new NotImplementedException();
}
@Override
public void visit(Block block) {
for(Statement stmt : block.getStatements()){
stmt.accept(this);
}
}
@Override
public void visit(CastExpr castExpr) {
throw new NotImplementedException();
}
@Override
public void visit(EmptyStmt emptyStmt) {
//Nothing :)
}
@Override
public void visit(FieldVar fieldVar) {
fieldVar.receiver.accept(this);
Set<Constraint> oderConstraints = new HashSet<>();
for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){
Constraint constraint = new Constraint();
constraint.add(ConstraintsFactory.createPair(
fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info));
constraint.add(ConstraintsFactory.createPair(
fieldVar.getType(),fieldAssumption.getType(), info));
oderConstraints.add(constraint);
}
if(oderConstraints.size() == 0)
throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints);
}
@Override
public void visit(ForStmt forStmt) {
throw new NotImplementedException();
}
@Override
public void visit(IfStmt ifStmt) {
throw new NotImplementedException();
}
@Override
public void visit(InstanceOf instanceOf) {
throw new NotImplementedException();
}
@Override
public void visit(LocalVar localVar) {
// Es werden nur bei Feldvariablen Constraints generiert. Lokale Variablen sind eindeutig
}
@Override
public void visit(LocalVarDecl localVarDecl) {
//Hier ist nichts zu tun. Allen lokalen Variablen bekommen beim parsen schon den korrekten Typ
}
@Override
public void visit(MethodCall methodCall) {
methodCall.receiver.accept(this);
constraintsSet.addAll(this.getArgumentListConstraints(methodCall, info));
//Overloading:
Set<Constraint> methodConstraints = new HashSet<>();
for(MethodAssumption m : this.getMethods(methodCall.name, methodCall.arglist, info)){
methodConstraints.add(generateConstraint(methodCall, m, info));
}
if(methodConstraints.size()<1){
throw new TypeinferenceException("Methode "+methodCall.name+" ist nicht vorhanden!",methodCall.getOffset());
}
constraintsSet.addOderConstraint(methodConstraints);
}
@Override
public void visit(NewClass methodCall) {
constraintsSet.addAll(this.getArgumentListConstraints(methodCall, info));
//Overloading:
Set<Constraint> methodConstraints = new HashSet<>();
for(MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())){
methodConstraints.add(generateConstructorConstraint(methodCall, m, info));
}
if(methodConstraints.size()<1){
throw new TypeinferenceException("Konstruktor in Klasse "+methodCall.getType().toString()+" ist nicht vorhanden!",methodCall.getOffset());
}
constraintsSet.addOderConstraint(methodConstraints);
}
@Override
public void visit(NewArray newArray) {
throw new NotImplementedException();
}
@Override
public void visit(Receiver receiver) {
receiver.expr.accept(this);
}
@Override
public void visit(Return returnExpr) {
returnExpr.retexpr.accept(this);
constraintsSet.addUndConstraint(ConstraintsFactory.createPair(
returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT, info));
}
@Override
public void visit(ReturnVoid aReturn) {
visit((Return) aReturn);
}
@Override
public void visit(StaticClassName staticClassName) {
throw new NotImplementedException();
}
@Override
public void visit(Super aSuper) {
throw new NotImplementedException();
}
@Override
public void visit(This aThis) {
constraintsSet.addUndConstraint(ConstraintsFactory.createPair( aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info));
}
@Override
public void visit(UnaryPlus unaryPlus) {
throw new NotImplementedException();
}
@Override
public void visit(WhileStmt whileStmt) {
throw new NotImplementedException();
}
@Override
public void visit(DoStmt whileStmt) {
throw new NotImplementedException();
}
@Override
public void visit(Null aNull) {
throw new NotImplementedException();
}
@Override
public void visit(Literal literal) {
throw new NotImplementedException();
}
@Override
public void visit(AssignToField assignLeftSide) {
//Hier ist kein Code nötig. Es werden keine extra Constraints generiert
}
@Override
public void visit(AssignToLocal assignLeftSide) {
//Hier ist kein Code nötig. Es werden keine extra Constraints generiert
}
/*
METHOD CALL Section:
*/
protected Constraint<Pair> generateConstraint(MethodCall forMethod, MethodAssumption assumption, TypeInferenceBlockInformation info){
Constraint methodConstraint = new Constraint();
methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), assumption.getReceiverType(), PairOperator.SMALLERDOT, info));
methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(), PairOperator.EQUALSDOT, info));
methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info));
return methodConstraint;
}
protected Set<Pair> generateParameterConstraints(MethodCall foMethod, MethodAssumption assumption, TypeInferenceBlockInformation info) {
Set<Pair> ret = new HashSet<>();
for(int i = 0;i<foMethod.arglist.getArguments().size();i++){
ret.add(ConstraintsFactory.createPair(foMethod.arglist.getArguments().get(i).getType(),
assumption.getArgTypes().get(i), PairOperator.SMALLERDOT, info));
}
return ret;
}
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) {
List<MethodAssumption> ret = new ArrayList<>();
if(name.equals("apply")){
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
for(int i = 0; i< numArgs + 1 ; i++){
funNParams.add(TypePlaceholder.fresh(new NullToken()));
}
ret.add(new MethodAssumption(new FunN(funNParams), funNParams.get(0), funNParams.subList(1, funNParams.size())));
}
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)));
}
}
}
return ret;
}
public static List<MethodAssumption> getMethods(String name, ArgumentList arglist, TypeInferenceBlockInformation info) {
return getMethods(name, arglist.getArguments().size(), info);
}
protected static List<RefTypeOrTPHOrWildcardOrGeneric> convertParams(ParameterList parameterList, TypeInferenceBlockInformation info){
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(FormalParameter fp : parameterList.getFormalparalist()){
params.add(info.checkGTV(fp.getType()));
}
return params;
}
public ConstraintSet getArgumentListConstraints(MethodCall forMethod, TypeInferenceBlockInformation info) {
TYPEStmt ret = new TYPEStmt(info);
for(int i = 0;i<forMethod.arglist.getArguments().size();i++){
forMethod.arglist.getArguments().get(i).accept(ret);
}
return ret.constraintsSet;
}
public List<MethodAssumption> getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList){
List<MethodAssumption> ret = new ArrayList<>();
for(ClassOrInterface cl : info.getAvailableClasses()){
if(cl.getClassName().equals(ofType.getName())){
for(Method m : cl.getConstructors()){
if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){
ret.add(new MethodAssumption(ofType, ofType, convertParams(m.getParameterList(), info)));
}
}
}
}
return ret;
}
protected Constraint<Pair> generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption, TypeInferenceBlockInformation info){
Constraint methodConstraint = new Constraint();
methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forConstructor.getType(), PairOperator.SMALLERDOT, info));
methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info));
return methodConstraint;
}
}

View File

@ -1,14 +1,13 @@
class Matrix extends Menge<Menge<Integer>> { import java.util.Vector;
class Matrix extends Vector<Vector<Integer>> {
Matrix mul_rec(Matrix m) { Matrix mul_rec(Matrix m) {
v1; auto v1 = new Vector<Integer>();
v1 = new Menge<Integer>(); auto v2 = new Vector<Integer>();
v2; auto i = 0;
v2 = new Menge<Integer>();
i;
i = 0;
while(i < m.size()) { while(i < m.size()) {
v; auto v;
v = m.elementAt(i); v = m.elementAt(i);
v2.addElement(v.remove(v.size()-1)); v2.addElement(v.remove(v.size()-1));
i++; i++;
@ -21,14 +20,14 @@ class Matrix extends Menge<Menge<Integer>> {
ret = new Matrix(); ret = new Matrix();
i = 0; i = 0;
while (i < this.size()) { while (i < this.size()) {
ret.addElement(new Menge<Integer>()); ret.addElement(new Vector<Integer>());
i++; i++;
} }
} }
i = 0; i = 0;
while (i < this.size()) { while (i < this.size()) {
int erg = 0; int erg = 0;
j; auto j;
j = 0; j = 0;
while (j < v2.size()) { while (j < v2.size()) {
erg = erg + this.elementAt(i).elementAt(j).intValue() erg = erg + this.elementAt(i).elementAt(j).intValue()

View File

@ -33,15 +33,16 @@ public class JavaTXCompilerTest extends JavaTXCompiler {
@Test @Test
public void test() throws IOException, java.lang.ClassNotFoundException { public void test() throws IOException, java.lang.ClassNotFoundException {
filesToTest.add(new File(rootDirectory+"Faculty.jav")); //filesToTest.add(new File(rootDirectory+"Faculty.jav"));
filesToTest.add(new File(rootDirectory+"mathStruc.jav")); //filesToTest.add(new File(rootDirectory+"mathStruc.jav"));
filesToTest.add(new File(rootDirectory+"Lambda.jav")); //filesToTest.add(new File(rootDirectory+"Lambda.jav"));
filesToTest.add(new File(rootDirectory+"Lambda2.jav")); //filesToTest.add(new File(rootDirectory+"Lambda2.jav"));
filesToTest.add(new File(rootDirectory+"Lambda3.jav")); //filesToTest.add(new File(rootDirectory+"Lambda3.jav"));
filesToTest.add(new File(rootDirectory+"Vector.jav")); //filesToTest.add(new File(rootDirectory+"Vector.jav"));
filesToTest.add(new File(rootDirectory+"Generics.jav")); //filesToTest.add(new File(rootDirectory+"Generics.jav"));
filesToTest.add(new File(rootDirectory+"MethodsEasy.jav")); //filesToTest.add(new File(rootDirectory+"MethodsEasy.jav"));
filesToTest.add(new File(rootDirectory+"Matrix.jav")); //filesToTest.add(new File(rootDirectory+"Matrix.jav"));
filesToTest.add(new File(rootDirectory+"Import.jav"));
for(File f : filesToTest){ for(File f : filesToTest){
SourceFile sf = this.parse(f); SourceFile sf = this.parse(f);
System.out.println(ASTTypePrinter.print(this.sourceFiles.get(sourceFiles.size()-1))); System.out.println(ASTTypePrinter.print(this.sourceFiles.get(sourceFiles.size()-1)));