forked from JavaTX/JavaCompilerCore
1830 lines
86 KiB
Java
Executable File
1830 lines
86 KiB
Java
Executable File
// ino.module.SourceFile.8722.package
|
||
package de.dhbwstuttgart.syntaxtree;
|
||
// ino.end
|
||
|
||
// ino.module.SourceFile.8722.import
|
||
import java.util.Collection;
|
||
import java.util.Enumeration;
|
||
import java.util.HashMap;
|
||
import java.util.Hashtable;
|
||
import java.util.Iterator;
|
||
import de.dhbwstuttgart.typeinference.Menge;
|
||
import java.util.stream.Stream;
|
||
|
||
import de.dhbwstuttgart.logger.Logger;
|
||
import de.dhbwstuttgart.logger.Section;
|
||
import de.dhbwstuttgart.core.AClassOrInterface;
|
||
import de.dhbwstuttgart.core.MyCompiler;
|
||
import de.dhbwstuttgart.myexception.CTypeReconstructionException;
|
||
import de.dhbwstuttgart.myexception.JVMCodeException;
|
||
import de.dhbwstuttgart.myexception.SCClassException;
|
||
import de.dhbwstuttgart.myexception.SCException;
|
||
import de.dhbwstuttgart.parser.JavaClassName;
|
||
import de.dhbwstuttgart.syntaxtree.misc.DeclId;
|
||
import de.dhbwstuttgart.syntaxtree.misc.UsedId;
|
||
import de.dhbwstuttgart.syntaxtree.modifier.Modifiers;
|
||
import de.dhbwstuttgart.syntaxtree.modifier.Public;
|
||
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
|
||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||
import de.dhbwstuttgart.syntaxtree.type.Type;
|
||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||
import de.dhbwstuttgart.typeinference.ConstraintsSet;
|
||
import de.dhbwstuttgart.typeinference.FunN;
|
||
import de.dhbwstuttgart.typeinference.FunNInterface;
|
||
import de.dhbwstuttgart.typeinference.FunNMethod;
|
||
import de.dhbwstuttgart.typeinference.Pair;
|
||
import de.dhbwstuttgart.typeinference.ResultSet;
|
||
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
|
||
import de.dhbwstuttgart.typeinference.UndConstraint;
|
||
import de.dhbwstuttgart.typeinference.assumptions.ClassAssumption;
|
||
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
|
||
import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption;
|
||
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
|
||
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
|
||
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
|
||
import de.dhbwstuttgart.typeinference.unify.FC_TTO;
|
||
import de.dhbwstuttgart.typeinference.unify.Unifier;
|
||
import de.dhbwstuttgart.typeinference.unify.Unify;
|
||
|
||
|
||
|
||
|
||
// ino.class.SourceFile.21355.declaration
|
||
public class SourceFile
|
||
extends SyntaxTreeNode
|
||
// ino.end
|
||
// ino.class.SourceFile.21355.body
|
||
{
|
||
// ino.attribute.LOAD_BASIC_ASSUMPTIONS_FROM_JRE.21358.decldescription type=javadoc
|
||
/**
|
||
* @autor HOTI
|
||
* Dieses Flag bestimmt, ob die basicAssumptions (Integer, Menge, ...) direkt von
|
||
* der Java-Laufzeitumgebung anhand der Imports oder von den "Fixed Hacks" geladen
|
||
* werden (Mit Fixed Hacks sind die von Hand eingetragene Basetypes gemeint)
|
||
*/
|
||
// ino.end
|
||
// ino.attribute.LOAD_BASIC_ASSUMPTIONS_FROM_JRE.21358.declaration
|
||
private static final boolean LOAD_BASIC_ASSUMPTIONS_FROM_JRE = true;
|
||
// ino.end
|
||
|
||
// ino.attribute.READ_OBJECT_SUPERCLASSES_FROM_JRE.21361.decldescription type=javadoc
|
||
/**
|
||
* @autor HOTI
|
||
* Wenn dieses Flag auf <b>true</b> gesetzt ist, wird immer als Superklasse Object
|
||
* mit rein geladen. Dies hat natürlich zur Folge, dass man in der GUI jeden Typ
|
||
* auswählen muss, weil ALLES in Java von Object erbt. Sobald die GUI das über eine
|
||
* Checkbox o.ä. ausblendbar macht kann es aktiviert werden. Ebenso beeinflusst es
|
||
* die superclass von allen Class-Objekten. (Wenn true ist jede Class automatisch
|
||
* wenn nicht anders eingegeben Subclass von Object (Wie es sein muss))
|
||
*/
|
||
// ino.end
|
||
// ino.attribute.READ_OBJECT_SUPERCLASSES_FROM_JRE.21361.declaration
|
||
public static final boolean READ_OBJECT_SUPERCLASSES_FROM_JRE = false;
|
||
// ino.end
|
||
|
||
// ino.attribute.READ_BASE_TYPE_SUPERCLASSES_FROM_JRE.21364.decldescription type=javadoc
|
||
/**
|
||
* Wenn dieses Flag auf <b>false</b> ist, werden für alle Basisklassen (definiert
|
||
* durch die Hashtable baseTypeTranslationTable) KEINE Superklassen geladen. D.h.
|
||
* Integer hat bspw. nicht die Superklasse Number sondern OBJECT.
|
||
* Dies verursacht bei den Int-Operationen ein Problem
|
||
* (+,-,*,/,<,>,...)
|
||
*/
|
||
// ino.end
|
||
// ino.attribute.READ_BASE_TYPE_SUPERCLASSES_FROM_JRE.21364.declaration
|
||
private static final boolean READ_BASE_TYPE_SUPERCLASSES_FROM_JRE = false;
|
||
// ino.end
|
||
|
||
/**
|
||
* @autor PL
|
||
* Wenn dieses Flag auf <b>false</b> ist, werden für alle importierten Klassen
|
||
* KEINE Superklassen geladen.
|
||
*/
|
||
private static final boolean READ_IMPORTED_SUPERCLASSES_FROM_JRE = false;
|
||
|
||
// ino.attribute.codegenlog.21367.decldescription type=line
|
||
// Logger fuer Code-Gen
|
||
// ino.end
|
||
// ino.attribute.codegenlog.21367.declaration
|
||
protected static Logger codegenlog = Logger.getLogger("codegen");
|
||
// ino.end
|
||
// ino.attribute.inferencelog.21370.declaration
|
||
protected static Logger inferencelog = Logger.getLogger("inference");
|
||
// ino.end
|
||
|
||
// ino.attribute.pkgName.21373.declaration
|
||
private UsedId pkgName;
|
||
// ino.end
|
||
|
||
// ino.attribute.KlassenVektor.21376.declaration
|
||
public Menge<Class> KlassenVektor = new Menge<Class>();
|
||
// ino.end
|
||
|
||
// ino.attribute.InterfaceVektor.21379.declaration
|
||
public Menge<Interface> InterfaceVektor = new Menge<Interface>();
|
||
// ino.end
|
||
|
||
/**
|
||
* Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei.
|
||
* SourceFile stellt dabei den Wurzelknoten des Syntaxbaumes dar.
|
||
*/
|
||
public SourceFile(){
|
||
// HOTI 4.5.06
|
||
// Base-Type-Translations anlegen (siehe kommentar BaseTypeTranslationTable)
|
||
baseTypeTranslationTable=new Hashtable<String,String>();
|
||
baseTypeTranslationTable.put("int","java.lang.Integer");
|
||
baseTypeTranslationTable.put("char","java.lang.Character");
|
||
baseTypeTranslationTable.put("boolean","java.lang.Boolean");
|
||
baseTypeTranslationTable.put("double","java.lang.Double");
|
||
baseTypeTranslationTable.put("long","java.lang.Long");
|
||
baseTypeTranslationTable.put("float","java.lang.Float");
|
||
//baseTypeTranslationTable.put("this.is.a.temporary.entry","de.dhbwstuttgart.typeinference.Menge"); auskommentiert PL 07-08-11
|
||
|
||
|
||
this.imports=new ImportDeclarations();
|
||
|
||
this.imports.add(UsedId.createFromQualifiedName("java.lang.Integer",-1));
|
||
this.imports.add(UsedId.createFromQualifiedName("java.lang.String",-1));
|
||
this.imports.add(UsedId.createFromQualifiedName("java.lang.Character",-1));
|
||
this.imports.add(UsedId.createFromQualifiedName("java.lang.Boolean",-1));
|
||
this.imports.add(UsedId.createFromQualifiedName("java.lang.Double",-1));
|
||
this.imports.add(UsedId.createFromQualifiedName("java.lang.Float",-1));
|
||
this.imports.add(UsedId.createFromQualifiedName("java.lang.Long",-1));
|
||
//this.imports.add(UsedId.createFromQualifiedName("java.lang.Byte"));
|
||
|
||
// HOTI 4.5.06 Wenn die Klassen immer als "Daddy" Object haben,
|
||
// muss das der JCC auch kennen
|
||
if(READ_OBJECT_SUPERCLASSES_FROM_JRE){
|
||
this.imports.add(UsedId.createFromQualifiedName("java.lang.Object",-1));
|
||
}
|
||
}
|
||
|
||
public SourceFile(Menge<Class> classDefinitions) {
|
||
this.KlassenVektor = classDefinitions;
|
||
}
|
||
|
||
// ino.attribute.imports.21382.decldescription type=javadoc
|
||
/**
|
||
* HOTI 4.5.06
|
||
* Beinhaltet alle Imports des aktuell geparsten Files
|
||
* in Form einer UsedId
|
||
*/
|
||
// ino.end
|
||
// ino.attribute.imports.21382.declaration
|
||
private ImportDeclarations imports=new ImportDeclarations();
|
||
// ino.end
|
||
// ino.attribute.baseTypeTranslationTable.21385.decldescription type=javadoc
|
||
/**
|
||
* Table zum Ãbersetzen der nicht implementierten Base-Types:
|
||
* Ãberall im Compiler wird statt bspw. int Integer verwendet
|
||
* d.h. 1+2 liefert ein Integer
|
||
* Deshalb benötigen wir hier eine Tabelle, mit der man die von
|
||
* der JRE gelieferten Base-Typen (int,char, etc) und die Objekt-
|
||
* Typen umwandeln können
|
||
*/
|
||
// ino.end
|
||
// ino.attribute.baseTypeTranslationTable.21385.declaration
|
||
private Hashtable<String,String> baseTypeTranslationTable;
|
||
// ino.end
|
||
|
||
|
||
|
||
|
||
// ino.method.addElement.21394.defdescription type=javadoc
|
||
/**
|
||
* Fuegt ein neues Element (Interface oder Klasse) hinzu.
|
||
* @param c
|
||
*/
|
||
// ino.end
|
||
// ino.method.addElement.21394.definition
|
||
public void addElement(AClassOrInterface e)
|
||
// ino.end
|
||
// ino.method.addElement.21394.body
|
||
{
|
||
if (e instanceof Class) {
|
||
KlassenVektor.addElement((Class) e);
|
||
} else if (e instanceof Interface) {
|
||
InterfaceVektor.addElement((Interface) e);
|
||
}
|
||
}
|
||
// ino.end
|
||
|
||
|
||
|
||
// ino.method.codegen.21397.defdescription type=javadoc
|
||
/**
|
||
* Startet die Bytecodegenerierung fuer alle in der Datei
|
||
* enthaltenen Klassen und Interfaces.
|
||
*
|
||
|
||
// ino.end
|
||
// ino.method.codegen.21397.definition
|
||
public Menge<ClassFile> codegen(ResultSet result)
|
||
throws JVMCodeException
|
||
// ino.end
|
||
// ino.method.codegen.21397.body
|
||
{
|
||
Menge<ClassFile> ret = new Menge<ClassFile>();
|
||
codegenlog.info("Anzahl der Interfaces: "
|
||
+ Integer.toString(InterfaceVektor.size()));
|
||
for(int i = 0; i < InterfaceVektor.size(); i++) {
|
||
InterfaceVektor.elementAt(i).codegen(result);
|
||
}
|
||
|
||
codegenlog.info("Anzahl der Klassen: "
|
||
+ Integer.toString(KlassenVektor.size()));
|
||
for(int i = 0; i < KlassenVektor.size(); i++) {
|
||
ret.add(KlassenVektor.elementAt(i).codegen(result));
|
||
}
|
||
return ret;
|
||
}
|
||
// ino.end
|
||
*/
|
||
// ino.method.createPairFromClassAndSuperclass.21400.defdescription type=javadoc
|
||
/**
|
||
* Erstellt ein Typ-Paar, welches im 1. Durchlauf in die Menge der Finite Closure
|
||
* aufgenommen wird Input: Klassenname, Name der Superklasse, ParameterDerKlasse,
|
||
* Parameter der Superklasse
|
||
* @return
|
||
*/
|
||
// ino.end
|
||
// ino.method.createPairFromClassAndSuperclass.21400.definition
|
||
private Pair createPairFromClassAndSuperclass(Class baseClass, Type superclass, Menge classParaOrg, Menge superclassParaOrg, TypeAssumptions ass)
|
||
// ino.end
|
||
// ino.method.createPairFromClassAndSuperclass.21400.body
|
||
{
|
||
// Paar erstellen
|
||
if(classParaOrg!=null && classParaOrg.size()==0){
|
||
classParaOrg=null;
|
||
}
|
||
if(superclassParaOrg!=null && superclassParaOrg.size()==0){
|
||
superclassParaOrg=null;
|
||
}
|
||
/*
|
||
Pair P = new Pair(
|
||
new RefType( className.toString(), classParaOrg,-1),
|
||
new RefType( superclassName.toString(), superclassParaOrg,-1)
|
||
);
|
||
*/
|
||
Pair P = new Pair(baseClass.getType().TYPE(ass, baseClass), superclass.TYPE(ass, baseClass));
|
||
//PL 04-12-29 freshe Variablen ANFANG
|
||
RefType r1 = (RefType)P.getTA1Copy();
|
||
RefType r2 = (RefType)P.getTA2Copy();
|
||
r1 = (RefType) r1.TYPE(ass, baseClass);
|
||
r2 = (RefType) r2.TYPE(ass, baseClass);
|
||
// #JB# 05.04.2005
|
||
// ###########################################################
|
||
Hashtable<JavaClassName,Type> substHash = new Hashtable<JavaClassName,Type>(); //fuer jedes Paar komplett neue Variablen
|
||
Unify.varSubst(r1, substHash);
|
||
Unify.varSubst(r2, substHash);
|
||
// ###########################################################
|
||
P = new Pair(r1, r2);
|
||
//PL 04-12-29 freshe Variablen ENDE
|
||
|
||
//HIER AUSKOMMENTIERT, SOLLTE MAN AM ENDE WIEDER DAZU NEHMEN PL 04-12-28
|
||
// gleiches Paar aufnehmen
|
||
//vFC.add( new Pair( P.getTA1Copy(), P.getTA1Copy() ) );
|
||
|
||
return(P);
|
||
|
||
}
|
||
// ino.end
|
||
// ino.method.makeFC.21403.defdescription type=javadoc
|
||
/**
|
||
* Erstellt die Finite Closure
|
||
* @return FC_TTO-Object, welches die Finite Closure repräsentiert
|
||
*/
|
||
// ino.end
|
||
// ino.method.makeFC.21403.definition
|
||
public FC_TTO makeFC( TypeAssumptions ass )
|
||
// ino.end
|
||
// ino.method.makeFC.21403.body
|
||
{
|
||
|
||
// Menge FC bilden
|
||
|
||
Menge<Pair> vFC = new Menge<Pair>(); // Menge FC
|
||
TypeAssumptions globalAssumptions = this.makeBasicAssumptionsFromJRE(imports, false);
|
||
globalAssumptions.add(this.getPublicFieldAssumptions());
|
||
// 1. Menge <= in FC aufnehmen --> Iteration ueber alle Klassen
|
||
|
||
Menge<Type> ignoreTypes = new Menge<>(); //Enthält die Typen, welche nicht in der FC als Supertypen enthalten sein sollen.
|
||
ignoreTypes.add(new RefType("Long",null,-1).TYPE(globalAssumptions, parent));
|
||
ignoreTypes.add(new RefType("Float",null,-1).TYPE(globalAssumptions, parent));
|
||
ignoreTypes.add(new RefType("Double",null,-1).TYPE(globalAssumptions, parent));
|
||
ignoreTypes.add(new RefType("String",null,-1).TYPE(globalAssumptions, parent));
|
||
ignoreTypes.add(new RefType("Integer",null,-1).TYPE(globalAssumptions, parent));
|
||
ignoreTypes.add(new RefType("Object",null,-1).TYPE(globalAssumptions, parent));
|
||
|
||
Menge<Class> basicAssumptionsClassMenge = new Menge<>(); //die Klassen aus den BasicAssumptions und den Importierten Klassen
|
||
for(ClassAssumption cAss : ass.getClassAssumptions()){
|
||
Type t1 = cAss.getAssumedClass().getType();
|
||
Type t2 = cAss.getAssumedClass().getSuperClass();
|
||
Pair p = new Pair(t1, t2);
|
||
//System.out.println("FCPair: "+p);
|
||
if(! t1.equals(t2)){//Um FC_TTO darf kein T <. T stehen.
|
||
Type superTypeFromAssumptions = ass.getTypeFor(t2, t2); //In den Assumptions den SuperTyp nachschlagen
|
||
if(superTypeFromAssumptions != null && ! ignoreTypes.contains(superTypeFromAssumptions)){//Die Superklasse eines Typs nur anfügen, wenn er auch in den Assumptions vorkommt.
|
||
vFC.add(p);
|
||
}
|
||
basicAssumptionsClassMenge.add(cAss.getAssumedClass());//Klasse ohne die Superklasse anfügen
|
||
}else{
|
||
//System.out.println("Wurde nicht aufgenommen");
|
||
}
|
||
}
|
||
|
||
for( int i = 0; i < KlassenVektor.size(); i++ )
|
||
{
|
||
Class tempKlasse = KlassenVektor.elementAt(i);
|
||
inferencelog.debug("Verarbeite "+tempKlasse.getName(), Section.TYPEINFERENCE);
|
||
//TODO: SuperKlasse erstellen, dies sollte am besten beim Konstruktoraufruf von Class geschehen. Diese kann dann mit getSuperClass abgefragt werden.
|
||
if( tempKlasse.superclassid != null ) { // Klasse hat Superklasse
|
||
Pair P=createPairFromClassAndSuperclass(tempKlasse,tempKlasse.getSuperClass(),tempKlasse.get_ParaList(),tempKlasse.superclassid.get_ParaList(), globalAssumptions);
|
||
vFC.add( P );
|
||
}
|
||
if(tempKlasse.getSuperInterfaces()!=null){
|
||
Iterator<Type> interfaceIterator=tempKlasse.getSuperInterfaces().iterator();
|
||
while(interfaceIterator.hasNext()){
|
||
RefType intf=(RefType) interfaceIterator.next();
|
||
Pair P=createPairFromClassAndSuperclass(tempKlasse,intf,tempKlasse.get_ParaList(),intf.get_ParaList(),globalAssumptions);
|
||
vFC.add( P );
|
||
|
||
}
|
||
}
|
||
} // Schleifenende durch Klassenvektor
|
||
for(int i=0; i<InterfaceVektor.size();i++){
|
||
Interface intf= InterfaceVektor.get(i);
|
||
if(intf.getSuperInterfaces()!=null){
|
||
Iterator<Type> interfaceIterator=intf.getSuperInterfaces().iterator();
|
||
while(interfaceIterator.hasNext()){
|
||
RefType superintf=(RefType) interfaceIterator.next();
|
||
Pair P=createPairFromClassAndSuperclass(intf,superintf,intf.getParaList(), superintf.get_ParaList(),globalAssumptions);
|
||
vFC.add( P );
|
||
|
||
}
|
||
}
|
||
}
|
||
Menge tto = (Menge)vFC.clone();
|
||
|
||
Unify.printMenge( "FC", vFC, 6 );
|
||
/* z.B.
|
||
*******************************
|
||
Menge FC = {
|
||
(Vektor< A >, Vektor< A >),
|
||
(Vektor< A >, AbstractList< A >),
|
||
(Matrix< A >, Matrix< A >),
|
||
(Matrix< A >, Vektor< Vektor< A > >),
|
||
(ExMatrix< A >, ExMatrix< A >),
|
||
(ExMatrix< A >, Matrix< A >) }
|
||
*******************************
|
||
|
||
ODER
|
||
|
||
*******************************
|
||
Menge FC = {
|
||
(BB< A >, BB< A >),
|
||
(BB< A >, CC< A >),
|
||
(AA< A, B >, AA< A, B >),
|
||
(AA< A, B >, BB< DD< B, A > >) }
|
||
*******************************
|
||
|
||
*/
|
||
|
||
// 2. Regel 2 der Huellendefinition "eingeschraenkt" anwenden
|
||
// d.h. sinnvolle Substitutionen suchen (nicht alle)
|
||
|
||
boolean bPaarHinzu = true;
|
||
while( bPaarHinzu )
|
||
{
|
||
bPaarHinzu = false; //PL 04-12-29 nur wenn hinzugefuegt auf true setzen
|
||
// konkret: rechte Seite von FC nach Typkonstruktoren in der Parameterliste durchsuchen
|
||
for( int n = 0; n < vFC.size(); n++ )
|
||
{
|
||
// Elemente in FC k�nnen nur Pair's sein --> Cast ohne Abfrage
|
||
Pair PTypKonst = vFC.elementAt(n);
|
||
|
||
// Parameter des rechten Typausdrucks des betrachteten Paars extrahieren
|
||
Menge<Type> vPara = ((RefType)(PTypKonst.TA2)).get_ParaList();
|
||
Integer Subst = null; // Substitution
|
||
int nSubstStelle = 0;
|
||
inferencelog.debug("nSubstStelleStart" + nSubstStelle + " " + n, Section.FINITECLOSURE);
|
||
|
||
// Parameter durchlaufen und nach Typkonstruktor suchen
|
||
// #JB# 17.05.2005
|
||
// ###########################################################
|
||
if(vPara!=null){
|
||
// ###########################################################
|
||
for( ; nSubstStelle < vPara.size(); nSubstStelle++ )
|
||
{
|
||
inferencelog.debug("nSubstStelle" + nSubstStelle, Section.FINITECLOSURE);
|
||
if( vPara.elementAt(nSubstStelle) instanceof RefType && ((RefType)vPara.elementAt(nSubstStelle)).get_ParaList() != null )
|
||
{
|
||
// Typkonstruktor gefunden -> wird nun als Substitution verwendet
|
||
Subst = 1;//new RefType( (RefType)vPara.elementAt(nSubstStelle) ,-1);
|
||
inferencelog.debug( "Ausgangstyp:" + ((RefType)PTypKonst.TA2).getName() , Section.FINITECLOSURE);
|
||
inferencelog.debug( "RefType = " + ((RefType)vPara.elementAt(nSubstStelle)).getName() , Section.FINITECLOSURE);
|
||
break; // Einschraenkung - nur fuer ein RefType wird eine Substitution gesucht
|
||
}
|
||
}
|
||
// ###########################################################
|
||
}
|
||
// ###########################################################
|
||
if( Subst != null )
|
||
{
|
||
// Rechter Typ hat einen Typkonstruktor --> sinvolles neues Paar bilden
|
||
// d.h. Rechter Typ auf linker Paarseite suchen
|
||
// System.out.println("Subststelle = " + nSubstStelle );
|
||
|
||
for( int t = 0; t < vFC.size(); t++ )
|
||
{
|
||
Pair PSuchen = vFC.elementAt(t);
|
||
if( ((RefType)(PTypKonst.TA2)).getTypeName().equals( ((RefType)PSuchen.TA1).getTypeName() ) )
|
||
{
|
||
inferencelog.debug(" gefundener Typ links: " + ((RefType)(PSuchen.TA1)).getName(), Section.FINITECLOSURE );
|
||
inferencelog.debug(" gefundener Typ rechts: " + ((RefType)(PSuchen.TA2)).getName() , Section.FINITECLOSURE);
|
||
// Paar gefunden, das als linken Typ den gleichen Typen enth�lt, der als Parameter einen Typkonstruktor hat
|
||
// Substitution
|
||
//Pair P = new Pair( PSuchen.getTA1Copy( ), PSuchen.getTA2Copy( ) );
|
||
//linker Typterm bleibt gleich
|
||
//rechter Typterm wird aussen auf den Supertyp gesetzt.
|
||
//restliches FC erfolgt ueber die Transitivitaet
|
||
//siehe im unteren Teil
|
||
Pair P = new Pair( PTypKonst.getTA1Copy( ), PSuchen.getTA2Copy( ) );
|
||
// System.out.println(" Subst " + Subst.getName() );
|
||
// System.out.println(" Vor: P = " + P.toString() + P.TA1 );
|
||
// System.out.println(" Vor: PSuchen = " + PSuchen.toString() + PSuchen.TA1 );
|
||
|
||
// Parameter, der substituiert wird, sollte TV sein ???
|
||
//TypePlaceholder TV = null;
|
||
// if( ((RefType)P.TA1).isTV( nSubstStelle ) )
|
||
// try
|
||
// {
|
||
// TV = new TypePlaceholder( ((RefType)P.TA1).getParaN( nSubstStelle ) );
|
||
// }
|
||
// catch( Exception E )
|
||
// {
|
||
// continue;
|
||
// }
|
||
// else
|
||
// continue;
|
||
|
||
//es werden alle Parameter in einem Typeterm, der
|
||
//der Argumente hat ersetzt PL 04-12-28
|
||
Hashtable<JavaClassName,Type> hts = new Hashtable<JavaClassName,Type>();
|
||
//for(int u = nSubstStelle; u < vPara.size(); u++) {
|
||
for(int u = 0; u < vPara.size(); u++) {
|
||
try {
|
||
// #JB# 05.04.2005
|
||
// ###########################################################
|
||
//TV = new TypePlaceholder( ((RefType)PSuchen.TA1).getParaN(u) );
|
||
//System.out.println("TV_Name: " + u + TV.Type2String());
|
||
// ###########################################################
|
||
inferencelog.debug("Typterm_Name: " + vPara.elementAt(u), Section.FINITECLOSURE);
|
||
inferencelog.debug("Typterm_Name: " + ((Type)vPara.elementAt(u)).Type2String(), Section.FINITECLOSURE);
|
||
hts.put(new JavaClassName(((RefType)PSuchen.TA1).getParaN(u)), vPara.elementAt(u));
|
||
}
|
||
catch( Exception E ) {
|
||
inferencelog.error(E.getMessage(), Section.FINITECLOSURE);
|
||
//FIXME Throw Exception or Error instead of exiting!
|
||
System.exit(0);
|
||
}
|
||
|
||
// Subst( P,
|
||
// 2,
|
||
// TV,
|
||
// new RefType( (RefType)vPara.elementAt(u) ),
|
||
// false ); // rechte Seite substituieren
|
||
//Es genuegt die rechte Seite zu substituieren, da
|
||
//die linke Seite ein Typterm ausschlie�lich mit
|
||
//Typvariablen ist
|
||
}
|
||
//Unify.SubstHashtableGeneric(((RefType)P.TA1), hts); //funktioniert nicht
|
||
Unify.SubstHashtableGeneric(((RefType)P.TA2), hts); //funktioniert nicht
|
||
// System.out.println(" TV!!!= " + TV.getName() );
|
||
//Subst( P, 1, TV, Subst, false ); // linke Seite substituieren
|
||
//Subst( P, 2, TV, Subst, false ); // rechte Seite substituieren
|
||
// System.out.println(" nach Subst: P = " + P.toString() );
|
||
// System.out.println(" Nach: PSuchen = " + PSuchen.toString() );
|
||
// System.out.println(" Nach: " + P.toString() );
|
||
|
||
// Paar einfuegen, falls noch nicht vorhanden
|
||
// System.out.println("Paar alt:" + PSuchen.toString() );
|
||
// System.out.println("Paar neu:" + P.toString() );
|
||
if( !P.isInMenge( vFC ) )
|
||
{
|
||
vFC.add( P );
|
||
Unify.printMenge( "FC", vFC, 6 );
|
||
bPaarHinzu = true;
|
||
}
|
||
//PL 04-12-29
|
||
// else //unnoetig, da am Anfang bereits false gesetzt
|
||
// {
|
||
// bPaarHinzu = false;
|
||
// }
|
||
|
||
}
|
||
}
|
||
} // end if: Substitution gefunden???
|
||
} // end for: Typkonstruktor suchen
|
||
|
||
|
||
// Transitivitaet berechnen
|
||
for( int u = 0; u < vFC.size(); u++ )
|
||
{
|
||
Pair PTemp = vFC.elementAt(u);
|
||
|
||
// falls rechtes Paar = RefType
|
||
if( PTemp.TA2 instanceof RefType )
|
||
{
|
||
RefType R = (RefType)PTemp.TA2;
|
||
|
||
// rechte Seite auf linker Seite suchen
|
||
for( int e = 0; e < vFC.size(); e++ )
|
||
{
|
||
Pair PSuch = vFC.elementAt(e);
|
||
// als linke Paarseite theortisch nur RefType's moeglich --> Cast
|
||
RefType RSuch = (RefType)PSuch.TA1;
|
||
|
||
//if( R.getName().equals(RSuch.getName()) )
|
||
if (R.is_Equiv(RSuch, new Hashtable<JavaClassName,Type>())) //eingefuegt PL 05-01-07
|
||
{
|
||
// Paar einfuegen, falls noch nicht vorhanden
|
||
RefType L1 = (RefType)PTemp.getTA1Copy();
|
||
RefType L2 = (RefType)PTemp.getTA2Copy();
|
||
RefType R1 = (RefType)PSuch.getTA1Copy();
|
||
RefType R2 = (RefType)PSuch.getTA2Copy();
|
||
|
||
//zunaechst Variablen disjunkt machen ANFANG
|
||
// #JB# 05.04.2005
|
||
// ###########################################################
|
||
Hashtable<JavaClassName,Type> substHash1 = new Hashtable<JavaClassName,Type>();
|
||
Unify.varSubst(L1, substHash1);
|
||
Unify.varSubst(L2, substHash1);
|
||
Hashtable<JavaClassName,Type> substHash2 = new Hashtable<JavaClassName,Type>();
|
||
Unify.varSubst(R1, substHash2);
|
||
Unify.varSubst(R2, substHash2);
|
||
// ###########################################################
|
||
//zunaechst Variablen disjunkt machen ENDE
|
||
|
||
//Variablen so umbennen, dass transitiver Abschluss richtige
|
||
//Namen hat ANFANG
|
||
|
||
// #JB# 05.04.2005
|
||
// ###########################################################
|
||
Hashtable<JavaClassName,Type> h = new Hashtable<JavaClassName,Type>();
|
||
L2.Equiv2Equal(R1, h);
|
||
Hashtable<JavaClassName,Type> substHash3 = h;
|
||
Unify.varSubst(L1, substHash3);
|
||
Unify.varSubst(R2, substHash3);
|
||
// ###########################################################
|
||
//Variablen so umbennen, dass transitiver Abschluss richitge
|
||
//Namen hat ENDE
|
||
|
||
//Pair P = new Pair( (RefType)PTemp.TA1, (RefType)PSuch.TA2 );
|
||
Pair P = new Pair(L1, R2);
|
||
if( !P.isInMenge( vFC ) )
|
||
{
|
||
vFC.add( P );
|
||
bPaarHinzu = true;
|
||
}
|
||
else
|
||
{
|
||
bPaarHinzu = false;
|
||
}
|
||
}
|
||
} // end for: linke Seite suchen
|
||
} // end if: Element ist RefType
|
||
} // end for: Transitivit�ten berechnen
|
||
//PL HIER REFLEXIVE HUELLE EINFUEGEN
|
||
// 05-01-07
|
||
|
||
} // Ende WHILE
|
||
|
||
/* z.B.
|
||
*******************************
|
||
Menge nach trans: FC = {
|
||
(Vektor< A >, Vektor< A >),
|
||
(Vektor< A >, AbstractList< A >),
|
||
(Matrix< A >, Matrix< A >),
|
||
(Matrix< A >, Vektor< Vektor< A > >),
|
||
(ExMatrix< A >, ExMatrix< A >),
|
||
(ExMatrix< A >, Matrix< A >),
|
||
(Vektor< Vektor< A > >, Vektor< Vektor< A > >),
|
||
(Vektor< Vektor< A > >, AbstractList< Vektor< A > >),
|
||
(Matrix< A >, AbstractList< Vektor< A > >),
|
||
(ExMatrix< A >, Vektor< Vektor< A > >),
|
||
(ExMatrix< A >, AbstractList< Vektor< A > >) }
|
||
|
||
ODER
|
||
|
||
*******************************
|
||
Menge nach trans: FC = {
|
||
(BB< A >, BB< A >),
|
||
(BB< A >, CC< A >),
|
||
(AA< A, B >, AA< A, B >),
|
||
(AA< A, B >, BB< DD< B, A > >),
|
||
(BB< DD< B, A > >, BB< DD< B, A > >),
|
||
(BB< DD< B, A > >, CC< DD< B, A > >),
|
||
(AA< A, B >, CC< DD< B, A > >) }
|
||
*******************************
|
||
|
||
******************************* */
|
||
|
||
|
||
// printMenge( "nach trans: FC", vFC, 6 );
|
||
|
||
Menge<Class> KlassenVektorunImportierteKlassen = new Menge<>();
|
||
KlassenVektorunImportierteKlassen.addAll(basicAssumptionsClassMenge);
|
||
KlassenVektorunImportierteKlassen.addAll(KlassenVektor);
|
||
|
||
FC_TTO fctto = new FC_TTO(vFC, tto, KlassenVektorunImportierteKlassen);
|
||
return fctto;
|
||
}
|
||
|
||
public TypeAssumptions getPublicFieldAssumptions(){
|
||
TypeAssumptions publicAssumptions = new TypeAssumptions(null);
|
||
//Alle PublicAssumptions der in dieser SourceFile enthaltenen Klassen sammeln:
|
||
for(Class klasse : KlassenVektor){
|
||
publicAssumptions.add(klasse.getPublicFieldAssumptions());
|
||
}
|
||
return publicAssumptions;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////
|
||
// TypeReconstructionAlgorithmus
|
||
/////////////////////////////////////////////////////////////////////////
|
||
// ino.method.typeReconstruction.21406.defdescription type=javadoc
|
||
/**
|
||
* Tyrekonstruktionsalgorithmus: ruft f�r jede Klasse den Algorithmus TRProg auf.
|
||
* Dessen Ergebnismenge A, die Menge aller Typannahmen, f�r eine Klasse dient als
|
||
* Eingabe f�r TRProg der n�chsten Klasse. Am Ende enth�lt A alle m�glichen
|
||
* Typkombinationen f�r alle Klassen zusammen.
|
||
* <br>Author: J�rg B�uerle
|
||
* @return Liste aller m�glichen Typkombinationen
|
||
* @throws CTypeReconstructionException Wenn was schief l�uft
|
||
*/
|
||
// ino.end
|
||
// ino.method.typeReconstruction.21406.definition
|
||
public Menge<TypeinferenceResultSet> typeReconstruction(TypeAssumptions globalAssumptions)
|
||
throws CTypeReconstructionException
|
||
// ino.end
|
||
// ino.method.typeReconstruction.21406.body
|
||
{
|
||
Menge<TypeinferenceResultSet> ret = new Menge<TypeinferenceResultSet>();
|
||
|
||
//Logger initialisieren:
|
||
Logger typinferenzLog = Logger.getLogger("Typeinference");
|
||
|
||
//Alle Assumptions für diese SourceFile sammeln:
|
||
for(Class klasse : this.KlassenVektor){
|
||
globalAssumptions.add(klasse.getPublicFieldAssumptions());
|
||
}
|
||
|
||
//Assumptions der importierten Klassen sammeln:
|
||
TypeAssumptions importAssumptions = this.makeBasicAssumptionsFromJRE(imports, true);
|
||
globalAssumptions.add(importAssumptions);
|
||
typinferenzLog.debug("Von JRE erstellte Assumptions: "+importAssumptions, Section.TYPEINFERENCE);
|
||
|
||
//FiniteClosure generieren:
|
||
FC_TTO finiteClosure = this.makeFC(globalAssumptions);
|
||
|
||
typinferenzLog.debug("FiniteClosure: \n"+finiteClosure, Section.TYPEINFERENCE);
|
||
|
||
ConstraintsSet oderConstraints = new ConstraintsSet();
|
||
//Alle Constraints der in dieser SourceFile enthaltenen Klassen sammeln:
|
||
for(Class klasse : KlassenVektor){
|
||
oderConstraints.add(klasse.typeReconstruction(finiteClosure, globalAssumptions));
|
||
}
|
||
|
||
////////////////
|
||
//Karthesisches Produkt bilden:
|
||
////////////////
|
||
|
||
//Unmögliche ConstraintsSets aussortieren durch Unifizierung
|
||
Unifier unifier = (pairs)->{
|
||
Menge<Menge<Pair>> retValue = new Menge<>();
|
||
retValue = Unify.unify(pairs, finiteClosure);
|
||
return retValue;};
|
||
//oderConstraints.filterWrongConstraints(unifier);
|
||
oderConstraints.unifyUndConstraints(unifier);
|
||
typinferenzLog.debug("Ãbriggebliebene Konstraints:\n"+oderConstraints+"\n", Section.TYPEINFERENCE);
|
||
//Die Constraints in Pair's umwandeln (Karthesisches Produkt bilden):
|
||
Menge<Menge<Pair>> xConstraints = oderConstraints.cartesianProduct();
|
||
/*
|
||
for(Menge<UndConstraint> uC : oderConstraints.getConstraints()){ //mit dem getConstraints-Aufruf wird das Karthesische Produkt erzeugt.
|
||
Menge<Pair> cons = new Menge<Pair>();
|
||
for(UndConstraint undCons:uC){
|
||
cons.addAll(undCons.getConstraintPairs());
|
||
}
|
||
xConstraints.add(cons);
|
||
}
|
||
*/
|
||
typinferenzLog.debug("Karthesisches Produkt der Constraints: "+xConstraints, Section.TYPEINFERENCE);
|
||
|
||
finiteClosure.generateFullyNamedTypes(globalAssumptions);
|
||
|
||
//////////////////////////////
|
||
// Unifizierung der Constraints:
|
||
//////////////////////////////
|
||
boolean unifyFail = true;
|
||
for(Menge<Pair> constraints : xConstraints){
|
||
//Alle durch das Karthesische Produkt entstandenen Möglichkeiten durchgehen:
|
||
Menge<Menge<Pair>> result = new Menge<Menge<Pair>>();
|
||
|
||
//Alle FunN-Typen werden per clone-methode in RefTypes verwandelt. (Die clone Methode in FunN darf nicht überschrieben werden.
|
||
for(Pair p : constraints){
|
||
if(p.TA1 instanceof FunN){
|
||
p.TA1 = p.TA1.clone();
|
||
}
|
||
if(p.TA2 instanceof FunN){
|
||
p.TA2 = p.TA2.clone();
|
||
}
|
||
}
|
||
|
||
/*
|
||
//Alle Generischen Typvariablen in TPH umwandeln:
|
||
HashMap<GenericTypeVar,TypePlaceholder> gtv2tph = new HashMap<GenericTypeVar,TypePlaceholder>();
|
||
for(Pair pair : constraints){
|
||
if(pair.TA1 instanceof GenericTypeVar){
|
||
TypePlaceholder tph = gtv2tph.get(pair.TA1);
|
||
if(tph == null){
|
||
tph = TypePlaceholder.fresh();
|
||
gtv2tph.put((GenericTypeVar)pair.TA1, tph);
|
||
}
|
||
pair.TA1 = tph;
|
||
}
|
||
if(pair.TA2 instanceof GenericTypeVar){
|
||
TypePlaceholder tph = gtv2tph.get(pair.TA2);
|
||
if(tph == null){
|
||
tph = TypePlaceholder.fresh();
|
||
gtv2tph.put((GenericTypeVar)pair.TA2, tph);
|
||
}
|
||
pair.TA2 = tph;
|
||
}
|
||
}
|
||
*/
|
||
//Erst die Unifizierung erstellen:
|
||
Menge<Pair> constraintsClone = (Menge<Pair>)constraints.clone();
|
||
|
||
/*
|
||
//Typen kontrollieren:
|
||
for(Pair p : constraintsClone){
|
||
Type t = p.TA1;
|
||
//TypeCheck, falls es sich um einen RefType handelt:
|
||
if(t!=null && (t instanceof RefType)&&
|
||
!(t instanceof de.dhbwstuttgart.syntaxtree.type.Void)){
|
||
Type replaceType = null;
|
||
replaceType = globalAssumptions.getTypeFor((RefType)t, null);
|
||
if(!(replaceType == null))p.TA1 = replaceType;
|
||
}
|
||
t = p.TA2;
|
||
//TypeCheck, falls es sich um einen RefType handelt:
|
||
if(t!=null && (t instanceof RefType)&&
|
||
!(t instanceof de.dhbwstuttgart.syntaxtree.type.Void)){
|
||
Type replaceType = null;
|
||
replaceType = globalAssumptions.getTypeFor((RefType)t, null);
|
||
if(!(replaceType == null))p.TA2 = replaceType;
|
||
}
|
||
}
|
||
*/
|
||
|
||
//IDEE: Man bildet Zusammenhangskomponenten von Paaren, die gemeinsame Variablen haben
|
||
// und unifizert nur die Zusammenhangskomponenten in Schritten 1 - 5
|
||
|
||
//Schritt 1: Alle Variablen in den Paaren von Elementen einsammeln
|
||
Menge<Menge<TypePlaceholder>> constraintsclonevars = constraintsClone.stream().map(p -> {Menge<TypePlaceholder> TPHs = new Menge<>();
|
||
TPHs.addAll(p.TA1.getInvolvedTypePlaceholder());
|
||
TPHs.addAll(p.TA2.getInvolvedTypePlaceholder());
|
||
return TPHs;}
|
||
).collect(Menge::new, Menge::add, Menge::addAll);
|
||
|
||
//Schritt 2: Schnittmengen jedes Elements mit jedem Elememt von vars bilden und dann index zusammenfassen
|
||
//in indexset sind dann die Mengen von Indizes enthalten, die gemeisam unifiziert wreden müssen
|
||
Menge<Menge<Integer>> indexeset = new Menge<>();
|
||
if (constraintsclonevars != null && constraintsclonevars.size()>0) {
|
||
indexeset = Unify.schnitt(constraintsclonevars);
|
||
}
|
||
|
||
//Schritt 3: Umwandlung der Indizes in die zugehoerigen Elemente
|
||
// In streamconstraintsclone sind die Mengen von Paar enthalten die unifiziert werden muessen
|
||
Stream<Menge<Pair>> streamconstraintsclone = indexeset.stream().map(x -> x.stream()
|
||
.map(i -> constraintsClone.elementAt(i))
|
||
.collect(Menge::new, Menge::add, Menge::addAll));
|
||
//Menge<Menge<Pair>> vecconstraintsclone = streamconstraintsclone.collect(Menge::new, Menge::add, Menge::addAll);
|
||
System.out.println();
|
||
//Schritt 4: Unifikation
|
||
Menge<Menge<Menge<Pair>>> vecunifyResult =
|
||
//streamconstraintsclone.map(x -> Unify.unify(x, finiteClosure)).collect(Menge::new, Menge::add, Menge::addAll);
|
||
//DEBUG-Variante
|
||
streamconstraintsclone.map(x ->
|
||
{ Menge<Menge<Pair>> z = Unify.unify(x, finiteClosure);
|
||
return z;
|
||
}
|
||
).collect(Menge::new, Menge::add, Menge::addAll);
|
||
|
||
|
||
//card gibt die Cardinalitaet der unifizierten Mengen an
|
||
Menge<Integer> card = vecunifyResult.stream().map(x -> x.size()).collect(Menge::new, Menge::add, Menge::addAll);
|
||
;//.reduce(1,(a,b) -> { if ((a > 0) && (b > 0)) return (a * b); else return 1; });
|
||
|
||
//Schritt 5: Bildung des cartesischen Produkts
|
||
//sollte wieder entfernt werden: Weiterarbeit mit:
|
||
//[[x_1 -> t_1, x_2 -> t2], [x_1 -> t'_1, x_2 -> t'_2]] x ... x [[x_n -> t_1n], [x_n -> t2n], [x_n -> t3n]]
|
||
Menge<Menge<Pair>> cardprodret_start = new Menge<>();
|
||
cardprodret_start.add(new Menge<Pair>());
|
||
|
||
//cart. Produkt mit kopieren
|
||
//Menge<Menge<Pair>> unifyResult = vecunifyResult.stream().reduce(cardprodret_start, (x, y) -> {
|
||
//Menge<Menge<Pair>> cardprodret= new Menge<>();
|
||
//if (y.size() > 0) {
|
||
////System.out.println(y);
|
||
//Menge<Menge<Pair>> cardprodretold = x;
|
||
//cardprodret = new Menge<>();
|
||
//for(int j = 0; j < cardprodretold.size(); j++) {
|
||
//for (int k = 0; k < y.size(); k++){
|
||
//Menge<Pair> help;
|
||
//if (y.size() == 1) help = cardprodretold.elementAt(j); //bei einem hinzuzufuegenden Element muss nicht kopiert werden
|
||
//else help = Unify.copyMengePair(cardprodretold.elementAt(j));
|
||
//help.addAll(y.elementAt(k));
|
||
//cardprodret.add(help);
|
||
//}
|
||
//}
|
||
//}
|
||
//else
|
||
//return new Menge<>(); //kein unifiziertes Ergebnis, damit wird das Geseamtergebnis []
|
||
//return cardprodret;
|
||
//});
|
||
|
||
//cart. Produkt mit Linkverschiebung
|
||
Menge<Menge<Pair>> unifyResult = vecunifyResult.stream().reduce(cardprodret_start, (x, y) -> {
|
||
Menge<Menge<Pair>> cardprodret= new Menge<>();
|
||
if (y.size() > 0) {
|
||
//System.out.println(y);
|
||
//Menge<Menge<Pair>> cardprodretold = x;
|
||
//cardprodret = new Menge<>();
|
||
for(int j = 0; j < x.size(); j++) {
|
||
for (int k = 0; k < y.size(); k++){
|
||
Menge<Pair> help = new Menge<>();
|
||
help.addAll(y.elementAt(k));
|
||
help.addAll(x.elementAt(j));
|
||
cardprodret.add(help);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
return new Menge<>(); //kein unifiziertes Ergebnis, damit wird das Geseamtergebnis []
|
||
return cardprodret;
|
||
});
|
||
|
||
//Menge<Menge<Pair>> unifyResult = Unify.unify(constraintsClone, finiteClosure);
|
||
//Dann den Ergebnissen anfügen
|
||
result.addAll(unifyResult);
|
||
|
||
// Debugoutput:Menge<Menge<Pair>>
|
||
|
||
//typinferenzLog.debug("Unifiziertes Ergebnis: "+result, Section.TYPEINFERENCE);
|
||
|
||
/*
|
||
// Prüfe ob eindeutige Lösung:
|
||
if(result.size()>1 && !Unify.hasSolvedForm(result.elementAt(0))){
|
||
|
||
typinferenzLog.debug("Keine eindeutige Lösung!");
|
||
|
||
}else if(result.size()>1){
|
||
|
||
//Replace TPH:
|
||
for(Pair res : result.elementAt(0)){
|
||
if(res.OperatorEqual()){
|
||
if(res.TA1 instanceof TypePlaceholder)((TypePlaceholder)res.TA1).fireReplaceTypeEvent(new CReplaceTypeEvent(res.TA1, res.TA2));
|
||
}
|
||
}
|
||
}
|
||
*/
|
||
//typinferenzLog.debug();
|
||
//typinferenzLog.debug(supportData.getFiniteClosure());
|
||
//typinferenzLog.debug("Typinformationen: \n"+this.getTypeInformation(this.getMethodList(), fieldInitializers));
|
||
|
||
typinferenzLog.debug("\nJavaFiles:\n", Section.TYPEINFERENCE);
|
||
|
||
//typinferenzLog.debug(this.printJavaCode(new ResultSet(new Menge<Pair>())));
|
||
|
||
|
||
//Für jede Klasse in diesem SourceFile gilt das selbe ResultSet:
|
||
for(Class klasse : this.KlassenVektor){
|
||
//Der Unifikationsalgorithmus kann wiederum auch mehrere Lösungen errechnen, diese werden im folgenden durchlaufen:
|
||
for(Menge<Pair> resultSet : result){
|
||
unifyFail = false; //Ein Unifiziertes Ergebnis ist entstanden (es kann auch leer sein, das bedeutet nur, dass die Constraints mindestens in einem Fall Sinn ergaben)
|
||
//Add Result set as a new ReconstructionResult to ret:
|
||
TypeinferenceResultSet reconstructionResult = new TypeinferenceResultSet(klasse, constraints, new ResultSet(resultSet));
|
||
ret.add(reconstructionResult);
|
||
|
||
//ResultSet res = new ResultSet(resultSet);
|
||
typinferenzLog.debug("JavaFile für ResultSet "+reconstructionResult+"\n", Section.TYPEINFERENCE);
|
||
typinferenzLog.debug(klasse.printJavaCode(reconstructionResult), Section.TYPEINFERENCE);
|
||
|
||
}
|
||
}
|
||
}
|
||
if(unifyFail){
|
||
if(!this.KlassenVektor.isEmpty())throw new TypeinferenceException("Fehler in Typinferierung", this.KlassenVektor.firstElement());
|
||
}
|
||
return ret;
|
||
/*
|
||
// HOTI: Nur zur Info.Ich habe den Loglevel auf Info geschaltet, damit
|
||
// in der GUI (Eclipse-Plugin) die Console nicht zugemüllt wird.
|
||
// Wers braucht kanns natürlich ausschalten
|
||
|
||
// inferencelog.setLevel(Level.INFO);
|
||
|
||
Menge<TypeinferenceResultSet> A = new Menge<TypeinferenceResultSet>();
|
||
|
||
TypeAssumptions basics;
|
||
|
||
basics = this.makeBasicAssumptions();
|
||
|
||
//A.addElement(basics); //auskommentiert von Andreas Stadelmeier
|
||
|
||
// PL 05-07-31 alle GenericTypeVars werden ueberprueft, ob sie nicht
|
||
// deklarierte Classen sind und dann ggfs. gewandelt.
|
||
for (int i = 0; i < this.KlassenVektor.size(); i++) {
|
||
Class tempKlasse = this.KlassenVektor.elementAt(i);
|
||
MyCompiler.wandleGeneric2RefType(tempKlasse.getContainedTypes(),
|
||
this.KlassenVektor);
|
||
if(tempKlasse.getSuperInterfaces()!=null){
|
||
for(int k=0;k<tempKlasse.getSuperInterfaces().size();k++){
|
||
MyCompiler.wandleGeneric2RefType(tempKlasse.getSuperInterfaces().elementAt(k).get_ParaList(),this.KlassenVektor);
|
||
}
|
||
|
||
}
|
||
}
|
||
for (int i = 0; i < this.InterfaceVektor.size(); i++) {
|
||
Interface tempIntf = this.InterfaceVektor.elementAt(i);
|
||
MyCompiler.wandleGeneric2RefType(tempIntf.getContainedTypes(),
|
||
this.KlassenVektor);
|
||
}
|
||
|
||
// HOTI 04-13-06 Alle Methoden der Klassen überprüfen, ob sie als
|
||
// RefType deklarierte Attribute haben, die aber GenericTypeVars sind
|
||
// Bsp.:
|
||
// bei public E elementAt(i){...} wird E vorerst als RefType erkannt
|
||
|
||
for (int i = 0; i < this.KlassenVektor.size(); i++) {
|
||
Class tempKlasse = this.KlassenVektor.elementAt(i);
|
||
tempKlasse.wandleRefTypeAttributes2GenericAttributes();
|
||
}
|
||
for (int i = 0;i< this.InterfaceVektor.size(); i++){
|
||
Interface tempInterface = this.InterfaceVektor.elementAt(i);
|
||
tempInterface.wandleRefTypeAttributes2GenericAttributes();
|
||
}
|
||
|
||
// HOT 8.5.06 Wandelt alle Referenzen auf p.ex. Menge in de.dhbwstuttgart.typeinference.Menge
|
||
for (int i = 0; i < this.KlassenVektor.size(); i++) {
|
||
Class tempKlasse = this.KlassenVektor.elementAt(i);
|
||
MyCompiler.makeRefTypesFullyQualified(tempKlasse.getContainedTypes(), this.imports);
|
||
String newSuperclass=MyCompiler.getFullyQualifiedNameFromClassname(tempKlasse.get_Superclass_Name(),this.imports);
|
||
if(newSuperclass!=null){
|
||
// Hier nicht setUsedID, sondern nur den Namen updaten. Sonst gehen die Parameter der Superklasse verloren
|
||
tempKlasse.superclassid.name=UsedId.createFromQualifiedName(newSuperclass,-1).name;
|
||
}
|
||
if(tempKlasse.getSuperInterfaces()!=null && tempKlasse.getSuperInterfaces().size()>0){
|
||
for(int j=0;j<tempKlasse.getSuperInterfaces().size();j++){
|
||
UsedId uid=tempKlasse.getSuperInterfaces().elementAt(j);
|
||
String newSuperif=MyCompiler.getFullyQualifiedNameFromClassname(uid.getQualifiedName(),this.imports);
|
||
if(newSuperif!=null){
|
||
UsedId newuid=UsedId.createFromQualifiedName(newSuperif,uid.getOffset());
|
||
uid.name=newuid.name;
|
||
}
|
||
MyCompiler.makeRefTypesFullyQualified(uid.get_ParaList(),this.imports);
|
||
}
|
||
}
|
||
for(int j=0;j<tempKlasse.getUsedIdsToCheck().size();j++){
|
||
UsedId id=tempKlasse.getUsedIdsToCheck().elementAt(j);
|
||
String newClassname=MyCompiler.getFullyQualifiedNameFromClassname(id.getQualifiedName(),this.imports);
|
||
if(newClassname!=null)
|
||
id.name=UsedId.createFromQualifiedName(newClassname,-1).name;
|
||
}
|
||
}
|
||
for (int i = 0; i < this.InterfaceVektor.size(); i++) {
|
||
Interface tempIntf = this.InterfaceVektor.elementAt(i);
|
||
MyCompiler.makeRefTypesFullyQualified(tempIntf.getContainedTypes(), this.imports);
|
||
}
|
||
|
||
|
||
inferencelog.info("Rufe \"SourceFile.makeFC()\"...");
|
||
inferencelog.info("������������������������������������");
|
||
FC_TTO finiteClosure = this.makeFC();
|
||
inferencelog.info("������������������������������������");
|
||
inferencelog.info("Bin aus \"SourceFile.makeFC()\" zur�ck.");
|
||
this.removeBasicAssumptions();
|
||
|
||
// PL 05-08-02
|
||
// verschoben nach Class.java am Ende von TRProg
|
||
// this.addClassNamesAndGenericsToRR(basics);
|
||
|
||
// HOTI 04-22-06 Fuer jede Klasse die Methoden und Instanzvariablen in die Assumptions aufnehmen
|
||
//
|
||
Iterator<Interface> intf_it = InterfaceVektor.iterator();
|
||
while (intf_it.hasNext()) {
|
||
Interface intf = intf_it.next();
|
||
|
||
// HOTI In diesem Moment gibt es nur _eine_ potentielle CTypeReconstructionResult, d.h.
|
||
// dort können die Definitionen der Interfaces (Methodintersectiontypes, FieldDecls) abgelegt werden
|
||
|
||
|
||
//intf.addThisToAssumptions(basics);
|
||
}
|
||
|
||
// Fuer jede Klasse die Assumptions der öffentlichen Felder zusammentragen:
|
||
TypeAssumptions publicFieldsAssumptions = new TypeAssumptions();
|
||
for(Class cl : KlassenVektor){
|
||
publicFieldsAssumptions.add(cl.getPublicFieldAssumptions());
|
||
}
|
||
|
||
// Die BasicAssumptions anfügen:
|
||
publicFieldsAssumptions.add(this.getBasicAssumptions());
|
||
|
||
// Fuer jede Klasse separat den TRA aufrufen
|
||
Iterator<Class> class_it = KlassenVektor.iterator();
|
||
while (class_it.hasNext()) {
|
||
Class cl = class_it.next();
|
||
CSupportData supportData = new CSupportData(finiteClosure, A, cl.getName(), cl.get_ParaList());
|
||
inferencelog.info("Rufe " + cl.getName() + ".TRProg()...");
|
||
A.addAll(cl.typeReconstruction(supportData, publicFieldsAssumptions));
|
||
}
|
||
|
||
return A;
|
||
*/
|
||
}
|
||
// ino.end
|
||
|
||
/**
|
||
* Erstellt die Basic Assumptions (siehe MakeBasicAssumptions) als AssumptionSet
|
||
* @return
|
||
|
||
@Deprecated //angefügt von Andreas Stadelmeier. Grund: Die Funktion wurde neu als makeBasicAssumptionsFromJRE angelegt
|
||
private TypeAssumptions getBasicAssumptions() {
|
||
TypeAssumptions ret = new TypeAssumptions(null);
|
||
|
||
// AB hier der Teil aus makeBasicAssumptionsFromJRE:
|
||
Menge<UsedId> doneImports=new Menge<UsedId>();
|
||
|
||
//CTypeReconstructionResult basicAssumptions = new CTypeReconstructionResult(null);
|
||
|
||
Modifiers mod = new Modifiers();
|
||
mod.addModifier(new Public());
|
||
|
||
|
||
// Für jede einzelne Klasse
|
||
while (imports.size()>0) {
|
||
UsedId importDecl = imports.get(0);
|
||
|
||
// Properties laden
|
||
java.lang.Class<?> x;
|
||
try {
|
||
x = java.lang.Class.forName(importDecl.getQualifiedName().toString());
|
||
} catch (ClassNotFoundException e) {
|
||
throw new CTypeReconstructionException("Fehlerhafte Import-Declaration: "+e.getMessage(),importDecl);
|
||
}
|
||
|
||
java.lang.reflect.Field[] fields=x.getDeclaredFields();
|
||
java.lang.reflect.Method[] methods=x.getDeclaredMethods();
|
||
java.lang.reflect.Constructor[] constructors=x.getConstructors();
|
||
java.lang.reflect.TypeVariable[] tvs=x.getTypeParameters();
|
||
//String className=x.getSimpleName();
|
||
String className=x.getName();
|
||
|
||
// Generische Typen erzeugen
|
||
|
||
|
||
Hashtable<String,GenericTypeVar> jreSpiderRegistry=new Hashtable<String,GenericTypeVar>();
|
||
Menge<GenericTypeVar> typeGenPara = new Menge<GenericTypeVar>();
|
||
for(int j=0;j<tvs.length;j++){
|
||
GenericTypeVar gtv=new GenericTypeVar(tvs[j].getName(),-1);
|
||
typeGenPara.addElement(gtv);
|
||
jreSpiderRegistry.put(tvs[j].getName(),gtv);
|
||
}
|
||
|
||
//BasicAssumptionClass myCl = new BasicAssumptionClass(className, mod);
|
||
|
||
if(typeGenPara.size()>0){
|
||
//basicAssumptions.addGenericTypeVars(className, typeGenPara);
|
||
//myCl.set_ParaList((Menge)typeGenPara);
|
||
}
|
||
|
||
|
||
if(x.getSuperclass()!=null){
|
||
//boolean isObject=x.getSuperclass().getSimpleName().equalsIgnoreCase("Object");
|
||
boolean isObject=x.getSuperclass().getName().equalsIgnoreCase("java.lang.Object");
|
||
boolean isBaseType=isBaseType(className);
|
||
|
||
//if((!isObject || READ_OBJECT_SUPERCLASSES_FROM_JRE) && (!isBaseType|| READ_BASE_TYPE_SUPERCLASSES_FROM_JRE))
|
||
if (((!isObject || READ_OBJECT_SUPERCLASSES_FROM_JRE) && READ_IMPORTED_SUPERCLASSES_FROM_JRE) //eingefuegt 07-08-11
|
||
|| (isBaseType && READ_BASE_TYPE_SUPERCLASSES_FROM_JRE))
|
||
{
|
||
String superclassFullyQualifiedName = x.getSuperclass().getCanonicalName();
|
||
//Andere Methode, da Menge.contains bei Strings nicht richtig vergleicht.
|
||
if(!containsString(imports,superclassFullyQualifiedName) && !containsString(doneImports,superclassFullyQualifiedName)){
|
||
imports.addElement(UsedId.createFromQualifiedName(superclassFullyQualifiedName,-1));
|
||
}
|
||
//UsedId ui = new UsedId();
|
||
//ui.set_Name(x.getSuperclass().getSimpleName());
|
||
UsedId ui=UsedId.createFromQualifiedName(x.getSuperclass().getName(),-1);
|
||
java.lang.Class superClass=x.getSuperclass();
|
||
java.lang.reflect.TypeVariable[] superclassTVS=superClass.getTypeParameters();
|
||
Menge<Type> supertypeGenPara = new Menge<Type>();
|
||
for(int tvi=0;tvi<superclassTVS.length;tvi++){
|
||
GenericTypeVar newGTV=new GenericTypeVar(superclassTVS[tvi].getName(),-1);
|
||
supertypeGenPara.addElement(newGTV);
|
||
}
|
||
|
||
if(supertypeGenPara.size()==0){
|
||
supertypeGenPara=null;
|
||
}
|
||
ui.set_ParaList(supertypeGenPara);
|
||
ui.vParaOrg=supertypeGenPara;
|
||
//myCl.set_UsedId(ui);
|
||
}
|
||
}
|
||
|
||
//this.addElement(myCl);
|
||
|
||
//basicAssumptions.addClassName(className);
|
||
|
||
for(int j=0;j<fields.length;j++){
|
||
if(java.lang.reflect.Modifier.isPublic(fields[j].getModifiers())){
|
||
//CInstVarTypeAssumption instVar = new CInstVarTypeAssumption(className, fields[j].getName(), new RefType(fields[j].getType().getSimpleName()), MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>());
|
||
CInstVarTypeAssumption instVar = new CInstVarTypeAssumption(className, fields[j].getName(), new RefType(fields[j].getType().getName(),-1), MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>());
|
||
//basicAssumptions.addFieldOrLocalVarAssumption(instVar);
|
||
//ret.add(instVar); //auskommentiert von Andreas Stadelmeier
|
||
}
|
||
}
|
||
for(int j=0;j<methods.length;j++){
|
||
if(java.lang.reflect.Modifier.isPublic(methods[j].getModifiers())){
|
||
String methodName=methods[j].getName();
|
||
java.lang.reflect.Type genericReturnType=methods[j].getGenericReturnType();
|
||
Type returnType=createTypeFromJavaGenericType(genericReturnType,methods[j].getReturnType(),jreSpiderRegistry);
|
||
|
||
java.lang.reflect.Type[] gpt=methods[j].getGenericParameterTypes();
|
||
java.lang.Class[] pt=methods[j].getParameterTypes();
|
||
|
||
CMethodTypeAssumption method = new CMethodTypeAssumption(new RefType(className, 0), methodName, returnType, pt.length,MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
|
||
|
||
for(int k=0;k<gpt.length;k++){
|
||
Type type=createTypeFromJavaGenericType(gpt[k],pt[k],jreSpiderRegistry);
|
||
// Fixme HOTI beachte overloaded id
|
||
method.addParaAssumption(new CParaTypeAssumption(className, methodName, pt.length,0,type.getName().toString(), type, MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>()));
|
||
}
|
||
//basicAssumptions.addMethodIntersectionType(new CIntersectionType(method));
|
||
//ret.add(method); //auskommentiert von Andreas Stadelmeier
|
||
}
|
||
}
|
||
|
||
for(int j=0;j<constructors.length;j++){
|
||
if(java.lang.reflect.Modifier.isPublic(constructors[j].getModifiers())){
|
||
String methodName="<init>";
|
||
CMethodTypeAssumption constructor = new CMethodTypeAssumption(new RefType(className, 0), methodName, new RefType(className,-1), constructors[j].getParameterTypes().length,MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
for(int k=0;k<constructors[j].getParameterTypes().length;k++){
|
||
String paraType=constructors[j].getParameterTypes()[k].getName();
|
||
//String paraType=constructors[j].getParameterTypes()[k].getSimpleName();
|
||
// Fixme HOTI beachte overloaded id
|
||
constructor.addParaAssumption(new CParaTypeAssumption(className, methodName, constructors[j].getParameterTypes().length,0,paraType, new RefType(paraType,-1), MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>()));
|
||
}
|
||
//basicAssumptions.addMethodIntersectionType(new CIntersectionType(constructor));
|
||
//ret.add(constructor); //auskommentiert von Andreas Stadelmeier
|
||
}
|
||
}
|
||
|
||
imports.removeElement(importDecl);
|
||
doneImports.addElement(importDecl);
|
||
|
||
}
|
||
|
||
imports.addAll(doneImports);
|
||
|
||
return ret;
|
||
}*/
|
||
|
||
/**
|
||
* Erstellt die Assumptions der standardmäÃig importierten Packages (java.lang.) sowie der von imports übergebenen Klassen zusammen.
|
||
* @param imports
|
||
* @param withSuptypes - Gibt an, ob auch die subklassen der Packages den Assumptions angefügt werden sollen.
|
||
* @return
|
||
*/
|
||
private TypeAssumptions makeBasicAssumptionsFromJRE(Menge<UsedId> imports, boolean withSubtypes)
|
||
// ino.end
|
||
// ino.method.makeBasicAssumptionsFromJRE.21409.body
|
||
{
|
||
//return null;
|
||
///*
|
||
Menge<UsedId> doneImports=new Menge<UsedId>();
|
||
|
||
//TypeinferenceResultSet basicAssumptions = new TypeinferenceResultSet(null);
|
||
TypeAssumptions basicAssumptions = new TypeAssumptions();
|
||
|
||
Modifiers mod = new Modifiers();
|
||
mod.addModifier(new Public());
|
||
|
||
//Für Object:
|
||
imports.add(new UsedId("java.lang.Object",-1));
|
||
|
||
// Für jede einzelne Klasse
|
||
while (imports.size()>0) {
|
||
UsedId importDecl = imports.get(0);
|
||
|
||
// Properties laden
|
||
java.lang.Class<?> x;
|
||
try {
|
||
x = java.lang.Class.forName(importDecl.getQualifiedName().toString());
|
||
} catch (ClassNotFoundException e) {
|
||
throw new CTypeReconstructionException("Fehlerhafte Import-Declaration: "+e.getMessage(),importDecl);
|
||
}
|
||
|
||
java.lang.reflect.Field[] fields=x.getDeclaredFields();
|
||
java.lang.reflect.Method[] methods=x.getDeclaredMethods();
|
||
java.lang.reflect.Constructor[] constructors=x.getConstructors();
|
||
java.lang.reflect.TypeVariable[] tvs=x.getTypeParameters();
|
||
//String className=x.getSimpleName();
|
||
String className=x.getName();
|
||
|
||
//Ermittle die Superklasse:
|
||
Class sClass = new Class("Object",0);
|
||
if(withSubtypes)sClass = getSuperClassOfJREClass(x, basicAssumptions);
|
||
|
||
// Namen von Generische Typen erzeugen
|
||
Hashtable<String,GenericTypeVar> jreSpiderRegistry=new Hashtable<String,GenericTypeVar>();
|
||
Menge<String> typeGenPara = new Menge<String>();
|
||
for(int j=0;j<tvs.length;j++){
|
||
//GenericTypeVar gtv=new GenericTypeVar(tvs[j].getName(), parentClass,-1);
|
||
typeGenPara.addElement(tvs[j].getName());
|
||
//jreSpiderRegistry.put(tvs[j].getName(),gtv);
|
||
}
|
||
|
||
Class parentClass = new Class(className, sClass.getType(),mod, typeGenPara);
|
||
|
||
//BasicAssumptionClass myCl = new BasicAssumptionClass(className, mod);
|
||
|
||
for(GenericTypeVar classParam : parentClass.getGenericParameter()){
|
||
jreSpiderRegistry.put(classParam.getName().toString(),classParam);
|
||
}
|
||
|
||
if(typeGenPara.size()>0){
|
||
//auskommentiert von Andreas Stadelmeier:
|
||
//basicAssumptions.addGenericTypeVars(className, typeGenPara);
|
||
//parentClass.set_ParaList((Menge)typeGenPara);//myCl.set_ParaList((Menge)typeGenPara);
|
||
}
|
||
|
||
|
||
if(x.getSuperclass()!=null){
|
||
//boolean isObject=x.getSuperclass().getSimpleName().equalsIgnoreCase("Object");
|
||
boolean isObject=x.getSuperclass().getName().equalsIgnoreCase("java.lang.Object");
|
||
boolean isBaseType=isBaseType(className);
|
||
|
||
//if((!isObject || READ_OBJECT_SUPERCLASSES_FROM_JRE) && (!isBaseType|| READ_BASE_TYPE_SUPERCLASSES_FROM_JRE))
|
||
if (((!isObject || READ_OBJECT_SUPERCLASSES_FROM_JRE) && READ_IMPORTED_SUPERCLASSES_FROM_JRE) //eingefuegt 07-08-11
|
||
|| (isBaseType && READ_BASE_TYPE_SUPERCLASSES_FROM_JRE))
|
||
{
|
||
String superclassFullyQualifiedName = x.getSuperclass().getCanonicalName();
|
||
//Andere Methode, da Menge.contains bei Strings nicht richtig vergleicht.
|
||
if(!containsString(imports,superclassFullyQualifiedName) && !containsString(doneImports,superclassFullyQualifiedName)){
|
||
imports.addElement(UsedId.createFromQualifiedName(superclassFullyQualifiedName,-1));
|
||
}
|
||
//UsedId ui = new UsedId();
|
||
//ui.set_Name(x.getSuperclass().getSimpleName());
|
||
UsedId ui=UsedId.createFromQualifiedName(x.getSuperclass().getName(),-1);
|
||
java.lang.Class superClass=x.getSuperclass();
|
||
java.lang.reflect.TypeVariable[] superclassTVS=superClass.getTypeParameters();
|
||
Menge<Type> supertypeGenPara = new Menge<Type>();
|
||
for(int tvi=0;tvi<superclassTVS.length;tvi++){
|
||
GenericTypeVar newGTV=new GenericTypeVar(superclassTVS[tvi].getName(),parentClass,-1);
|
||
supertypeGenPara.addElement(newGTV);
|
||
}
|
||
|
||
if(supertypeGenPara.size()==0){
|
||
supertypeGenPara=null;
|
||
}
|
||
ui.set_ParaList(supertypeGenPara);
|
||
ui.vParaOrg=supertypeGenPara;
|
||
parentClass.set_UsedId(ui);
|
||
}
|
||
}
|
||
|
||
//auskommentiert von Andreas Stadelmeier
|
||
//this.addElement(myCl);
|
||
//basicAssumptions.addClassName(className);
|
||
|
||
for(int j=0;j<fields.length;j++){
|
||
if(java.lang.reflect.Modifier.isPublic(fields[j].getModifiers())){
|
||
parentClass.addField(new FieldDeclaration(fields[j].getName(),new RefType(fields[j].getType().getName(),parentClass,-1)));
|
||
}
|
||
}
|
||
for(int j=0;j<methods.length;j++){
|
||
if(java.lang.reflect.Modifier.isPublic(methods[j].getModifiers())){
|
||
String methodName=methods[j].getName();
|
||
//if(methodName.equals("add")){
|
||
|
||
java.lang.reflect.Type genericReturnType=methods[j].getGenericReturnType();
|
||
Type returnType=createTypeFromJavaGenericType(genericReturnType,methods[j].getReturnType(),jreSpiderRegistry, parentClass);
|
||
|
||
java.lang.reflect.Type[] gpt=methods[j].getGenericParameterTypes();
|
||
java.lang.Class[] pt=methods[j].getParameterTypes();
|
||
|
||
//CMethodTypeAssumption method = new CMethodTypeAssumption(new RefType(className, 0), methodName, returnType, pt.length,MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
Method method = de.dhbwstuttgart.syntaxtree.Method.createEmptyMethod(methodName, parentClass);
|
||
method.setType(returnType);
|
||
ParameterList parameterList = new ParameterList();
|
||
|
||
for(int k=0;k<gpt.length;k++){
|
||
Type type=createTypeFromJavaGenericType(gpt[k],pt[k],jreSpiderRegistry, parentClass);
|
||
// Fixme HOTI beachte overloaded id
|
||
//method.addParaAssumption(new CParaTypeAssumption(className, methodName, pt.length,0,type.getName(), type, MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>()));
|
||
FormalParameter parameter = new FormalParameter(new DeclId(type.get_Name()));
|
||
parameter.setType(type);
|
||
parameterList.formalparameter.add(parameter);
|
||
}
|
||
method.setParameterList(parameterList);
|
||
//basicAssumptions.addMethodIntersectionType(new CIntersectionType(method));
|
||
|
||
parentClass.addField(method);
|
||
|
||
//}
|
||
}
|
||
}
|
||
|
||
for(int j=0;j<constructors.length;j++){
|
||
String methodName=className;
|
||
Method constructorMethod = de.dhbwstuttgart.syntaxtree.Method.createEmptyMethod(methodName, parentClass);
|
||
|
||
if(java.lang.reflect.Modifier.isPublic(constructors[j].getModifiers())){
|
||
ParameterList paraList = new ParameterList();
|
||
for(int k=0;k<constructors[j].getParameterTypes().length;k++){
|
||
String paraType=constructors[j].getParameterTypes()[k].getName();
|
||
//String paraType=constructors[j].getParameterTypes()[k].getSimpleName();
|
||
// Fixme HOTI beachte overloaded id
|
||
FormalParameter fpara = new FormalParameter(new DeclId("p"+k));
|
||
fpara.setType(new RefType(paraType,constructorMethod,-1));
|
||
paraList.formalparameter.add(fpara);
|
||
}
|
||
//basicAssumptions.addMethodIntersectionType(new CIntersectionType(constructor));
|
||
constructorMethod.parameterlist = paraList;
|
||
Constructor constructor = new Constructor(constructorMethod);
|
||
constructor.parserPostProcessing(parentClass);
|
||
parentClass.addField(constructor);
|
||
}
|
||
}
|
||
|
||
basicAssumptions.add(parentClass.getPublicFieldAssumptions());
|
||
basicAssumptions.addClassAssumption(new ClassAssumption(parentClass));
|
||
imports.removeElement(importDecl);
|
||
doneImports.addElement(importDecl);
|
||
}
|
||
imports.addAll(doneImports);
|
||
return basicAssumptions;
|
||
//*/
|
||
}
|
||
// ino.end
|
||
|
||
private Class getSuperClassOfJREClass(java.lang.Class<?> x, TypeAssumptions ass) {
|
||
Class ret;
|
||
java.lang.Class s = x.getSuperclass();
|
||
if(s == null){
|
||
return new Class("java.lang.Object",new Modifiers(), 0);
|
||
}
|
||
|
||
Menge<String> supertypeGenPara = new Menge<>();//Die Generischen Parameter für die Superklasse berechnen:
|
||
java.lang.reflect.TypeVariable[] superclassTVS=s.getTypeParameters();
|
||
for(int tvi=0;tvi<superclassTVS.length;tvi++){
|
||
supertypeGenPara.addElement(superclassTVS[tvi].getName());
|
||
}
|
||
|
||
Class ss = this.getSuperClassOfJREClass(s, ass);
|
||
ret = new Class(s.getName(),ss.getType(),new Modifiers(),supertypeGenPara);
|
||
|
||
|
||
ass.addClassAssumption(new ClassAssumption(ss)); //Die beiden SuperKlassen den Assumptions anfügen...
|
||
ass.addClassAssumption(new ClassAssumption(ret));
|
||
|
||
return ret;
|
||
}
|
||
|
||
// ino.method.isBaseType.21412.definition
|
||
private boolean isBaseType(String type)
|
||
// ino.end
|
||
// ino.method.isBaseType.21412.body
|
||
{
|
||
return baseTypeTranslationTable.containsValue(type);
|
||
}
|
||
// ino.end
|
||
|
||
/*Die contains Methode des Menges vergleicht bei Strings nicht korrekt,
|
||
* da zwei Strings mit dem gleichen Inhalt unterschiedliche Instanzen sind.
|
||
* Deshalb diese Methode 07-01-20 luar*/
|
||
private boolean containsString(Menge<UsedId> searchMenge, String searchString)
|
||
{
|
||
boolean found = false;
|
||
for(UsedId id : searchMenge)
|
||
{
|
||
String s = id.getQualifiedName().toString();
|
||
found |= s.equals(searchString);
|
||
}
|
||
return found;
|
||
}
|
||
|
||
|
||
// ino.method.createTypeFromJavaGenericType.21415.definition
|
||
private Type createTypeFromJavaGenericType(java.lang.reflect.Type type, java.lang.Class<?> cl, Hashtable<String,GenericTypeVar>jreSpiderRegistry, Class parentClass)
|
||
// ino.end
|
||
// ino.method.createTypeFromJavaGenericType.21415.body
|
||
{
|
||
/* auskommentiert, da die Klassen von Sun in der Open JDK 1.8 nicht unterstützt werden.
|
||
if(type instanceof TypeVariableImpl){
|
||
TypeVariableImpl tvi=((TypeVariableImpl)type);
|
||
return(new GenericTypeVar(jreSpiderRegistry.get(tvi.getName()).getName().toString(),parentClass,-1));
|
||
}else{
|
||
*/
|
||
GenericTypeVar gtv = jreSpiderRegistry.get(type.getTypeName());
|
||
if(gtv != null)return gtv;
|
||
//new GenericTypeVar(jreSpiderRegistry.get(type.getTypeName()).getName().toString(),parentClass,-1));
|
||
//String jccNameForClass=baseTypeTranslationTable.get(cl.getSimpleName());
|
||
String jccNameForClass=baseTypeTranslationTable.get(cl.getName());
|
||
if(cl.getSimpleName().equalsIgnoreCase("void")){
|
||
return(new Void(parentClass,-1));
|
||
}else if(jccNameForClass!=null){
|
||
RefType rt=new RefType(jccNameForClass,parentClass,-1);
|
||
rt.setPrimitiveFlag(true);
|
||
return(rt);
|
||
}else{
|
||
//return(new RefType(cl.getSimpleName()));
|
||
return(new RefType(cl.getName(),parentClass,-1));
|
||
}
|
||
//}
|
||
}
|
||
// ino.end
|
||
|
||
|
||
// ino.method.makeBasicAssumptions.21418.defdescription type=javadoc
|
||
/**
|
||
* Erzeugt die Anfangsinformationen �ber bereits bekannte Klassen.
|
||
* <br/>Achtung Workaround: Die RefTypes m�ssen sp�ter noch durch BaseTypes
|
||
* ersetzt werden. <br>
|
||
* Author: J�rg B�uerle
|
||
*
|
||
* @return A priori Typinformationen
|
||
* @throws ClassNotFoundException
|
||
*/
|
||
// ino.end
|
||
// ino.method.makeBasicAssumptions.21418.definition
|
||
private TypeAssumptions makeBasicAssumptions()
|
||
// ino.end
|
||
// ino.method.makeBasicAssumptions.21418.body
|
||
{
|
||
/*
|
||
if(LOAD_BASIC_ASSUMPTIONS_FROM_JRE){
|
||
|
||
Menge<UsedId> strImports=new Menge<UsedId>();
|
||
ImportDeclarations usedIdImports=getImports();
|
||
for(int i=0;i<usedIdImports.size();i++){
|
||
UsedId uid=usedIdImports.get(i);
|
||
if(uid.hasWildCard()){
|
||
throw new CTypeReconstructionException("Wildcards in den Imports werden bislang nicht unterstuetzt: "+uid.getQualifiedName(),uid);
|
||
|
||
//throw new ClassNotFoundException("Bei den Imports sind momentan keine Wildcards erlaubt!");
|
||
}else{
|
||
strImports.addElement(uid);
|
||
}
|
||
}
|
||
TypeinferenceResultSet res=makeBasicAssumptionsFromJRE(strImports);
|
||
|
||
ImportDeclarations newImports=new ImportDeclarations();
|
||
for(int i=0;i<strImports.size();i++){
|
||
newImports.addElement(strImports.get(i));
|
||
}
|
||
setImports(newImports);
|
||
|
||
return(res);
|
||
}
|
||
|
||
|
||
TypeinferenceResultSet foo = new TypeinferenceResultSet(null);
|
||
CMethodTypeAssumption meth = null;
|
||
CInstVarTypeAssumption instVar = null;
|
||
Class c = null;
|
||
UsedId ui = null;
|
||
//Menge pl = null;
|
||
|
||
Modifiers mod = new Modifiers();
|
||
mod.addModifier(new Public());
|
||
|
||
//------------------------
|
||
// Integer bauen:
|
||
//------------------------
|
||
foo.addClassName("java.lang.Integer"); //PL 05-08-01 eingefuegt
|
||
instVar = new CInstVarTypeAssumption("java.lang.Integer", "MAX_VALUE", new RefType("java.lang.Integer",-1), MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>());
|
||
foo.addFieldOrLocalVarAssumption(instVar);
|
||
|
||
meth = new CMethodTypeAssumption(new RefType("java.lang.Integer", 0), "<init>", new RefType("java.lang.Integer",-1), 0,MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
foo.addMethodIntersectionType(new CIntersectionType(meth));
|
||
|
||
meth = new CMethodTypeAssumption(new RefType("java.lang.Integer", 0), "<init>", new RefType("java.lang.Integer",-1),1, MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
meth.addParaAssumption(new CParaTypeAssumption("java.lang.Integer", "<init>", 1, 0,"value", new RefType("java.lang.Integer",-1), MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>()));
|
||
foo.addMethodIntersectionType(new CIntersectionType(meth));
|
||
|
||
meth = new CMethodTypeAssumption(new RefType("java.lang.Integer", 0), "intValue", new RefType("java.lang.Integer",-1), 0,MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
foo.addMethodIntersectionType(new CIntersectionType(meth));
|
||
|
||
|
||
|
||
c = new BasicAssumptionClass("java.lang.Integer", mod);
|
||
|
||
// ui = new UsedId();
|
||
// ui.set_Name("Super-Class-Blub");
|
||
// c.set_UsedId(ui);
|
||
// pl = new Menge();
|
||
// pl.addElement(new GenericTypeVar("bla"));
|
||
// c.set_ParaList(pl);
|
||
this.addElement(c);
|
||
|
||
//------------------------
|
||
// Boolean bauen:
|
||
//------------------------
|
||
foo.addClassName("java.lang.Boolean"); //PL 05-08-01 eingefuegt
|
||
meth = new CMethodTypeAssumption(new RefType("java.lang.Boolean", 0), "<init>", new RefType("java.lang.Boolean",-1),0, MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
foo.addMethodIntersectionType(new CIntersectionType(meth));
|
||
|
||
meth = new CMethodTypeAssumption(new RefType("java.lang.Boolean", 0), "<init>", new RefType("java.lang.Boolean",-1), 1,MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
meth.addParaAssumption(new CParaTypeAssumption("java.lang.Boolean", "<init>", 1, 0, "value", new RefType("java.lang.Boolean",-1), MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>()));
|
||
foo.addMethodIntersectionType(new CIntersectionType(meth));
|
||
|
||
meth = new CMethodTypeAssumption(new RefType("java.lang.Boolean", 0), "booleanValue", new RefType("java.lang.Boolean",-1), 0,MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
foo.addMethodIntersectionType(new CIntersectionType(meth));
|
||
|
||
c = new BasicAssumptionClass("java.lang.Boolean", mod);
|
||
|
||
// ui = new UsedId();
|
||
// ui.set_Name("Super-Class-Blub");
|
||
// c.set_UsedId(ui);
|
||
// pl = new Menge();
|
||
// pl.addElement(new GenericTypeVar("bla"));
|
||
// c.set_ParaList(pl);
|
||
this.addElement(c);
|
||
|
||
//------------------------
|
||
// Character bauen:
|
||
//------------------------
|
||
foo.addClassName("java.lang.Character"); //PL 05-08-01 eingefuegt
|
||
meth = new CMethodTypeAssumption(new RefType("java.lang.Character", 0), "<init>", new RefType("java.lang.Character",-1),0, MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
foo.addMethodIntersectionType(new CIntersectionType(meth));
|
||
|
||
meth = new CMethodTypeAssumption(new RefType("java.lang.Character", 0), "<init>", new RefType("java.lang.Character",-1),1, MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
meth.addParaAssumption(new CParaTypeAssumption("java.lang.Character", "<init>", 1, 0,"value", new RefType("java.lang.Character",-1), MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>()));
|
||
foo.addMethodIntersectionType(new CIntersectionType(meth));
|
||
|
||
meth = new CMethodTypeAssumption(new RefType("java.lang.Character", 0), "charValue", new BooleanType(),0, MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
foo.addMethodIntersectionType(new CIntersectionType(meth));
|
||
|
||
c = new BasicAssumptionClass("java.lang.Character", mod);
|
||
|
||
// ui = new UsedId();
|
||
// ui.set_Name("Super-Class-Blub");
|
||
// c.set_UsedId(ui);
|
||
// pl = new Menge();
|
||
// pl.addElement(new GenericTypeVar("bla"));
|
||
// c.set_ParaList(pl);
|
||
this.addElement(c);
|
||
|
||
//------------------------
|
||
// Menge bauen:
|
||
//------------------------
|
||
foo.addClassName("java.lang.Menge"); //PL 05-08-01 eingefuegt
|
||
TypePlaceholder E = TypePlaceholder.fresh(); // Sp�ter ersetzen durch GenericTypeVar
|
||
Menge<GenericTypeVar> typeGenPara = new Menge<GenericTypeVar>();
|
||
typeGenPara.addElement(new GenericTypeVar(E.getName(),-1));
|
||
foo.addGenericTypeVars("java.lang.Menge", typeGenPara);
|
||
meth = new CMethodTypeAssumption(new RefType("java.lang.Menge", 0), "elementAt", new GenericTypeVar(E.getName(),-1), 1,MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
meth.addParaAssumption(new CParaTypeAssumption("java.lang.Menge", "elementAt", 1, 0, "index", new RefType("java.lang.Integer",-1), MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>()));
|
||
foo.addMethodIntersectionType(new CIntersectionType(meth));
|
||
|
||
meth = new CMethodTypeAssumption(new RefType("java.lang.Menge", 0), "addElement", new Void(-1),1, MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
meth.addParaAssumption(new CParaTypeAssumption("java.lang.Menge", "addElement", 1, 0,"element", new GenericTypeVar(E.getName(),-1), MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>()));
|
||
foo.addMethodIntersectionType(new CIntersectionType(meth));
|
||
|
||
meth = new CMethodTypeAssumption(new RefType("java.lang.Menge", 0), "size", new RefType("java.lang.Integer",-1), 0,MyCompiler.NO_LINENUMBER,MyCompiler.NO_LINENUMBER,new Menge<Integer>(),null);
|
||
foo.addMethodIntersectionType(new CIntersectionType(meth));
|
||
|
||
c = new BasicAssumptionClass("java.lang.Menge", mod);
|
||
|
||
// ui = new UsedId();
|
||
// ui.set_Name("Super-Class-Blub");
|
||
// c.set_UsedId(ui);
|
||
// pl = new Menge();
|
||
// pl.addElement(E);
|
||
// c.set_ParaList(pl);
|
||
this.addElement(c);
|
||
|
||
//------------------------
|
||
// Stack bauen:
|
||
//------------------------
|
||
foo.addClassName("java.lang.Stack"); //PL 05-08-01 eingefuegt
|
||
c = new BasicAssumptionClass("java.lang.Stack", mod);
|
||
ui = new UsedId(-1);
|
||
ui.set_Name("java.lang.Menge");
|
||
c.set_UsedId(ui);
|
||
// pl = new Menge();
|
||
// pl.addElement(E);
|
||
// c.set_ParaList(pl);
|
||
this.addElement(c);
|
||
|
||
return foo;
|
||
*/
|
||
TypeAssumptions ret = new TypeAssumptions();
|
||
|
||
//Basic Assumptions für die FunN Interfaces:
|
||
//TODO: Hier mehr als Fun1-Fun5 implementieren
|
||
for(int i = 0; i<6; i++){
|
||
FunNInterface funN = new FunNInterface(i);
|
||
ret.add(funN.getPublicFieldAssumptions());
|
||
}
|
||
|
||
|
||
return ret; //TODO: Diese TypeAssumptions mit basic-Assumptions füllen
|
||
}
|
||
// ino.end
|
||
|
||
// ino.method.setImports.21421.definition
|
||
private void setImports(ImportDeclarations newImports)
|
||
// ino.end
|
||
// ino.method.setImports.21421.body
|
||
{
|
||
this.imports=newImports;
|
||
|
||
}
|
||
// ino.end
|
||
|
||
|
||
// ino.method.removeBasicAssumptions.21424.defdescription type=javadoc
|
||
/**
|
||
* L�scht die Anfangsinformation wieder aus dem Klassenvektor
|
||
* <br/>Author: J�rg B�uerle
|
||
*/
|
||
// ino.end
|
||
// ino.method.removeBasicAssumptions.21424.definition
|
||
private void removeBasicAssumptions()
|
||
// ino.end
|
||
// ino.method.removeBasicAssumptions.21424.body
|
||
{
|
||
for(int i=0; i<KlassenVektor.size(); i++){
|
||
Class cl = KlassenVektor.elementAt(i);
|
||
if(cl instanceof BasicAssumptionClass){
|
||
KlassenVektor.removeElementAt(i);
|
||
i--;
|
||
}
|
||
}
|
||
}
|
||
// ino.end
|
||
|
||
// ino.method.getPackageName.21427.defdescription type=javadoc
|
||
/**
|
||
* Erzeugt f�r jede Klasse einen Menge, in den Referenzen auf die GenericTypeVars
|
||
* dieser Klasse gespeichert werden. Diese Mengeen werden unter den Klassennamen
|
||
* in der
|
||
* Ergebnisdatenstruktur abgelegt. Au�erdem werden alle Klassennamen gespeichert.
|
||
* <br/>Author: J�rg B�uerle
|
||
* @param res
|
||
* /
|
||
* /*private void addClassNamesAndGenericsToRR(CTypeReconstructionResult res){
|
||
* Iterator<Class> it = this.getClassIterator();
|
||
* while(it.hasNext()){
|
||
* Class cl = it.next();
|
||
* res.addClassName(cl.get_classname());
|
||
* Menge<GenericTypeVar> genericsList = new Menge<GenericTypeVar>();
|
||
*
|
||
* for(int i =0; i<cl.get_ParaList().size(); i++){
|
||
* Type para = (Type)cl.get_ParaList().elementAt(i);
|
||
* if(para instanceof GenericTypeVar){
|
||
* genericsList.addElement((GenericTypeVar)para);
|
||
* }
|
||
* }
|
||
* res.addGenericTypeVars(cl.get_classname(), genericsList);
|
||
* }
|
||
* }
|
||
*/
|
||
// ino.end
|
||
|
||
// ino.method.getPackageName.21427.definition
|
||
public UsedId getPackageName()
|
||
// ino.end
|
||
// ino.method.getPackageName.21427.body
|
||
{
|
||
return pkgName;
|
||
}
|
||
// ino.end
|
||
|
||
// ino.method.setPackageName.21430.definition
|
||
public void setPackageName(UsedId pkgName)
|
||
// ino.end
|
||
// ino.method.setPackageName.21430.body
|
||
{
|
||
this.pkgName = pkgName;
|
||
|
||
// Die Package-Namen fuer alle Klassen und Interfaces
|
||
// im Source-File nachziehen
|
||
for (int i=0; i<KlassenVektor.size(); i++) {
|
||
KlassenVektor.elementAt(i).setPackageName(pkgName);
|
||
}
|
||
|
||
}
|
||
// ino.end
|
||
|
||
// ino.method.addImports.21433.definition
|
||
public void addImports(ImportDeclarations imports)
|
||
// ino.end
|
||
// ino.method.addImports.21433.body
|
||
{
|
||
this.imports.addAll(imports);
|
||
}
|
||
// ino.end
|
||
// ino.method.getImports.21436.definition
|
||
public ImportDeclarations getImports()
|
||
// ino.end
|
||
// ino.method.getImports.21436.body
|
||
{
|
||
if(imports==null){
|
||
return(new ImportDeclarations());
|
||
}
|
||
return(imports);
|
||
}
|
||
// ino.end
|
||
|
||
|
||
// ino.method.getClassIterator.21439.definition
|
||
public Iterator<Class> getClassIterator()
|
||
// ino.end
|
||
// ino.method.getClassIterator.21439.body
|
||
{
|
||
return KlassenVektor.iterator();
|
||
}
|
||
// ino.end
|
||
|
||
// ino.method.getInterfaceIterator.21442.definition
|
||
public Iterator<Interface> getInterfaceIterator()
|
||
// ino.end
|
||
// ino.method.getInterfaceIterator.21442.body
|
||
{
|
||
return InterfaceVektor.iterator();
|
||
}
|
||
// ino.end
|
||
|
||
|
||
@Override
|
||
public void parserPostProcessing(SyntaxTreeNode parent) {
|
||
if(parent!=null)throw new DebugException("Eine SourceFile hat kein Elternelement im Syntaxbaum");
|
||
super.parserPostProcessing(parent);
|
||
//for(SyntaxTreeNode node : this.getChildren())node.parserPostProcessing(this);
|
||
}
|
||
|
||
|
||
@Override
|
||
public SyntaxTreeNode getParent() {
|
||
return null;
|
||
}
|
||
|
||
|
||
@Override
|
||
public Menge<SyntaxTreeNode> getChildren() {
|
||
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
|
||
for(Class cl : this.KlassenVektor){
|
||
ret.add(cl);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
/**
|
||
* SourceFile stellt eine geparste Java-Datei dar. Mit dieser Methode wird der Name der eingelesenen Datei gesetzt.
|
||
* @param filename - Der Name der eingelesenen JavaDatei
|
||
*/
|
||
@Deprecated
|
||
public void setFileName(String filename) {
|
||
//this.filename = filename;
|
||
}
|
||
|
||
|
||
|
||
@Override
|
||
public int getOffset() {
|
||
// TODO Auto-generated method stub
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
@Override
|
||
public int getVariableLength() {
|
||
// TODO Auto-generated method stub
|
||
return 0;
|
||
}
|
||
|
||
}
|
||
// ino.end
|