JavaPatternMatching/src/de/dhbwstuttgart/syntaxtree/FieldDeclaration.java

202 lines
7.5 KiB
Java
Raw Normal View History

2014-09-02 08:33:54 +00:00
package de.dhbwstuttgart.syntaxtree;
2014-02-11 01:47:39 +00:00
import org.apache.bcel.Constants;
import org.apache.commons.bcel6.generic.FieldGen;
import org.apache.commons.bcel6.generic.FieldInstruction;
import org.apache.commons.bcel6.generic.InstructionList;
import org.apache.commons.bcel6.generic.ObjectType;
import org.apache.commons.bcel6.generic.ClassGen;
2014-02-11 01:47:39 +00:00
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
2014-09-04 14:35:44 +00:00
import de.dhbwstuttgart.myexception.JVMCodeException;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.syntaxtree.misc.DeclId;
import de.dhbwstuttgart.syntaxtree.statement.Expr;
import de.dhbwstuttgart.syntaxtree.statement.This;
2014-09-02 08:33:54 +00:00
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.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.OderConstraint;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
2016-04-01 14:12:30 +00:00
import de.dhbwstuttgart.typeinference.UndConstraint;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
2014-02-11 01:47:39 +00:00
2014-02-12 01:12:12 +00:00
/**
* Eine Feldinitialisation steht ¼r eine Felddeklaration mit gleichzeitiger Wertzuweisung
2014-02-12 01:12:12 +00:00
* Beispiel: 'public Feld FeldVar = FeldWert;'
* @author janulrich
*
*/
2014-02-11 01:47:39 +00:00
public class FieldDeclaration extends Field{
2014-02-12 01:12:12 +00:00
private Expr wert;
2014-02-11 01:47:39 +00:00
//private Type type;
//private Menge<GenericTypeVar> parameter;
2014-02-11 01:47:39 +00:00
2014-04-03 08:35:25 +00:00
/**
* Dieser Konstruktor der FieldDeclaration erstellt den Syntaxknoten vollständig.
* Kein nachträgliches hinzfügen von Informationen oder aufrufen von parserPostProcessing ist notwendig.
2014-04-03 08:35:25 +00:00
*/
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);
}
2014-02-11 01:47:39 +00:00
public void setWert(Expr initialExpression){
this.wert = initialExpression;
}
public Expr getWert(){
return this.wert;
}
2014-02-19 04:20:54 +00:00
public String getIdentifier(){
2014-02-11 01:47:39 +00:00
return this.get_Name().elementAt(0).name;
}
2014-02-12 01:12:12 +00:00
2014-02-11 01:47:39 +00:00
@Override
2014-02-12 01:12:12 +00:00
public String toString()
{
2014-03-17 16:55:55 +00:00
if(getWert()!=null)return super.toString() + "=" + getWert().toString();
return super.toString();
2014-02-12 01:12:12 +00:00
}
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult();
2014-02-19 04:20:54 +00:00
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);
2014-02-12 01:12:12 +00:00
return ret;
2014-02-11 01:47:39 +00:00
}
2014-02-12 01:12:12 +00:00
@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.
2014-02-12 01:12:12 +00:00
* Wird das Feld mit einem Typ initialisiert so muss dieser auch in die Assumptions.
*/
2014-04-15 12:56:20 +00:00
if(this.getType() == null)throw new TypeinferenceException("Der Typ eines Feldes darf nicht null sein", this);
2014-02-19 04:20:54 +00:00
//assumptions.add(TypeAssumptions.createFieldVarAssumption(classmember.getName(), this.getName(), this.getType()));
2014-04-09 12:12:55 +00:00
assumptions.addAssumption(new FieldAssumption(this,classmember));
2014-02-12 01:12:12 +00:00
return assumptions;
}
2014-02-11 01:47:39 +00:00
@Override
2014-02-12 01:12:12 +00:00
public void parserPostProcessing(SyntaxTreeNode parent){
super.parserPostProcessing(parent);
if(this.getType() == null)this.setType(TypePlaceholder.fresh(this));
2014-02-11 01:47:39 +00:00
}
2014-02-12 01:12:12 +00:00
2014-02-11 01:47:39 +00:00
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = super.getChildren();
if(this.wert!=null)ret.add(this.wert);
2014-02-12 01:12:12 +00:00
return ret;
}
public int getVariableLength()
{
return declid.elementAt(0).get_Name().length();
}
@Override
public ConstraintsSet TYPE(TypeAssumptions publicAssumptions) {
2014-08-28 16:42:40 +00:00
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();
2014-07-16 16:38:55 +00:00
TypeAssumptions localAssumptions = publicAssumptions.clone();
for(GenericTypeVar gp : this.getGenericParameter()){
localAssumptions.add(gp.createAssumptions());
}
for(GenericTypeVar gp : this.getGenericParameter()){
gp.TYPE(localAssumptions);
}
2014-04-09 12:12:55 +00:00
/*
if(this.getType() instanceof GenericTypeVar){
//Falls Typ ein GTV ist muss er syntaktisch kontrolliert werden...
GenericTypeVar gtv = (GenericTypeVar) this.getType();
}
*/
2014-04-15 12:56:20 +00:00
//TypeCheck, falls es sich um einen RefType handelt:
Type thisType = this.getType().TYPE(localAssumptions, this);
this.setType(thisType);
2014-06-18 09:30:14 +00:00
/*
2014-04-15 12:56:20 +00:00
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);
}
2014-06-18 09:30:14 +00:00
*/
2014-04-15 12:56:20 +00:00
2016-04-01 14:12:30 +00:00
UndConstraint c1 = ConstraintsSet.createSingleConstraint(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:
2014-07-16 16:38:55 +00:00
ret.add(this.wert.TYPEExpr(localAssumptions));
2016-04-01 14:12:30 +00:00
ret.add(ConstraintsSet.createSingleConstraint(this.wert.getType().TYPE(localAssumptions,this), thisType));
}
return ret;
}
2014-02-19 04:20:54 +00:00
@Override
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist){
super.wandleRefTypeAttributes2GenericAttributes(paralist);
if(this.getWert()!=null)this.getWert().wandleRefTypeAttributes2GenericAttributes(paralist, new Menge<GenericTypeVar>()); //FieldDeclaration hat keine Generischen Variablen, daher leere Liste übergeben
}
2014-02-11 01:47:39 +00:00
/**
* Das besondere bei genByteCode einer FieldDeclaration ist, dass ein InstructionList zurückgegeben wird.
* Dieser muss in jeden Konstruktor eingefügt werden um das Feld zu initialisieren.
* @param cg
* @return - Die InstructionList, welche das Feld initialisiert
*/
public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) {
//Das Feld an die Klasse anfügen:
FieldGen field = new FieldGen(0, this.getType().getBytecodeType(cg, rs), this.getDescription(), cg.getConstantPool());
field.addAttribute(cg.getInstructionFactory().createSignatureAttribute(this.getType().getBytecodeSignature(cg, rs)));
cg.addField(field.getField());
2015-09-23 13:30:35 +00:00
//Die Felddekleration an den Konstruktor anhängen:
InstructionList il = new InstructionList();
il.append(new This(this).genByteCode(cg, rs));
2016-03-30 08:14:05 +00:00
if(wert != null){
il.append(this.wert.genByteCode(cg, rs));
}
FieldInstruction putFieldInstruction =
cg.getInstructionFactory().createFieldAccess(this.getParentClass().getName().toString(),
this.getDescription(), this.getType().getBytecodeType(cg, rs), Constants.PUTFIELD);
2015-09-23 13:30:35 +00:00
il.append(putFieldInstruction );
return il;
}
2015-06-16 09:55:15 +00:00
/*@Override
public void genByteCode(ClassGen cg) {
// TODO Auto-generated method stub
}*/
2014-02-11 01:47:39 +00:00
}