forked from JavaTX/JavaCompilerCore
167 lines
5.9 KiB
Java
167 lines
5.9 KiB
Java
package de.dhbwstuttgart.syntaxtree;
|
|
|
|
import java.util.Vector;
|
|
|
|
import de.dhbwstuttgart.bytecode.ClassFile;
|
|
import de.dhbwstuttgart.myexception.JVMCodeException;
|
|
import de.dhbwstuttgart.syntaxtree.misc.DeclId;
|
|
import de.dhbwstuttgart.syntaxtree.statement.Expr;
|
|
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
|
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
|
import de.dhbwstuttgart.syntaxtree.type.Type;
|
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
|
import de.dhbwstuttgart.typeinference.ConstraintType;
|
|
import de.dhbwstuttgart.typeinference.ConstraintsSet;
|
|
import de.dhbwstuttgart.typeinference.JavaCodeResult;
|
|
import de.dhbwstuttgart.typeinference.OderConstraint;
|
|
import de.dhbwstuttgart.typeinference.ResultSet;
|
|
import de.dhbwstuttgart.typeinference.SingleConstraint;
|
|
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
|
|
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
|
|
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
|
|
|
|
/**
|
|
* 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<GenericTypeVar> 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<SyntaxTreeNode> getChildren() {
|
|
Vector<SyntaxTreeNode> ret = super.getChildren();
|
|
if(this.wert!=null)ret.add(this.wert);
|
|
return ret;
|
|
}
|
|
|
|
public int getVariableLength()
|
|
{
|
|
return declid.elementAt(0).get_Name().length();
|
|
}
|
|
@Override
|
|
public ConstraintsSet TYPE(TypeAssumptions publicAssumptions) {
|
|
if(this.wert == null && (this.getType() == null || this.getType() instanceof TypePlaceholder))
|
|
throw new TypeinferenceException("Typlose Felder müssen mit Wert initialisiert werden", this);
|
|
ConstraintsSet ret = new ConstraintsSet();
|
|
TypeAssumptions localAssumptions = publicAssumptions.clone();
|
|
|
|
for(GenericTypeVar gp : this.getGenericParameter()){
|
|
localAssumptions.add(gp.createAssumptions());
|
|
}
|
|
|
|
for(GenericTypeVar gp : this.getGenericParameter()){
|
|
gp.TYPE(localAssumptions);
|
|
}
|
|
/*
|
|
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:
|
|
ConstraintType thisType = this.getType().TYPE(localAssumptions, this);
|
|
/*
|
|
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(thisType, thisType);
|
|
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(localAssumptions));
|
|
ret.add(new SingleConstraint(this.wert.getType().TYPE(localAssumptions,this), thisType));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
@Override
|
|
public void wandleRefTypeAttributes2GenericAttributes(Vector<Type> paralist){
|
|
super.wandleRefTypeAttributes2GenericAttributes(paralist);
|
|
if(this.getWert()!=null)this.getWert().wandleRefTypeAttributes2GenericAttributes(paralist, new Vector<GenericTypeVar>()); //FieldDeclaration hat keine Generischen Variablen, daher leere Liste übergeben
|
|
}
|
|
|
|
}
|