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

276 lines
9.6 KiB
Java
Raw Normal View History

2014-09-02 08:33:54 +00:00
package de.dhbwstuttgart.syntaxtree;
2015-10-23 14:22:44 +00:00
2016-07-21 14:36:33 +00:00
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
2014-10-09 10:01:16 +00:00
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.logger.SectionLogger;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWConstantPoolGen;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.core.IItemWithOffset;
import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.modifier.Modifiers;
2015-10-23 14:22:44 +00:00
import de.dhbwstuttgart.syntaxtree.modifier.Static;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.Expr;
import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.*;
import de.dhbwstuttgart.typeinference.assumptions.ClassAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
2013-10-18 11:33:46 +00:00
2016-12-07 13:32:48 +00:00
import java.util.ArrayList;
import java.util.List;
/**
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
*/
public class Class extends GTVDeclarationContext implements IItemWithOffset, Generic, GenericTypeInsertable
2013-10-18 11:33:46 +00:00
{
2014-02-12 01:12:12 +00:00
/**
2016-12-07 13:32:48 +00:00
* Loggerinstanzen
2014-02-12 01:12:12 +00:00
*/
protected static Logger inferencelog = Logger.getLogger("inference");
2015-06-16 09:55:15 +00:00
protected static Logger codegenlog = Logger.getLogger("codegen");
protected static Logger parserlog = Logger.getLogger("parser");
protected Logger typinferenzLog = Logger.getLogger(Class.class.getName());
2016-12-02 00:23:01 +00:00
2014-02-12 01:12:12 +00:00
protected Modifiers modifiers;
protected JavaClassName name;
2013-10-18 11:33:46 +00:00
private Block class_block;
2016-12-07 13:32:48 +00:00
private List<Field> fielddecl = new ArrayList<>();
private GenericDeclarationList genericClassParameters;
private int offset;
2016-03-22 12:17:56 +00:00
private RefType superClass;
2016-12-07 13:32:48 +00:00
protected boolean isInterface;
private List<RefType> implementedInterfaces;
2013-10-18 11:33:46 +00:00
/////////////////////////////////////////////////////////////////////////
// TypeReconstructionAlgorithmus
/////////////////////////////////////////////////////////////////////////
/**
* Ausgangspunkt ¯Â¿Â½r den Typrekonstruktionsalgorithmus. Hier werden zun�chst
2013-10-18 11:33:46 +00:00
* die Mengen von Typannahmen V_fields_methods und V_i erstellt, die als Eingabe
* ¯Â¿Â½r den Algorithmus dienen.<br/>
* (siehe Algorithmus 5.17 TRProg, Martin Pl�micke)
* <br/>Author: ¯Â¿Â½rg ¯Â¿Â½uerle
2013-10-18 11:33:46 +00:00
* @param supportData
* @param globalAssumptions
* @return Liste aller bisher berechneten, ¯Â¿Â½glichen Typkombinationen
2013-10-18 11:33:46 +00:00
* @throws CTypeReconstructionException
*/
2016-03-24 10:57:17 +00:00
public ConstraintsSet typeReconstruction(TypeAssumptions globalAssumptions)
2013-10-18 11:33:46 +00:00
{
//////////////////////////////
// Und los geht's:
//////////////////////////////
2014-11-04 12:47:05 +00:00
inferencelog.info("Rufe TRStart()...", Section.TYPEINFERENCE);
2014-09-02 16:49:19 +00:00
2016-03-24 10:57:17 +00:00
//////////////////////////////
2013-10-18 11:33:46 +00:00
// Ab hier ...
// @author A10023 - Andreas Stadelmeier:
//////////////////////////////
//Erzeuge Assumptions:
TypeAssumptions assumptions = this.getPrivateFieldAssumptions();
//Globale Assumptions anfügen:
2013-10-18 11:33:46 +00:00
assumptions.add(globalAssumptions);
ConstraintsSet oderConstraints = new ConstraintsSet();
2015-06-17 10:03:54 +00:00
for(Type gparam : this.get_ParaList()){
if(gparam instanceof GenericTypeVar)assumptions.add(((GenericTypeVar)gparam).createAssumptions()); //Constraints für die Generischen Variablen erstellen und diese dem AssumptionsSet hinzufügen
}
for(Type gparam : this.get_ParaList()){
if(gparam instanceof GenericTypeVar)oderConstraints.add(((GenericTypeVar)gparam).TYPE(assumptions)); //Constraints für die Generischen Variablen erstellen und diese dem AssumptionsSet hinzufügen
2014-06-18 09:30:14 +00:00
}
typinferenzLog.debug("Erstellte Assumptions: "+assumptions, Section.TYPEINFERENCE);
2016-03-22 12:17:56 +00:00
//Gibt es hier eine ClassCastException stimmt etwas grundsätzlich nicht!
//this.superClass = (RefType)this.superClass.TYPE(assumptions, this);
2015-06-17 10:03:54 +00:00
for(Field f:this.getFields()){
oderConstraints.add(f.TYPE(assumptions));
}
typinferenzLog.debug("Erstellte Constraints: "+oderConstraints, Section.TYPEINFERENCE);
2013-10-18 11:33:46 +00:00
2014-02-11 01:47:39 +00:00
return oderConstraints;
2013-10-18 11:33:46 +00:00
}
2014-02-19 04:20:54 +00:00
2013-10-18 11:33:46 +00:00
/**
* Ermittelt alle privaten Felder und Methoden der Klasse und Erstellt eine Assumption ¼r diese.
* Bemerkung: Momentan werden noch alle Felder dieser Klasse zurückgegeben.
2013-10-18 11:33:46 +00:00
* @return Die erstellten TypeAssumptions
*/
private TypeAssumptions getPrivateFieldAssumptions() {
if(this.typeAssumptions != null)return this.typeAssumptions; //Das sorgt dafür, dass die Assumptions nur einmalig generiert werden.
2013-10-18 11:33:46 +00:00
TypeAssumptions assumptions = new TypeAssumptions(this.getName());
for(Field field : this.getFields()){
if(!field.isPublic())assumptions.add(field.createTypeAssumptions(this));
2013-10-18 11:33:46 +00:00
}
this.typeAssumptions = assumptions; //Diese müssen anschließend nicht wieder generiert werden.
2013-10-18 11:33:46 +00:00
return assumptions;
2016-12-02 00:23:01 +00:00
}
2013-10-18 11:33:46 +00:00
/**
* <br/>Author: Martin Pl�micke
2013-10-18 11:33:46 +00:00
* @return
*/
public String toString()
{
2016-11-11 10:01:55 +00:00
return name.toString();
2013-10-18 11:33:46 +00:00
}
public String getTypeInformation(Menge<Method> methodList, Menge<Expr> fieldList){
2013-10-18 11:33:46 +00:00
String ret = this.name+": ";
for(Expr field : fieldList){
ret+=field.getTypeInformation()+"\n";
}
for(Method m : methodList){
ret+=m.getTypeInformation()+"\n";
}
return ret;
}
/**
* Generiert den JavaCode dieser Klasse im Falle ¼r das übergebene resultSet.
2013-10-18 11:33:46 +00:00
* Dem ResultSet entsprechend werden in diesem Java-Code die TypePlaceholder durch die in ResultSet stehenden Typen ersetzt.
* @return Java-Sourcefile
*/
2016-09-30 10:46:02 +00:00
public JavaCodeResult printJavaCode(ResultSet reconstructionResult){
2013-10-18 11:33:46 +00:00
JavaCodeResult ret = new JavaCodeResult("class ");
JavaCodeResult classBodyCode = new JavaCodeResult();
2016-09-30 10:46:02 +00:00
if(this.modifiers!=null)classBodyCode.attach(this.modifiers.printJavaCode(reconstructionResult)).attach(" ");
2013-10-18 11:33:46 +00:00
2016-09-30 10:46:02 +00:00
classBodyCode.attach(this.name + " extends ").attach(this.superClass.printJavaCode(reconstructionResult)).attach("\n");
JavaCodeResult bodyString = new JavaCodeResult("{\n");
2016-09-30 10:46:02 +00:00
for(Field field : this.fielddecl)bodyString.attach( field.printJavaCode(reconstructionResult) ).attach( "\n" );
bodyString.attach("}\n");
2013-10-18 11:33:46 +00:00
classBodyCode.attach(bodyString);
//Zuerst die generischen Parameter für diese Klasse berechnen:
2014-07-09 08:52:23 +00:00
//this.createGenericTypeVars(classBodyCode.getUnresolvedTPH());
2013-10-18 11:33:46 +00:00
if(this.genericClassParameters != null && this.genericClassParameters.size()>0){
ret.attach("<");
Iterator<GenericTypeVar> it = this.genericClassParameters.iterator();
while(it.hasNext()){
GenericTypeVar tph = it.next();
2016-09-30 10:46:02 +00:00
ret.attach(tph.printJavaCode(reconstructionResult));
2013-10-18 11:33:46 +00:00
if(it.hasNext())ret.attach(", ");
}
ret.attach(">");
}
String stringReturn = ret.attach(classBodyCode).toString();
2016-09-30 10:46:02 +00:00
return new JavaCodeResult(stringReturn);
2013-10-18 11:33:46 +00:00
}
2016-12-07 13:32:48 +00:00
public int getOffset(){
return this.offset;
}
2013-10-18 11:33:46 +00:00
/**
* Erstellt einen RefType, welcher auf diese Klasse verweist
2014-04-09 12:12:55 +00:00
* Ersetzt alle Generischen Variablen in der Parameterliste mit TPH
2013-10-18 11:33:46 +00:00
* @return
*/
public RefType getType() {
return new RefType(this.getName().toString(), this.get_ParaList(),this, 0);
2013-10-18 11:33:46 +00:00
}
/**
* Ermittelt die Sichtbaren Felder und Methoden der Klasse.
* (Momentan sind im Projekt alle Felder und Methoden "package private", da der Parser keine Access-Modifier einlesen kann.
* @return
*/
public TypeAssumptions getPublicFieldAssumptions() {
TypeAssumptions ret = new TypeAssumptions();//this.getPrivateFieldAssumptions();
2014-04-09 12:12:55 +00:00
ret.addClassAssumption(new ClassAssumption(this));
for(Field f : this.getFields()){
if(f.isPublic())ret.add(f.createTypeAssumptions(this));
}
for(GenericTypeVar gtv : this.getGenericParameter()){
ret.add(gtv.createAssumptions());
}
2013-10-18 11:33:46 +00:00
return ret;
}
2014-02-19 04:20:54 +00:00
@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;
}
2014-07-16 08:33:34 +00:00
@Override
2016-09-16 11:25:20 +00:00
public GenericDeclarationList getGenericParameter() {
return this.genericClassParameters;
2014-07-16 08:33:34 +00:00
}
@Override
public String getDescription(){
return "class "+this.getName();
}
@Override
public void setGenericParameter(GenericDeclarationList params) {
this.genericClassParameters = params;
}
@Override
public String getGenericVarDeclarationString(String genericVarDeclaration) {
if(this.genericClassParameters != null){
return ", "+genericVarDeclaration;
}else{
return "<"+genericVarDeclaration+">";
}
}
@Override
public int getGenericVarDeclarationOffset(){
// Falls Generische Parameterliste vorhanden, hier Wert der Liste zurückgegebn
if(this.genericClassParameters != null){
return this.genericClassParameters.getEndOffset();
}else{
return this.offset;
}
}
2014-07-16 08:33:34 +00:00
/**
* Die Super Klasse dieser Klasse.
* @return null ¼r Klasse Object
*/
2016-03-22 12:17:56 +00:00
public RefType getSuperClass(){
return this.superClass;
}
@Override
public boolean isClass() {
return true;
}
2016-12-07 13:32:48 +00:00
2015-08-27 14:36:19 +00:00
public boolean isInterface(){
2016-10-28 16:31:42 +00:00
return isInterface;
2015-08-27 14:36:19 +00:00
}
2013-10-18 11:33:46 +00:00
}