TypeAssumptions überarbeitet. Neue AssumptionTypes angefügt. CType... Assumptions werden abgelöst

This commit is contained in:
JanUlrich 2014-02-14 17:31:55 +01:00
parent 95d7553482
commit c242061541
18 changed files with 611 additions and 625 deletions

View File

@ -1,278 +0,0 @@
Block DEBUG [Typeinference] Prozessing statement: TPH EM [var]
Block DEBUG [Typeinference] Prozessing statement: WHILE void { [void(var: TPH EM = mycompiler.mystatement.StringLiteral@b6c3ef9)]
Block DEBUG [Typeinference] Prozessing statement: void(var: TPH EM = mycompiler.mystatement.StringLiteral@b6c3ef9)
Block DEBUG [Typeinference] Prozessing statement: void(var: TPH EY = mycompiler.mystatement.StringLiteral@b6c3ef9)
Block DEBUG [Typeinference] Prozessing statement: WHILE void { [void(var: TPH EY = mycompiler.mystatement.StringLiteral@b6c3ef9)]
Block DEBUG [Typeinference] Prozessing statement: TPH EY [var]
Class DEBUG [Typeinference] Erstellte Constraints: boolean < boolean
String < TPH EY
TPH EY < TPH EZ
void < TPH A
SourceFile DEBUG [Typeinference] Karthesisches Produkt der Constraints: [[(boolean <. boolean), (String <. TPH EY), (TPH EY <. TPH EZ), (void <. TPH A)]]
SourceFile DEBUG [Typeinference] Unifiziertes Ergebnis: [[(TPH EZ = String), (TPH EY = String), (TPH A = void)]]
SourceFile DEBUG [Typeinference]
JavaFiles:
SourceFile DEBUG [Typeinference] JavaFile für ResultSet Unified Constraints: [(TPH EZ = String), (TPH EY = String), (TPH A = void)]
SourceFile DEBUG [Typeinference] class WhileTest extends Object
{
void method()
{
String var;
while(true){
var = "String";
}
}
}
Block DEBUG [Typeinference] Prozessing statement: TPH EO Return TestMethodCall (this(null))
Block DEBUG [Typeinference] Prozessing statement: TPH FA Return TestMethodCall (this(null))
Block DEBUG [Typeinference] Prozessing statement: TPH EQ Return TPH EP (TestMethodCall (this(null)).getSomething( [ ]))
Block DEBUG [Typeinference] Prozessing statement: TPH FC Return TPH FB (TestMethodCall (this(null)).getSomething( [ ]))
Block DEBUG [Typeinference] Prozessing statement: void(var: TPH H = TPH ER (TestMethodCall (this(null)).getSomethingMore( [ ])))
Block DEBUG [Typeinference] Prozessing statement: void(var: TPH H = TPH FD (TestMethodCall (this(null)).getSomethingMore( [ ])))
Class DEBUG [Typeinference] Erstellte Constraints: TPH H < TPH H
TestMethodCall < TPH FA
TPH FA < TPH D
[(TPH D <. TPH FB), (TestMethodCall <. TestMethodCall), ]
TPH FB < TPH FC
TPH FC < TPH E
[(TPH E <. TPH FD), (TestMethodCall <. TestMethodCall), ]
TPH FD < TPH H
TPH H < TPH FE
void < void
SourceFile DEBUG [Typeinference] Karthesisches Produkt der Constraints: [[(TPH H <. TPH H), (TestMethodCall <. TPH FA), (TPH FA <. TPH D), (TPH D <. TPH FB), (TestMethodCall <. TestMethodCall), (TPH FB <. TPH FC), (TPH FC <. TPH E), (TPH E <. TPH FD), (TestMethodCall <. TestMethodCall), (TPH FD <. TPH H), (TPH H <. TPH FE), (void <. void)]]
SourceFile DEBUG [Typeinference] Unifiziertes Ergebnis: [[(TPH FE = TestMethodCall), (TPH H = TestMethodCall), (TPH FD = TestMethodCall), (TPH E = TestMethodCall), (TPH FC = TestMethodCall), (TPH FB = TestMethodCall), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)], [(TPH FE = Object), (TPH H = TestMethodCall), (TPH FD = TestMethodCall), (TPH E = TestMethodCall), (TPH FC = TestMethodCall), (TPH FB = TestMethodCall), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)], [(TPH FE = Object), (TPH H = Object), (TPH FD = TestMethodCall), (TPH E = TestMethodCall), (TPH FC = TestMethodCall), (TPH FB = TestMethodCall), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)], [(TPH FE = Object), (TPH H = Object), (TPH FD = Object), (TPH E = TestMethodCall), (TPH FC = TestMethodCall), (TPH FB = TestMethodCall), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)], [(TPH FE = Object), (TPH H = Object), (TPH FD = Object), (TPH E = Object), (TPH FC = TestMethodCall), (TPH FB = TestMethodCall), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)], [(TPH FE = Object), (TPH H = Object), (TPH FD = Object), (TPH E = Object), (TPH FC = Object), (TPH FB = TestMethodCall), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)], [(TPH FE = Object), (TPH H = Object), (TPH FD = Object), (TPH E = Object), (TPH FC = Object), (TPH FB = Object), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)], [(TPH FE = Object), (TPH H = Object), (TPH FD = Object), (TPH E = Object), (TPH FC = Object), (TPH FB = Object), (TPH D = Object), (TPH FA = TestMethodCall)], [(TPH FE = Object), (TPH H = Object), (TPH FD = Object), (TPH E = Object), (TPH FC = Object), (TPH FB = Object), (TPH D = Object), (TPH FA = Object)]]
SourceFile DEBUG [Typeinference]
JavaFiles:
SourceFile DEBUG [Typeinference] JavaFile für ResultSet Unified Constraints: [(TPH FE = TestMethodCall), (TPH H = TestMethodCall), (TPH FD = TestMethodCall), (TPH E = TestMethodCall), (TPH FC = TestMethodCall), (TPH FB = TestMethodCall), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)]
SourceFile DEBUG [Typeinference] class TestMethodCall extends Object
{
TestMethodCall var;
TestMethodCall getSomething()
{
return this;
}
TestMethodCall getSomethingMore()
{
return this.getSomething();;
}
void setVar()
{
var = this.getSomethingMore();;
}
}
SourceFile DEBUG [Typeinference] JavaFile für ResultSet Unified Constraints: [(TPH FE = Object), (TPH H = TestMethodCall), (TPH FD = TestMethodCall), (TPH E = TestMethodCall), (TPH FC = TestMethodCall), (TPH FB = TestMethodCall), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)]
SourceFile DEBUG [Typeinference] class TestMethodCall extends Object
{
TestMethodCall var;
TestMethodCall getSomething()
{
return this;
}
TestMethodCall getSomethingMore()
{
return this.getSomething();;
}
void setVar()
{
var = this.getSomethingMore();;
}
}
SourceFile DEBUG [Typeinference] JavaFile für ResultSet Unified Constraints: [(TPH FE = Object), (TPH H = Object), (TPH FD = TestMethodCall), (TPH E = TestMethodCall), (TPH FC = TestMethodCall), (TPH FB = TestMethodCall), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)]
SourceFile DEBUG [Typeinference] class TestMethodCall extends Object
{
Object var;
TestMethodCall getSomething()
{
return this;
}
TestMethodCall getSomethingMore()
{
return this.getSomething();;
}
void setVar()
{
var = this.getSomethingMore();;
}
}
SourceFile DEBUG [Typeinference] JavaFile für ResultSet Unified Constraints: [(TPH FE = Object), (TPH H = Object), (TPH FD = Object), (TPH E = TestMethodCall), (TPH FC = TestMethodCall), (TPH FB = TestMethodCall), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)]
SourceFile DEBUG [Typeinference] class TestMethodCall extends Object
{
Object var;
TestMethodCall getSomething()
{
return this;
}
TestMethodCall getSomethingMore()
{
return this.getSomething();;
}
void setVar()
{
var = this.getSomethingMore();;
}
}
SourceFile DEBUG [Typeinference] JavaFile für ResultSet Unified Constraints: [(TPH FE = Object), (TPH H = Object), (TPH FD = Object), (TPH E = Object), (TPH FC = TestMethodCall), (TPH FB = TestMethodCall), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)]
SourceFile DEBUG [Typeinference] class TestMethodCall extends Object
{
Object var;
TestMethodCall getSomething()
{
return this;
}
TestMethodCall getSomethingMore()
{
return this.getSomething();;
}
void setVar()
{
var = this.getSomethingMore();;
}
}
SourceFile DEBUG [Typeinference] JavaFile für ResultSet Unified Constraints: [(TPH FE = Object), (TPH H = Object), (TPH FD = Object), (TPH E = Object), (TPH FC = Object), (TPH FB = TestMethodCall), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)]
SourceFile DEBUG [Typeinference] class TestMethodCall extends Object
{
Object var;
TestMethodCall getSomething()
{
return this;
}
Object getSomethingMore()
{
return this.getSomething();;
}
void setVar()
{
var = this.getSomethingMore();;
}
}
SourceFile DEBUG [Typeinference] JavaFile für ResultSet Unified Constraints: [(TPH FE = Object), (TPH H = Object), (TPH FD = Object), (TPH E = Object), (TPH FC = Object), (TPH FB = Object), (TPH D = TestMethodCall), (TPH FA = TestMethodCall)]
SourceFile DEBUG [Typeinference] class TestMethodCall extends Object
{
Object var;
TestMethodCall getSomething()
{
return this;
}
Object getSomethingMore()
{
return this.getSomething();;
}
void setVar()
{
var = this.getSomethingMore();;
}
}
SourceFile DEBUG [Typeinference] JavaFile für ResultSet Unified Constraints: [(TPH FE = Object), (TPH H = Object), (TPH FD = Object), (TPH E = Object), (TPH FC = Object), (TPH FB = Object), (TPH D = Object), (TPH FA = TestMethodCall)]
SourceFile DEBUG [Typeinference] class TestMethodCall extends Object
{
Object var;
TestMethodCall getSomething()
{
return this;
}
Object getSomethingMore()
{
return this.getSomething();;
}
void setVar()
{
var = this.getSomethingMore();;
}
}
SourceFile DEBUG [Typeinference] JavaFile für ResultSet Unified Constraints: [(TPH FE = Object), (TPH H = Object), (TPH FD = Object), (TPH E = Object), (TPH FC = Object), (TPH FB = Object), (TPH D = Object), (TPH FA = Object)]
SourceFile DEBUG [Typeinference] class TestMethodCall extends Object
{
Object var;
Object getSomething()
{
return this;
}
Object getSomethingMore()
{
return this.getSomething();;
}
void setVar()
{
var = this.getSomethingMore();;
}
}
Block DEBUG [Typeinference] Prozessing statement: TPH EV Return TPH EU(test: TPH V = mycompiler.mystatement.StringLiteral@488f612f)
Block DEBUG [Typeinference] Prozessing statement: TPH FH Return TPH FG(test: TPH V = mycompiler.mystatement.StringLiteral@488f612f)
Class DEBUG [Typeinference] Erstellte Constraints: TPH U < TPH U
String < TPH V
TPH V < TPH FG
TPH FG < TPH FH
Fun1< TPH FH, TPH V > < TPH FF
TPH FF < TPH U
SourceFile DEBUG [Typeinference] Karthesisches Produkt der Constraints: [[(TPH U <. TPH U), (String <. TPH V), (TPH V <. TPH FG), (TPH FG <. TPH FH), (Fun1< TPH FH, TPH V > <. TPH FF), (TPH FF <. TPH U)]]
SourceFile DEBUG [Typeinference] Unifiziertes Ergebnis: [[(TPH FH = String), (TPH FG = String), (TPH U = Fun1< String, String >), (TPH V = String), (TPH FF = Fun1< String, String >)], [(TPH FH = String), (TPH FG = String), (TPH U = Fun1< String, ? extends String >), (TPH V = String), (TPH FF = Fun1< String, String >)], [(TPH FH = String), (TPH FG = String), (TPH U = Fun1< String, ? super String >), (TPH V = String), (TPH FF = Fun1< String, String >)]]
SourceFile DEBUG [Typeinference]
JavaFiles:
SourceFile DEBUG [Typeinference] JavaFile für ResultSet Unified Constraints: [(TPH FH = String), (TPH FG = String), (TPH U = Fun1< String, String >), (TPH V = String), (TPH FF = Fun1< String, String >)]
SourceFile DEBUG [Typeinference] class TestLambda extends Object
{
Fun1<String, String> op = (String test) -> {
return test = "string";
};
}
SourceFile DEBUG [Typeinference] JavaFile für ResultSet Unified Constraints: [(TPH FH = String), (TPH FG = String), (TPH U = Fun1< String, ? extends String >), (TPH V = String), (TPH FF = Fun1< String, String >)]
SourceFile DEBUG [Typeinference] class TestLambda extends Object
{
Fun1<String, ? extends String> op = (String test) -> {
return test = "string";
};
}
SourceFile DEBUG [Typeinference] JavaFile für ResultSet Unified Constraints: [(TPH FH = String), (TPH FG = String), (TPH U = Fun1< String, ? super String >), (TPH V = String), (TPH FF = Fun1< String, String >)]
SourceFile DEBUG [Typeinference] class TestLambda extends Object
{
Fun1<String, ? super String> op = (String test) -> {
return test = "string";
};
}
Block DEBUG [Typeinference] Prozessing statement: void(var: TPH AK = int 1)
Block DEBUG [Typeinference] Prozessing statement: (varString: TPH AJ = TPH EX (varString: TPH AJ.toString( [ ])))

View File

@ -15,7 +15,7 @@ import java.util.Vector;
import mycompiler.myclass.Class; import mycompiler.myclass.Class;
import mycompiler.myclass.ClassBody; import mycompiler.myclass.ClassBody;
import mycompiler.myclass.Constructor; import mycompiler.myclass.Constructor_Backup;
import mycompiler.myclass.DeclId; import mycompiler.myclass.DeclId;
import mycompiler.myclass.FieldDecl; import mycompiler.myclass.FieldDecl;
import mycompiler.myclass.FormalParameter; import mycompiler.myclass.FormalParameter;

View File

@ -640,6 +640,11 @@ public class SourceFile
//FiniteClosure generieren: //FiniteClosure generieren:
FC_TTO finiteClosure = this.makeFC(); FC_TTO finiteClosure = this.makeFC();
//Alle Assumptions für diese SourceFile sammeln:
for(Class klasse : this.KlassenVektor){
globalAssumptions.add(klasse.getPublicFieldAssumptions());
}
//Alle Constraints der in dieser SourceFile enthaltenen Klassen sammeln: //Alle Constraints der in dieser SourceFile enthaltenen Klassen sammeln:
for(Class klasse : KlassenVektor){ for(Class klasse : KlassenVektor){
ConstraintsSet oderConstraints = klasse.typeReconstruction(finiteClosure, globalAssumptions); ConstraintsSet oderConstraints = klasse.typeReconstruction(finiteClosure, globalAssumptions);

View File

@ -1,6 +1,7 @@
package mycompiler; package mycompiler;
import java.util.Vector; import java.util.Vector;
import mycompiler.myclass.Class;
public abstract class SyntaxTreeNode { public abstract class SyntaxTreeNode {
@ -25,4 +26,10 @@ public abstract class SyntaxTreeNode {
public Vector<SyntaxTreeNode> getChildren(){ public Vector<SyntaxTreeNode> getChildren(){
return new Vector<SyntaxTreeNode>(); return new Vector<SyntaxTreeNode>();
} }
public Class getParentClass(){
SyntaxTreeNode parent = this.getParent();
if(parent instanceof Class)return (Class)parent;
return parent.getParentClass();
}
} }

View File

@ -54,6 +54,8 @@ import org.apache.log4j.Logger;
import sun.reflect.generics.reflectiveObjects.NotImplementedException; import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import typinferenz.ConstraintsSet; import typinferenz.ConstraintsSet;
import typinferenz.JavaCodeResult; import typinferenz.JavaCodeResult;
@ -133,9 +135,6 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
// ino.attribute.superclassid.23014.declaration // ino.attribute.superclassid.23014.declaration
public UsedId superclassid = (SourceFile.READ_OBJECT_SUPERCLASSES_FROM_JRE?UsedId.createFromQualifiedName("Object",-1):null); public UsedId superclassid = (SourceFile.READ_OBJECT_SUPERCLASSES_FROM_JRE?UsedId.createFromQualifiedName("Object",-1):null);
// ino.end // ino.end
// ino.attribute.body.23017.declaration
private ClassBody body;
// ino.end
// ino.attribute.class_block.23020.decldescription type=line // ino.attribute.class_block.23020.decldescription type=line
// private Class java; // private Class java;
// ino.end // ino.end
@ -173,6 +172,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
// ino.end // ino.end
protected Logger typinferenzLog = Logger.getLogger("Typeinference"); protected Logger typinferenzLog = Logger.getLogger("Typeinference");
private SyntaxTreeNode parent; private SyntaxTreeNode parent;
private Vector<Field> fielddecl;
// ino.method.Class.23041.definition // ino.method.Class.23041.definition
@ -234,6 +234,21 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
} }
// ino.end // ino.end
public Vector<Field> getFields()
{
return fielddecl;
}
/**
* @author Andreas Stadelmeier, a10023
* Fügt der Klasse eine Feld hinzu.
* @param feld
*/
public void addField(Field i)
{
fielddecl.addElement(i);
}
// ino.method.getUsedIdsToCheck.23050.definition // ino.method.getUsedIdsToCheck.23050.definition
public Vector<UsedId> getUsedIdsToCheck() public Vector<UsedId> getUsedIdsToCheck()
// ino.end // ino.end
@ -313,9 +328,9 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
classfile.addGenerics(this.paralist,superclassid, this.getSuperInterfaces()); classfile.addGenerics(this.paralist,superclassid, this.getSuperInterfaces());
// Body der Classfile generieren // Body der Classfile generieren
if(body != null) { //if(body != null) {
body.codegen(classfile, this.paralist); this.codegen(classfile, this.paralist);
} //}
// Ueberpruefung, ob Konstruktor generiert // Ueberpruefung, ob Konstruktor generiert
// Falls nicht, default-Konstruktor erzeugen // Falls nicht, default-Konstruktor erzeugen
@ -327,9 +342,25 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
codegenlog.info("Compilierung erfolgreich abgeschlossen, "+ getName() + ".class erstellt."); codegenlog.info("Compilierung erfolgreich abgeschlossen, "+ getName() + ".class erstellt.");
} }
// ino.end
// ino.method.set_UsedId.23074.definition public void codegen(ClassFile classfile, Vector paralist)
throws JVMCodeException
{
for(int i=0 ; i < this.getFields().size() ; i++)
{
/*
* if(this.fielddecl.elementAt(i) instanceof InstVarDecl)
{
((InstVarDecl)this.fielddecl.elementAt(i)).codegen(classfile, paralist);
}
else
*/
{
this.fielddecl.elementAt(i).codegen(classfile, paralist);
}
}
}
public void set_UsedId (UsedId uid) public void set_UsedId (UsedId uid)
// ino.end // ino.end
// ino.method.set_UsedId.23074.body // ino.method.set_UsedId.23074.body
@ -338,14 +369,42 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
} }
// ino.end // ino.end
// ino.method.set_ClassBody.23077.definition /**
* Setzt den ClassBody dieser Klasse. Wird zum Parsen benötigt.
* Der ClassBody enthält sämtliche Felder dieser Klasse.
* Mit dem Aufruf dieser Methode werden alle Felder des ClassBody in diese Class übertragen.
* (Nur einmal während des Parsens aufrufen!)
*/
public void set_ClassBody(ClassBody body) public void set_ClassBody(ClassBody body)
// ino.end
// ino.method.set_ClassBody.23077.body
{ {
this.body = body; Vector<Field> tempFields=body.getFields();
for(Field f : this.getFields()){
if(f instanceof Method){ //Wenn es sich um eine Methode handelt ist eine zusätzliche Prüfung erfoderlich: (Ist es ein Konstruktor?)
Method m = (Method)f;
/*
* Ermitteln ob es sich bei der Methode um einen Konstruktor handelt:
* (Parser kann nicht zwischen Methode und Konstruktor unterscheiden.
* Denn für einen Konstruktor gelten besondere Regeln:
* -Typ des Blocks eines Konstruktor ist void (kein Return-Statement)
* -Rückgabetyp der Methode/Konstruktors ist der Typ der Klasse
* -Ein Konstruktor kann nicht aufgerufen werden (nur mit new)
*/
if(m.get_Method_Name().equals("<init>"))throw new TypinferenzException("<init> ist kein gültiger Methodenname");
if((m.get_Method_Name().equals(this.getName()))) {
Constructor constructor = new Constructor(m);
tempFields.add(constructor); //Den Konstruktor anstatt der Methode anfügen
}else{
//Handelt es sich um keinen Konstruktor, dann die Methode unverändert den Feldern hinzufügen:
tempFields.add(m);
}
}else{
tempFields.add(f); //Ansonsten das Feld anfügen...
}
}
this.fielddecl = tempFields;
} }
// ino.end
// ino.method.set_class_block.23080.definition // ino.method.set_class_block.23080.definition
public void set_class_block(Block block) public void set_class_block(Block block)
@ -370,14 +429,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
} }
// ino.end // ino.end
// ino.method.get_ClassBody.23089.definition
public ClassBody get_ClassBody()
// ino.end
// ino.method.get_ClassBody.23089.body
{
return body;
}
// ino.end
// ino.method.get_class_block.23092.definition // ino.method.get_class_block.23092.definition
public Block get_class_block() public Block get_class_block()
@ -594,7 +646,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
//ConstraintsSet oderConstraints = this.TYPE(this.getMethodList(), fieldInitializers, assumptions); //ConstraintsSet oderConstraints = this.TYPE(this.getMethodList(), fieldInitializers, assumptions);
ConstraintsSet oderConstraints = new ConstraintsSet(); ConstraintsSet oderConstraints = new ConstraintsSet();
for(Field f:this.body.getFields()){ for(Field f:this.getFields()){
oderConstraints.add(f.TYPE(assumptions)); oderConstraints.add(f.TYPE(assumptions));
} }
typinferenzLog.debug("Erstellte Constraints: "+oderConstraints); typinferenzLog.debug("Erstellte Constraints: "+oderConstraints);
@ -672,7 +724,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
// ge�ndert: hoth 06.04.2006 // ge�ndert: hoth 06.04.2006
////////////////////////////// //////////////////////////////
for(Field field : body.getFields()) for(Field field : this.getFields())
{ {
////////////////////////////// //////////////////////////////
// Attribut: // Attribut:
@ -680,7 +732,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
} }
for(Field field : body.getFields()) for(Field field : this.getFields())
{ {
////////////////////////////// //////////////////////////////
// Methode: // Methode:
@ -771,7 +823,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
//CLocalVarTypeAssumption thisAssumption = new CLocalVarTypeAssumption(this.name, name, 0, 0, name, "this", new RefType(name,0), 0, 0, null); //CLocalVarTypeAssumption thisAssumption = new CLocalVarTypeAssumption(this.name, name, 0, 0, name, "this", new RefType(name,0), 0, 0, null);
//assumptions.setThisV(thisAssumption); //assumptions.setThisV(thisAssumption);
for(Field field : body.getFields()){ for(Field field : this.getFields()){
assumptions.add(field.createTypeAssumptions(this)); assumptions.add(field.createTypeAssumptions(this));
} }
@ -864,7 +916,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
{ {
//return superclassid.toString() + body.toString(); //return superclassid.toString() + body.toString();
//geaendert PL 07-07-28 //geaendert PL 07-07-28
return name + body.toString(); return name;
} }
// ino.end // ino.end
@ -886,12 +938,8 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
// ino.method.wandleRefTypeAttributes2GenericAttributes.23128.body // ino.method.wandleRefTypeAttributes2GenericAttributes.23128.body
{ {
// Klassen ohne Body werden hier nicht durchsucht
// (p.ex. BaseTypes)
if(body==null)
return;
Vector fieldsAndMethods=body.getFields(); Vector fieldsAndMethods=this.getFields();
// Alle Methoden und Instanzvariablen durchgehen // Alle Methoden und Instanzvariablen durchgehen
for(int i=0;i<fieldsAndMethods.size();i++){ for(int i=0;i<fieldsAndMethods.size();i++){
@ -1110,7 +1158,11 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
} }
classBodyCode.attach(this.name + " extends ").attach(superclassid.printJavaCode(reconstructionResult.getUnifiedConstraints())).attach("\n"); classBodyCode.attach(this.name + " extends ").attach(superclassid.printJavaCode(reconstructionResult.getUnifiedConstraints())).attach("\n");
JavaCodeResult bodyString = this.body.printJavaCode(reconstructionResult.getUnifiedConstraints()).attach("\n");
JavaCodeResult bodyString = new JavaCodeResult("{\n");
for(Field field : this.fielddecl)bodyString.attach( field.printJavaCode(reconstructionResult.getUnifiedConstraints()) ).attach( "\n" );
bodyString.attach("}\n");
classBodyCode.attach(bodyString); classBodyCode.attach(bodyString);
//Zuerst die generischen Parameter für diese Klasse berechnen: //Zuerst die generischen Parameter für diese Klasse berechnen:
@ -1212,7 +1264,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface
@Override @Override
public Vector<SyntaxTreeNode> getChildren() { public Vector<SyntaxTreeNode> getChildren() {
Vector<SyntaxTreeNode> ret = new Vector<SyntaxTreeNode>(); Vector<SyntaxTreeNode> ret = new Vector<SyntaxTreeNode>();
for(Field f : this.body.getFields()){ for(Field f : this.getFields()){
ret.add(f); ret.add(f);
} }
return ret; return ret;

View File

@ -23,8 +23,6 @@ import typinferenz.ResultSet;
// ino.class.ClassBody.23143.declaration // ino.class.ClassBody.23143.declaration
public class ClassBody public class ClassBody
// ino.end
// ino.class.ClassBody.23143.body
{ {
// ino.attribute.fielddecl.23146.declaration // ino.attribute.fielddecl.23146.declaration
private Vector<Field>fielddecl = new Vector<Field>(); private Vector<Field>fielddecl = new Vector<Field>();
@ -359,10 +357,6 @@ public void istParameterOK( Vector Parameter, Vector<Class> KlassenVektor )
} }
// ino.end // ino.end
private Vector<FieldInitialization> fieldInitialisations = new Vector<FieldInitialization>();
public JavaCodeResult printJavaCode(ResultSet resultSet) { public JavaCodeResult printJavaCode(ResultSet resultSet) {
@ -374,14 +368,6 @@ public void istParameterOK( Vector Parameter, Vector<Class> KlassenVektor )
@Deprecated
public Vector<FieldDeclaration> getFieldInitializations() {
Vector<FieldDeclaration> ret = new Vector<FieldDeclaration>();
for(Field f:this.getFields()){
if(f instanceof FieldDeclaration)ret.add((FieldDeclaration)f);
}
return ret;
}
} }
// ino.end // ino.end

84
src/mycompiler/myclass/Constructor.java Executable file → Normal file
View File

@ -1,79 +1,13 @@
// ino.module.Constructor.8557.package
package mycompiler.myclass; package mycompiler.myclass;
// ino.end
// ino.module.Constructor.8557.import
import java.util.Iterator;
import java.util.Vector;
import typinferenz.ConstraintsSet; public class Constructor extends Method {
import typinferenz.assumptions.TypeAssumptions; private Method methode;
import mycompiler.mybytecode.ClassFile;
import mycompiler.myexception.JVMCodeException;
// ino.end
import mycompiler.mytype.TypePlaceholder;
import mycompiler.mytypereconstruction.set.CTypeAssumptionSet;
import mycompiler.mytypereconstruction.typeassumption.CInstVarTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CLocalVarTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CMethodTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CParaTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CTypeAssumption;
/**
* Parser kann nicht zwischen einem Konstruktor und einer Methode unterscheiden.
* Diese Klasse beherbegt den als Methode geparsten Konstruktor und wandelt sein verhalten zu dem eines Konstruktors ab.
// ino.class.Constructor.23267.declaration */
public class Constructor extends Method public Constructor(Method methode){
// ino.end this.methode = methode;
// ino.class.Constructor.23267.body }
{
// ino.method.Constructor.23271.definition
public Constructor()
// ino.end
// ino.method.Constructor.23271.body
{
this.setParameterList(null);
// #JB# 04.06.2005
// ###########################################################
DeclId decl = new DeclId();
decl.set_Name("<init>");
this.set_DeclId(decl);
// ###########################################################
}
// ino.end
// ino.method.get_codegen_Param_Type.23274.definition
public String get_codegen_Param_Type(Vector paralist)
// ino.end
// ino.method.get_codegen_Param_Type.23274.body
{
String ret = new String();
if(this.getParameterList() == null)
{
ret += "()";
}
else
{
ret += this.getParameterList().get_codegen_ParameterList(paralist);
}
ret += "V";
return ret;
}
// ino.end
// ino.method.codegen.23277.definition
public void codegen(ClassFile classfile, Vector paralist)
throws JVMCodeException
// ino.end
// ino.method.codegen.23277.body
{
classfile.set_constructor_founded(true);
classfile.add_method("<init>", this.get_codegen_Param_Type(paralist), this.getParameterList(), null, get_Block(), declid.firstElement().get_access_flags(), paralist, false);
}
// ino.end
} }
// ino.end

View File

@ -0,0 +1,79 @@
// ino.module.Constructor.8557.package
package mycompiler.myclass;
// ino.end
// ino.module.Constructor.8557.import
import java.util.Iterator;
import java.util.Vector;
import typinferenz.ConstraintsSet;
import typinferenz.assumptions.TypeAssumptions;
import mycompiler.mybytecode.ClassFile;
import mycompiler.myexception.JVMCodeException;
// ino.end
import mycompiler.mytype.TypePlaceholder;
import mycompiler.mytypereconstruction.set.CTypeAssumptionSet;
import mycompiler.mytypereconstruction.typeassumption.CInstVarTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CLocalVarTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CMethodTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CParaTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CTypeAssumption;
// ino.class.Constructor.23267.declaration
public class Constructor_Backup extends Method
// ino.end
// ino.class.Constructor.23267.body
{
// ino.method.Constructor.23271.definition
public Constructor_Backup()
// ino.end
// ino.method.Constructor.23271.body
{
this.setParameterList(null);
// #JB# 04.06.2005
// ###########################################################
DeclId decl = new DeclId();
decl.set_Name("<init>");
this.set_DeclId(decl);
// ###########################################################
}
// ino.end
// ino.method.get_codegen_Param_Type.23274.definition
public String get_codegen_Param_Type(Vector paralist)
// ino.end
// ino.method.get_codegen_Param_Type.23274.body
{
String ret = new String();
if(this.getParameterList() == null)
{
ret += "()";
}
else
{
ret += this.getParameterList().get_codegen_ParameterList(paralist);
}
ret += "V";
return ret;
}
// ino.end
// ino.method.codegen.23277.definition
public void codegen(ClassFile classfile, Vector paralist)
throws JVMCodeException
// ino.end
// ino.method.codegen.23277.body
{
classfile.set_constructor_founded(true);
classfile.add_method("<init>", this.get_codegen_Param_Type(paralist), this.getParameterList(), null, get_Block(), declid.firstElement().get_access_flags(), paralist, false);
}
// ino.end
}
// ino.end

View File

@ -37,12 +37,19 @@ import typinferenz.SingleConstraint;
import typinferenz.ConstraintsSet; import typinferenz.ConstraintsSet;
import typinferenz.ResultSet; import typinferenz.ResultSet;
import typinferenz.TypeInsertable; import typinferenz.TypeInsertable;
import typinferenz.assumptions.MethodAssumption;
import typinferenz.assumptions.TypeAssumptions; import typinferenz.assumptions.TypeAssumptions;
// ino.class.Method.23482.declaration // ino.class.Method.23482.declaration
/**
* Stellt eine Methode dar.
* Problem: Parser kann nicht zwischen Methode und Konstruktor unterscheiden. Daher kann diese Klasse beides sein. Dies wird mit dem ParserPostProcessing behoben.
* @author janulrich
*
*/
public class Method extends Field implements ITypeReplacementListener, IItemWithOffset, TypeInsertable public class Method extends Field implements ITypeReplacementListener, IItemWithOffset, TypeInsertable
// ino.end // ino.end
// ino.class.Method.23482.body // ino.class.Method.23482.body
@ -574,6 +581,11 @@ public class Method extends Field implements ITypeReplacementListener, IItemWith
@Override @Override
public TypeAssumptions createTypeAssumptions(Class classmember) { public TypeAssumptions createTypeAssumptions(Class classmember) {
Class parentClass = this.getParentClass();
TypeAssumptions ret = new TypeAssumptions(parentClass.getName());
ret.addMethodAssumption(new MethodAssumption(this, parentClass));
return ret;
/*
TypeAssumptions assumptions = new TypeAssumptions(); TypeAssumptions assumptions = new TypeAssumptions();
this.assumedType = null; this.assumedType = null;
//if((this.get_Method_Name().equals(classmember.getName()) || this.get_Method_Name().equals("<init>")) && ((this.getReturnType().equals(new mycompiler.mytype.Void(0))) || this.getReturnType() instanceof TypePlaceholder)){ //if((this.get_Method_Name().equals(classmember.getName()) || this.get_Method_Name().equals("<init>")) && ((this.getReturnType().equals(new mycompiler.mytype.Void(0))) || this.getReturnType() instanceof TypePlaceholder)){
@ -649,6 +661,7 @@ public class Method extends Field implements ITypeReplacementListener, IItemWith
this.assumedType = methodAssum.getAssumedType(); this.assumedType = methodAssum.getAssumedType();
return assumptions; return assumptions;
*/
} }
@ -656,6 +669,9 @@ public class Method extends Field implements ITypeReplacementListener, IItemWith
public void parserPostProcessing(SyntaxTreeNode parent){ public void parserPostProcessing(SyntaxTreeNode parent){
super.parserPostProcessing(parent); super.parserPostProcessing(parent);
if(this.getType()==null)this.setType(TypePlaceholder.fresh(this)); 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;
} }
@Override @Override

View File

@ -15,7 +15,7 @@ import mycompiler.SourceFile;
import mycompiler.AClassOrInterface; import mycompiler.AClassOrInterface;
import mycompiler.myclass.Class; import mycompiler.myclass.Class;
import mycompiler.myclass.ClassBody; import mycompiler.myclass.ClassBody;
import mycompiler.myclass.Constructor; import mycompiler.myclass.Constructor_Backup;
import mycompiler.myclass.Constant; import mycompiler.myclass.Constant;
import mycompiler.myclass.ImportDeclarations; import mycompiler.myclass.ImportDeclarations;
import mycompiler.myclass.DeclId; import mycompiler.myclass.DeclId;
@ -1335,16 +1335,16 @@ case 73:
case 74: case 74:
// line 837 "./../src/mycompiler/myparser/JavaParser.jay" // line 837 "./../src/mycompiler/myparser/JavaParser.jay"
{ {
((Constructor)yyVals[-1+yyTop]).set_Block(((Block)yyVals[0+yyTop])); ((Constructor_Backup)yyVals[-1+yyTop]).set_Block(((Block)yyVals[0+yyTop]));
yyVal = ((Constructor)yyVals[-1+yyTop]); yyVal = ((Constructor_Backup)yyVals[-1+yyTop]);
} }
break; break;
case 75: case 75:
// line 842 "./../src/mycompiler/myparser/JavaParser.jay" // line 842 "./../src/mycompiler/myparser/JavaParser.jay"
{ {
((Constructor)yyVals[-1+yyTop]).set_Block(((Block)yyVals[0+yyTop])); ((Constructor_Backup)yyVals[-1+yyTop]).set_Block(((Block)yyVals[0+yyTop]));
((Constructor)yyVals[-1+yyTop]).set_Modifiers(((Modifiers)yyVals[-2+yyTop])); ((Constructor_Backup)yyVals[-1+yyTop]).set_Modifiers(((Modifiers)yyVals[-2+yyTop]));
yyVal = ((Constructor)yyVals[-1+yyTop]); yyVal = ((Constructor_Backup)yyVals[-1+yyTop]);
} }
break; break;
case 76: case 76:
@ -1434,7 +1434,7 @@ case 86:
case 87: case 87:
// line 929 "./../src/mycompiler/myparser/JavaParser.jay" // line 929 "./../src/mycompiler/myparser/JavaParser.jay"
{ {
Constructor CON = new Constructor(); Constructor_Backup CON = new Constructor_Backup();
DeclId DIDCon = new DeclId(); DeclId DIDCon = new DeclId();
DIDCon.set_Name(((UsedId)yyVals[-2+yyTop]).get_Name_1Element()); DIDCon.set_Name(((UsedId)yyVals[-2+yyTop]).get_Name_1Element());
CON.set_DeclId(DIDCon); CON.set_DeclId(DIDCon);
@ -1444,7 +1444,7 @@ case 87:
case 88: case 88:
// line 937 "./../src/mycompiler/myparser/JavaParser.jay" // line 937 "./../src/mycompiler/myparser/JavaParser.jay"
{ {
Constructor CONpara = new Constructor(); Constructor_Backup CONpara = new Constructor_Backup();
DeclId DIconpara = new DeclId(); DeclId DIconpara = new DeclId();
DIconpara.set_Name(((UsedId)yyVals[-3+yyTop]).get_Name_1Element()); DIconpara.set_Name(((UsedId)yyVals[-3+yyTop]).get_Name_1Element());
CONpara.set_DeclId(DIconpara); CONpara.set_DeclId(DIconpara);

View File

@ -0,0 +1,5 @@
package typinferenz.assumptions;
public class Assumption {
}

View File

@ -0,0 +1,302 @@
package typinferenz.assumptions;
import java.util.Iterator;
import java.util.Vector;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import typinferenz.FunN;
import typinferenz.TypinferenzException;
import mycompiler.mytype.GenericTypeVar;
import mycompiler.mytype.RefType;
import mycompiler.mytype.Type;
import mycompiler.mytype.TypePlaceholder;
import mycompiler.mytypereconstruction.set.CTypeAssumptionSet;
import mycompiler.mytypereconstruction.typeassumption.CInstVarTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CLocalVarTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CMethodTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CParaTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CTypeAssumption;
/**
* Eine Sammlung von TypeAssumptions.
* Jede Expression und jedes Statement erhält beim Aufrufen ihrer TYPE-Methode ein AssumptionSet mit den Assumptions ihrer Umgebung als Parameter übergeben.
* @author janulrich
*
* Es gibt verschiedene Assumptions:
* 1. Methoden Assumptions
* 2. Konstruktor Assumptions
* 3. Lokale Variablen Assumptions
* 4. Feldvariablen Assumptions
*
*/
public class CopyOfTypeAssumptions implements Iterable<CTypeAssumption> {
//private static CTypeAssumptionSet globalAssumptions = new CTypeAssumptionSet();
private String thisClassName;
//private Vector<CTypeAssumption> assumptions;
CTypeAssumptionSet assumptions = new CTypeAssumptionSet();
private Vector<MethodAssumption> methodAssumptions = new Vector<MethodAssumption>();
public CopyOfTypeAssumptions(){
assumptions = new CTypeAssumptionSet();
}
/**
* Dieser Konstruktor setzt bei der Initialisierung auch den Wert von "this"
* @param klassenname - Wert für "this"
*/
public CopyOfTypeAssumptions(String klassenname){
this();
this.setThisClassname(klassenname);
}
public CopyOfTypeAssumptions(CTypeAssumptionSet ass, String classname){
assumptions = ass;
this.setThisClassname(classname);
}
public CopyOfTypeAssumptions(CopyOfTypeAssumptions assumptions2) {
assumptions = new CTypeAssumptionSet();
this.add(assumptions2);
}
/**
* Im AssumptionSet muss je nach Umfeld der Wert von "this" neu gesetzt werden.
* Dies übernimmt diese Funktion.
* @param name - Der Klassenname der von this referenzierten Klasse.
*/
public void setThisClassname(String name){
this.thisClassName = name;
}
/**
* Erstellt eine CInstVarTypeAssumption und fügt sie den Assumptions hinzu.
* @param className
* @param identifier
* @param assumedType
*/
public void addInstVarAssumption(String className, String identifier, Type assumedType){
this.add(createFieldVarAssumption(className, identifier, assumedType));
}
/**
* Ruft createMethodAssumption auf und fügt die Assumption dem AssumptionSet hinzu
* @param classType
* @param identifier
* @param assumedType
* @param parameterTypes
*/
@Deprecated
public void addMethodAssumption_Backup(Type classType, String identifier, Type assumedType, Vector<CParaTypeAssumption> parameterTypes){
CMethodTypeAssumption ass = createMethodAssumption(classType, identifier, assumedType, parameterTypes);
this.add(ass);
}
public void addMethodAssumption(MethodAssumption mAss){
this.methodAssumptions.add(mAss);
}
/**
*
* @param className
* @param identifier
* @param assumedType - ReturnTyp der Methode
* @param parameterTypes - Liste der Parameter der Methode. TIPP: Zur Erstellung der CParaTypeAssumption-Liste kann die Methode TypeAssumptions.createCParaTypeAssumption verwendert werden.
*/
public static CMethodTypeAssumption createMethodAssumption_backup(Type classType, String identifier, Type assumedType, Vector<CParaTypeAssumption> parameterTypes){
CMethodTypeAssumption ass = new CMethodTypeAssumption(classType, identifier, assumedType, parameterTypes.size(), 0, 0, null, null);
for(CParaTypeAssumption paraAssumption : parameterTypes){
//Es wird eine neue ParameterAssumption generiert. Nur der Identifier und der AssumedType der CParaTypeAssumption wird dabei übernommen.
CParaTypeAssumption newParaAssumption = new CParaTypeAssumption(classType.get_Name(), identifier, parameterTypes.size(),0, paraAssumption.getIdentifier(), paraAssumption.getAssumedType(), 0,0,null);
ass.addParaAssumption(newParaAssumption);
}
return ass;
}
public static CInstVarTypeAssumption createFieldVarAssumption_backup(String className, String fieldName, Type type){
if(className==null || fieldName == null || type == null) throw new TypinferenzException("Ungültige Feld-Assumption");
CInstVarTypeAssumption ret = new CInstVarTypeAssumption(className, fieldName, type, 0,0,null);
return ret;
}
/**
* Erstellt eine CParaTypeAssumption.
* Diese enthält nur den Identifier und den Typ des Parameters. Die Zuordnung zu einer Methode und einer Klasse erhält die Assumption erst durch den Einsatz in der TypeAssumptions.addMethodAssumption.
* @param identifier
* @param assumedType
* @return
*/
public static CParaTypeAssumption createCParaTypeAssumption_backup( String identifier, Type assumedType){
CParaTypeAssumption ret;
ret = new CParaTypeAssumption( null, null, 0, 0, identifier, assumedType, 0,0, null);
return ret;
}
public void addLocalVarAssumption(){
throw new NotImplementedException();
}
/**
* Durchsucht die Assumptions des aktuellen Gültigkeitsbereichs (lokale Variablen und Felder der aktuellen Klasse) nach einem Eintrag für den übergebenen Variablennamen.
* In den Assumptions wird dann in der Reihenfolge LocalVarAssumptions, FieldAssumption nach dem übergebenen Variablennamen gesucht.
* @param variableName - der Identifier der gesuchten Variablen
* @return - Der Typ für diesen Identifier.
*/
public Type getVarType(String variableName){
//Zuerst die Parameter durchsuchen
for(CTypeAssumption ass : this.assumptions){//this.getParameterAssumptions(null)){
if(ass.getIdentifier().equals(variableName))return ass.getAssumedType();
}
//TODO: Dann die lokalen Variablen
// ... (noch nicht implementiert)
//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();
}
//Wird keine Assumption gefunden, muss ein Fehler vorliegen:
throw new TypinferenzException("Eine Variable "+variableName+" ist in den Assumptions nicht vorhanden");
}
/**
* Ermittelt alle Assumptions zu Instanzvariablen, welche sich in der Klasse "this" befinden, also der Klasse für welche dieses AssumptionSet gültig ist.
* @return
*/
public CopyOfTypeAssumptions getInstVarAssumptions(){
String className = this.getThisValue().getName();
CopyOfTypeAssumptions ret = new CopyOfTypeAssumptions();
for(CTypeAssumption ass : this.assumptions){
if(ass instanceof CInstVarTypeAssumption && ass.getClassName().equals(className))ret.add(ass);
}
return ret;
}
/**
* @return - Alle Assumptions dieses AssumptionSets, welche Annahmen für Parameter darstellen
*/
private CopyOfTypeAssumptions getParameterAssumptions(CMethodTypeAssumption method) {
CopyOfTypeAssumptions ret = new CopyOfTypeAssumptions();
if(method==null)return ret;
for(CParaTypeAssumption ass : method.getParaAssumptions()){
//if(ass instanceof CParaTypeAssumption)ret.add(ass);
ret.add(ass);
}
return ret;
}
/**
* Sucht nach MethodAssumptions einer bestimmten Klasse mit einem bestimmten Namen.
* @param className
* @param methodName
* @param parameterCount
* @return
*/
public Vector<CMethodTypeAssumption> getMethodAssumptions(String className, String methodName){
Vector<CMethodTypeAssumption> ret = new Vector<CMethodTypeAssumption>();
for(CTypeAssumption ass : this.getAssumptionsFor(className)){
//System.out.println(ass.getIdentifier());
if(ass.getIdentifier().equals(methodName) && ass instanceof CMethodTypeAssumption)ret.add((CMethodTypeAssumption)ass);
}
//if(ret.size()==0)throw new TypinferenzException("Eine Methode "+methodName+" ist in den Assumptions nicht vorhanden");
return ret;
}
/**
* Sucht nach Assumptions zu einer Methode mit dem Namen methodName und parameterCount Parametern.
* @param methodName
* @param parameterCount Anzahl der Parameter der gesuchten Methoden-Assumption
* @return
*/
public Vector<CMethodTypeAssumption> getMethodAssumptions(String methodName, int parameterCount){
Vector<CMethodTypeAssumption> ret = new Vector<CMethodTypeAssumption>();
for(CTypeAssumption ass : assumptions){
//System.out.println(ass.getIdentifier());
if(ass.getIdentifier().equals(methodName) && ass instanceof CMethodTypeAssumption){
CMethodTypeAssumption toAdd = (CMethodTypeAssumption)ass;
if(toAdd.getParaCount() == parameterCount)ret.add(toAdd);
}
}
//Falls es sich um die apply-Methode eines FunN-Interface handelt:
if(methodName.equals("apply")){ //Ein Workaround für den Typinferenzalgorithmus TODO: Das hier rausnehmen.
CMethodTypeAssumption funNAssumption = new FunN(parameterCount).toCMethodTypeAssumption();
ret.add(funNAssumption);
}
if(ret.size()==0)throw new TypinferenzException("Eine Methode "+methodName+" ist in den Assumptions nicht vorhanden");
return ret;
}
/**
* Fügt dem Assumption-Set eine neue Assumption hinzu.
* @param ass
* @return
*/
public CopyOfTypeAssumptions add(CTypeAssumption ass){
if(ass.getAssumedType()==null)throw new NullPointerException();//ass.setAssumedType(TypePlaceholder.fresh());
//if(ass instanceof CParaTypeAssumption)throw new TypinferenzException("ParameterAssumptions müssen einer Methode zugewiesen sein");
//globalAssumptions.addElement(ass);
assumptions.addElement(ass);
return this;
}
public void remove(CTypeAssumption typeAssumption){
throw new NotImplementedException();
}
public CopyOfTypeAssumptions add(CopyOfTypeAssumptions assumptions){
for(CTypeAssumption ass : assumptions){
this.add(ass);
}
return this;
}
public CopyOfTypeAssumptions add(CTypeAssumptionSet assumptionSet){
assumptions.unite(assumptionSet);
return this;
}
public Iterator<CTypeAssumption> iterator() {
return assumptions.iterator();
}
@Override
public CopyOfTypeAssumptions clone(){
CTypeAssumptionSet assSet = new CTypeAssumptionSet();
for(CTypeAssumption ass : assumptions){
assSet.addElement(ass);
}
return new CopyOfTypeAssumptions(assSet, thisClassName);
}
/**
* Jede erstellte Assumption wird von der TypeAssumptions-Klasse gespeichert.
* Diese Funktion ermittelt alle zu einer Klasse gehörenden Assumptions.
* @param classname
* @return Alle Assumptions mit - assumption.getClassname().equals(classname) - der this-Wert ist auf "classname" gesetzt.
*/
public CopyOfTypeAssumptions getAssumptionsFor(String classname){
CTypeAssumptionSet assumptions = new CTypeAssumptionSet();
//for(CTypeAssumption ass : globalAssumptions){
for(CTypeAssumption ass : this.assumptions){
if(ass.getClassName().equals(classname))assumptions.addElement(ass);
}
return new CopyOfTypeAssumptions(assumptions, classname);
}
@Override
public String toString(){
return assumptions.toString();
}
public Type getThisValue() {
return new RefType(thisClassName, 0);
}
}

View File

@ -0,0 +1,12 @@
package typinferenz.assumptions;
import mycompiler.myclass.Field;
import mycompiler.myclass.Class;
public class FieldVarAssumption extends Assumption {
public FieldVarAssumption(Field fieldVar, Class inClass){
}
}

View File

@ -0,0 +1,5 @@
package typinferenz.assumptions;
public class LocalVarAssumption extends Assumption {
}

View File

@ -0,0 +1,12 @@
package typinferenz.assumptions;
import mycompiler.myclass.Method;
import mycompiler.myclass.Class;
public class MethodAssumption extends Assumption {
public MethodAssumption(Method assumedMethod, Class parentClass){
}
}

View File

@ -0,0 +1,5 @@
package typinferenz.assumptions;
public class ParameterAssumption extends Assumption {
}

View File

@ -21,265 +21,117 @@ import mycompiler.mytypereconstruction.typeassumption.CTypeAssumption;
* Eine Sammlung von TypeAssumptions. * Eine Sammlung von TypeAssumptions.
* Jede Expression und jedes Statement erhält beim Aufrufen ihrer TYPE-Methode ein AssumptionSet mit den Assumptions ihrer Umgebung als Parameter übergeben. * Jede Expression und jedes Statement erhält beim Aufrufen ihrer TYPE-Methode ein AssumptionSet mit den Assumptions ihrer Umgebung als Parameter übergeben.
* @author janulrich * @author janulrich
*
* Es gibt verschiedene Assumptions:
* 1. Methoden Assumptions
* 2. Konstruktor Assumptions
* 3. Lokale Variablen Assumptions
* 4. Feldvariablen Assumptions
* *
*/ */
public class TypeAssumptions implements Iterable<CTypeAssumption> { public class TypeAssumptions {
/*
* Folgende Vorgehensweise:
* -Lokale Variablen werden in einem extra AssumptionSet gespeichert. Das Assumption Set hat nicht die Aufgabe Closures zu verwalten.
* -... genauso verhält es sich für Parameter. Parameter verhalten sich beim Abrufen wie lokale Variablen, werden aber zuerst durchsucht.
*
*/
//private static CTypeAssumptionSet globalAssumptions = new CTypeAssumptionSet(); //private static CTypeAssumptionSet globalAssumptions = new CTypeAssumptionSet();
private String thisClassName; private String thisClassName;
//private Vector<CTypeAssumption> assumptions;
CTypeAssumptionSet assumptions = new CTypeAssumptionSet();
public TypeAssumptions(){ private Vector<MethodAssumption> methodAssumptions = new Vector<MethodAssumption>();
assumptions = new CTypeAssumptionSet(); private Vector<FieldVarAssumption> fieldAssumptions = new Vector<FieldVarAssumption>();
} private Vector<LocalVarAssumption> localVarAssumptions = new Vector<LocalVarAssumption>();
private Vector<ParameterAssumption> parameterAssumptions = new Vector<ParameterAssumption>();
/** /**
* Dieser Konstruktor setzt bei der Initialisierung auch den Wert von "this" * Dieser Konstruktor setzt bei der Initialisierung auch den Wert von "this"
* @param klassenname - Wert für "this" * @param klassenname - Wert für "this"
*/ */
public TypeAssumptions(String klassenname){ public TypeAssumptions(String klassenname){
this(); this.thisClassName = klassenname;
this.setThisClassname(klassenname);
} }
public TypeAssumptions(CTypeAssumptionSet ass, String classname){
assumptions = ass;
this.setThisClassname(classname);
}
public TypeAssumptions(TypeAssumptions assumptions2) { public void addMethodAssumption(MethodAssumption mAss){
assumptions = new CTypeAssumptionSet(); this.methodAssumptions.add(mAss);
this.add(assumptions2);
}
/**
* Im AssumptionSet muss je nach Umfeld der Wert von "this" neu gesetzt werden.
* Dies übernimmt diese Funktion.
* @param name - Der Klassenname der von this referenzierten Klasse.
*/
public void setThisClassname(String name){
this.thisClassName = name;
} }
/** /**
* Erstellt eine CInstVarTypeAssumption und fügt sie den Assumptions hinzu. * Liefert alle bekannten öffentlichen Feldern mit dem Namen withName. Dabei werden alle bekannten Klassen durchsucht.
* @param className * @param withName
* @param identifier
* @param assumedType
*/
public void addInstVarAssumption(String className, String identifier, Type assumedType){
this.add(createFieldVarAssumption(className, identifier, assumedType));
}
/**
* Ruft createMethodAssumption auf und fügt die Assumption dem AssumptionSet hinzu
* @param classType
* @param identifier
* @param assumedType
* @param parameterTypes
*/
public void addMethodAssumption(Type classType, String identifier, Type assumedType, Vector<CParaTypeAssumption> parameterTypes){
CMethodTypeAssumption ass = createMethodAssumption(classType, identifier, assumedType, parameterTypes);
this.add(ass);
}
/**
*
* @param className
* @param identifier
* @param assumedType - ReturnTyp der Methode
* @param parameterTypes - Liste der Parameter der Methode. TIPP: Zur Erstellung der CParaTypeAssumption-Liste kann die Methode TypeAssumptions.createCParaTypeAssumption verwendert werden.
*/
public static CMethodTypeAssumption createMethodAssumption(Type classType, String identifier, Type assumedType, Vector<CParaTypeAssumption> parameterTypes){
CMethodTypeAssumption ass = new CMethodTypeAssumption(classType, identifier, assumedType, parameterTypes.size(), 0, 0, null, null);
for(CParaTypeAssumption paraAssumption : parameterTypes){
//Es wird eine neue ParameterAssumption generiert. Nur der Identifier und der AssumedType der CParaTypeAssumption wird dabei übernommen.
CParaTypeAssumption newParaAssumption = new CParaTypeAssumption(classType.get_Name(), identifier, parameterTypes.size(),0, paraAssumption.getIdentifier(), paraAssumption.getAssumedType(), 0,0,null);
ass.addParaAssumption(newParaAssumption);
}
return ass;
}
public static CInstVarTypeAssumption createFieldVarAssumption(String className, String fieldName, Type type){
if(className==null || fieldName == null || type == null) throw new TypinferenzException("Ungültige Feld-Assumption");
CInstVarTypeAssumption ret = new CInstVarTypeAssumption(className, fieldName, type, 0,0,null);
return ret;
}
/**
* Erstellt eine CParaTypeAssumption.
* Diese enthält nur den Identifier und den Typ des Parameters. Die Zuordnung zu einer Methode und einer Klasse erhält die Assumption erst durch den Einsatz in der TypeAssumptions.addMethodAssumption.
* @param identifier
* @param assumedType
* @return * @return
*/ */
public static CParaTypeAssumption createCParaTypeAssumption( String identifier, Type assumedType){ public Vector<FieldVarAssumption> getFieldVars(String withName){
CParaTypeAssumption ret; //TODO: Implementieren
ret = new CParaTypeAssumption( null, null, 0, 0, identifier, assumedType, 0,0, null); return null;
return ret;
} }
public void addLocalVarAssumption(){ public Type getTypeOfFieldVar(String withName, Class inClass){
throw new NotImplementedException(); return null;
}
/**
* Durchsucht die Assumptions des aktuellen Gültigkeitsbereichs (lokale Variablen und Felder der aktuellen Klasse) nach einem Eintrag für den übergebenen Variablennamen.
* In den Assumptions wird dann in der Reihenfolge LocalVarAssumptions, FieldAssumption nach dem übergebenen Variablennamen gesucht.
* @param variableName - der Identifier der gesuchten Variablen
* @return - Der Typ für diesen Identifier.
*/
public Type getVarType(String variableName){
//Zuerst die Parameter durchsuchen
for(CTypeAssumption ass : this.assumptions){//this.getParameterAssumptions(null)){
if(ass.getIdentifier().equals(variableName))return ass.getAssumedType();
}
//TODO: Dann die lokalen Variablen
// ... (noch nicht implementiert)
//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();
}
//Wird keine Assumption gefunden, muss ein Fehler vorliegen:
throw new TypinferenzException("Eine Variable "+variableName+" ist in den Assumptions nicht vorhanden");
} }
/** /**
* Ermittelt alle Assumptions zu Instanzvariablen, welche sich in der Klasse "this" befinden, also der Klasse für welche dieses AssumptionSet gültig ist. * Ermittelt alle bekannten Methoden mit dem Namen withName
* @param withName
* @return * @return
*/ */
public TypeAssumptions getInstVarAssumptions(){ public Vector<MethodAssumption> getMethods(String withName){
String className = this.getThisValue().getName(); return null;
TypeAssumptions ret = new TypeAssumptions();
for(CTypeAssumption ass : this.assumptions){
if(ass instanceof CInstVarTypeAssumption && ass.getClassName().equals(className))ret.add(ass);
}
return ret;
} }
/** /**
* @return - Alle Assumptions dieses AssumptionSets, welche Annahmen für Parameter darstellen * Liefert den Typ einer lokalen Variable. Zuerst werden die Parameter dieses AssumptionSets durchsucht, dann die lokalen Variablen. Anschließend die Felder der, "this" repräsentierenden Klasse
*/ * @param withName
private TypeAssumptions getParameterAssumptions(CMethodTypeAssumption method) {
TypeAssumptions ret = new TypeAssumptions();
if(method==null)return ret;
for(CParaTypeAssumption ass : method.getParaAssumptions()){
//if(ass instanceof CParaTypeAssumption)ret.add(ass);
ret.add(ass);
}
return ret;
}
/**
* Sucht nach MethodAssumptions einer bestimmten Klasse mit einem bestimmten Namen.
* @param className
* @param methodName
* @param parameterCount
* @return * @return
*/ */
public Vector<CMethodTypeAssumption> getMethodAssumptions(String className, String methodName){ public Type getTypeOfLocalVar(String withName){
Vector<CMethodTypeAssumption> ret = new Vector<CMethodTypeAssumption>(); return null;
for(CTypeAssumption ass : this.getAssumptionsFor(className)){
//System.out.println(ass.getIdentifier());
if(ass.getIdentifier().equals(methodName) && ass instanceof CMethodTypeAssumption)ret.add((CMethodTypeAssumption)ass);
}
//if(ret.size()==0)throw new TypinferenzException("Eine Methode "+methodName+" ist in den Assumptions nicht vorhanden");
return ret;
}
/**
* Sucht nach Assumptions zu einer Methode mit dem Namen methodName und parameterCount Parametern.
* @param methodName
* @param parameterCount Anzahl der Parameter der gesuchten Methoden-Assumption
* @return
*/
public Vector<CMethodTypeAssumption> getMethodAssumptions(String methodName, int parameterCount){
Vector<CMethodTypeAssumption> ret = new Vector<CMethodTypeAssumption>();
for(CTypeAssumption ass : assumptions){
//System.out.println(ass.getIdentifier());
if(ass.getIdentifier().equals(methodName) && ass instanceof CMethodTypeAssumption){
CMethodTypeAssumption toAdd = (CMethodTypeAssumption)ass;
if(toAdd.getParaCount() == parameterCount)ret.add(toAdd);
}
}
//Falls es sich um die apply-Methode eines FunN-Interface handelt:
if(methodName.equals("apply")){ //Ein Workaround für den Typinferenzalgorithmus TODO: Das hier rausnehmen.
CMethodTypeAssumption funNAssumption = new FunN(parameterCount).toCMethodTypeAssumption();
ret.add(funNAssumption);
}
if(ret.size()==0)throw new TypinferenzException("Eine Methode "+methodName+" ist in den Assumptions nicht vorhanden");
return ret;
} }
/**
* Fügt dem Assumption-Set eine neue Assumption hinzu.
* @param ass
* @return
*/
public TypeAssumptions add(CTypeAssumption ass){
if(ass.getAssumedType()==null)throw new NullPointerException();//ass.setAssumedType(TypePlaceholder.fresh());
//if(ass instanceof CParaTypeAssumption)throw new TypinferenzException("ParameterAssumptions müssen einer Methode zugewiesen sein");
//globalAssumptions.addElement(ass);
assumptions.addElement(ass);
return this;
}
public void remove(CTypeAssumption typeAssumption){
throw new NotImplementedException();
}
public TypeAssumptions add(TypeAssumptions assumptions){ public TypeAssumptions add(TypeAssumptions assumptions){
for(CTypeAssumption ass : assumptions){ this.methodAssumptions.addAll(assumptions.methodAssumptions);
this.add(ass); this.fieldAssumptions.addAll(assumptions.fieldAssumptions);
} this.localVarAssumptions.addAll(assumptions.localVarAssumptions);
this.parameterAssumptions.addAll(assumptions.parameterAssumptions);
return this; return this;
} }
public TypeAssumptions add(CTypeAssumptionSet assumptionSet){
assumptions.unite(assumptionSet);
return this;
}
public Iterator<CTypeAssumption> iterator() {
return assumptions.iterator();
}
@Override @Override
public TypeAssumptions clone(){ public TypeAssumptions clone(){
CTypeAssumptionSet assSet = new CTypeAssumptionSet(); TypeAssumptions ret = new TypeAssumptions(thisClassName);
for(CTypeAssumption ass : assumptions){ ret.add(this);
assSet.addElement(ass); return ret;
}
return new TypeAssumptions(assSet, thisClassName);
} }
/**
* Jede erstellte Assumption wird von der TypeAssumptions-Klasse gespeichert.
* Diese Funktion ermittelt alle zu einer Klasse gehörenden Assumptions.
* @param classname
* @return Alle Assumptions mit - assumption.getClassname().equals(classname) - der this-Wert ist auf "classname" gesetzt.
*/
public TypeAssumptions getAssumptionsFor(String classname){
CTypeAssumptionSet assumptions = new CTypeAssumptionSet();
//for(CTypeAssumption ass : globalAssumptions){
for(CTypeAssumption ass : this.assumptions){
if(ass.getClassName().equals(classname))assumptions.addElement(ass);
}
return new TypeAssumptions(assumptions, classname);
}
@Override @Override
public String toString(){ public String toString(){
return assumptions.toString(); String ret = "this: "+this.thisClassName;
ret += "Method Assumptions:\n" + this.methodAssumptions.toString() + "\n";
ret += "FieldVar Assumptions:\n" + this.fieldAssumptions.toString() + "\n";
ret += "LocalVar Assumptions:\n" + this.localVarAssumptions.toString() + "\n";
ret += "Parameter Assumptions:\n" + this.parameterAssumptions.toString() + "\n";
//return assumptions.toString();
return ret;
} }
public Type getThisValue() { public Type getThisValue() {

View File

@ -1,8 +0,0 @@
Class DEBUG [Typeinference] Erstellte Assumptions: Set {
varString: TPH A,
methode: NOPARAS --> void,
var: TPH B,
<init>: NOPARAS --> BasicAssumptionsTest
}
Block DEBUG [Typeinference] Prozessing statement: (var = int 1)
Block DEBUG [Typeinference] Prozessing statement: (varString = null (varString.toString( [ ])))