From 8d26f0609200a4b2d001553761672c302d227656 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 19 Feb 2014 05:20:54 +0100 Subject: [PATCH] Constructor implementiert --- bin/mycompiler/myparser/JavaParser.jay | 4 +- src/mycompiler/SyntaxTreeNode.java | 5 +- src/mycompiler/myclass/Class.java | 62 ++++- src/mycompiler/myclass/Constant.java | 2 +- src/mycompiler/myclass/Constructor.java | 260 ++++++++++++++++++ src/mycompiler/myclass/Field.java | 6 +- src/mycompiler/myclass/FieldDeclaration.java | 8 +- .../myclass/FieldInitialization.java | 4 +- src/mycompiler/myclass/FormalParameter.java | 13 +- src/mycompiler/myclass/Method.java | 26 +- src/mycompiler/myparser/JavaParser.java | 16 +- src/mycompiler/myparser/JavaParser.jay | 4 +- .../mystatement/LambdaExpression.java | 3 +- src/mycompiler/mystatement/LocalVarDecl.java | 19 +- src/mycompiler/mystatement/Statement.java | 4 +- src/typinferenz/FunNInterface.java | 11 + src/typinferenz/FunNMethod.java | 15 + src/typinferenz/TypeInsertable.java | 3 +- src/typinferenz/assumptions/Assumption.java | 9 +- .../assumptions/FieldAssumption.java | 28 ++ .../assumptions/FieldVarAssumption.java | 12 - .../assumptions/MethodAssumption.java | 4 +- .../assumptions/TypeAssumptions.java | 70 ++++- .../test/lambda/testResults/LambdaTest.log | 26 ++ 24 files changed, 533 insertions(+), 81 deletions(-) create mode 100644 src/typinferenz/FunNInterface.java create mode 100644 src/typinferenz/FunNMethod.java create mode 100644 src/typinferenz/assumptions/FieldAssumption.java delete mode 100644 src/typinferenz/assumptions/FieldVarAssumption.java diff --git a/bin/mycompiler/myparser/JavaParser.jay b/bin/mycompiler/myparser/JavaParser.jay index 9beb8edf0..a2755734b 100755 --- a/bin/mycompiler/myparser/JavaParser.jay +++ b/bin/mycompiler/myparser/JavaParser.jay @@ -927,7 +927,7 @@ block : '{' '}' constructordeclarator : simplename '(' ')' { - Constructor CON = new Constructor(); + Constructor CON = new Constructor(null); //TODO: Der Parser kann sowieso nicht zwischen einem Konstruktor und einer Methode unterscheiden. Das hier kann wegfallen... DeclId DIDCon = new DeclId(); DIDCon.set_Name($1.get_Name_1Element()); CON.set_DeclId(DIDCon); @@ -935,7 +935,7 @@ constructordeclarator : simplename '(' ')' } | simplename '('formalparameterlist')' { - Constructor CONpara = new Constructor(); + Constructor CONpara = new Constructor(null); DeclId DIconpara = new DeclId(); DIconpara.set_Name($1.get_Name_1Element()); CONpara.set_DeclId(DIconpara); diff --git a/src/mycompiler/SyntaxTreeNode.java b/src/mycompiler/SyntaxTreeNode.java index 6225c4eea..5252ab876 100644 --- a/src/mycompiler/SyntaxTreeNode.java +++ b/src/mycompiler/SyntaxTreeNode.java @@ -1,11 +1,13 @@ package mycompiler; import java.util.Vector; + +import typinferenz.TypinferenzException; import mycompiler.myclass.Class; public abstract class SyntaxTreeNode { - private SyntaxTreeNode parent; + protected SyntaxTreeNode parent; /** * Wird nach dem Parsen aufgerufen. @@ -30,6 +32,7 @@ public abstract class SyntaxTreeNode { public Class getParentClass(){ SyntaxTreeNode parent = this.getParent(); if(parent instanceof Class)return (Class)parent; + if(parent == null)throw new TypinferenzException("Das Wurzelelement eines Syntaxbaumes muss Class sein"); return parent.getParentClass(); } } diff --git a/src/mycompiler/myclass/Class.java b/src/mycompiler/myclass/Class.java index 589be3534..90988cf64 100755 --- a/src/mycompiler/myclass/Class.java +++ b/src/mycompiler/myclass/Class.java @@ -56,6 +56,7 @@ import org.apache.log4j.Logger; + import sun.reflect.generics.reflectiveObjects.NotImplementedException; import typinferenz.ConstraintsSet; import typinferenz.JavaCodeResult; @@ -165,14 +166,13 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface // ino.end private TypeAssumptions typeAssumptions = null;//muss mit null Initialisiert werden. Darf nur über getTypeAssumptions abgerufen werden. - private Vector methodList = null; // gleich wie typeAssumptions // ino.attribute.parserlog.23038.declaration protected Logger parselog = Logger.getLogger("parser"); // ino.end protected Logger typinferenzLog = Logger.getLogger("Typeinference"); private SyntaxTreeNode parent; - private Vector fielddecl; + private Vector fielddecl = new Vector(); // ino.method.Class.23041.definition @@ -242,11 +242,19 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface /** * @author Andreas Stadelmeier, a10023 * Fügt der Klasse eine Feld hinzu. + * Prüft dabei, ob es sich um einen Constructor handelt und wandelt diesen direkt um. * @param feld */ public void addField(Field i) { - fielddecl.addElement(i); + Field tempField = i; + if(i instanceof Method){ + Method method = (Method)i; + if(method.get_Method_Name().equals(this.getName()) ){ + tempField = new Constructor(method); + } + } + fielddecl.addElement(tempField); } // ino.method.getUsedIdsToCheck.23050.definition @@ -703,9 +711,9 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface /** * @return Eine Liste mit allen Methoden dieser Klasse - */ + private Vector getMethodList() { - //TODO: Diese Methode ersetzen: Nach dem Parsen muss es ein Parser-Postprocessing geben. Anschließend sind alle Felder und Methoden der Klasse bekannt + if(this.methodList != null) return this.methodList; //TODO: Unnötige Berechnungen im folgenden Code rauskürzen: @@ -782,7 +790,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface for(int i=0; i()); + CParaTypeAssumption paraAssum = new CParaTypeAssumption(this.getName(), method.get_Method_Name(), method.getParameterCount(), method.getOverloadedID(),para.getIdentifier(), para.getType(), para.getLineNumber(),para.getOffset(),new Vector()); //fuege Offsets fuer Parameter hinzu, hoth: 06.04.2006 Class.isFirstLocalVarDecl=false; @@ -795,7 +803,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface // F�r die V_i: - CLocalVarTypeAssumption varAssum = new CLocalVarTypeAssumption(this.getName(), method.get_Method_Name(), method.getParameterCount(), method.getOverloadedID(),"1", para.get_Name(),para.getType(), para.getLineNumber(),para.getOffset(),new Vector()); + CLocalVarTypeAssumption varAssum = new CLocalVarTypeAssumption(this.getName(), method.get_Method_Name(), method.getParameterCount(), method.getOverloadedID(),"1", para.getIdentifier(),para.getType(), para.getLineNumber(),para.getOffset(),new Vector()); localAssum.addElement(varAssum); rememberLocals.addElement(varAssum); } @@ -808,8 +816,10 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface this.methodList = methodList; return methodList; + } - +*/ + /** * Die Funktion ist erst nach dem Aufruf von getMethodList() nutzbar. * Ermittelt alle Felder und Methoden der Klasse und Erstellt eine Assumption für diese. @@ -818,7 +828,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface private TypeAssumptions getTypeAssumptions() { if(this.typeAssumptions != null)return this.typeAssumptions; //Das sorgt dafür, dass die Assumptions nur einmalig generiert werden. TypeAssumptions assumptions = new TypeAssumptions(this.getName()); - this.getMethodList(); //Diese Funktion muss zuerst ausgeführt werden. + //this.getMethodList(); //Diese Funktion muss zuerst ausgeführt werden. //Assumption für this, also die aktuelle Klasse: (ist nicht mehr nötig, da jedes AssumptionSet einer Klasse (dem namen einer Klasse) zugewiesen ist. //CLocalVarTypeAssumption thisAssumption = new CLocalVarTypeAssumption(this.name, name, 0, 0, name, "this", new RefType(name,0), 0, 0, null); //assumptions.setThisV(thisAssumption); @@ -829,9 +839,10 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface //Eine Assumption für den Standardkonstruktor: // (Ein Standardkonstruktor wird immer angefügt, da es momentan keine statischen Klassen gibt) - if(assumptions.getMethodAssumptions(this.getName(), "").size()==0){ //Falls kein Konstruktor für diese Klasse definiert wurde: - assumptions.addMethodAssumption(new RefType(this.getName(),0), "", new RefType(this.getName(),0), new Vector()); - } + //auskommentiert, da der Standardkonstruktor beim Parser-Postprocessing angefügt wird. + //if(assumptions.getMethodAssumptions(this.getName(), "").size()==0){ //Falls kein Konstruktor für diese Klasse definiert wurde: + // assumptions.addMethodAssumption(new RefType(this.getName(),0), "", new RefType(this.getName(),0), new Vector()); + //} typinferenzLog.debug("Erstellte Assumptions: "+assumptions); @@ -1252,13 +1263,26 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface @Override public void parserPostProcessing(SyntaxTreeNode parent) { - this.parent = parent; - for(SyntaxTreeNode node : this.getChildren())node.parserPostProcessing(this); + super.parserPostProcessing(parent); + //Prüfen ob ein Konstruktor vorhanden ist: + boolean constructorVorhanden = false; + for(Field f : this.getFields()){ + if(f instanceof Constructor){ + constructorVorhanden = true; + break; + } + } + if(!constructorVorhanden){//Falls kein Konstruktor vorhanden ist, muss noch der Standardkonstruktor angefügt werden: + + + Constructor standardKonstruktor = new Constructor(Method.createEmptyMethod(this.getName(), this)); + this.addField(standardKonstruktor); + } } @Override public SyntaxTreeNode getParent() { - return null; + return this; } @Override @@ -1270,5 +1294,13 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface return ret; } + @Override + public boolean equals(Object obj){ + if(!(obj instanceof Class))return false; + Class cl = (Class) obj; + if(!(cl.getName().equals(this.getName())))return false; + + return true; + } } // ino.end diff --git a/src/mycompiler/myclass/Constant.java b/src/mycompiler/myclass/Constant.java index f43a60c2c..86a347bba 100755 --- a/src/mycompiler/myclass/Constant.java +++ b/src/mycompiler/myclass/Constant.java @@ -125,7 +125,7 @@ public class Constant extends Method // ino.end // ino.method.getName.23246.definition - public String getName() + public String getIdentifier() // ino.end // ino.method.getName.23246.body { diff --git a/src/mycompiler/myclass/Constructor.java b/src/mycompiler/myclass/Constructor.java index 18be97ded..b019affb0 100644 --- a/src/mycompiler/myclass/Constructor.java +++ b/src/mycompiler/myclass/Constructor.java @@ -1,5 +1,21 @@ package mycompiler.myclass; +import java.util.Vector; + +import mycompiler.SyntaxTreeNode; +import mycompiler.mybytecode.ClassFile; +import mycompiler.myexception.JVMCodeException; +import mycompiler.mymodifier.Modifiers; +import mycompiler.mystatement.Block; +import mycompiler.mytype.GenericTypeVar; +import mycompiler.mytype.RefType; +import mycompiler.mytype.Type; +import mycompiler.mytypereconstruction.replacementlistener.CReplaceTypeEvent; +import typinferenz.ConstraintsSet; +import typinferenz.JavaCodeResult; +import typinferenz.ResultSet; +import typinferenz.assumptions.TypeAssumptions; + public class Constructor extends Method { private Method methode; @@ -9,5 +25,249 @@ public class Constructor extends Method { */ public Constructor(Method methode){ this.methode = methode; + this.setDeclIdVector(methode.getDeclIdVector()); } + + @Override + public void setGenericMethodParameters( + Vector genericMethodParameters) { + + this.methode.setGenericMethodParameters(genericMethodParameters); + } + + @Override + public Vector getGenericMethodParameters() { + + return this.methode.getGenericMethodParameters(); + } + + @Override + public void sc_init_parameterlist(boolean ext) { + + this.methode.sc_init_parameterlist(ext); + } + + @Override + public String getTypeName() { + + return this.methode.getTypeName(); + } + + @Override + public Block get_Block() { + + return this.methode.get_Block(); + } + + @Override + public void setReturnType(Type type) { + + this.methode.setReturnType(type); + } + + @Override + public void set_Block(Block blo) { + + this.methode.set_Block(blo); + } + + @Override + public void set_Modifiers(Modifiers modif) { + + this.methode.set_Modifiers(modif); + } + + @Override + public void set_ExceptionList(ExceptionList exlist) { + + this.methode.set_ExceptionList(exlist); + } + + @Override + public void setParameterList(ParameterList paralist) { + + this.methode.setParameterList(paralist); + } + + @Override + public ParameterList getParameterList() { + + return this.methode.getParameterList(); + } + + @Override + public int getParameterCount() { + + return this.methode.getParameterCount(); + } + + @Override + public ExceptionList get_ExceptionList() { + + return this.methode.get_ExceptionList(); + } + + @Override + public int getOverloadedID() { + + return this.methode.getOverloadedID(); + } + + @Override + public void setOverloadedID(int overloadedID) { + + this.methode.setOverloadedID(overloadedID); + } + + @Override + public Type getReturnType() { + + return this.methode.getReturnType(); + } + + @Override + public String get_codegen_Param_Type(Vector paralist) { + + return this.methode.get_codegen_Param_Type(paralist); + } + + @Override + public String get_Method_Name() { + + return this.methode.get_Method_Name(); + } + + @Override + public Vector get_Type_Paralist() { + + return this.methode.get_Type_Paralist(); + } + + @Override + public void codegen(ClassFile classfile, Vector paralist) + throws JVMCodeException { + + this.methode.codegen(classfile, paralist); + } + + @Override + public int getLineNumber() { + + return this.methode.getLineNumber(); + } + + @Override + public void setLineNumber(int lineNumber) { + + this.methode.setLineNumber(lineNumber); + } + + @Override + public int getOffset() { + + return this.methode.getOffset(); + } + + @Override + public int getVariableLength() { + + return this.methode.getVariableLength(); + } + + @Override + public void setOffset(int Offset) { + + this.methode.setOffset(Offset); + } + + @Override + public void replaceType(CReplaceTypeEvent e) { + + this.methode.replaceType(e); + } + + @Override + public int getTypeLineNumber() { + + return this.methode.getTypeLineNumber(); + } + + @Override + public String toString() { + + return this.methode.toString(); + } + + @Override + public void setAbstract(boolean b) { + + this.methode.setAbstract(b); + } + + @Override + public boolean isAbstract() { + + return this.methode.isAbstract(); + } + + @Override + public void wandleRefTypeAttributes2GenericAttributes(Vector paralist) { + + this.methode.wandleRefTypeAttributes2GenericAttributes(paralist); + } + + @Override + public void set_Method_Name(String string) { + + this.methode.set_Method_Name(string); + } + + @Override + public ConstraintsSet TYPE(TypeAssumptions ass) { + + return this.methode.TYPE(ass); + } + + @Override + public String getTypeInformation() { + + return this.methode.getTypeInformation(); + } + + @Override + public JavaCodeResult printJavaCode(ResultSet resultSet) { + + return this.methode.printJavaCode(resultSet); + } + + @Override + public TypeAssumptions createTypeAssumptions(Class classmember) { + + return this.methode.createTypeAssumptions(classmember); + } + + @Override + public void parserPostProcessing(SyntaxTreeNode parent) { + + this.methode.parserPostProcessing(parent); + } + + @Override + public Vector getChildren() { + + return this.methode.getChildren(); + } + + @Override + public void setType(Type t) { + + this.methode.setType(t); + } + + @Override + public Type getType() { + return new RefType(this.methode.getParentClass().getName(),0); + } + + } diff --git a/src/mycompiler/myclass/Field.java b/src/mycompiler/myclass/Field.java index d60517668..552b4f847 100644 --- a/src/mycompiler/myclass/Field.java +++ b/src/mycompiler/myclass/Field.java @@ -20,8 +20,6 @@ public abstract class Field extends SyntaxTreeNode implements TypeInsertable, Ty private Type typ; - private SyntaxTreeNode parent; - private int offset; @Override @@ -84,4 +82,8 @@ public abstract class Field extends SyntaxTreeNode implements TypeInsertable, Ty public abstract TypeAssumptions createTypeAssumptions(Class classmember); public abstract ConstraintsSet TYPE(TypeAssumptions publicAssumptions); + + public String getIdentifier() { + return this.get_Name().firstElement().get_Name(); + } } diff --git a/src/mycompiler/myclass/FieldDeclaration.java b/src/mycompiler/myclass/FieldDeclaration.java index f4f592503..70edf82f5 100644 --- a/src/mycompiler/myclass/FieldDeclaration.java +++ b/src/mycompiler/myclass/FieldDeclaration.java @@ -34,7 +34,7 @@ public class FieldDeclaration extends Field{ return this.wert; } - public String getName(){ + public String getIdentifier(){ return this.get_Name().elementAt(0).name; } @@ -54,7 +54,7 @@ public class FieldDeclaration extends Field{ public JavaCodeResult printJavaCode(ResultSet resultSet) { JavaCodeResult ret = new JavaCodeResult(); - JavaCodeResult toAttach = this.getType().printJavaCode(resultSet).attach(" ").attach( this.getName()); + 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); @@ -72,7 +72,8 @@ public class FieldDeclaration extends Field{ * Wird das Feld mit einem Typ initialisiert so muss dieser auch in die Assumptions. */ if(this.getType() == null)this.setType(TypePlaceholder.fresh(this)); - assumptions.add(TypeAssumptions.createFieldVarAssumption(classmember.getName(), this.getName(), this.getType())); + //assumptions.add(TypeAssumptions.createFieldVarAssumption(classmember.getName(), this.getName(), this.getType())); + return assumptions; } @@ -117,6 +118,7 @@ public class FieldDeclaration extends Field{ } return ret; } + } diff --git a/src/mycompiler/myclass/FieldInitialization.java b/src/mycompiler/myclass/FieldInitialization.java index babdc2e5a..39779a2c8 100755 --- a/src/mycompiler/myclass/FieldInitialization.java +++ b/src/mycompiler/myclass/FieldInitialization.java @@ -26,8 +26,8 @@ public class FieldInitialization extends InstVarDecl { return this.wert; } - public String getName(){ - return this.get_Name().elementAt(0).name; + public String getIdentifier(){ + return this.getIdentifier().elementAt(0).name; } diff --git a/src/mycompiler/myclass/FormalParameter.java b/src/mycompiler/myclass/FormalParameter.java index 3a9295d63..2244e00e5 100755 --- a/src/mycompiler/myclass/FormalParameter.java +++ b/src/mycompiler/myclass/FormalParameter.java @@ -15,6 +15,7 @@ import org.apache.log4j.Logger; + import sun.reflect.generics.reflectiveObjects.NotImplementedException; import typinferenz.JavaCodeResult; import typinferenz.ResultSet; @@ -74,7 +75,7 @@ public class FormalParameter implements ITypeReplacementListener, Typeable, Type // ino.method.get_Name.23410.definition - public String get_Name() + public String getIdentifier() // ino.end // ino.method.get_Name.23410.body { @@ -156,7 +157,7 @@ public class FormalParameter implements ITypeReplacementListener, Typeable, Type // ino.end // ino.method.replaceType.23428.body { - inferencelog.debug("Ersetze Typ in FormalParameter \""+this.get_Name()+"\""); + inferencelog.debug("Ersetze Typ in FormalParameter \""+this.getIdentifier()+"\""); if(type instanceof TypePlaceholder){ ((TypePlaceholder)type).removeReplacementListener(this); } @@ -183,14 +184,14 @@ public class FormalParameter implements ITypeReplacementListener, Typeable, Type //private Type typeVariable; public String getTypeInformation() { - return getType().toString() + " " +this.get_Name(); + return getType().toString() + " " +this.getIdentifier(); } @Override public String toString(){ String ret = ""; if(this.getType() != null)ret += this.getType().toString(); - if(this.get_Name() != null)ret += " "+get_Name(); + if(this.getIdentifier() != null)ret += " "+getIdentifier(); return ret; } @@ -198,7 +199,7 @@ public class FormalParameter implements ITypeReplacementListener, Typeable, Type public JavaCodeResult printJavaCode(ResultSet resultSet) { JavaCodeResult ret = new JavaCodeResult(); if(this.getType() != null)ret.attach(this.getType().printJavaCode(resultSet)); - if(this.get_Name() != null)ret.attach(" "+get_Name()); + if(this.getIdentifier() != null)ret.attach(" "+getIdentifier()); return ret; } @@ -210,5 +211,7 @@ public class FormalParameter implements ITypeReplacementListener, Typeable, Type //Das Offset steht in declId throw new NotImplementedException(); } + + } // ino.end diff --git a/src/mycompiler/myclass/Method.java b/src/mycompiler/myclass/Method.java index ff26f8e9e..38035d345 100755 --- a/src/mycompiler/myclass/Method.java +++ b/src/mycompiler/myclass/Method.java @@ -547,17 +547,14 @@ public class Method extends Field implements ITypeReplacementListener, IItemWith } // ino.end - /** - * Diese Variable wird beim Aufruf von - */ - private Type assumedType; + public ConstraintsSet TYPE(TypeAssumptions ass) { ConstraintsSet ret = new ConstraintsSet(); ret.add(this.block.TYPEStmt(ass)); //eine Verknüpfung mit der Type Assumption aus dem Assumption Set und dem ermittelten Typ der Methode: - ret.add(new SingleConstraint(this.block.getType(), assumedType)); + ret.add(new SingleConstraint(this.block.getType(), this.returntype)); return ret; } @@ -671,7 +668,7 @@ public class Method extends Field implements ITypeReplacementListener, IItemWith if(this.getType()==null)this.setType(TypePlaceholder.fresh(this)); //Bei dem Elterntyp der Methode darf es sich nur um eine Klasse handeln, daher Cast ohne Prüfung: Class parentClass = (Class)parent; - + if(this.returntype == null)this.returntype = TypePlaceholder.fresh(this); } @Override @@ -684,7 +681,8 @@ public class Method extends Field implements ITypeReplacementListener, IItemWith @Override public void setType(Type t){ // Methode und Block teilen sich einen ReturnType: - this.block.setType(t); + //this.block.setType(t); + this.returntype = t; } @Override @@ -692,5 +690,19 @@ public class Method extends Field implements ITypeReplacementListener, IItemWith //Methode und Block teilen sich einen ReturnType: return this.block.getType(); } + + public static Method createEmptyMethod(String withSignature, Class parent){ + Method ret = new Method(); + DeclId DImethod = new DeclId(); + DImethod.set_Name(withSignature); + ret.set_DeclId(DImethod); + Block tempBlock = new Block(); + //tempBlock.setType(new RefType(parent.getName(),0)); + ret.set_Block(tempBlock); + ret.setType(TypePlaceholder.fresh(ret)); + ret.parent = parent; + return ret; + } + } // ino.end diff --git a/src/mycompiler/myparser/JavaParser.java b/src/mycompiler/myparser/JavaParser.java index 0508574b1..4c0a9726d 100644 --- a/src/mycompiler/myparser/JavaParser.java +++ b/src/mycompiler/myparser/JavaParser.java @@ -15,7 +15,7 @@ import mycompiler.SourceFile; import mycompiler.AClassOrInterface; import mycompiler.myclass.Class; import mycompiler.myclass.ClassBody; -import mycompiler.myclass.Constructor_Backup; +import mycompiler.myclass.Constructor; import mycompiler.myclass.Constant; import mycompiler.myclass.ImportDeclarations; import mycompiler.myclass.DeclId; @@ -1335,16 +1335,16 @@ case 73: case 74: // line 837 "./../src/mycompiler/myparser/JavaParser.jay" { - ((Constructor_Backup)yyVals[-1+yyTop]).set_Block(((Block)yyVals[0+yyTop])); - yyVal = ((Constructor_Backup)yyVals[-1+yyTop]); + ((Constructor)yyVals[-1+yyTop]).set_Block(((Block)yyVals[0+yyTop])); + yyVal = ((Constructor)yyVals[-1+yyTop]); } break; case 75: // line 842 "./../src/mycompiler/myparser/JavaParser.jay" { - ((Constructor_Backup)yyVals[-1+yyTop]).set_Block(((Block)yyVals[0+yyTop])); - ((Constructor_Backup)yyVals[-1+yyTop]).set_Modifiers(((Modifiers)yyVals[-2+yyTop])); - yyVal = ((Constructor_Backup)yyVals[-1+yyTop]); + ((Constructor)yyVals[-1+yyTop]).set_Block(((Block)yyVals[0+yyTop])); + ((Constructor)yyVals[-1+yyTop]).set_Modifiers(((Modifiers)yyVals[-2+yyTop])); + yyVal = ((Constructor)yyVals[-1+yyTop]); } break; case 76: @@ -1434,7 +1434,7 @@ case 86: case 87: // line 929 "./../src/mycompiler/myparser/JavaParser.jay" { - Constructor_Backup CON = new Constructor_Backup(); + Constructor CON = new Constructor(null); /*TODO: Der Parser kann sowieso nicht zwischen einem Konstruktor und einer Methode unterscheiden. Das hier kann wegfallen...*/ DeclId DIDCon = new DeclId(); DIDCon.set_Name(((UsedId)yyVals[-2+yyTop]).get_Name_1Element()); CON.set_DeclId(DIDCon); @@ -1444,7 +1444,7 @@ case 87: case 88: // line 937 "./../src/mycompiler/myparser/JavaParser.jay" { - Constructor_Backup CONpara = new Constructor_Backup(); + Constructor CONpara = new Constructor(null); DeclId DIconpara = new DeclId(); DIconpara.set_Name(((UsedId)yyVals[-3+yyTop]).get_Name_1Element()); CONpara.set_DeclId(DIconpara); diff --git a/src/mycompiler/myparser/JavaParser.jay b/src/mycompiler/myparser/JavaParser.jay index 9beb8edf0..a2755734b 100755 --- a/src/mycompiler/myparser/JavaParser.jay +++ b/src/mycompiler/myparser/JavaParser.jay @@ -927,7 +927,7 @@ block : '{' '}' constructordeclarator : simplename '(' ')' { - Constructor CON = new Constructor(); + Constructor CON = new Constructor(null); //TODO: Der Parser kann sowieso nicht zwischen einem Konstruktor und einer Methode unterscheiden. Das hier kann wegfallen... DeclId DIDCon = new DeclId(); DIDCon.set_Name($1.get_Name_1Element()); CON.set_DeclId(DIDCon); @@ -935,7 +935,7 @@ constructordeclarator : simplename '(' ')' } | simplename '('formalparameterlist')' { - Constructor CONpara = new Constructor(); + Constructor CONpara = new Constructor(null); DeclId DIconpara = new DeclId(); DIconpara.set_Name($1.get_Name_1Element()); CONpara.set_DeclId(DIconpara); diff --git a/src/mycompiler/mystatement/LambdaExpression.java b/src/mycompiler/mystatement/LambdaExpression.java index 2e87d03c2..ea4d47a3e 100755 --- a/src/mycompiler/mystatement/LambdaExpression.java +++ b/src/mycompiler/mystatement/LambdaExpression.java @@ -11,6 +11,7 @@ import typinferenz.FunN; import typinferenz.ResultSet; import typinferenz.Typeable; import typinferenz.TypinferenzException; +import typinferenz.assumptions.ParameterAssumption; import typinferenz.assumptions.TypeAssumptions; import mycompiler.mybytecode.ClassFile; import mycompiler.mybytecode.CodeAttribute; @@ -129,7 +130,7 @@ public class LambdaExpression extends Expr{ if(param.getType()==null)param.setType(TypePlaceholder.fresh(this)); int offset = 0; //Jeder Parameter der LambdaExpression wird als CParaTypeAssumption der Assumption liste hinzugefügt: - ArgumentAssumptions.add(new CParaTypeAssumption("", "", offset, offset, param.get_Name(), param.getType(), offset, offset, null)); + ArgumentAssumptions.addParameterAssumption(new ParameterAssumption(param)); paramTypes.add(param.getType()); } this.setType(TypePlaceholder.fresh(this)); diff --git a/src/mycompiler/mystatement/LocalVarDecl.java b/src/mycompiler/mystatement/LocalVarDecl.java index 8d00c2111..7c0f301cd 100755 --- a/src/mycompiler/mystatement/LocalVarDecl.java +++ b/src/mycompiler/mystatement/LocalVarDecl.java @@ -34,17 +34,22 @@ import org.apache.log4j.Logger; // ino.end + + + import typinferenz.ConstraintsSet; import typinferenz.FreshTypeVariable; import typinferenz.JavaCodeResult; import typinferenz.ResultSet; +import typinferenz.TypeInsertable; +import typinferenz.assumptions.LocalVarAssumption; import typinferenz.assumptions.TypeAssumptions; // ino.class.LocalVarDecl.25540.declaration -public class LocalVarDecl extends Statement implements ITypeReplacementListener +public class LocalVarDecl extends Statement implements TypeInsertable // ino.end // ino.class.LocalVarDecl.25540.body { @@ -482,7 +487,7 @@ public class LocalVarDecl extends Statement implements ITypeReplacementListener public ConstraintsSet TYPEStmt(TypeAssumptions assumptions) { ConstraintsSet ret = new ConstraintsSet(); if(this.getDeclType()==null || this.getDeclType() instanceof TypePlaceholder)this.setDeclType(TypePlaceholder.fresh(this)); - assumptions.addInstVarAssumption(assumptions.getThisValue().getName(), this.get_Name(), this.getDeclType()); + assumptions.addLocalVarAssumption(new LocalVarAssumption(this)); //assumptions.remove(null); // falls Variable mit diesem Namen bereits vorhanden. this.setType(new Void(0)); //Return typ einer Variablendeklaration ist Void return ret; @@ -500,6 +505,16 @@ public class LocalVarDecl extends Statement implements ITypeReplacementListener public JavaCodeResult printJavaCode(ResultSet resultSet) { return new JavaCodeResult().attach(getDeclType().printJavaCode(resultSet)) .attach( " "+this.get_Name()+";"); } + + @Override + public void setOffset(int offset) { + this.offset = offset; + } + + @Override + public String getIdentifier() { + return this.get_Name(); + } } // ino.end diff --git a/src/mycompiler/mystatement/Statement.java b/src/mycompiler/mystatement/Statement.java index cbc912859..032b1fd6b 100755 --- a/src/mycompiler/mystatement/Statement.java +++ b/src/mycompiler/mystatement/Statement.java @@ -43,7 +43,7 @@ public abstract class Statement extends SyntaxTreeNode implements IItemWithOffse { // ino.attribute.offset.26188.declaration - private int offset; + protected int offset; // ino.end // ino.attribute.variableLength.26191.declaration private int variableLength; @@ -144,8 +144,6 @@ public abstract class Statement extends SyntaxTreeNode implements IItemWithOffse public abstract JavaCodeResult printJavaCode(ResultSet resultSet); - - } // ino.end diff --git a/src/typinferenz/FunNInterface.java b/src/typinferenz/FunNInterface.java new file mode 100644 index 000000000..2141951c1 --- /dev/null +++ b/src/typinferenz/FunNInterface.java @@ -0,0 +1,11 @@ +package typinferenz; + +import mycompiler.myclass.Class; + +public class FunNInterface extends Class{ + + public FunNInterface() { + super("FunN"); + } + +} diff --git a/src/typinferenz/FunNMethod.java b/src/typinferenz/FunNMethod.java new file mode 100644 index 000000000..48d60fa37 --- /dev/null +++ b/src/typinferenz/FunNMethod.java @@ -0,0 +1,15 @@ +package typinferenz; + +import mycompiler.myclass.Method; + +public class FunNMethod extends Method{ + + /** + * + * @param N - Anzahl der Parameter (Beispiel: Fun2) + */ + public FunNMethod(int N){ + + } + +} diff --git a/src/typinferenz/TypeInsertable.java b/src/typinferenz/TypeInsertable.java index 68410363c..f3e9409a0 100644 --- a/src/typinferenz/TypeInsertable.java +++ b/src/typinferenz/TypeInsertable.java @@ -2,9 +2,10 @@ package typinferenz; import mycompiler.mytypereconstruction.replacementlistener.ITypeReplacementListener; -public interface TypeInsertable extends ITypeReplacementListener { +public interface TypeInsertable extends ITypeReplacementListener, Typeable { public int getOffset(); public void setOffset(int offset); + public String getIdentifier(); } diff --git a/src/typinferenz/assumptions/Assumption.java b/src/typinferenz/assumptions/Assumption.java index 583d6d30f..8e92c5e89 100644 --- a/src/typinferenz/assumptions/Assumption.java +++ b/src/typinferenz/assumptions/Assumption.java @@ -1,14 +1,15 @@ package typinferenz.assumptions; +import typinferenz.TypeInsertable; import typinferenz.Typeable; import mycompiler.mytype.*; import mycompiler.myclass.Class; public class Assumption { - private Typeable typable; + private TypeInsertable typable; - public Assumption(Typeable ass){ + public Assumption(TypeInsertable ass){ this.typable = ass; } @@ -16,6 +17,8 @@ public class Assumption { return this.typable.getType(); } - + public String getIdentifier(){ + return typable.getIdentifier(); + } } diff --git a/src/typinferenz/assumptions/FieldAssumption.java b/src/typinferenz/assumptions/FieldAssumption.java new file mode 100644 index 000000000..0eb6df619 --- /dev/null +++ b/src/typinferenz/assumptions/FieldAssumption.java @@ -0,0 +1,28 @@ +package typinferenz.assumptions; + +import mycompiler.myclass.Field; +import mycompiler.myclass.Class; +import mycompiler.mytype.RefType; + +public class FieldAssumption extends Assumption { + + private Class parentClass; + private Field field; + + public FieldAssumption(Field fieldVar, Class inClass){ + super(fieldVar); + this.parentClass = inClass; + this.field = fieldVar; + } + + public Class getParentClass() { + return this.parentClass; + } + + public String getIdentifier(){ + return this.field.getIdentifier(); + } + + + +} diff --git a/src/typinferenz/assumptions/FieldVarAssumption.java b/src/typinferenz/assumptions/FieldVarAssumption.java deleted file mode 100644 index c76bdd718..000000000 --- a/src/typinferenz/assumptions/FieldVarAssumption.java +++ /dev/null @@ -1,12 +0,0 @@ -package typinferenz.assumptions; - -import mycompiler.myclass.Field; -import mycompiler.myclass.Class; - -public class FieldVarAssumption extends Assumption { - - public FieldVarAssumption(Field fieldVar, Class inClass){ - super(fieldVar); - } - -} diff --git a/src/typinferenz/assumptions/MethodAssumption.java b/src/typinferenz/assumptions/MethodAssumption.java index 26b08c397..4b4c51843 100644 --- a/src/typinferenz/assumptions/MethodAssumption.java +++ b/src/typinferenz/assumptions/MethodAssumption.java @@ -6,13 +6,13 @@ import mycompiler.mytypereconstruction.typeassumption.CParaTypeAssumption; import mycompiler.mytype.*; import mycompiler.myclass.Class; -public class MethodAssumption extends Assumption { +public class MethodAssumption extends FieldAssumption { private Method method; private Class parentClass; public MethodAssumption(Method assumedMethod, Class parentClass){ - super(assumedMethod); + super(assumedMethod, parentClass); this.method = assumedMethod; this.parentClass = parentClass; } diff --git a/src/typinferenz/assumptions/TypeAssumptions.java b/src/typinferenz/assumptions/TypeAssumptions.java index b429df327..8dc9562a4 100755 --- a/src/typinferenz/assumptions/TypeAssumptions.java +++ b/src/typinferenz/assumptions/TypeAssumptions.java @@ -45,7 +45,7 @@ public class TypeAssumptions { private Vector methodAssumptions = new Vector(); - private Vector fieldAssumptions = new Vector(); + private Vector fieldAssumptions = new Vector(); private Vector localVarAssumptions = new Vector(); private Vector parameterAssumptions = new Vector(); @@ -58,12 +58,16 @@ public class TypeAssumptions { //this.thisClassName = klassenname; } + public TypeAssumptions(String thisClassName){ + this(); + this.thisClassName = thisClassName; + } public void addMethodAssumption(MethodAssumption mAss){ this.methodAssumptions.add(mAss); } - public void addFieldAssumption(FieldVarAssumption ass){ + public void addFieldAssumption(FieldAssumption ass){ this.fieldAssumptions.add(ass); } @@ -80,7 +84,7 @@ public class TypeAssumptions { * @param withName * @return */ - public Vector getFieldVars(String withName){ + public Vector getFieldVars(String withName){ //TODO: Implementieren return null; } @@ -145,19 +149,67 @@ public class TypeAssumptions { */ public Type getVarType(String variableName){ //Zuerst die Parameter durchsuchen - for(CTypeAssumption ass : this.assumptions){//this.getParameterAssumptions(null)){ + for(ParameterAssumption ass : this.parameterAssumptions){//this.getParameterAssumptions(null)){ if(ass.getIdentifier().equals(variableName))return ass.getAssumedType(); } - //TODO: Dann die lokalen Variablen - // ... (noch nicht implementiert) + //Dann die lokalen Variablen + for(LocalVarAssumption ass : this.localVarAssumptions){ + if(ass.getIdentifier().equals(variableName))return ass.getAssumedType(); + } + //und zuletzt die Felder der Klasse in dessen Namensraum sich dieses AssumptionSet befindet. - for(CTypeAssumption ass : this.getInstVarAssumptions()){ - if(ass.getIdentifier().equals(variableName))return ass.getAssumedType(); - } + if(this.thisClassName!=null){ + for(FieldAssumption ass : this.getAssumptionsFor(this.thisClassName)){ + if(ass.getIdentifier().equals(variableName) && ass instanceof FieldAssumption)return ass.getAssumedType(); + } + } //Wird keine Assumption gefunden, muss ein Fehler vorliegen: throw new TypinferenzException("Eine Variable "+variableName+" ist in den Assumptions nicht vorhanden"); } + /** + * Sucht nach MethodAssumptions einer bestimmten Klasse mit einem bestimmten Namen. + * @param className + * @param methodName + * @param parameterCount + * @return + */ + public Vector getMethodAssumptions(String className, String methodName){ + Vector ret = new Vector(); + for(FieldAssumption ass : this.getAssumptionsFor(className)){ + //System.out.println(ass.getIdentifier()); + if(ass.getIdentifier().equals(methodName) && ass instanceof MethodAssumption)ret.add((MethodAssumption)ass); + } + //if(ret.size()==0)throw new TypinferenzException("Eine Methode "+methodName+" ist in den Assumptions nicht vorhanden"); + return ret; + } + + /** + * Liefert alle Assumptions, außer die der lokalen Variablen, welche einer bestimmten Klasse zugeordnet sind. + * @param className + * @return + */ + private Vector getAssumptionsFor(String className) { + Vector ret = new Vector(); + for(Assumption a : this.getAllAssumptions()){ + if(a instanceof FieldAssumption){ + FieldAssumption fA = (FieldAssumption) a; + if(fA.getParentClass().getName().equals(className))ret.add(fA); + } + } + return ret; + } + + + private Vector getAllAssumptions(){ + Vector ret = new Vector(); + for(Assumption f : this.localVarAssumptions)ret.add(f); + for(Assumption f : this.methodAssumptions)ret.add(f); + for(Assumption f : this.fieldAssumptions)ret.add(f); + for(Assumption f : this.parameterAssumptions)ret.add(f); + return ret; + } + public TypeAssumptions add(TypeAssumptions assumptions){ this.methodAssumptions.addAll(assumptions.methodAssumptions); this.fieldAssumptions.addAll(assumptions.fieldAssumptions); diff --git a/test/mycompiler/test/lambda/testResults/LambdaTest.log b/test/mycompiler/test/lambda/testResults/LambdaTest.log index e69de29bb..47cc141d6 100644 --- a/test/mycompiler/test/lambda/testResults/LambdaTest.log +++ b/test/mycompiler/test/lambda/testResults/LambdaTest.log @@ -0,0 +1,26 @@ +Class DEBUG [Typeinference] Erstellte Assumptions: this: WhileTestMethod Assumptions: +[typinferenz.assumptions.MethodAssumption@757828eb, typinferenz.assumptions.MethodAssumption@23c6988d] +FieldVar Assumptions: +[] +LocalVar Assumptions: +[] +Parameter Assumptions: +[] + +Block DEBUG [Typeinference] Prozessing statement: no type [var] +Block DEBUG [Typeinference] Prozessing statement: WHILE null { [(var = mycompiler.mystatement.StringLiteral@7bec09b0)] +Block DEBUG [Typeinference] Prozessing statement: (var = mycompiler.mystatement.StringLiteral@7bec09b0) +Block DEBUG [Typeinference] Prozessing statement: void(var: void = mycompiler.mystatement.StringLiteral@7bec09b0) +Block DEBUG [Typeinference] Prozessing statement: WHILE void { [void(var: void = mycompiler.mystatement.StringLiteral@7bec09b0)] +Block DEBUG [Typeinference] Prozessing statement: TPH C [var] +Class DEBUG [Typeinference] Erstellte Constraints: boolean < boolean +String < void +void < TPH D +void < TPH A +void < TPH B + +SourceFile DEBUG [Typeinference] Karthesisches Produkt der Constraints: [[(boolean <. boolean), (String <. void), (void <. TPH D), (void <. TPH A), (void <. TPH B)]] +SourceFile DEBUG [Typeinference] Unifiziertes Ergebnis: [] +SourceFile DEBUG [Typeinference] +JavaFiles: +