GenericVarAssumption eingeführt

This commit is contained in:
JanUlrich 2014-06-18 11:30:14 +02:00
parent 27c4a61ed3
commit 05f4dbbff3
12 changed files with 58 additions and 23 deletions

View File

@ -652,6 +652,10 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
//Globale Assumptions anfügen: //Globale Assumptions anfügen:
assumptions.add(globalAssumptions); assumptions.add(globalAssumptions);
for(GenericTypeVar gparam : this.genericClassParameters){
gparam.TYPE(assumptions); //Constraints für die Generischen Variablen erstellen und diese dem AssumptionsSet hinzufügen
}
typinferenzLog.debug("Erstellte Assumptions: "+assumptions); typinferenzLog.debug("Erstellte Assumptions: "+assumptions);
/* /*
//Generiere Liste mit Expressions, welche zur Initialisierung von Feldern verwendet werden. //Generiere Liste mit Expressions, welche zur Initialisierung von Feldern verwendet werden.
@ -1210,7 +1214,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
* Die berechneten Variablen werden anschließend in die this.genericTypeVars eingesetzt. Dabei werden alte genericTypeVars überschrieben. * Die berechneten Variablen werden anschließend in die this.genericTypeVars eingesetzt. Dabei werden alte genericTypeVars überschrieben.
* @param tphs : Alle übriggebliebenen TypePLaceholder * @param tphs : Alle übriggebliebenen TypePLaceholder
*/ */
public void createGenericTypeVars(Vector<TypePlaceholder> tphs){ private void createGenericTypeVars(Vector<TypePlaceholder> tphs){
this.genericClassParameters = new Vector<GenericTypeVar>(); this.genericClassParameters = new Vector<GenericTypeVar>();
for(TypePlaceholder tph : tphs){ for(TypePlaceholder tph : tphs){
GenericTypeVar toAdd = new GenericTypeVar(tph,this.getOffset()); GenericTypeVar toAdd = new GenericTypeVar(tph,this.getOffset());
@ -1222,7 +1226,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
* Errechnet die Generischen Parameter der Klasse für diese Klasse. * Errechnet die Generischen Parameter der Klasse für diese Klasse.
* Die berechneten Variablen werden anschließend in die this.genericTypeVars eingesetzt. Dabei werden alte genericTypeVars überschrieben. * Die berechneten Variablen werden anschließend in die this.genericTypeVars eingesetzt. Dabei werden alte genericTypeVars überschrieben.
* @param reconstructionResult * @param reconstructionResult
*/
public void createGenericTypeVars(TypeinferenceResultSet reconstructionResult){ public void createGenericTypeVars(TypeinferenceResultSet reconstructionResult){
this.genericClassParameters = new Vector<GenericTypeVar>(); this.genericClassParameters = new Vector<GenericTypeVar>();
for(Pair pair : reconstructionResult.getUnifiedConstraints()){ for(Pair pair : reconstructionResult.getUnifiedConstraints()){
@ -1231,14 +1235,6 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
Type ta2=reconstructionResult.getUnifiedConstraints().getTypeEqualTo(pair.TA2); Type ta2=reconstructionResult.getUnifiedConstraints().getTypeEqualTo(pair.TA2);
this.genericClassParameters.add(new GenericTypeVar(new Pair(ta1,ta2),this.getOffset())); this.genericClassParameters.add(new GenericTypeVar(new Pair(ta1,ta2),this.getOffset()));
} }
/*
// Auf SuperWildcardTypes überprüfen:
ArrayList<SuperWildcardType> wildcardTypes = pair.TA2.getSuperWildcardTypes();
wildcardTypes.addAll(pair.TA1.getSuperWildcardTypes());
for(SuperWildcardType wildcardType : wildcardTypes){
this.genericClassParameters.add(new GenericTypeVar(new Pair(TypePlaceholder.fresh(), wildcardType.getContainedType())));
}
*/
} }
for(Pair pair : reconstructionResult.getConstraints()){ for(Pair pair : reconstructionResult.getConstraints()){
@ -1250,6 +1246,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
} }
} }
} }
*/
public int getOffset(){ public int getOffset(){
//TODO: richtiges Offset: //TODO: richtiges Offset:

View File

@ -137,12 +137,15 @@ public class FieldDeclaration extends Field{
*/ */
//TypeCheck, falls es sich um einen RefType handelt: //TypeCheck, falls es sich um einen RefType handelt:
this.getType().checkType(publicAssumptions, this);
/*
if(this.getType()!=null && (this.getType() instanceof RefType)){ if(this.getType()!=null && (this.getType() instanceof RefType)){
Type replaceType = null; Type replaceType = null;
replaceType = publicAssumptions.getTypeFor((RefType)this.getType()); replaceType = publicAssumptions.getTypeFor((RefType)this.getType());
if(replaceType == null)throw new TypeinferenceException("Der Typ "+this.getType().getName()+" ist nicht korrekt",this); if(replaceType == null)throw new TypeinferenceException("Der Typ "+this.getType().getName()+" ist nicht korrekt",this);
this.setType(replaceType); this.setType(replaceType);
} }
*/
SingleConstraint c1 = new SingleConstraint(this.getType(), this.getType()); SingleConstraint c1 = new SingleConstraint(this.getType(), this.getType());
ret.add(c1); //Damit die TypVariable des Felds in den Constraints auftaucht ret.add(c1); //Damit die TypVariable des Felds in den Constraints auftaucht

View File

@ -555,6 +555,8 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
} }
//TypeCheck, falls es sich um einen RefType handelt: //TypeCheck, falls es sich um einen RefType handelt:
this.returntype = this.returntype.checkType(localAss, this);
/*
if(this.returntype!=null && (this.returntype instanceof RefType)&& if(this.returntype!=null && (this.returntype instanceof RefType)&&
!(this.returntype instanceof mycompiler.mytype.Void)){//Sonderfall der Methode: Ihr Typ darf Void definiert werden. !(this.returntype instanceof mycompiler.mytype.Void)){//Sonderfall der Methode: Ihr Typ darf Void definiert werden.
Type replaceType = null; Type replaceType = null;
@ -562,10 +564,12 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
if(replaceType == null)throw new TypeinferenceException("Der Typ "+this.getType().getName()+" ist nicht korrekt",this); if(replaceType == null)throw new TypeinferenceException("Der Typ "+this.getType().getName()+" ist nicht korrekt",this);
this.returntype = replaceType; this.returntype = replaceType;
} }
*/
//Die Parameter zu den Assumptions hinzufügen: //Die Parameter zu den Assumptions hinzufügen:
if(this.parameterlist!=null)for(FormalParameter param : this.parameterlist){ if(this.parameterlist!=null)for(FormalParameter param : this.parameterlist){
param.setType(param.getType().checkType(localAss, this));
/*
if(param.getType() instanceof RefType) if(param.getType() instanceof RefType)
{ {
Type replaceType = null; Type replaceType = null;
@ -574,7 +578,7 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
throw new TypeinferenceException("Der Typ "+param.getType().getName()+" ist nicht korrekt",param); throw new TypeinferenceException("Der Typ "+param.getType().getName()+" ist nicht korrekt",param);
param.setType(replaceType); param.setType(replaceType);
} }
*/
localAss.addAssumption(new ParameterAssumption(param)); localAss.addAssumption(new ParameterAssumption(param));
} }

View File

@ -50,6 +50,7 @@ public class BoundedGenericTypeVar extends GenericTypeVar
// ino.end // ino.end
// ino.method.BoundedGenericTypeVar.29409.body // ino.method.BoundedGenericTypeVar.29409.body
{ {
//TODO: Dieser Konstruktor muss this.genericConstraint setzen
super(s, offset); super(s, offset);
if(bounds != null)for(Type t : bounds){ if(bounds != null)for(Type t : bounds){
if(t!=null)this.extendVars.add(t); if(t!=null)this.extendVars.add(t);

View File

@ -42,7 +42,7 @@ public class GenericTypeVar extends Type
{ {
Type genericTypeVar; Type genericTypeVar;
Vector<Type> extendVars = new Vector<Type>(); Vector<Type> extendVars = new Vector<Type>();
private Pair genericConstraint; protected Pair genericConstraint;
/** /**
* Eine Registry f<EFBFBD>r alle Generic-Instanzen, die vor der Bytecode-Generierung durch * Eine Registry f<EFBFBD>r alle Generic-Instanzen, die vor der Bytecode-Generierung durch
* Ihre Superklasse ersetzt werden m<EFBFBD>ssen. Siehe "Type Erasure" in Sun Spezifikation. * Ihre Superklasse ersetzt werden m<EFBFBD>ssen. Siehe "Type Erasure" in Sun Spezifikation.
@ -202,4 +202,3 @@ public class GenericTypeVar extends Type
} }
// ino.end // ino.end

View File

@ -7,6 +7,8 @@ import java.util.Vector;
import typinferenz.JavaCodeResult; import typinferenz.JavaCodeResult;
import typinferenz.ResultSet; import typinferenz.ResultSet;
import typinferenz.assumptions.TypeAssumptions;
import typinferenz.exceptions.TypeinferenceException;
import mycompiler.IItemWithOffset; import mycompiler.IItemWithOffset;
import mycompiler.SyntaxTreeNode; import mycompiler.SyntaxTreeNode;
import mycompiler.mybytecode.JVMCode; import mycompiler.mybytecode.JVMCode;
@ -278,5 +280,16 @@ public class Type implements IItemWithOffset
return false; return false;
} }
/**
* Prüft ob der Typ in den Assumptions ass vorhanden ist.
* Dabei kann eine neue Instanz eines Typs entstehen, welche von der Methode zurückgegeben wird.
* @param ass - Die Assumptions für den jeweiligen Kontext in dem sich der Typ befindet.
*/
public Type checkType(TypeAssumptions ass, IItemWithOffset parent){
Type t = ass.getTypeFor(this);
if(t==null)throw new TypeinferenceException("Der Typ "+this.getName()+" ist nicht korrekt", parent);
return t;
}
} }
// ino.end // ino.end

View File

@ -1,5 +1,11 @@
// ino.module.Void.8679.package // ino.module.Void.8679.package
package mycompiler.mytype; package mycompiler.mytype;
import mycompiler.IItemWithOffset;
import mycompiler.myclass.Method;
import typinferenz.assumptions.TypeAssumptions;
import typinferenz.exceptions.TypeinferenceException;
// ino.end // ino.end
// ino.class.Void.26857.declaration // ino.class.Void.26857.declaration
public class Void extends RefType public class Void extends RefType
@ -61,5 +67,10 @@ public class Void extends RefType
return new Void(getOffset()); return new Void(getOffset());
} }
// ino.end // ino.end
@Override
public Type checkType(TypeAssumptions ass, IItemWithOffset parent){
return this;
}
} }
// ino.end // ino.end

View File

@ -55,8 +55,8 @@ public class SingleConstraint extends UndConstraint{
if(p1 instanceof RefType)((RefType)p1).GTV2TPH(); if(p1 instanceof RefType)((RefType)p1).GTV2TPH();
if(p2 instanceof RefType)((RefType)p2).GTV2TPH(); if(p2 instanceof RefType)((RefType)p2).GTV2TPH();
if((p1 instanceof GenericTypeVar))p1 = ((GenericTypeVar)p1).getTypePlaceHolder(); if((p1 instanceof GenericTypeVar))p1 = ((GenericTypeVar)p1).getTypePlaceHolder();//throw new DebugException("GenericTypeVar sind in den Constraints nicht erlaubt");//
if((p2 instanceof GenericTypeVar))p2 = ((GenericTypeVar)p2).getTypePlaceHolder(); if((p2 instanceof GenericTypeVar))p2 = ((GenericTypeVar)p2).getTypePlaceHolder();//throw new DebugException("GenericTypeVar sind in den Constraints nicht erlaubt");//
// BaseTypes werden in RefTypes umgewandelt. Constraints dürfen nur RefTypes oder TypePlaceholder enthalten, da sonst der Unify-Algorithmus nicht funktioniert. // BaseTypes werden in RefTypes umgewandelt. Constraints dürfen nur RefTypes oder TypePlaceholder enthalten, da sonst der Unify-Algorithmus nicht funktioniert.
if(!(p1 instanceof RefType) && !(p1 instanceof TypePlaceholder) && !(p1 instanceof GenericTypeVar))p1 = new RefType(p1); if(!(p1 instanceof RefType) && !(p1 instanceof TypePlaceholder) && !(p1 instanceof GenericTypeVar))p1 = new RefType(p1);

View File

@ -15,10 +15,10 @@ public class GenericVarAssumption extends Assumption{
} }
public Type getAssumedType() { public Type getAssumedType() {
return new RefType(genericVar.getTypePlaceHolder().getName(), -1); return new RefType(this.getIdentifier(), -1);
} }
public String getIdentifier(){ public String getIdentifier(){
return genericVar.getTypePlaceHolder().getName(); return genericVar.getName();
} }
} }

View File

@ -2,6 +2,7 @@ package typinferenz.assumptions;
import java.util.Iterator; import java.util.Iterator;
import mycompiler.IItemWithOffset;
import mycompiler.myclass.Class; import mycompiler.myclass.Class;
import java.util.Vector; import java.util.Vector;
@ -294,7 +295,11 @@ public class TypeAssumptions {
* @param t * @param t
* @return null, falls der Typ nicht vorhanden ist. * @return null, falls der Typ nicht vorhanden ist.
*/ */
public Type getTypeFor(RefType t){ public Type getTypeFor(Type t){
if(t instanceof TypePlaceholder)
return t; //Handelt es sich um einen TypePlaceholder kann dieser nicht in den Assumptions vorkommen.
//Alle bekannten Klassen nach diesem Typ durchsuchen: //Alle bekannten Klassen nach diesem Typ durchsuchen:
String typName = t.getName(); String typName = t.getName();
String[] names = typName.split("[.]"); String[] names = typName.split("[.]");
@ -309,9 +314,10 @@ public class TypeAssumptions {
}else for(int i = names.length-1; i>-1;i--){ }else for(int i = names.length-1; i>-1;i--){
if(!names[i].equals(assNames[i]))match = false; if(!names[i].equals(assNames[i]))match = false;
} }
if(match){ if(match && t instanceof RefType){
RefType tr = (RefType)t;
RefType ret = ass.getAssumedClass().getType(); //Dadurch erhält der RefType den vollen Namen (bsp. java.lang.Integer) RefType ret = ass.getAssumedClass().getType(); //Dadurch erhält der RefType den vollen Namen (bsp. java.lang.Integer)
ret.set_ParaList(t.get_ParaList()); ret.set_ParaList(tr.get_ParaList());
return ret; return ret;
} }
} }

View File

@ -2,7 +2,7 @@ class Test{
m; m;
<CT> CT methode(){ <CT, CT extends String> CT methode(){
return m; return m;
} }

View File

@ -9,6 +9,7 @@ public class MutlitpleTestCases {
private static final String TEST_FILE = "Test1.jav"; private static final String TEST_FILE = "Test1.jav";
private static final String TEST_FILE2 = "Test2.jav"; private static final String TEST_FILE2 = "Test2.jav";
@Test @Test
public void test1(){ public void test1(){
Vector<String> mustContain = new Vector<String>(); Vector<String> mustContain = new Vector<String>();