From c6ddc8036d42a8ce43f6a5875b0a9174387de21e Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 7 May 2014 13:01:14 +0200 Subject: [PATCH] =?UTF-8?q?Einsetzen=20von=20Generischen=20Variablen=20?= =?UTF-8?q?=C3=BCberarbeitet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 7 +-- src/mycompiler/SyntaxTreeNode.java | 38 ++++++++++--- src/mycompiler/myclass/Class.java | 6 +- src/mycompiler/myclass/FormalParameter.java | 12 +--- .../TypeinferenceResultSet.java | 3 +- src/typinferenz/GenericTypeInsertPoint.java | 45 ++++++++++----- src/typinferenz/TypeInsertSet.java | 57 +++++++++++++------ 7 files changed, 109 insertions(+), 59 deletions(-) diff --git a/Readme.md b/Readme.md index 3ef949bd2..641d10f18 100644 --- a/Readme.md +++ b/Readme.md @@ -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 diff --git a/src/mycompiler/SyntaxTreeNode.java b/src/mycompiler/SyntaxTreeNode.java index d2dd879f7..162fe915c 100644 --- a/src/mycompiler/SyntaxTreeNode.java +++ b/src/mycompiler/SyntaxTreeNode.java @@ -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 ret = new Vector(); + 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 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 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); - } } } diff --git a/src/mycompiler/myclass/Class.java b/src/mycompiler/myclass/Class.java index d6386369b..0d4f868ee 100755 --- a/src/mycompiler/myclass/Class.java +++ b/src/mycompiler/myclass/Class.java @@ -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 params) { + this.genericClassParameters = params; + } } // ino.end diff --git a/src/mycompiler/myclass/FormalParameter.java b/src/mycompiler/myclass/FormalParameter.java index 5510d8280..a9d99ff61 100755 --- a/src/mycompiler/myclass/FormalParameter.java +++ b/src/mycompiler/myclass/FormalParameter.java @@ -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 VectorgetTypeInsertPoints(ResultSet result) { - Vector 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 = ""; diff --git a/src/mycompiler/mytypereconstruction/TypeinferenceResultSet.java b/src/mycompiler/mytypereconstruction/TypeinferenceResultSet.java index 7673f123c..ee5a04619 100755 --- a/src/mycompiler/mytypereconstruction/TypeinferenceResultSet.java +++ b/src/mycompiler/mytypereconstruction/TypeinferenceResultSet.java @@ -116,8 +116,7 @@ public class TypeinferenceResultSet public TypeInsertSet getTypeInsertionPoints(){ TypeInsertSet ret = new TypeInsertSet(); - Vector insertPoints = this.ownerOfResultSet.getTypeInsertPoints(this.unifiedConstraints); - ret.add(insertPoints); + this.ownerOfResultSet.addTypeInsertPoints(ret,this.unifiedConstraints); return ret; } diff --git a/src/typinferenz/GenericTypeInsertPoint.java b/src/typinferenz/GenericTypeInsertPoint.java index 32a241550..d2dce726c 100644 --- a/src/typinferenz/GenericTypeInsertPoint.java +++ b/src/typinferenz/GenericTypeInsertPoint.java @@ -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 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 pairs = new Vector(); //Problem: ist falsch! Es muss: 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 merge(GenericTypeInsertPoint p2) { + * Versucht den GenericTypeInsertPoint mit dem bergebenenen p2 zusam + * basierend auf ihren insertPoints. + * @param p2 + * @return - Die bei der Zusammenfhrung entstandene GenericTypeInser + */ + public Vector merge(GenericTypeInsertPoint p2) { Vector ret = new Vector(); 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; - } + } + } diff --git a/src/typinferenz/TypeInsertSet.java b/src/typinferenz/TypeInsertSet.java index a492647a0..80a17581d 100644 --- a/src/typinferenz/TypeInsertSet.java +++ b/src/typinferenz/TypeInsertSet.java @@ -23,6 +23,7 @@ import mycompiler.mytype.TypePlaceholder; public class TypeInsertSet { public Vector points = new Vector(); + private Vector genericTypeInsertPoints = new Vector(); public TypeInsertSet() { } @@ -41,6 +42,11 @@ public class TypeInsertSet { } return new Vector(); } + + 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 genericTIPs = new Vector(); - //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 mergedPoints = new Vector(); + //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 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 getUnresolvedTPHs(){ + Vector ret = new Vector(); + for(TypeInsertPoint p : this.points){ + ret.addAll(p.getUnresolvedTPH()); + } + return ret; + } + }