package mycompiler.myclass; import java.util.Vector; import typinferenz.ConstraintsSet; import typinferenz.JavaCodeResult; import typinferenz.OderConstraint; import typinferenz.ResultSet; import typinferenz.SingleConstraint; import typinferenz.assumptions.FieldAssumption; import typinferenz.assumptions.TypeAssumptions; import typinferenz.exceptions.TypeinferenceException; import mycompiler.SyntaxTreeNode; import mycompiler.mybytecode.ClassFile; import mycompiler.myexception.JVMCodeException; import mycompiler.mystatement.Expr; import mycompiler.mytype.GenericTypeVar; import mycompiler.mytype.RefType; import mycompiler.mytype.Type; import mycompiler.mytype.TypePlaceholder; import mycompiler.mytypereconstruction.replacementlistener.CReplaceTypeEvent; /** * Eine Feldinitialisation steht für eine Felddeklaration mit gleichzeitiger Wertzuweisung * Beispiel: 'public Feld FeldVar = FeldWert;' * @author janulrich * */ public class FieldDeclaration extends Field{ private Expr wert; //private Type type; private Vector parameter; /** * Dieser Konstruktor der FieldDeclaration erstellt den Syntaxknoten vollständig. * Kein nachträgliches hinzfügen von Informationen oder aufrufen von parserPostProcessing ist notwendig. */ public FieldDeclaration(String name, Type typ){ super(0);//Dieser Deklarator wird nicht vom Parser aufgerufen. Dadurch gibt es auch keinen Offset this.setType(typ); this.set_DeclId(new DeclId(name)); } public FieldDeclaration(int offset){ super(offset); } public void setWert(Expr initialExpression){ this.wert = initialExpression; } public Expr getWert(){ return this.wert; } public String getIdentifier(){ return this.get_Name().elementAt(0).name; } @Override public void codegen(ClassFile classfile, Vector paralist) throws JVMCodeException { // TODO Auto-generated method stub } @Override public String toString() { if(getWert()!=null)return super.toString() + "=" + getWert().toString(); return super.toString(); } public JavaCodeResult printJavaCode(ResultSet resultSet) { JavaCodeResult ret = new JavaCodeResult(); JavaCodeResult toAttach = this.getType().printJavaCode(resultSet).attach(" ").attach( this.getIdentifier()); if(this.wert!=null)toAttach.attach(" = ").attach(this.getWert().printJavaCode(resultSet) ); toAttach.attach( ";"); ret.attach(toAttach); return ret; } @Override public TypeAssumptions createTypeAssumptions(Class classmember) { ////////////////////////////// //Felder: ////////////////////////////// TypeAssumptions assumptions = new TypeAssumptions(); /* * Der Feld-Assumption muss ein TPH als Typ hinzugefügt werden, falls er Typlos initialisiert wurde. Dies kann auch der Type-Algorithmus der Inst/FieldVar - Klasse machen. * Wird das Feld mit einem Typ initialisiert so muss dieser auch in die Assumptions. */ if(this.getType() == null)throw new TypeinferenceException("Der Typ eines Feldes darf nicht null sein", this); //assumptions.add(TypeAssumptions.createFieldVarAssumption(classmember.getName(), this.getName(), this.getType())); assumptions.addAssumption(new FieldAssumption(this,classmember)); return assumptions; } @Override public void parserPostProcessing(SyntaxTreeNode parent){ super.parserPostProcessing(parent); if(this.getType() == null)this.setType(TypePlaceholder.fresh(this)); } @Override public Vector getChildren() { Vector ret = new Vector(); if(this.wert!=null)ret.add(this.wert); return ret; } @Override public void replaceType(CReplaceTypeEvent e) { // TODO Auto-generated method stub } @Override public int getTypeLineNumber() { // TODO Auto-generated method stub return 0; } public int getVariableLength() { return declid.elementAt(0).get_Name().length(); } @Override public ConstraintsSet TYPE(TypeAssumptions publicAssumptions) { ConstraintsSet ret = new ConstraintsSet(); /* if(this.getType() instanceof GenericTypeVar){ //Falls Typ ein GTV ist muss er syntaktisch kontrolliert werden... GenericTypeVar gtv = (GenericTypeVar) this.getType(); } */ //TypeCheck, falls es sich um einen RefType handelt: if(this.getType()!=null && (this.getType() instanceof RefType)){ Type replaceType = null; replaceType = publicAssumptions.getTypeFor((RefType)this.getType()); if(replaceType == null)throw new TypeinferenceException("Der Typ "+this.getType().getName()+" ist nicht korrekt",this); this.setType(replaceType); } SingleConstraint c1 = new SingleConstraint(this.getType(), this.getType()); ret.add(c1); //Damit die TypVariable des Felds in den Constraints auftaucht if(this.wert!=null){ //Falls bei der Deklaration ein Wert zugewiesen wird, verhält sich das Constraintserzeugen wie bei dem Assign-Statement: ret.add(this.wert.TYPEExpr(publicAssumptions)); ret.add(new SingleConstraint(this.wert.getType(), this.getType())); } return ret; } @Override public void wandleRefTypeAttributes2GenericAttributes(Vector paralist){ super.wandleRefTypeAttributes2GenericAttributes(paralist); if(this.getWert()!=null)this.getWert().wandleRefTypeAttributes2GenericAttributes(paralist, new Vector()); //FieldDeclaration hat keine Generischen Variablen, daher leere Liste übergeben } @Override public void setGenericParameter(Vector params) { this.parameter = params; } }