JavaPatternMatching/src/de/dhbwstuttgart/syntaxtree/SourceFile.java
2016-04-12 10:06:58 +02:00

1039 lines
46 KiB
Java
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ino.module.SourceFile.8722.package
package de.dhbwstuttgart.syntaxtree;
// ino.end
// ino.module.SourceFile.8722.import
import java.io.IOException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Function;
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.factory.UnifyTypeFactory;
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.FunN;
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.ByteCodeResult;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.FunNInterface;
import de.dhbwstuttgart.typeinference.FunNMethod;
import de.dhbwstuttgart.typeinference.KomplexeMenge;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResults;
import de.dhbwstuttgart.typeinference.UndConstraint;
import de.dhbwstuttgart.typeinference.UnifyConstraintsSet;
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.Unify;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
public class SourceFile
extends SyntaxTreeNode
{
// 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;
}
/**
* HOTI 4.5.06
* Beinhaltet alle Imports des aktuell geparsten Files
* in Form einer UsedId
*/
private ImportDeclarations imports=new ImportDeclarations();
/**
* 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
*/
private Hashtable<String,String> baseTypeTranslationTable;
/**
* Fuegt ein neues Element (Interface oder Klasse) hinzu.
* @param c
*/
public void addElement(AClassOrInterface e)
{
if (e instanceof Class) {
KlassenVektor.addElement((Class) e);
} else if (e instanceof Interface) {
InterfaceVektor.addElement((Interface) e);
}
}
/////////////////////////////////////////////////////////////////////////
// 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:
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(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(globalAssumptions));
}
/*////////////////
* Paare in MPairs umwandeln
* (Wird zunächst mal weggelassen. Constraints werden erst beim Unifizieren umgewandelt
*/////////////////
//UnifyTypeFactory.convert(oderConstraints);
////////////////
//Typen in UnifyTypen umwandeln:
////////////////
UnifyConstraintsSet unifyConstraints = UnifyTypeFactory.convert(oderConstraints);
//Unmögliche ConstraintsSets aussortieren durch Unifizierung
Function<Menge<UnifyPair>,Menge<Menge<UnifyPair>>> unifier = (pairs)->{
Menge<Menge<UnifyPair>> retValue = new Menge<>();
Set<Set<UnifyPair>> unifiedPairs = new Unify().unify(pairs, finiteClosure);
return retValue;};
//oderConstraints.filterWrongConstraints(unifier);
//oderConstraints.unifyUndConstraints(unifier); //rausgeworfen für Tests (08.12.2015)
typinferenzLog.debug("Übriggebliebene Konstraints:\n"+oderConstraints+"\n", Section.TYPEINFERENCE);
typinferenzLog.debug("Übriggebliebene Konvertierte Konstraints:\n"+unifyConstraints+"\n", Section.TYPEINFERENCE);
////////////////
//Karthesisches Produkt bilden:
////////////////
Set<Set<UnifyPair>> xConstraints = unifyConstraints.cartesianProduct();
typinferenzLog.debug("Finite Closure: "+finiteClosure, Section.TYPEINFERENCE);
typinferenzLog.debug("Karthesisches Produkt der Constraints: "+xConstraints, Section.TYPEINFERENCE);
//finiteClosure.generateFullyNamedTypes(globalAssumptions);
//////////////////////////////
// Unifizierung der Constraints:
//////////////////////////////
boolean unifyFail = true;
for(Set<UnifyPair> constraints : xConstraints){
//Alle durch das Karthesische Produkt entstandenen Möglichkeiten durchgehen:
//Menge<Menge<Pair>> result = new Menge<Menge<Pair>>();
//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 = constraints.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<MPair>> streamconstraintsclone = indexeset.stream().map(x -> x.stream()
.map(i -> constraintsClone.elementAt(i))
.<Menge<MPair>>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
Set<Set<Set<MPair>>> vecunifyResult =
//streamconstraintsclone.map(x -> Unify.unify(x, finiteClosure)).collect(Menge::new, Menge::add, Menge::addAll);
//DEBUG-Variante
streamconstraintsclone.map(x ->
{ Set<Set<MPair>> z = new 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]]
Set<Set<Pair>> cardprodret_start = new Menge<>();
cardprodret_start.add(new Menge<Pair>());
//cart. Produkt mit Linkverschiebung
Set<Set<Pair>> unifyResult = vecunifyResult.stream().reduce(cardprodret_start, (x, y) -> {
Set<Set<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++){
Set<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;
});
*/
typinferenzLog.debug("\nUnifiziere Constraints:\n"+constraints, Section.TYPEINFERENCE);
Set<Set<UnifyPair>> unifyResult = new Unify().unify(constraints, finiteClosure);
Menge<Menge<Pair>> convertedResult = unifyResult.parallelStream().<Menge<Pair>>map((Set<UnifyPair> resultSet)->{
Menge<Pair> innerConvert = resultSet.stream().map((UnifyPair mp)->UnifyTypeFactory.convert(mp))
.collect(Menge<Pair>::new, Menge::add, Menge::addAll);
return innerConvert;
}).collect(Menge::new, Menge::add, Menge::addAll);
Menge<Pair> convertedConstraints = constraints.stream().map(
(UnifyPair mp)->{return UnifyTypeFactory.convert(mp);}
).collect(Menge<Pair>::new, Menge::add, Menge::addAll);
//Dann den Ergebnissen anfügen
typinferenzLog.debug("\nErgebnis der Unifizierung:\n"+unifyResult, Section.TYPEINFERENCE);
//result.addAll(convertedResult);
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 : convertedResult){
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, convertedConstraints, 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;
}
/**
* 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
*/
public 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, parentClass);
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(this);
//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;
}
/**
* Bisher wird nur der Bytecode der Klassen generiert. Nicht der Interfaces.
* @return
*/
public Menge<ByteCodeResult> generateBytecode(TypeinferenceResults results) {
Menge<ByteCodeResult> ret = new Menge<>();
for(Class cl : this.KlassenVektor){
ret.add(cl.genByteCode(results));
}
return ret;
}
}
// ino.end