Einsetzen von Generischen Variablen überarbeitet

This commit is contained in:
JanUlrich 2014-05-07 13:01:14 +02:00
parent ef641065e2
commit c6ddc8036d
7 changed files with 109 additions and 59 deletions

View File

@ -33,11 +33,8 @@
4. Erstellen von TypeInsertSet 4. Erstellen von TypeInsertSet
* Durchlaufen des Syntaxbaumes * Durchlaufen des Syntaxbaumes
* Jeder Knoten erstellt TypeInsertSets anhand des ResultSets. * Jeder Knoten erstellt TypeInsertSets anhand des ResultSets.
* Bei nichtauflösung eines TPH muss GenericVar eingesetzt werden: * Bei Knoten, welche Generische Variablen beinhalten können werden GenericTypeInsertPoints erstellt
* Dazu alle Abhängigkeite in Form von Pairs aus dem ResultSet ermitteln.
* GenericVarTypeInsertPoints generieren und in TypeInsertSet speichern.
* Beim Hinzufügen von GenericVarTypeInsertPoints wird kontrolliert, ob diese bereits (auch in Teilen) schon vorhanden sind.
5. Einsetzen eines TypeInsertSet (optional) 5. Einsetzen eines TypeInsertSet (optional)
1. Auf allen TypeInsertPoints die getUnresolvedTPHs-Methoden aufrufen 1. Auf allen TypeInsertPoints die getUnresolvedTPHs-Methoden aufrufen
2. Alle Abhängigkeiten dieser 2. Alle Abhängigkeiten dieser

View File

@ -2,6 +2,7 @@ package mycompiler;
import java.util.Vector; import java.util.Vector;
import typinferenz.GenericTypeInsertPoint;
import typinferenz.ResultSet; import typinferenz.ResultSet;
import typinferenz.TypeInsertPoint; import typinferenz.TypeInsertPoint;
import typinferenz.TypeInsertSet; import typinferenz.TypeInsertSet;
@ -9,7 +10,9 @@ import typinferenz.TypeInsertable;
import typinferenz.exceptions.DebugException; import typinferenz.exceptions.DebugException;
import typinferenz.exceptions.TypeinferenceException; import typinferenz.exceptions.TypeinferenceException;
import mycompiler.myclass.Class; import mycompiler.myclass.Class;
import mycompiler.myclass.Generic;
import mycompiler.mytype.GenericTypeVar; import mycompiler.mytype.GenericTypeVar;
import mycompiler.mytype.Pair;
import mycompiler.mytype.Type; import mycompiler.mytype.Type;
import mycompiler.mytype.TypePlaceholder; import mycompiler.mytype.TypePlaceholder;
@ -70,20 +73,37 @@ public abstract class SyntaxTreeNode {
* @param result - Das ResultSet auf dessen Basis die InsertPoints generiert werden * @param result - Das ResultSet auf dessen Basis die InsertPoints generiert werden
*/ */
public void addTypeInsertPoints(TypeInsertSet insertSet,ResultSet result) { public void addTypeInsertPoints(TypeInsertSet insertSet,ResultSet result) {
Vector<TypeInsertPoint> ret = new Vector<TypeInsertPoint>(); for(SyntaxTreeNode node : this.getChildren()){
node.addTypeInsertPoints(insertSet, result);
}
TypeInsertPoint tip = null; //Der TypInsertPoint für diesen Knoten
//Fall der Knoten ein TypeInsertable ist, kann direkt der TypeInsertPoint generiert werden. //Fall der Knoten ein TypeInsertable ist, kann direkt der TypeInsertPoint generiert werden.
if(this instanceof TypeInsertable){ if(this instanceof TypeInsertable){
TypeInsertable that = (TypeInsertable)this; TypeInsertable that = (TypeInsertable)this;
Type t = that.getType(); Type t = that.getType();
if(t instanceof TypePlaceholder) if(t instanceof TypePlaceholder){
ret.add(that.createTypeInsertPoint((TypePlaceholder) t, result));//ret.addAll(((TypePlaceholder)t).getTypeInsertPoints(result)); tip = that.createTypeInsertPoint((TypePlaceholder) t, result);
insertSet.add(tip);//ret.addAll(((TypePlaceholder)t).getTypeInsertPoints(result));
}
//Für den Fall, dass dieser Knoten Generische Variablen halten kann.
if(that instanceof Generic && that.getOffset()>=0){
//Alle unresolvedTPHs ermitteln und GenericTypeVarInsertPoints bilden:
Vector<TypePlaceholder> uTPHs = insertSet.getUnresolvedTPHs();
for(TypePlaceholder tph : uTPHs){//GenericInsertPoints für diese TPHs bilden:
GenericTypeInsertPoint genericTIP = new GenericTypeInsertPoint(that,tph,result);
insertSet.add(genericTIP);
}
if(uTPHs.size()>0){//Nur wenn es auch unresolvedTPHs gibt:
Vector<Pair> gPairs = result.getConstraintsFor(uTPHs);
if(gPairs.size()>0){
GenericTypeInsertPoint genericTIP = new GenericTypeInsertPoint(that,gPairs,result);
insertSet.add(genericTIP);
}
}
}
} }
insertSet.add(ret);
//Nachdem die InsertPoints und GenericVarTypeInsertPoints angefügt wurden, kann im Knoten abgestiegen werden:
for(SyntaxTreeNode node : this.getChildren()){
node.addTypeInsertPoints(insertSet, result);
}
} }
} }

View File

@ -79,7 +79,7 @@ import typinferenz.*;
// ino.class.Class.23010.declaration // ino.class.Class.23010.declaration
public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWithOffset public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWithOffset, Generic
// ino.end // ino.end
// ino.class.Class.23010.body // ino.class.Class.23010.body
{ {
@ -1360,6 +1360,10 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
// TODO Auto-generated method stub // TODO Auto-generated method stub
return 0; return 0;
} }
@Override
public void setGenericParameter(Vector<GenericTypeVar> params) {
this.genericClassParameters = params;
}
} }
// ino.end // ino.end

View File

@ -27,10 +27,12 @@ import org.apache.log4j.Logger;
import sun.reflect.generics.reflectiveObjects.NotImplementedException; import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import typinferenz.JavaCodeResult; import typinferenz.JavaCodeResult;
import typinferenz.ResultSet; import typinferenz.ResultSet;
import typinferenz.TypeInsertPoint; import typinferenz.TypeInsertPoint;
import typinferenz.TypeInsertSet;
import typinferenz.Typeable; import typinferenz.Typeable;
import typinferenz.TypeInsertable; import typinferenz.TypeInsertable;
import typinferenz.exceptions.TypeinferenceException; import typinferenz.exceptions.TypeinferenceException;
@ -281,16 +283,6 @@ public class FormalParameter extends SyntaxTreeNode implements ITypeReplacementL
return this.declid; return this.declid;
} }
@Override
public Vector<TypeInsertPoint>getTypeInsertPoints(ResultSet result) {
Vector<TypeInsertPoint> ret = super.getTypeInsertPoints(result);
if(this.getType() instanceof TypePlaceholder){
ret.add(this.createTypeInsertPoint((TypePlaceholder)this.getType(), result));//this.getType()).getTypeInsertPoints(result));
}
return ret;
}
@Override @Override
public String getDescription() { public String getDescription() {
String ret = ""; String ret = "";

View File

@ -116,8 +116,7 @@ public class TypeinferenceResultSet
public TypeInsertSet getTypeInsertionPoints(){ public TypeInsertSet getTypeInsertionPoints(){
TypeInsertSet ret = new TypeInsertSet(); TypeInsertSet ret = new TypeInsertSet();
Vector<TypeInsertPoint> insertPoints = this.ownerOfResultSet.getTypeInsertPoints(this.unifiedConstraints); this.ownerOfResultSet.addTypeInsertPoints(ret,this.unifiedConstraints);
ret.add(insertPoints);
return ret; return ret;
} }

View File

@ -3,11 +3,14 @@ package typinferenz;
import java.util.Iterator; import java.util.Iterator;
import java.util.Vector; import java.util.Vector;
import typinferenz.exceptions.DebugException;
import mycompiler.IItemWithOffset; import mycompiler.IItemWithOffset;
import mycompiler.SyntaxTreeNode;
import mycompiler.mytype.GenericTypeVar; import mycompiler.mytype.GenericTypeVar;
import mycompiler.mytype.Pair; import mycompiler.mytype.Pair;
import mycompiler.mytype.RefType; import mycompiler.mytype.RefType;
import mycompiler.mytype.Type; import mycompiler.mytype.Type;
import mycompiler.mytype.TypePlaceholder;
/** /**
* Ein InsertPoint für Generische Variablen * Ein InsertPoint für Generische Variablen
@ -22,6 +25,18 @@ public class GenericTypeInsertPoint extends TypeInsertPoint {
super(p.point, p.type, p.resultSet); super(p.point, p.type, p.resultSet);
} }
public GenericTypeInsertPoint(TypeInsertable syntaxTreeNode,
TypePlaceholder tph ,ResultSet resultSet) {
super(syntaxTreeNode, tph, resultSet);
}
public GenericTypeInsertPoint(TypeInsertable syntaxTreeNode,
Vector<Pair> pairs,ResultSet resultSet) {
super(syntaxTreeNode, null, resultSet);
this.genericPairs = pairs;
if(this.genericPairs.size() == 0)throw new DebugException("Menge der generischen Paare ist leer");
}
/** /**
* Fügt eine generische Variable in Form eines Pairs an. * Fügt eine generische Variable in Form eines Pairs an.
* @param p * @param p
@ -32,13 +47,15 @@ public class GenericTypeInsertPoint extends TypeInsertPoint {
@Override @Override
public JavaCodeResult getTypeInsertString() { public JavaCodeResult getTypeInsertString() {
if(genericPairs.size()==0)return new JavaCodeResult(); //if(genericPairs.size()==0)return new JavaCodeResult();
return super.getTypeInsertString(); return super.getTypeInsertString();
} }
@Override @Override
protected Type getInsertType(){ protected Type getInsertType(){
if(genericPairs.size()==0)return this.type; if(genericPairs.size()==0){
return new RefType("<"+this.type.printJavaCode(resultSet)+">",-1);
}
Vector<Pair> pairs = new Vector<Pair>(); Vector<Pair> pairs = new Vector<Pair>();
//Problem: <P1 extends P2> ist falsch! Es muss: <P2, P1 extends P2> heißen: //Problem: <P1 extends P2> ist falsch! Es muss: <P2, P1 extends P2> heißen:
@ -86,22 +103,22 @@ public class GenericTypeInsertPoint extends TypeInsertPoint {
public IItemWithOffset getInsertNode(){ public IItemWithOffset getInsertNode(){
return super.getGenericTypeVarInsertNode(); return super.getGenericTypeVarInsertNode();
} }
/** /**
* Versucht den GenericTypeInsertPoint mit dem übergebenenen p2 zusammenzuführen, * Versucht den GenericTypeInsertPoint mit dem <FC>bergebenenen p2 zusam
* basierend auf ihren insertPoints. * basierend auf ihren insertPoints.
* @param p2 * @param p2
* @return - Die bei der Zusammenführung entstandene GenericTypeInsertPoints * @return - Die bei der Zusammenf<FC>hrung entstandene GenericTypeInser
*/ */
public Vector<GenericTypeInsertPoint> merge(GenericTypeInsertPoint p2) { public Vector<GenericTypeInsertPoint> merge(GenericTypeInsertPoint p2) {
Vector<GenericTypeInsertPoint> ret = new Vector<GenericTypeInsertPoint>(); Vector<GenericTypeInsertPoint> ret = new Vector<GenericTypeInsertPoint>();
if(this.getInsertNode().equals(p2.getInsertNode())){ if(this.getInsertNode().equals(p2.getInsertNode())){
for(Pair p : p2.genericPairs)this.addGenericPair(p); for(Pair p : p2.genericPairs)this.addGenericPair(p);
ret.add(this); ret.add(this);
}else{ }else{
ret.add(this); ret.add(this);
ret.add(p2); ret.add(p2);
} }
return ret; return ret;
} }
} }

View File

@ -23,6 +23,7 @@ import mycompiler.mytype.TypePlaceholder;
public class TypeInsertSet { public class TypeInsertSet {
public Vector<TypeInsertPoint> points = new Vector<TypeInsertPoint>(); public Vector<TypeInsertPoint> points = new Vector<TypeInsertPoint>();
private Vector<GenericTypeInsertPoint> genericTypeInsertPoints = new Vector<GenericTypeInsertPoint>();
public TypeInsertSet() { public TypeInsertSet() {
} }
@ -41,6 +42,11 @@ public class TypeInsertSet {
} }
return new Vector<TypePlaceholder>(); return new Vector<TypePlaceholder>();
} }
public void add(GenericTypeInsertPoint typeInsertPoint) {
//this.add((TypeInsertPoint)typeInsertPoint);
this.genericTypeInsertPoints.add(typeInsertPoint);
}
/** /**
* Fügt alle Typen dieses TypeInsertSets in den übergebenen Quellcode ein * Fügt alle Typen dieses TypeInsertSets in den übergebenen Quellcode ein
@ -52,28 +58,25 @@ public class TypeInsertSet {
int additionalOffset = 0; int additionalOffset = 0;
String ret = fileContent; String ret = fileContent;
Vector<GenericTypeInsertPoint> genericTIPs = new Vector<GenericTypeInsertPoint>();
//Alle gebrauchten Generischen Variablen ermitteln:
for(TypeInsertPoint p : points){ Vector<GenericTypeInsertPoint> mergedPoints = new Vector<GenericTypeInsertPoint>();
GenericTypeInsertPoint toAdd = new GenericTypeInsertPoint(p); //GenericTypeInsertPoints mergen und dem TypeInsertSet anfügen:
for(Pair genericPair : p.getResultSet().getConstraintsFor(p.getUnresolvedTPH())){ for(GenericTypeInsertPoint p : this.genericTypeInsertPoints){
toAdd.addGenericPair(genericPair); GenericTypeInsertPoint mergePoint = null;
for(GenericTypeInsertPoint mp : mergedPoints){
if(mp.getOffset() == p.getOffset())mergePoint = mp;
} }
genericTIPs.add(toAdd); if(mergePoint == null){
} mergedPoints.add(p);
/* }else{
//... und dem TypeInsertSet anfügen: mergePoint.merge(p);
for(GenericTypeInsertPoint p : genericTIPs){
for(GenericTypeInsertPoint p2 : genericTIPs){
//Doppelte Generische Variablen definitionen ausschließen:
for(TypeInsertPoint toAdd : p.merge(p2)){
this.add(toAdd);
}
} }
//this.add(p);
} }
*/ for(TypeInsertPoint mp : mergedPoints){
this.add(mp);
}
//Anschließend sortieren (nach dem Offset der InsertPoints): //Anschließend sortieren (nach dem Offset der InsertPoints):
Collections.sort(points); Collections.sort(points);
@ -114,10 +117,28 @@ public class TypeInsertSet {
return true; return true;
} }
/**
* Fügt TypeInsertPoints an
* @param insertPoints
*/
public void add(Vector<TypeInsertPoint> insertPoints) { public void add(Vector<TypeInsertPoint> insertPoints) {
for(TypeInsertPoint p : insertPoints){ for(TypeInsertPoint p : insertPoints){
this.add(p); this.add(p);
} }
} }
/**
* Durchsucht alle bisher angefügten TypeInsertPoints nach nicht aufgelösten TypePlaceholdern.
* Diese sollten als Generische Variablen eingesetzt werden.
* TODO: Es dürfen nur die TypePlaceholder zurückgegeben werden, welche noch in keinem GenericVarTypeInsertPoint verwendet wurden.
* @return
*/
public Vector<TypePlaceholder> getUnresolvedTPHs(){
Vector<TypePlaceholder> ret = new Vector<TypePlaceholder>();
for(TypeInsertPoint p : this.points){
ret.addAll(p.getUnresolvedTPH());
}
return ret;
}
} }