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
* Durchlaufen des Syntaxbaumes
* Jeder Knoten erstellt TypeInsertSets anhand des ResultSets.
* Bei nichtauflösung eines TPH muss GenericVar eingesetzt werden:
* 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.
* Bei Knoten, welche Generische Variablen beinhalten können werden GenericTypeInsertPoints erstellt
5. Einsetzen eines TypeInsertSet (optional)
1. Auf allen TypeInsertPoints die getUnresolvedTPHs-Methoden aufrufen
2. Alle Abhängigkeiten dieser

View File

@ -2,6 +2,7 @@ package mycompiler;
import java.util.Vector;
import typinferenz.GenericTypeInsertPoint;
import typinferenz.ResultSet;
import typinferenz.TypeInsertPoint;
import typinferenz.TypeInsertSet;
@ -9,7 +10,9 @@ import typinferenz.TypeInsertable;
import typinferenz.exceptions.DebugException;
import typinferenz.exceptions.TypeinferenceException;
import mycompiler.myclass.Class;
import mycompiler.myclass.Generic;
import mycompiler.mytype.GenericTypeVar;
import mycompiler.mytype.Pair;
import mycompiler.mytype.Type;
import mycompiler.mytype.TypePlaceholder;
@ -70,20 +73,37 @@ public abstract class SyntaxTreeNode {
* @param result - Das ResultSet auf dessen Basis die InsertPoints generiert werden
*/
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.
if(this instanceof TypeInsertable){
TypeInsertable that = (TypeInsertable)this;
Type t = that.getType();
if(t instanceof TypePlaceholder)
ret.add(that.createTypeInsertPoint((TypePlaceholder) t, result));//ret.addAll(((TypePlaceholder)t).getTypeInsertPoints(result));
if(t instanceof TypePlaceholder){
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
public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWithOffset
public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWithOffset, Generic
// ino.end
// ino.class.Class.23010.body
{
@ -1360,6 +1360,10 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
// TODO Auto-generated method stub
return 0;
}
@Override
public void setGenericParameter(Vector<GenericTypeVar> params) {
this.genericClassParameters = params;
}
}
// ino.end

View File

@ -27,10 +27,12 @@ import org.apache.log4j.Logger;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import typinferenz.JavaCodeResult;
import typinferenz.ResultSet;
import typinferenz.TypeInsertPoint;
import typinferenz.TypeInsertSet;
import typinferenz.Typeable;
import typinferenz.TypeInsertable;
import typinferenz.exceptions.TypeinferenceException;
@ -281,16 +283,6 @@ public class FormalParameter extends SyntaxTreeNode implements ITypeReplacementL
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
public String getDescription() {
String ret = "";

View File

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

View File

@ -3,11 +3,14 @@ package typinferenz;
import java.util.Iterator;
import java.util.Vector;
import typinferenz.exceptions.DebugException;
import mycompiler.IItemWithOffset;
import mycompiler.SyntaxTreeNode;
import mycompiler.mytype.GenericTypeVar;
import mycompiler.mytype.Pair;
import mycompiler.mytype.RefType;
import mycompiler.mytype.Type;
import mycompiler.mytype.TypePlaceholder;
/**
* Ein InsertPoint für Generische Variablen
@ -22,6 +25,18 @@ public class GenericTypeInsertPoint extends TypeInsertPoint {
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.
* @param p
@ -32,13 +47,15 @@ public class GenericTypeInsertPoint extends TypeInsertPoint {
@Override
public JavaCodeResult getTypeInsertString() {
if(genericPairs.size()==0)return new JavaCodeResult();
//if(genericPairs.size()==0)return new JavaCodeResult();
return super.getTypeInsertString();
}
@Override
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>();
//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(){
return super.getGenericTypeVarInsertNode();
}
/**
* Versucht den GenericTypeInsertPoint mit dem übergebenenen p2 zusammenzuführen,
* basierend auf ihren insertPoints.
* @param p2
* @return - Die bei der Zusammenführung entstandene GenericTypeInsertPoints
*/
public Vector<GenericTypeInsertPoint> merge(GenericTypeInsertPoint p2) {
* Versucht den GenericTypeInsertPoint mit dem <FC>bergebenenen p2 zusam
* basierend auf ihren insertPoints.
* @param p2
* @return - Die bei der Zusammenf<FC>hrung entstandene GenericTypeInser
*/
public Vector<GenericTypeInsertPoint> merge(GenericTypeInsertPoint p2) {
Vector<GenericTypeInsertPoint> ret = new Vector<GenericTypeInsertPoint>();
if(this.getInsertNode().equals(p2.getInsertNode())){
for(Pair p : p2.genericPairs)this.addGenericPair(p);
ret.add(this);
for(Pair p : p2.genericPairs)this.addGenericPair(p);
ret.add(this);
}else{
ret.add(this);
ret.add(p2);
ret.add(this);
ret.add(p2);
}
return ret;
}
}
}

View File

@ -23,6 +23,7 @@ import mycompiler.mytype.TypePlaceholder;
public class TypeInsertSet {
public Vector<TypeInsertPoint> points = new Vector<TypeInsertPoint>();
private Vector<GenericTypeInsertPoint> genericTypeInsertPoints = new Vector<GenericTypeInsertPoint>();
public TypeInsertSet() {
}
@ -41,6 +42,11 @@ public class TypeInsertSet {
}
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
@ -52,28 +58,25 @@ public class TypeInsertSet {
int additionalOffset = 0;
String ret = fileContent;
Vector<GenericTypeInsertPoint> genericTIPs = new Vector<GenericTypeInsertPoint>();
//Alle gebrauchten Generischen Variablen ermitteln:
for(TypeInsertPoint p : points){
GenericTypeInsertPoint toAdd = new GenericTypeInsertPoint(p);
for(Pair genericPair : p.getResultSet().getConstraintsFor(p.getUnresolvedTPH())){
toAdd.addGenericPair(genericPair);
Vector<GenericTypeInsertPoint> mergedPoints = new Vector<GenericTypeInsertPoint>();
//GenericTypeInsertPoints mergen und dem TypeInsertSet anfügen:
for(GenericTypeInsertPoint p : this.genericTypeInsertPoints){
GenericTypeInsertPoint mergePoint = null;
for(GenericTypeInsertPoint mp : mergedPoints){
if(mp.getOffset() == p.getOffset())mergePoint = mp;
}
genericTIPs.add(toAdd);
}
/*
//... und dem TypeInsertSet anfügen:
for(GenericTypeInsertPoint p : genericTIPs){
for(GenericTypeInsertPoint p2 : genericTIPs){
//Doppelte Generische Variablen definitionen ausschließen:
for(TypeInsertPoint toAdd : p.merge(p2)){
this.add(toAdd);
}
if(mergePoint == null){
mergedPoints.add(p);
}else{
mergePoint.merge(p);
}
//this.add(p);
}
*/
for(TypeInsertPoint mp : mergedPoints){
this.add(mp);
}
//Anschließend sortieren (nach dem Offset der InsertPoints):
Collections.sort(points);
@ -114,10 +117,28 @@ public class TypeInsertSet {
return true;
}
/**
* Fügt TypeInsertPoints an
* @param insertPoints
*/
public void add(Vector<TypeInsertPoint> insertPoints) {
for(TypeInsertPoint p : insertPoints){
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;
}
}