package mycompiler; import java.util.Vector; import typinferenz.GenericTypeInsertPoint; import typinferenz.ResultSet; import typinferenz.TypeInsertPoint; import typinferenz.TypeInsertSet; 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; public abstract class SyntaxTreeNode { protected SyntaxTreeNode parent; /** * Wird nach dem Parsen aufgerufen. * Erfüllt folgenden Aufgaben: * 1. Füllt fehlende Typangaben mit TPHs auf. * 2. Verknüpft die Knoten des Syntaxbaums. (setzt Parent) * 3. Wechselt RefTypes gegebenenfalls mit GenericTypeVars aus. * 4. Führt einen Teil des Syntaxckecks durch. * */ public void parserPostProcessing(SyntaxTreeNode parent) { this.parent = parent; for(SyntaxTreeNode node : this.getChildren())node.parserPostProcessing(this); } public SyntaxTreeNode getParent() { return this.parent; } public abstract Vector getChildren(); public Class getParentClass(){ SyntaxTreeNode parent = this.getParent(); if(parent instanceof Class)return (Class)parent; if(parent == null) throw new DebugException("Das Wurzelelement eines Syntaxbaumes muss Class sein"); return parent.getParentClass(); } /** * Eine Beschreibung/Name des SyntaxTree-Nodes * @return */ public String getDescription(){ return this.toString(); } @Override public boolean equals(Object object){ if(!(object instanceof SyntaxTreeNode))return false; SyntaxTreeNode equal = (SyntaxTreeNode)object; if(!equal.getDescription().equals(this.getDescription()))return false; if(this.getParent()!=null) if(!this.getParent().equals(equal.getParent()))return false; //auch das Elternelement überprüfen. return true; } /** * Methode zur Generierung der TypeInsertPoints * @param insertSet - Generierte InsertPoints werden dem insertSet angefügt * @param result - Das ResultSet auf dessen Basis die InsertPoints generiert werden */ public void addTypeInsertPoints(TypeInsertSet insertSet,ResultSet result) { 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){ 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); } } } } } }