Merge mit unify und bytecode

This commit is contained in:
JanUlrich 2015-10-23 15:14:18 +02:00
commit ca447fd44e
43 changed files with 1142 additions and 8004 deletions

16
notizen/stf/Notes Normal file
View File

@ -0,0 +1,16 @@
- Was sind / wofür brauch man TTO und Classes
- Unify löst auch zirkuläre Abhängigkeiten a <. b <. c <. a
- Tests dazu?
- Prüfung im Builder?
- Unterschied Wildcard und FreshWildcard, ExtendsWildcard und FreshExtendsWildcard etc...
- FreshWildcard = TPH für Wildcards?
- Warum ist result von unify = Menge<Menge<Pair>> und nicht Menge<Pair>
- Menge Equals überarbeiten (Momentan Reihenfolgensensitiv)
- Wie kommen die Mengen des Unify-Algorithmus zustande? Siehe test:
/*
* Test b <. a, a <. b
*/

View File

@ -1,6 +1,8 @@
package de.dhbwstuttgart.bytecode;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.bcel6.classfile.BootstrapMethod;
import org.apache.commons.bcel6.classfile.BootstrapMethods;
@ -30,8 +32,9 @@ public class ClassGenerator extends ClassGen{
private Menge<TypePlaceholder> usedTPHs = new Menge<>();
public ClassGenerator(String name, Type superClass, String string,
short accPublic, String[] strings, TypeinferenceResultSet resultSet) {
private Map<String, ClassGenerator> extraClasses = new HashMap<>();
public ClassGenerator(String name, Type superClass, String string, short accPublic, String[] strings, TypeinferenceResultSet resultSet) {
super(name,superClass.get_Name(),string,accPublic,strings, new DHBWConstantPoolGen());
this.tiResult = resultSet;
this.superClass = superClass;
@ -156,4 +159,12 @@ public class ClassGenerator extends ClassGen{
return ret;
}
public void addExtraClass(ClassGenerator cg){
extraClasses.put(cg.getClassName(), cg);
}
public Map<String, ClassGenerator> getExtraClasses() {
return extraClasses;
}
}

View File

@ -1,9 +1,6 @@
// ino.module.MyCompiler.8569.package
package de.dhbwstuttgart.core;
// ino.end
// ino.module.MyCompiler.8569.import
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
@ -48,67 +45,28 @@ import de.dhbwstuttgart.typeinference.exceptions.ParserError;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
// ino.class.MyCompiler.21258.declaration
public class MyCompiler implements MyCompilerAPI
// ino.end
// ino.class.MyCompiler.21258.body
{
// ino.attribute.NO_LINENUMBER.21262.decldescription type=line
public class MyCompiler implements MyCompilerAPI{
// PL: Der Zusammenhang zwischen paralist und vParaOrg muesste
// noch geklaert werden 05-01-07
// ino.end
// ino.attribute.NO_LINENUMBER.21262.declaration
public static final int NO_LINENUMBER = -1;
// ino.end
// ino.attribute.codegenlog.21265.decldescription type=line
// Logger
// ino.end
// ino.attribute.codegenlog.21265.declaration
//protected static Logger codegenlog = Logger.getLogger("codegen");
// ino.end
// ino.attribute.inferencelog.21268.declaration
protected static Logger inferencelog = Logger.getLogger(MyCompiler.class.getName());
// ino.end
// ino.attribute.parserlog.21271.declaration
//protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.attribute.OutputDir.21274.declaration
protected String OutputDir = "";
// ino.end
public Menge<Pair> testPair = null;
// ino.attribute.m_AbstractSyntaxTree.21280.decldescription type=javadoc
/**
* Der abstrake Syntaxbaum
* <br/>Autor: ¯Â¿Â½rg ¯Â¿Â½uerle
*/
// ino.end
// ino.attribute.m_AbstractSyntaxTree.21280.declaration
private Menge<SourceFile> m_AbstractSyntaxTree = new Menge<SourceFile>();
// ino.end
// ino.method.MyCompiler.21283.defdescription type=javadoc
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
* Der private Konstruktor. Es soll von au�en kein Compiler angelegt werden
* ¯Â¿Â½nnen, sondern nur eine API zur Verf�gung gestellt werden.
* @param logger Konfiguration ¼r Debug Ausgabe TODO
*/
// ino.end
// ino.method.MyCompiler.21283.definition
private MyCompiler()
// ino.end
// ino.method.MyCompiler.21283.body
{
private MyCompiler(){
this.init();
}
// ino.end
// ino.method.getAPI.21286.defdescription type=javadoc
/**
* Author: rg ¤uerle<br/>
* Stellt eine neue Instanz der CompilerAPI zur Verf�gung.
@ -116,116 +74,11 @@ public class MyCompiler implements MyCompilerAPI
* um eine Quellcode-Datei zu kompilieren.
* @return Die Compiler-API
*/
// ino.end
// ino.method.getAPI.21286.definition
public static MyCompilerAPI getAPI(LoggerConfiguration loggerConfig)
// ino.end
// ino.method.getAPI.21286.body
{
public static MyCompilerAPI getAPI(LoggerConfiguration loggerConfig){
Logger.setStandardConfiguration(loggerConfig);
return new MyCompiler();
}
// ino.end
public Menge<Pair> testPair = null;
// ino.method.wandleGeneric2RefType.21289.defdescription type=javadoc
/**
* Author: Thomas Ott<br/>
* Ersetzt in der Superklassenparameterliste einer Klasse, diejenigen
* <code>GenericTypeVars</code>, zu denen es eine Klasse gibt, die gleich hei�t.
* Beim Parsen werden ¯Â¿Â½mlich vom Jay nur GenericTypeVars erzeugt und keine
* RefTypes. Dies wird durch diese Methode nachgeholt.<br/>
* Bsp.: class JoergsTolleKlasse<A> extends MartinsSuperklasse<Integer, B>
* <br/>Wie man an diesem Beispiel sieht, kann nur eine Superklasse instantiierte
* Typvariablen zwischen den eckigen Klammern stehen haben, nicht jedoch die
* abgeleitete Klasse.
*
* @param className Klassenname der aktuell betrachteten Klasse
* @param Parameter Parameter der Superklasse
* @param KlassenVektor
// ino.end
// ino.method.wandleGeneric2RefType.21289.definition
public static void wandleGeneric2RefType(Menge<Type> Parameter, Menge<Class> KlassenVektor )
// ino.end
// ino.method.wandleGeneric2RefType.21289.body
{
//wandleGeneric2RefType SOLLTE NICHT NUR FUER LISTEN
//VON TYPEN FUNKTIONIEREN PL 05-01-19
// otth: GenericTypeVar in Superklassenparameterlisten in RefTypes mit Parameterlsite = NULL umwandeln,
// falls: ¯Â¿Â½r GenericTypeVar existiert eine gleichnamige Klasse
if(Parameter == null) return;
for( int i = 0; i < Parameter.size(); i++)
{
Type TempParameter = Parameter.elementAt(i);
inferencelog.debug("Nr. des Parameters: " + i);
// an dieser Stelle: Parametername
if ( TempParameter instanceof GenericTypeVar)
{
inferencelog.debug("Generic, WANDLE: " + TempParameter.getName());
// existiert ¯Â¿Â½r GenericTypeVar eine deklarierte Klasse
for( int k = 0; k < KlassenVektor.size(); k++)
{
if( KlassenVektor.elementAt(k).getSimpleName().equals(TempParameter.getSimpleName()) )
{
// Klasse existiert, darf aber keine Parameterliste in der Definition haben
if( KlassenVektor.elementAt(k).get_ParaList().size() == 0 )
{
RefType RNeu = new RefType( TempParameter.getName().toString(), null,TempParameter.getOffset());
inferencelog.debug( "Vorher: " + Parameter );
// i-te Stelle ersetzen
Parameter.set( i, RNeu );
inferencelog.debug( "GenericTypeVar " + TempParameter.getName() + " umwandeln..." );
inferencelog.debug( "Nachher: " + Parameter );
}
else
{
//parserlog.error( "SEMANTIK-CHECK-FEHLER: Parameter " + TempParameter.getName() + " muss weitere Parameter besitzen (laut Klassendefinition)" );
//FIXME Throw exception instead of simple exit
System.exit( 1 );
}
}
else {
inferencelog.debug("Ist echter Generic, wird nicht ersetzt!");
}
} // end for
} // end if
else
{
inferencelog.debug("Nicht Generic, WANDLE nicht: " + TempParameter.getName());
// RefType --> u.U. rekursiv weiterwandeln
if(TempParameter instanceof RefType)
{
RefType R = (RefType)TempParameter;
if( R.get_ParaList() != null )
wandleGeneric2RefType( R.get_ParaList(), KlassenVektor );
}
else if(TempParameter instanceof ITypeContainer)
{
Type T = ((ITypeContainer)TempParameter).getContainedType();
if(T instanceof RefType)
{
RefType R = (RefType)T;
if( R.get_ParaList() != null )
wandleGeneric2RefType( R.get_ParaList(), KlassenVektor );
}
}
else
{
inferencelog.error("Internal Error");
System.exit( 1 );
}
}
} //end for
} //end wandleGeneric2RefType
// ino.end
*/
// ino.method.parse.21292.defdescription type=javadoc
/**
* Parst den Quellcode und baut den abstrakten Syntaxbaum auf. Danach wird
* automatisch der von Thomas Ott implementierte Algorithmus
@ -236,246 +89,19 @@ public class MyCompiler implements MyCompilerAPI
* @throws IOException
* @throws JavaParser.yyException
*/
// ino.end
// ino.method.parse.21292.definition
private void parse_backup(Reader reader)
throws IOException, JavaParser.yyException
// ino.end
// ino.method.parse.21292.body
{
/*
parserlog.info("#########################################");
parserlog.info("# Parsen - START #");
parserlog.info("#########################################\n");
//////////////////////////////////////
// Alte Daten ¯Â¿Â½schen:
//////////////////////////////////////
m_AbstractSyntaxTree = null;
//////////////////////////////////////
// Scanner und Parser erzeugen:
//////////////////////////////////////
Scanner scanner = new Scanner(reader);
JavaParser parser = new JavaParser();
//////////////////////////////////////
// Parsen ==> Ergebnis: srcFile = Abstrakter Syntaxbaum
//////////////////////////////////////
SourceFile srcFile = (SourceFile) parser.yyparse( scanner );
this.testPair = parser.testPair;
parserlog.info( "Parsen war erfolgreich!\n");
//PL 05-07-31 verschoben nach SourceFile.java in Methode typeReconstruction
// otth: TypePlaceholders in Superklassenparameterlisten in RefTypes mit Parameterlsite = NULL umwandeln,
// falls: ¯Â¿Â½r TypePlaceholder existiert eine gleichnamige Klasse
// Superklasse suchen
//for( int i = 0; i < srcFile.KlassenVektor.size(); i++ )
//{
//Class tempKlasse = (Class)srcFile.KlassenVektor.elementAt( i );
//PL 05-07-30 ausgetauscht um alle Typedeklarationen zu wandeln
// if( tempKlasse.superclassid != null && tempKlasse.get_ParaList() != null )
// {
// // aktuelle Klasse hat Superklasse und Parameter
// Menge Parameter = tempKlasse.superclassid.get_ParaList();
// this.wandleGeneric2RefType(Parameter, srcFile.KlassenVektor );
// }
//wandleGeneric2RefType(tempKlasse.getContainedTypes(), srcFile.KlassenVektor );
//}
// otth: echte Konstruktoren von Methodendeklarationen ohne Typen unterscheiden
if ( srcFile != null )
{
Class tempKlasse = null;
ClassBody tempKlassBody = null;
Menge<mycompiler.myclass.Field> tempMengeFieldDecl;
mycompiler.myclass.Field tempFieldDecl = null;
String strKlasse;
for( int i = 0; i < srcFile.KlassenVektor.size(); i++ )
{
// Unterscheidung zwischen Class und Interfaces
if (srcFile.KlassenVektor.elementAt(i) instanceof Class) {
tempKlasse = (Class)srcFile.KlassenVektor.elementAt( i );
tempKlassBody = tempKlasse.get_ClassBody();
} else {
tempKlasse = null;
tempKlassBody = null;
}
if ( tempKlassBody != null )
{
strKlasse = tempKlasse.getName();
parserlog.debug("T->Felddeklarationen f�r die Klasse:" + strKlasse);
parserlog.debug( "------------------------------------");
// Schleife �ber alle fielddeclarations
tempMengeFieldDecl = tempKlassBody.getFields();
for( int k = 0; k < tempMengeFieldDecl.size(); k++ )
{
tempFieldDecl = tempMengeFieldDecl.elementAt(k);
if( tempFieldDecl instanceof Constructor )
{
//parserlog.debug("T->Konstruktor: " + ((DeclId)tempFieldDecl.get_Name().elementAt(0)).get_Name() + " - ReturnType: " + tempFieldDecl.getTypeName());
// pr�fen, ob Construktorname == Klassenname - falls nein: Construktor in Methode umwandeln !!!
String strConstName = ((DeclId)tempFieldDecl.get_Name().elementAt(0)).get_Name(); // Konstruktorname
if ( !strConstName.equals( strKlasse ) )
{
// Element k durch neues ersetzen!
Method Methode = new Method();
Method Konstruktor = (Constructor)tempFieldDecl;
// Elementweise vom Konstruktor in die Methode kopieren
Methode.set_Block( Konstruktor.get_Block() );
Methode.setParameterList( Konstruktor.getParameterList() );
Methode.set_ExceptionList( Konstruktor.get_ExceptionList() );
Methode.setReturnType( Konstruktor.getReturnType() );
Methode.setDeclIdMenge( Konstruktor.getDeclIdMenge() );
// types_in_parameterlist wird wohl erst sp�ter und intern gef�llt
// ¯Â¿Â½ckgabetyp = Objekt der Klasse 'TypePlaceholder'
// #JB# 31.03.2005
// ###########################################################
Methode.setReturnType(TypePlaceholder.fresh(Methode));
//Methode.setReturnType( new TypePlaceholder("###NEU###") );
// ###########################################################
// Element an der Position k durch neues ersetzen!
tempMengeFieldDecl.setElementAt( Methode, k );
}
}
if( tempFieldDecl instanceof Method && !(tempFieldDecl instanceof Constructor) )
{
//parserlog.debug("T->Methode: " + ((DeclId)tempFieldDecl.get_Name().elementAt(0)).get_Name() + " - ReturnType: " + tempFieldDecl.getTypeName());
}
private void parse_backup(Reader reader) throws IOException, JavaParser.yyException{
}
// Debugg-Infos
parserlog.debug("");
parserlog.debug("T->NEUE Felddeklarationen f�r die Klasse:" + strKlasse);
parserlog.debug( "-----------------------------------------");
for( int k = 0; k < tempMengeFieldDecl.size(); k++ )
{
tempFieldDecl = tempMengeFieldDecl.elementAt(k);
//parserlog.debug("T->" + ((DeclId)tempFieldDecl.get_Name().elementAt(0)).get_Name() + " - Typ: " + tempFieldDecl + " - ReturnType: " + tempFieldDecl.getTypeName());
}
// otth: TypePlaceholders durchnummerieren mit A, B, ...
parserlog.debug("");
parserlog.debug("");
parserlog.debug("Suche TypePlaceholders in den FieldDecls:");
parserlog.debug( "------------------------------------------");
ParameterList tempParameterList;
Menge<FormalParameter> tempVFktPara;
FormalParameter tempFP;
Method tempMethod;
Type tempReturn;
Type tempType;
for( int k = 0; k < tempMengeFieldDecl.size(); k++ )
{
tempFieldDecl = tempMengeFieldDecl.elementAt(k);
tempMethod = null;
if( tempFieldDecl instanceof Method )
{
tempMethod = (Method)tempFieldDecl;
tempReturn = tempMethod.getReturnType();
// Funktionen ohne definierten ¯Â¿Â½ckgabetyp suchen!!!
if( tempReturn instanceof TypePlaceholder )
{
// Methode mit nicht-definiertem ¯Â¿Â½ckgabetyp gefunden!
// #JB# 31.03.2005
// ###########################################################
// Wird bereits �ber fresh() gemacht!!
//tempReturn.setName( TypePlaceholder.makeNewName() );
// ###########################################################
parserlog.debug("");
parserlog.debug("Methode ohne Rueckgabetyp: " + tempMethod.get_Method_Name() + " --> " + tempReturn.getName());
}
else
{
parserlog.debug("");
parserlog.debug("Methode mit Rueckgabetyp / Konstruktor: " + tempMethod.get_Method_Name());
}
// Methoden-Funktionsparameter durchsuchen
tempParameterList = tempMethod.getParameterList();
if ( tempParameterList != null )
{
tempVFktPara = tempParameterList.sc_get_Formalparalist();
for( int l = 0; l < tempVFktPara.size(); l++ )
{
tempFP = tempVFktPara.elementAt(l);
tempType = tempFP.getType();
if( tempType instanceof TypePlaceholder )
{
if( tempType != null )
{
// neuer Name berechnen
// #JB# 31.03.2005
// ###########################################################
// Wird bereits �ber fresh() gemacht!!
//tempType.setName( TypePlaceholder.makeNewName() );
// ###########################################################
}
}
parserlog.debug("");
parserlog.debug(" Parameter: " + tempFP.get_Name() + " --> " + tempType.getName());
}
}
else
{
parserlog.debug("");
parserlog.debug(" Methode hat keine Parameter!");
}
}
}
} //end if
} //end for
} //end if
m_AbstractSyntaxTree = srcFile;
parserlog.info("#########################################");
parserlog.info("# Parsen - ENDE #");
parserlog.info("#########################################\n");
*/
} // end Methode parse()
// ino.end
/////////////////////////////////////////////////////////////////////////////////////////////////
// Implementierte API-Methoden:
/////////////////////////////////////////////////////////////////////////////////////////////////
// ino.method.init.21295.defdescription type=javadoc
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
* Initialisiert den Compiler
*/
// ino.end
// ino.method.init.21295.definition
public void init()
// ino.end
// ino.method.init.21295.body
{
public void init(){
TypePlaceholder.deleteRegistry();
// Log4J fuer die Ausgabe vorbereiten
//DOMConfigurator.configure("log4j.xml");
}
// ino.end
// ino.method.parse.21298.defdescription type=javadoc
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
* Ruft die Parse-Methode.
@ -484,22 +110,13 @@ public class MyCompiler implements MyCompilerAPI
* @throws IOException Wenn was schief ¯Â¿Â½uft.
* @throws JavaParser.yyException Wenn ein Fehler beim Parsen auftritt.
*/
// ino.end
// ino.method.parse.21298.definition
public SourceFile parse(File file)
throws FileNotFoundException, IOException, JavaParser.yyException
// ino.end
// ino.method.parse.21298.body
{
public SourceFile parse(File file) throws FileNotFoundException, IOException, JavaParser.yyException{
FileReader fr = new FileReader(file);
SourceFile ret = this.parse2SyntaxTree(fr);
this.m_AbstractSyntaxTree.add(ret);
fr.close();
return ret;
}
// ino.end
// ino.method.typeReconstruction.21304.defdescription type=javadoc
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
* Ruft den Typrekonstruktionsalgorithmus auf.
@ -508,16 +125,7 @@ public class MyCompiler implements MyCompilerAPI
* ist. @throws CTypeReconstructionException Wenn ein Fehler bei der
* Typrekonstruktion auftritt.
*/
// ino.end
// ino.method.typeReconstruction.21304.definition
public Menge<TypeinferenceResultSet> typeReconstruction()
throws NullPointerException, CTypeReconstructionException
// ino.end
// ino.method.typeReconstruction.21304.body
{
if(m_AbstractSyntaxTree==null){
throw new NullPointerException("Es wurde noch kein Abstrakter Syntaxbaum erstellt!");
}
public Menge<TypeinferenceResultSet> typeReconstruction(Menge<SourceFile> m_AbstractSyntaxTree) throws NullPointerException, CTypeReconstructionException{
inferencelog.info("##########################################", Section.TYPEINFERENCE);
inferencelog.info("# TypeReconstruction-Algorithmus - START #", Section.TYPEINFERENCE);
inferencelog.info("##########################################\n", Section.TYPEINFERENCE);
@ -535,7 +143,6 @@ public class MyCompiler implements MyCompilerAPI
return result;
}
// ino.end
/**
* Erstellt die FunN-Assumptions
@ -560,44 +167,12 @@ public class MyCompiler implements MyCompilerAPI
return ret;
}
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
* Generiert den Bytecode und das Class-File ¯Â¿Â½r den Syntaxbaum.
* @throws NullPointerException Wenn noch kein abstrakter Syntaxbaum vorhanden
* ist.
@Override
public Menge<ClassFile> codeGeneration(ResultSet result)
throws NullPointerException, JVMCodeException
{
if(m_AbstractSyntaxTree==null){
throw new NullPointerException("Es wurde noch kein Abstrakter Syntaxbaum erstellt!");
}
codegenlog.info("Beginn der Codegenerierung ...");
Menge<ClassFile> ret = new Menge<ClassFile>();
for(SourceFile sf : m_AbstractSyntaxTree){
ret.addAll(sf.codegen(result));
}
codegenlog.info("Codegenerierung beendet!");
return ret;
}*/
// ino.method.main.21313.defdescription type=javadoc
/**
* Die Main-Funktion, �ber die der Compiler auch per Konsole gestartet
* werden kann.
* @param args Klassendatei
*/
// ino.end
// ino.method.main.21313.definition
public static void main(String[] args)
// ino.end
// ino.method.main.21313.body
{
public static void main(String[] args){
MyCompilerAPI compiler = MyCompiler.getAPI(new LoggerConfiguration());
// Hier koennten ggf. Aenderungen der Ausgabeeinstellungen
@ -617,33 +192,9 @@ public class MyCompiler implements MyCompilerAPI
System.err.println(e);
System.exit(0);
}
/////////////////////////
// Semantik-Check:
/////////////////////////
// try {
// compiler.semanticCheck();
// } catch (NullPointerException e) {
// System.out.println("Fehler beim Aufrufen des Semantik-Checks:");
// System.out.println(e);
// System.exit(0);
// } catch (SCException e) {
// e.fehlerausgabe();
// System.exit(0);
// }
/////////////////////////
// Code-Generierung:
/////////////////////////
//compiler.codeGeneration();
}
// ino.end
// ino.method.setOutputDir.21316.definition
public void setOutputDir(String dir)
// ino.end
// ino.method.setOutputDir.21316.body
{
public void setOutputDir(String dir){
char c = dir.charAt(dir.length()-1);
if (c != '/' & c != '\\') dir = dir + "/";
OutputDir = dir;
@ -652,75 +203,11 @@ public class MyCompiler implements MyCompilerAPI
File f = new File(dir);
f.mkdirs();
}
// ino.end
// ino.method.getOutputDir.21319.definition
public String getOutputDir()
// ino.end
// ino.method.getOutputDir.21319.body
{
public String getOutputDir(){
return OutputDir;
}
// ino.end
/*
// ino.method.getFullyQualifiedNameFromClassname.21322.definition
public static String getFullyQualifiedNameFromClassname(String typ, ImportDeclarations declarations)
// ino.end
// ino.method.getFullyQualifiedNameFromClassname.21322.body
{
String ret=null;
// Es ist kein FullyQualifiedName => In den Imports die Klasse suchen
for(int j=0;j<declarations.size();j++){
UsedId impDecl=declarations.elementAt(j);
if(impDecl.getSimpleName().equals(typ)){
ret=(impDecl.getQualifiedName().toString());
break;
}
}
return ret;
}
// ino.end
*/
// ino.method.makeRefTypesFullyQualified.21325.defdescription type=javadoc
/**
* @author HOTI
* Macht alle Referenzen auf Objekte zu fully qualified Names
* p.ex Menge x; => de.dhbwstuttgart.typeinference.Menge x;
* @param containedTypes Alle Typen, die die Klasse beinhaltet
* @param name Alle Klassen, die es in den BasicAssumptions und im
* AbstractSyntaxTree gibt @param declarations Alle Import-Declarations
// ino.end
// ino.method.makeRefTypesFullyQualified.21325.definition
public static void makeRefTypesFullyQualified(Menge<Type> containedTypes, ImportDeclarations declarations)
// ino.end
// ino.method.makeRefTypesFullyQualified.21325.body
{
// HOTI 8.5.06 Anhand der ContainedTypes alle Variablen aendern
for( int i = 0; i < containedTypes.size(); i++)
{
Type tempParameter = (Type)(containedTypes.elementAt(i));
// Nat�rlich nur RefTypes updaten
if(tempParameter instanceof RefType){
RefType typ=(RefType)tempParameter;
UsedId fullyQualifiedName=UsedId.createFromQualifiedName(typ.getTypeName(),typ.getOffset());
// Kein FullyQualifiedName
if(fullyQualifiedName.name.size()==1){
String newType=getFullyQualifiedNameFromClassname(typ.getSimpleName(),declarations);
if(newType!=null){
typ.setName(newType);
}
}
if(typ.get_ParaList()!=null){
makeRefTypesFullyQualified(typ.get_ParaList(),declarations);
}
}
}
}
// ino.end
*/
/**
* @author Arne ¼dtke
* Ersetzt alle GTVs durch TPHs mit gleichem Namen. Arbeitet Rekursiv.
@ -790,8 +277,10 @@ public class MyCompiler implements MyCompilerAPI
/**
* Diese Funktion nimmt einen Menge von Dateinamen. Alle diese Dateien werden zu einem SyntaxBaum geparst.
* @return
*/
public void parse(Menge<String> filenames) throws ParserError {
public Menge<SourceFile> parse(Menge<String> filenames) throws ParserError {
Menge<SourceFile> m_AbstractSyntaxTree = new Menge<SourceFile>();
for(String filename : filenames){
StringBuffer fileData = new StringBuffer();
@ -816,58 +305,25 @@ public class MyCompiler implements MyCompilerAPI
StringReader srcreader = new StringReader(fileData.toString());
//Den aus der Datei ausgelesenen Quellcode zu einem Syntaxbaum parsen:
this.m_AbstractSyntaxTree.add(parse2SyntaxTree(srcreader)); // Alle Dateien nacheinander hintereinander anhängen...
}
/*
String gesamterSrc = "";
//Hier werden alle übergebenen Dateinamen abgearbeitet:
for(String filename : filenames){
try {
StringBuffer fileData = new StringBuffer();
BufferedReader reader = new BufferedReader(
new FileReader(filename));
char[] buf = new char[1024];
int numRead=0;
while((numRead=reader.read(buf)) != -1){
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
}
reader.close();
gesamterSrc += fileData.toString() + "\n"; // Alle Dateien nacheinander hintereinander anhängen...
} catch (Exception e) {
e.printStackTrace();
throw new TypinferenzException("Die übergebenen Dateien konnten nicht zum Parsen eingelesen werden.");
}
m_AbstractSyntaxTree.add(parse2SyntaxTree(srcreader)); // Alle Dateien nacheinander hintereinander anhängen...
}
try {
// und anschließend zum Parsen übergeben.
this.parse(gesamterSrc.toString());
} catch (Exception e) {
e.printStackTrace();
//throw new TypinferenzException("Fehler beim Parsen");
}
*/
return m_AbstractSyntaxTree;
}
@Override
public SourceFile parse(String sourceCode) {
SourceFile ret = this.parse2SyntaxTree(new StringReader(sourceCode));
this.m_AbstractSyntaxTree.add(ret);
return ret;
return parse2SyntaxTree(new StringReader(sourceCode));
}
@Override
public Menge<ByteCodeResult> generateBytecode(TypeinferenceResultSet typeinferenceResult) {
public Menge<ByteCodeResult> generateBytecode(Menge<SourceFile> m_AbstractSyntaxTree, TypeinferenceResultSet typeinferenceResult) {
//SourceFile parsedFile = this.m_AbstractSyntaxTree.firstElement();
//Class parsedClass = parsedFile.KlassenVektor.firstElement();
Menge<ByteCodeResult> ret = new Menge<>();
for(SourceFile sf : this.m_AbstractSyntaxTree){
for(SourceFile sf : m_AbstractSyntaxTree){
ret.addAll(sf.generateBytecode(typeinferenceResult));
}
return ret;
}
}
// ino.end

View File

@ -85,8 +85,7 @@ public interface MyCompilerAPI
*/
// ino.end
// ino.method.typeReconstruction.21340.declaration
public Menge<TypeinferenceResultSet> typeReconstruction()
throws NullPointerException, TypeinferenceException;
public Menge<TypeinferenceResultSet> typeReconstruction(Menge<SourceFile> m_AbstractSyntaxTree) throws NullPointerException, CTypeReconstructionException;
// ino.end
// ino.method.setOutputDir.21349.decldescription type=javadoc
@ -112,8 +111,9 @@ public interface MyCompilerAPI
/**
* Parst zusammenhängende JavaKlassen in verschiedenen Dateien.
* @param filenames - Eine Liste von Quellcodedateien, welche gseparst werden sollen
* @return
*/
public void parse(Menge<String> filenames) throws ParserError;
public Menge<SourceFile> parse(Menge<String> filenames) throws ParserError;
/**
* Parst den SourceCode einer Datei.
@ -127,6 +127,6 @@ public interface MyCompilerAPI
* Dafür müssen die Schritte Parsen und typeReconstruction ausgeführt werden.
* @return
*/
public Menge<ByteCodeResult> generateBytecode(TypeinferenceResultSet rs);
public Menge<ByteCodeResult> generateBytecode(Menge<SourceFile> m_AbstractSyntaxTree, TypeinferenceResultSet typeinferenceResult);
}
// ino.end

View File

@ -15,7 +15,6 @@ import org.apache.commons.bcel6.generic.InstructionHandle;
import org.apache.commons.bcel6.generic.InstructionList;
import org.apache.commons.bcel6.generic.MethodGen;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.logger.SectionLogger;
@ -25,6 +24,7 @@ import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.core.AClassOrInterface;
import de.dhbwstuttgart.core.IItemWithOffset;
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.statement.Block;
@ -80,6 +80,8 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
DHBWConstantPoolGen _cp;
ClassGenerator _cg;
Menge<ByteCodeResult> results = new Menge<ByteCodeResult>();
SectionLogger logger = Logger.getSectionLogger(this.getClass().getName(), Section.CODEGEN);
logger.debug("Test");
@ -111,8 +113,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
c.genByteCode(_cg, fieldInitializations);
}
ByteCodeResult code = new ByteCodeResult(_cg);
return code;
return new ByteCodeResult(_cg);
}
private Menge<Type> superif = new Menge<Type>();
@ -222,8 +223,8 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
superclassid=null;
}
this.offset = offset;
if(!name.equals("Object"))//Alle Klassen außer Object erben von Object:
this.superClass = new Class("Object", -1).getType();
if(!name.equals("Object") && !name.equals("java.lang.Object"))//Alle Klassen außer Object erben von Object:
this.superClass = new Class("java.lang.Object", -1).getType();
}
// ino.end
@ -593,112 +594,6 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
{
return this.parahash;
}
// ino.end
/*static void string_rec(Hashtable ht){
String record="";
boolean isError=false;
record=record.concat("[");
for(Enumeration e=ht.elements(),k=ht.keys();e.hasMoreElements();){
String s = (String)k.nextElement();
Object o = e.nextElement();
record=record.concat(" "+s);
if(o instanceof Type){
record=record.concat(" = "+((Type)o).getName());
} else if(o instanceof Hashtable){
record=record.concat("= ");
string_rec((Hashtable)o);
if(e.hasMoreElements())
record=record.concat(", ");
} else if(o instanceof String){
record=record.concat(" = "+o);
if(e.hasMoreElements())
record=record.concat(", ");
}
else {
record=("[FEHLER: string_rec: unbekannter Typ!!!!!!");
isError=true;
}
}
record=record.concat("]");
if(isError){
parserlog.error(record);
}else{
parserlog.debug(record);
}
}*/
/*static void string_rec(Menge v){
String record=("{");
for(Enumeration e=v.elements();e.hasMoreElements();){
Type t = (Type)e.nextElement();
record=record.concat(" "+t.getName());
if(e.hasMoreElements())
record=record.concat(",");
}
record=record.concat("}");
parserlog.debug(record);
}*/
/*static void string_rec(String st, Hashtable ht){
String record=(st);
boolean isError=false;
record=record.concat("[");
for(Enumeration e=ht.elements(),k=ht.keys();e.hasMoreElements();){
String s = (String)k.nextElement();
Object o = e.nextElement();
record=record.concat(" "+s);
if(o instanceof Type){
record=record.concat(" = "+((Type)o).getName());
}
else if(o instanceof Hashtable){
record=record.concat("= ");
string_rec((Hashtable)o);
if(e.hasMoreElements())
record=record.concat(", ");
}
else if(o instanceof String){
record=record.concat(" = "+o);
if(e.hasMoreElements())
record=record.concat(", ");
}
else {
record=("[FEHLER: string_rec: unbekannter Typ!!!!!! " +o);
isError = true;
}
}
record=record.concat("]");
if(isError){
parserlog.error(record);
}else{
parserlog.debug(record);
}
}*/
/*static void string_rec(String st,Menge v)
{
String record=(st);
record=record.concat("{");
for(Enumeration e=v.elements();e.hasMoreElements();)
{
Type t = (Type)e.nextElement();
record=record.concat(" "+t.getName());
if(e.hasMoreElements())
{
record=record.concat(", ");
}
}
record=record.concat("}");
parserlog.debug(record);
}*/
/////////////////////////////////////////////////////////////////////////
// TypeReconstructionAlgorithmus
@ -771,165 +666,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
typinferenzLog.debug("Erstellte Constraints: "+oderConstraints, Section.TYPEINFERENCE);
return oderConstraints;
/*
CReconstructionTupleSet retTupleSet = this.TRStart(methodList, V, V_fields_methods, supportData);
inferencelog.debug("Bin aus TRStart() zur�ck in TRProg().");
//////////////////////////////
// Neu Ergebnismenge A aller
// Typannahmen erzeugen:
//////////////////////////////
inferencelog.debug("Erstelle Ergebnismenge...");
Menge<CTypeReconstructionResult> newA = new Menge<CTypeReconstructionResult>();
// Alle bisherigen ¯Â¿Â½glichkeiten an Typkombinationen durchgehen:
Menge<CTypeReconstructionResult> oldA = supportData.getA();
for(int i=0; i<oldA.size(); i++){
CTypeReconstructionResult oneReconResult = oldA.elementAt(i);
// Und mit den neuen ¯Â¿Â½glichen Typkombinationen vereinigen:
Iterator<CReconstructionTuple> retTupleIt = retTupleSet.getIterator();
while(retTupleIt.hasNext()){
CReconstructionTuple possibleTuple = retTupleIt.next();
this.clear(possibleTuple.getAssumSet(), rememberLocals);
// Neue Typinformationen mit alten Typinformationen vereinigen:
CTypeReconstructionResult newReconResult = oneReconResult.shallowCopy();
newReconResult.addDataFromTupel(possibleTuple);
//PL 05-08-02 eingefuegt
//Fuegt Klassen und GenericTypeVars zu A hinzu
newReconResult.addClassName(this.getName());
Menge<GenericTypeVar> genericsList = new Menge<GenericTypeVar>();
for(int ii =0; ii<this.get_ParaList().size(); ii++){
Type para = (Type)this.get_ParaList().elementAt(ii);
if(para instanceof GenericTypeVar){
genericsList.addElement((GenericTypeVar)para);
}
}
newReconResult.addGenericTypeVars(this.getName(), genericsList);
//Hinzuf�gen:
newA.addElement(newReconResult);
}
}
return newA;
*/
}
// ino.end
/**
* @return Eine Liste mit allen Methoden dieser Klasse
private Menge<Method> getMethodList() {
if(this.methodList != null) return this.methodList;
//TODO: UnnÃtige Berechnungen im folgenden Code rauskürzen:
//////////////////////////////
// Die Eingabedaten bauen:
//////////////////////////////
inferencelog.debug("Baue Eingabedaten...");
TypeAssumptions V_fields_methods = new TypeAssumptions(this.getName());
Menge<Method> methodList = new Menge<Method>();
Menge<CTypeAssumptionSet> V = new Menge<CTypeAssumptionSet>();
Menge<CTypeAssumption> rememberLocals = new Menge<CTypeAssumption>();
//////////////////////////////
// Alle Felder durchgehen:
// Zuerst alle Attribute, dann Methoden
// ge�ndert: hoth 06.04.2006
//////////////////////////////
for(Field field : this.getFields())
{
//////////////////////////////
// Attribut:
//////////////////////////////
}
for(Field field : this.getFields())
{
//////////////////////////////
// Methode:
//////////////////////////////
if(field instanceof Method){
Method method = (Method)field;
//if(method.get_Method_Name().equals(this.getName()) && ((method.getReturnType().equals(new mycompiler.mytype.Void(0))) || method.getReturnType() instanceof TypePlaceholder)){
if(method.get_Method_Name().equals(this.getName()) ){
method.set_Method_Name("<init>");
}
//hoth: 06.04.2006
//durchlaufe Block und suche nach Objektvariablen fuer Offset-Markierung
Iterator<CTypeAssumption> fieldVarIterator = V_fields_methods.iterator();
while (fieldVarIterator.hasNext())
{
//Wenn ObjektVariable
CTypeAssumption dieAssum = fieldVarIterator.next();
if(dieAssum instanceof CInstVarTypeAssumption)
{
Class.isFirstLocalVarDecl=false;
if(method.get_Block() != null)
method.get_Block().addOffsetsToAssumption(dieAssum,dieAssum.getIdentifier(),true);
}
}
methodList.addElement(method);
// ¯Â¿Â½r V_fields_methods:
CMethodTypeAssumption methodAssum = new CMethodTypeAssumption(this.getType(), method.get_Method_Name(), method.getReturnType(), method.getParameterCount(),method.getLineNumber(),method.getOffset(),new Menge<Integer>(),method.getGenericMethodParameters()); // Typannahme bauen...
// Methode in V_Fields_methods ablegen
// Dabei wird die OverloadedMethodID ermittelt !!
// => Method setzenuct
V_fields_methods.add(methodAssum);
method.setOverloadedID(methodAssum.getHashSetKey().getOverloadedMethodID());
// ¯Â¿Â½r die V_i:
CTypeAssumptionSet localAssum = new CTypeAssumptionSet();
// Bauen...
ParameterList parameterList = method.getParameterList();
if(parameterList!=null){
for(int i=0; i<parameterList.sc_get_Formalparalist().size(); i++){
FormalParameter para = parameterList.sc_get_Formalparalist().elementAt(i);
// ¯Â¿Â½r V_fields_methods:
CParaTypeAssumption paraAssum = new CParaTypeAssumption(this.getName(), method.get_Method_Name(), method.getParameterCount(), method.getOverloadedID(),para.getIdentifier(), para.getType(), para.getLineNumber(),para.getOffset(),new Menge<Integer>());
//fuege Offsets fuer Parameter hinzu, hoth: 06.04.2006
Class.isFirstLocalVarDecl=false;
if(method.get_Block() != null)
method.get_Block().addOffsetsToAssumption(paraAssum,paraAssum.getIdentifier(),true);
methodAssum.addParaAssumption(paraAssum);
// ¯Â¿Â½r die V_i:
CLocalVarTypeAssumption varAssum = new CLocalVarTypeAssumption(this.getName(), method.get_Method_Name(), method.getParameterCount(), method.getOverloadedID(),"1", para.getIdentifier(),para.getType(), para.getLineNumber(),para.getOffset(),new Menge<Integer>());
localAssum.addElement(varAssum);
rememberLocals.addElement(varAssum);
}
}
// ...und hinzuf�gen:
V.addElement(localAssum);
}
}
this.methodList = methodList;
return methodList;
}
*/
/**
* Ermittelt alle privaten Felder und Methoden der Klasse und Erstellt eine Assumption ¼r diese.
@ -957,49 +694,8 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
this.typeAssumptions = assumptions; //Diese ¼ssen anschließend nicht wieder generiert werden.
return assumptions;
}
/*
public ConstraintsSet TYPE(Menge<Method> methodList, Menge<Expr> fielddeclarationList, TypeAssumptions assumptions){
ConstraintsSet ret = new ConstraintsSet();
// Die Felddeklarationen werden zu den Assumptions hinzugefügt und gelten danach ¼r jede Methode.
//TypeAssumptions assumptionsPlusFieldAssumptions = new TypeAssumptions(assumptions);
for(Expr expr : fielddeclarationList){
//ret.add(expr.TYPEStmt(assumptionsPlusFieldAssumptions));
ret.add(expr.TYPEStmt(assumptions));
}
for(Method methode : methodList){
//ret.add(methode.TYPE(assumptionsPlusFieldAssumptions));
ret.add(methode.TYPE(assumptions));
}
return ret;
}
*/
// ino.method.RetType.23119.defdescription type=javadoc
/**
* Liefert den berechneten ¯Â¿Â½ckgabetyp ¯Â¿Â½r die �bergebene Methode zur�ck.<br/>
* (siehe Algorithmus RetType, Martin Pl�micke)
* <br/>Author: ¯Â¿Â½rg ¯Â¿Â½uerle
* @param me
* @param V
* @return
// ino.end
// ino.method.RetType.23119.definition
private Type RetType(Method me, CTypeAssumptionSet V)
// ino.end
// ino.method.RetType.23119.body
{
CTypeAssumption assum = V.getElement(new CMethodKey(this.getName(), me.get_Method_Name(), me.getParameterCount(),me.getOverloadedID()));
if(assum instanceof CMethodTypeAssumption){
return ((CMethodTypeAssumption)assum).getAssumedType();
}
else return null;
}
// ino.end
*/
// ino.method.toString.23125.defdescription type=javadoc
/**
* <br/>Author: Martin Pl�micke
@ -1037,48 +733,8 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
for(Field f : this.getFields()){
//f.wandleRefTypeAttributes2GenericAttributes(paralist);
}
/*
Menge fieldsAndMethods=this.getFields();
// Alle Methoden und Instanzvariablen durchgehen
for(int i=0;i<fieldsAndMethods.size();i++){
// Ist es eine Methode?
if(fieldsAndMethods.get(i) instanceof Method){
Method method=(Method)fieldsAndMethods.get(i);
method.wandleRefTypeAttributes2GenericAttributes(paralist);
}// Ist es eine InstanzVariable?
*//*
else if(fieldsAndMethods.get(i) instanceof InstVarDecl){
InstVarDecl instVar=(InstVarDecl)fieldsAndMethods.get(i);
Type type=instVar.getType();
// Nur wenn es sich um ein RefType-Field handelt
if(type instanceof RefType){
GenericTypeVar pendant=ClassHelper.findGenericType((RefType)type,paralist,null);
if(pendant!=null){ //Wenn generisch, dann modifizieren
instVar.setType(pendant);
}
}
}
}*/
}
// ino.end
// private void removeOldLocalVars(CTypeAssumptionSet V_i, CTypeAssumptionSet V_last){
// Enumeration<IHashSetKey> enumer = V_last.getHashtable().keys();
// while(enumer.hasMoreElements()){
// CTypeAssumption currentAssum = V_last.getElement(enumer.nextElement());
// if(currentAssum instanceof CLocalVarTypeAssumption){
// V_i.removeElement(currentAssum);
// }
// }
//
// }
// ino.method.getSimpleName.23140.defdescription type=javadoc
/**
* HOTI
* Liefert bei Klassen die fullyQualified angegeben wurden
@ -1116,18 +772,6 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
public String printJavaCode(TypeinferenceResultSet reconstructionResult){
JavaCodeResult ret = new JavaCodeResult("class ");
//Generiere JavaCode der extends-Typen:
/*
String containedTypesJavaCode = "";
for(Type containedType : containedTypes){
containedTypesJavaCode += containedType.printJavaCode(resultSet)+ ", ";
}
if(containedTypesJavaCode.length()>1)containedTypesJavaCode = containedTypesJavaCode.substring(0, containedTypesJavaCode.length() -2);
*/
JavaCodeResult classBodyCode = new JavaCodeResult();
if(this.modifiers!=null)classBodyCode.attach(this.modifiers.printJavaCode(reconstructionResult.getUnifiedConstraints())).attach(" ");
@ -1382,5 +1026,67 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
public boolean isInterface(){
return false;
}
/*
private Collection<? extends ByteCodeResult> getGenericClasses() {
Collection<ByteCodeResult> results = new Menge<>();
for(Field field : this.fielddecl){
Type type = field.getType();
//Der Type des Feldes
if(type instanceof RefType){
RefType refType = (RefType) type;
if(!refType.getCombinedType(null).equals(refType.get_Name().replace(".", "%"))){
results.addAll(generateGenericClass(refType.getCombinedType(null), new Class("java/util/Vector",-1)));
}
}
if(field instanceof Method){
Method method = (Method) field;
ParameterList parameterList = method.getParameterList();
//Die Typen der Methodenparameter
for(FormalParameter parameter: parameterList){
Type parameterType = parameter.getType();
if(parameterType instanceof RefType){
RefType refType = (RefType) parameterType;
if(!refType.getCombinedType(null).equals(refType.get_Name().replace(".", "%"))){
results.addAll(generateGenericClass(refType.getCombinedType(null), new Class("java/util/Vector",-1)));
}
}
}
}
}
return results;
}
*/
/*
private Menge<ByteCodeResult> generateGenericClass(String name, Class superClass){
//TODO: bytecode -- Generics hinzuf<EFBFBD>gen
//Type superClassType = superClass.getType();
//TODO: bytecode
//ClassGenerator genericClassGenerator = new ClassGenerator(name, superClassType, name + ".java", Constants.ACC_PUBLIC , new String[] { }, new TypeinferenceResultSet(null, null, null));
//TODO: bytecode -- Namen der neuen Klasse
Class generatedClass = new Class(name, 0);
//TODO: bytecode -- alle Konstruktoren generieren
Block konstruktorBlock = new Block();
konstruktorBlock.setType(new de.dhbwstuttgart.syntaxtree.type.Void(konstruktorBlock, 0));
konstruktorBlock.statements.add(new SuperCall(konstruktorBlock));
Constructor standardKonstruktor = new Constructor(Method.createEmptyMethod(konstruktorBlock, name, superClass), superClass);
standardKonstruktor.parserPostProcessing(generatedClass);
generatedClass.addField(standardKonstruktor);
return generatedClass.genByteCode(new TypeinferenceResultSet(generatedClass, new Menge<>(), new ResultSet()));
}
*/
}
// ino.end

View File

@ -541,8 +541,7 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
ret.add(this.block.TYPEStmt(localAss));
// eine Verknüpfung mit der Type Assumption aus dem Assumption Set
// und dem ermittelten Typ der Methode:
ret.add(new SingleConstraint(this.block.getType().TYPE(localAss, this),
this.returntype.TYPE(localAss, this)));
ret.add(new SingleConstraint(this.block.getType().TYPE(localAss, this), this.returntype.TYPE(localAss, this)));
return ret;
}

View File

@ -1834,7 +1834,7 @@ public class SourceFile
* Bisher wird nur der Bytecode der Klassen generiert. Nicht der Interfaces.
* @return
*/
public Collection<? extends ByteCodeResult> generateBytecode(TypeinferenceResultSet rs) {
public Menge<ByteCodeResult> generateBytecode(TypeinferenceResultSet rs) {
Menge<ByteCodeResult> ret = new Menge<>();
for(Class cl : this.KlassenVektor){
ret.add(cl.genByteCode(rs));

View File

@ -0,0 +1,56 @@
package de.dhbwstuttgart.syntaxtree.factory;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.misc.DeclId;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
public class ASTFactory {
public static Method createMethod(String name, Block block, Class parent) {
block.parserPostProcessing(parent);
Method method = new Method(0);
DeclId DImethod = new DeclId();
DImethod.set_Name(name);
method.set_DeclId(DImethod);
method.set_Block(block);
method.parserPostProcessing(parent);
return method;
}
public static Method createEmptyMethod(String withSignature, Class parent) {
return ASTFactory.createMethod(withSignature, new Block(), parent);
}
public static Constructor createEmptyConstructor(Class parent){
Block block = new Block();
block.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0));
block.statements.add(new SuperCall(block));
return ASTFactory.createConstructor(parent, block);
}
public static Constructor createConstructor(Class superClass, Block block){
block.parserPostProcessing(superClass);
Method method = ASTFactory.createMethod("<init>", block, superClass);
method.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0));
return new Constructor(method, superClass);
}
public static Class createClass(String className, Class superClass) {
// TODO bytecode createClass
Class generatedClass = new Class(className, 0);
generatedClass.addField(ASTFactory.createEmptyConstructor(superClass));
generatedClass.parserPostProcessing(superClass);
return generatedClass;
}
}

View File

@ -0,0 +1,39 @@
package de.dhbwstuttgart.syntaxtree.factory;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.Pair.PairOperator;
public class UnifyPairMengenBuilder {
private Menge<Pair> buildMenge = new Menge<Pair>();
public void addPair(Type t1, Type t2) {
buildMenge.add(new Pair(t1, t2));
}
public void addPair(Type t1, Type t2, PairOperator pairOp) {
buildMenge.add(new Pair(t1, t2, pairOp));
}
public Menge<Pair> getPairMenge() {
return buildMenge;
}
public Menge<Menge<Pair>> getNestedPairMenge() {
Menge<Menge<Pair>> nested = new Menge<>();
for(Pair p : buildMenge) {
Menge<Pair> m = new Menge<Pair>();
m.add(p);
nested.add(m);
}
return nested;
}
public void clear() {
buildMenge = new Menge<Pair>();
}
}

View File

@ -0,0 +1,43 @@
package de.dhbwstuttgart.syntaxtree.factory;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.WildcardType;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.ObjectType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.Pair.PairOperator;
public class UnifyTypeFactory {
public RefType GetSimpleType(String name, Type... parameters) {
if(parameters.length == 0)
return new RefType(name, null, 0);
Menge<Type> typeParams = new Menge<Type>();
for(Type t : parameters)
typeParams.add(t);
return new RefType(name, typeParams, null, 0);
}
public ExtendsWildcardType GetExtendsType(ObjectType extendedType) {
return new ExtendsWildcardType(extendedType);
}
public SuperWildcardType GetSuperType(ObjectType superedType) {
return new SuperWildcardType(superedType);
}
public WildcardType GetWildcardType() {
return new WildcardType(null, null, 0);
}
public TypePlaceholder GetTypePlaceholder(String name) {
return TypePlaceholder.backdoorCreate(name);
}
}

View File

@ -0,0 +1,33 @@
package de.dhbwstuttgart.syntaxtree.factory;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.unify.FC_TTO;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
public class Unify_FC_TTO_Builder {
private Menge<Pair> fc = new Menge<Pair>();
private Menge<Class> classes = new Menge<Class>();
public void AddInheritance(Type t1, Type t2) {
if(t1 instanceof RefType)
classes.add(new Class(t1.get_Name(), t1.getOffset()));
if(t2 instanceof RefType)
classes.add(new Class(t2.get_Name(), t2.getOffset()));
fc.add(new Pair(t1, t2));
}
public FC_TTO Get_FC_TTO() {
return new FC_TTO(fc, (Menge<?>) fc.clone(), classes);
}
public void clear() {
fc = new Menge<Pair>();
classes = new Menge<Class>();
}
}

View File

@ -6,8 +6,13 @@ import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import org.apache.commons.bcel6.generic.BranchInstruction;
import org.apache.commons.bcel6.generic.ClassGen;
import org.apache.commons.bcel6.generic.GOTO;
import org.apache.commons.bcel6.generic.IF_ICMPNE;
import org.apache.commons.bcel6.generic.InstructionConstants;
import org.apache.commons.bcel6.generic.InstructionList;
import org.apache.commons.bcel6.generic.NOP;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
@ -228,8 +233,22 @@ public JavaCodeResult printJavaCode(ResultSet resultSet) {
if(this.getReturnType().getName().equals(new JavaClassName("String"))){
throw new TypeinferenceException("Zeichenketten zusammenfügen ist noch nicht unterstützt",this);
}
//TODO: Je nachdem welches der Rückgabetyp ist, müssen die linke und rechte Seite unboxt und addiert werden.
return null;
linkeSeite.append(rechteSeite);
//TODO: bytecode (Bis jetzt wird jeder Condition als EQUALS behandelt)
//TODO: bytecode autoboxing
BranchInstruction if_icmpneInstruction = new IF_ICMPNE(null);
linkeSeite.append(if_icmpneInstruction);
linkeSeite.append(InstructionConstants.ICONST_1);
BranchInstruction gotoInstruction = new GOTO(null);
linkeSeite.append(gotoInstruction);
if_icmpneInstruction.setTarget(linkeSeite.append(InstructionConstants.ICONST_0));
gotoInstruction.setTarget(linkeSeite.append(new NOP()));
return linkeSeite;
}
}

View File

@ -4,8 +4,13 @@ import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import org.apache.commons.bcel6.generic.BranchInstruction;
import org.apache.commons.bcel6.generic.ClassGen;
import org.apache.commons.bcel6.generic.GOTO;
import org.apache.commons.bcel6.generic.IF_ICMPGE;
import org.apache.commons.bcel6.generic.InstructionHandle;
import org.apache.commons.bcel6.generic.InstructionList;
import org.apache.commons.bcel6.generic.NOP;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
@ -22,10 +27,13 @@ import de.dhbwstuttgart.syntaxtree.operator.RelOp;
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.JavaCodeResult;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.SingleConstraint;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import de.dhbwstuttgart.typeinference.unify.Unify;
@ -91,8 +99,13 @@ public class ForStmt extends Statement
@Override
public ConstraintsSet TYPEStmt(TypeAssumptions assumptions) {
// TODO Auto-generated method stub
return null;
//TODO: TYPEStmt
ConstraintsSet ret = new ConstraintsSet();
this.setType(TypePlaceholder.fresh(this));
ret.add(body_Loop_block.TYPEStmt(assumptions));
return ret;
}
public int getTypeLineNumber() {
@ -100,9 +113,9 @@ public class ForStmt extends Statement
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
// TODO Auto-generated method stub
throw new NotImplementedException();
public JavaCodeResult printJavaCode(ResultSet resultSet) {
// TODO printJavaCode
return new JavaCodeResult();
}
@Override
@ -121,7 +134,34 @@ public JavaCodeResult printJavaCode(ResultSet resultSet) {
@Override
public InstructionList genByteCode(ClassGenerator _cg) {
// TODO Bytecode
throw new NotImplementedException();
/*
0: iconst_0
1: istore_1
2: iload_1
3: bipush 10
5: if_icmpge 14
8: iinc 1, 1
11: goto 2
14: return
*/
InstructionList il = new InstructionList();
il.append(head_Initializer.genByteCode(_cg));
InstructionHandle ih = il.append(head_Condition.genByteCode(_cg));
BranchInstruction branch = new IF_ICMPGE(null);
il.append(branch);
il.append(body_Loop_block.genByteCode(_cg));
il.append(head_Loop_expr.genByteCode(_cg));
il.append(new GOTO(ih));
branch.setTarget(il.append(new NOP()));
return il;
}
}

View File

@ -179,8 +179,7 @@ public class IfStmt extends Statement
@Override
public InstructionList genByteCode(ClassGenerator _cg) {
InstructionFactory _factory = new InstructionFactory(_cg, _cg.getConstantPool());
InstructionFactory _factory = _cg.getInstructionFactory();
InstructionList il = new InstructionList();
IfInstruction ifInstruction = new IFEQ(null);

View File

@ -13,6 +13,7 @@ import org.apache.commons.bcel6.generic.ObjectType;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.myexception.CTypeReconstructionException;
import de.dhbwstuttgart.myexception.JVMCodeException;
import de.dhbwstuttgart.myexception.SCExcept;
@ -152,7 +153,13 @@ public class LocalOrFieldVar extends Expr
if(this.isFieldAccess){
il.append(cg.getInstructionFactory().createFieldAccess(this.getParentClass().getName().toString(), this.get_Name(), this.getType().getBytecodeType(cg), Constants.GETFIELD));
}
il.append(cg.getInstructionFactory().createLoad(this.getType().getBytecodeType(cg), this.get_Name()));
Type type = this.getType();
org.apache.commons.bcel6.generic.Type byteCodeType = type.getBytecodeType(cg);
String name = this.get_Name();
il.append(cg.getInstructionFactory().createLoad(byteCodeType, name));
return il;
}

View File

@ -8,7 +8,7 @@ import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
public class FreshWildcardType extends Type {
public class FreshWildcardType extends ObjectType {
private static String strNextName = "A";
private Menge<Type> upperBounds = new Menge<Type>();

View File

@ -14,11 +14,17 @@ import de.dhbwstuttgart.core.IItemWithOffset;
import de.dhbwstuttgart.myexception.SCException;
import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.misc.UsedId;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeInsertable;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
import de.dhbwstuttgart.typeinference.unify.CSubstitutionGenVar;
@ -815,7 +821,7 @@ public class RefType extends ObjectType implements IMatchable
}
public org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg) {
org.apache.commons.bcel6.generic.ObjectType ret = new org.apache.commons.bcel6.generic.ObjectType(this.getTypeName());
org.apache.commons.bcel6.generic.ObjectType ret = new org.apache.commons.bcel6.generic.ObjectType(getCombinedType(cg));
if(this.IsArray()){
//Hier wird einfachhalber von einer Dimension ausgegangen. Arrays sind im Bytecode nur für main-Methode relevant
return new org.apache.commons.bcel6.generic.ArrayType(ret, 1);
@ -826,6 +832,7 @@ public class RefType extends ObjectType implements IMatchable
@Override
public String getBytecodeSignature(ClassGenerator cg) {
/*
String paramString = "";
if(this.parameter != null && this.parameter.size()>0){
paramString+="<";
@ -833,14 +840,42 @@ public class RefType extends ObjectType implements IMatchable
while(it.hasNext()){
Type param = it.next();
paramString+=param.getBytecodeSignature(cg);
//if(it.hasNext())
//paramString+=";"; //kein Delimiter zwischen den Typen
}
paramString+=">";
}
String typeSignature = this.getBytecodeType(cg).getSignature();
typeSignature = typeSignature.substring(0, typeSignature.length()-1);
return typeSignature+paramString+";";
*/
//TODO: bytecode woher bekommt ich die parent klasse
String combinedType = getCombinedType(cg);
if(!combinedType.equals(get_Name())){
// TODO bytecode createClass
Class generatedClass = ASTFactory.createClass(getCombinedType(cg), getParentClass());
cg.addExtraClass(generatedClass.genByteCode(new TypeinferenceResultSet(generatedClass, new Menge<>(), new ResultSet())).getByteCode());
}
return "L"+getCombinedType(cg)+";";
}
public String getCombinedType(ClassGenerator cg){
//Bsp.: Ljava/util/Vector<Ljava/lang/String;>;
StringBuilder sb = new StringBuilder();
if(parameter != null && parameter.size() > 0){
sb.append(this.get_Name().replace(".", "%"));
sb.append("%%");
for(Type type: parameter){
sb.append(((RefType) type).getCombinedType(cg).replace(".", "%"));
sb.append("%");
}
}else{
sb.append(this.get_Name());
}
return sb.toString();
}
}

View File

@ -2,23 +2,26 @@ package de.dhbwstuttgart.typeinference;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.bcel6.generic.ClassGen;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class ByteCodeResult{
private ClassGen byteCode;
private ClassGenerator byteCode;
//TODO: unresolvedTPHs entfernen. BROKEN!
private Menge<TypePlaceholder> unresolvedTPHs = new Menge<TypePlaceholder>();
public ByteCodeResult(ClassGen byteCode){
public ByteCodeResult(ClassGenerator byteCode){
this.byteCode = byteCode;
}
public ClassGen getByteCode(){
public ClassGenerator getByteCode(){
return byteCode;
}

View File

@ -119,8 +119,7 @@ public class TypeinferenceResultSet
* Dabei wird die codegen-Methode der inferierten Klasse mit diesem ResultSet aufgerufen.
*/
public ByteCodeResult codegen(){
ByteCodeResult res = this.ownerOfResultSet.genByteCode(this);
return res;
return this.ownerOfResultSet.genByteCode(this);
}
}

View File

@ -0,0 +1,57 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import junit.framework.TestCase;
import org.junit.BeforeClass;
import org.junit.Test;
public abstract class BytecodeTest extends TestCase{
public String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
public String testFile;
public String outputDirectory;
protected String testName;
public BytecodeTest(){
init();
if(testName != null){
testFile = testName+".jav";
outputDirectory = "";
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputDirectory);
}else{
throw new RuntimeException("rootDirectory, testFile or outputFile is null.");
}
}
protected abstract void init();
protected Class getClassToTest(){
Class classToTest = null;
try {
File file = new File(rootDirectory);
URL url = file.toURL();
URL[] urls = new URL[]{url};
ClassLoader classLoader = new URLClassLoader(urls);
classToTest = classLoader.loadClass(testName);
} catch (Exception e) {
throw new RuntimeException(e);
}
return classToTest;
}
}

View File

@ -0,0 +1,7 @@
class Condition{
Boolean method() {
return 0 == 1;
}
}

View File

@ -0,0 +1,34 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import junit.framework.TestCase;
import org.junit.Test;
import plugindevelopment.TypeInsertTester;
import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.core.MyCompilerAPI;
import de.dhbwstuttgart.logger.LoggerConfiguration;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.parser.JavaParser.yyException;
import de.dhbwstuttgart.typeinference.ByteCodeResult;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet;
public class ConditionTest {
public final static String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
public final static String testFile = "Condition.jav";
public final static String outputFile = "Condition.class";
@Test
public void test() {
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile);
}
}

View File

@ -1,6 +1,6 @@
class IfElse{
method(){
while(true){
for( i = 0; i < 10 ; i = i++){
}
}

View File

@ -1,5 +1,6 @@
package bytecode;
import org.junit.Ignore;
import org.junit.Test;
public class ForTest {
@ -8,6 +9,7 @@ public class ForTest {
public final static String outputFile = "ForTest.class";
@Test
@Ignore
public void test() {
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile);
}

View File

@ -7,6 +7,7 @@ import java.io.IOException;
import junit.framework.TestCase;
import org.junit.Ignore;
import org.junit.Test;
import plugindevelopment.TypeInsertTester;
@ -27,6 +28,7 @@ public class LambdaExpr2 {
public final static String outputFile = "LambdaExpr2.class";
@Test
@Ignore
public void test() {
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile);
}

View File

@ -7,6 +7,7 @@ import java.io.IOException;
import junit.framework.TestCase;
import org.junit.Ignore;
import org.junit.Test;
import plugindevelopment.TypeInsertTester;
@ -27,6 +28,7 @@ public class PostDecrement {
public final static String outputFile = "PostDecrement.class";
@Test
@Ignore
public void test() {
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile);
}

View File

@ -7,6 +7,7 @@ import java.io.IOException;
import junit.framework.TestCase;
import org.junit.Ignore;
import org.junit.Test;
import plugindevelopment.TypeInsertTester;
@ -27,6 +28,7 @@ public class PostIncrement {
public final static String outputFile = "PostIncrement.class";
@Test
@Ignore
public void test() {
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile);
}

View File

@ -2,10 +2,14 @@ package bytecode;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import org.apache.commons.bcel6.classfile.JavaClass;
import com.google.common.io.Files;
import junit.framework.TestCase;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.core.MyCompilerAPI;
import de.dhbwstuttgart.logger.Logger;
@ -13,24 +17,44 @@ import de.dhbwstuttgart.logger.LoggerConfiguration;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.logger.Timewatch;
import de.dhbwstuttgart.parser.JavaParser.yyException;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.typeinference.ByteCodeResult;
import de.dhbwstuttgart.typeinference.Menge;
public class SingleClassTester {
public static void compileToBytecode(String inputFile, String outputFile){
public static void compileToBytecode(String inputFile, String outputDirectory){
LoggerConfiguration logConfig = new LoggerConfiguration().setOutput(Section.PARSER, System.out);
MyCompilerAPI compiler = MyCompiler.getAPI(logConfig);
try {
compiler.parse(new File(inputFile));
Menge<ByteCodeResult> bytecode = compiler.generateBytecode(compiler.typeReconstruction().firstElement());
System.out.println(bytecode);
bytecode.firstElement().getByteCode().getJavaClass().dump(new File(outputFile));
SourceFile sf = compiler.parse(new File(inputFile));
Menge<SourceFile> sourceFiles = new Menge<>();
sourceFiles.add(sf);
Menge<ByteCodeResult> bytecode = compiler.generateBytecode(sourceFiles, compiler.typeReconstruction(sourceFiles).firstElement());
//System.out.println(bytecode);
ByteCodeResult result = bytecode.firstElement();
JavaClass javaClass = result.getByteCode().getJavaClass();
javaClass.dump(new File(outputDirectory+javaClass.getClassName()+".class"));
for(ClassGenerator cg: result.getByteCode().getExtraClasses().values()){
JavaClass jc = cg.getJavaClass();
jc.dump(new File(outputDirectory+jc.getClassName()+".class"));
}
Logger.getLogger("SingleClassTester").error(result.getByteCode().getJavaClass().toString(), Section.CODEGEN);
} catch (IOException | yyException e) {
Logger.getLogger("SingleClassTester").error(e.toString(), Section.CODEGEN);
e.printStackTrace();
TestCase.fail();
}finally{
writeLog(outputFile+".log");
writeLog(outputDirectory+".log");
}
}

View File

@ -0,0 +1,3 @@
class ExtendsObject extends Object{
}

View File

@ -0,0 +1,48 @@
package bytecode.types;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Vector;
import junit.framework.TestCase;
import org.junit.Test;
import bytecode.BytecodeTest;
import plugindevelopment.TypeInsertTester;
import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.core.MyCompilerAPI;
import de.dhbwstuttgart.logger.LoggerConfiguration;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.parser.JavaParser.yyException;
import de.dhbwstuttgart.typeinference.ByteCodeResult;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet;
public class ExtendsObjectTest extends BytecodeTest{
@Override
protected void init() {
testName = "ExtendsObject";
rootDirectory = System.getProperty("user.dir")+"/test/bytecode/types/";
}
@Test
public void testConstruct(){
try{
Class cls = getClassToTest();
Constructor method = cls.getConstructor(new Class[]{});
method.newInstance();
assertTrue(true);
}catch(Exception e){
e.printStackTrace();
fail();
}
}
}

View File

@ -0,0 +1,5 @@
import java.util.Vector;
class ExtendsVector extends Vector<Object>{
}

View File

@ -0,0 +1,5 @@
import java.util.Vector;
class ExtendsVectorString extends Vector<String>{
}

View File

@ -0,0 +1,43 @@
package bytecode.types;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Vector;
import junit.framework.TestCase;
import org.junit.Test;
import bytecode.BytecodeTest;
import plugindevelopment.TypeInsertTester;
import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.core.MyCompilerAPI;
import de.dhbwstuttgart.logger.LoggerConfiguration;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.parser.JavaParser.yyException;
import de.dhbwstuttgart.typeinference.ByteCodeResult;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet;
public class ExtendsVectorStringTest extends BytecodeTest{
@Override
protected void init() {
testName = "ExtendsVectorString";
rootDirectory = System.getProperty("user.dir")+"/test/bytecode/types/";
}
@Test
public void testConstruct() throws Exception{
Class cls = getClassToTest();
Constructor method = cls.getConstructor(new Class[]{});
method.newInstance();
assertTrue(true);
}
}

View File

@ -0,0 +1,48 @@
package bytecode.types;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Vector;
import junit.framework.TestCase;
import org.junit.Test;
import bytecode.BytecodeTest;
import plugindevelopment.TypeInsertTester;
import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.core.MyCompilerAPI;
import de.dhbwstuttgart.logger.LoggerConfiguration;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.parser.JavaParser.yyException;
import de.dhbwstuttgart.typeinference.ByteCodeResult;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet;
public class ExtendsVectorTest extends BytecodeTest{
@Override
protected void init() {
testName = "ExtendsVector";
rootDirectory = System.getProperty("user.dir")+"/test/bytecode/types/";
}
@Test
public void testConstruct(){
try{
Class cls = getClassToTest();
Constructor method = cls.getConstructor(new Class[]{});
method.newInstance();
assertTrue(true);
}catch(Exception e){
e.printStackTrace();
fail();
}
}
}

View File

@ -0,0 +1,12 @@
import java.util.Vector;
class Overloading{
void method(Vector<String> v) {
}
void method(Vector<Integer> v) {
}
}

View File

@ -0,0 +1,61 @@
package bytecode.types;
import static org.junit.Assert.*;
import java.lang.reflect.Method;
import java.util.Vector;
import org.junit.Test;
import bytecode.BytecodeTest;
public class OverloadingTest extends BytecodeTest{
@Override
protected void init() {
testName = "Overloading";
rootDirectory = System.getProperty("user.dir")+"/test/bytecode/types/";
}
@Test
public void testString() {
try{
Class cls = getClassToTest();
Object obj = cls.newInstance();
Vector<String> stringVector = new Vector<String>();
Class[] params = new Class[1];
params[0] = stringVector.getClass();
Method method = cls.getDeclaredMethod("method", params);
method.invoke(obj, stringVector);
assertTrue(true);
}catch(Exception e){
e.printStackTrace();
fail();
}
}
@Test
public void testInteger() {
try{
Class cls = getClassToTest();
Object obj = cls.newInstance();
Vector<Integer> stringVector = new Vector<Integer>();
Class[] params = new Class[1];
params[0] = stringVector.getClass();
Method method = cls.getDeclaredMethod("method", params);
method.invoke(obj, stringVector);
assertTrue(true);
}catch(Exception e){
e.printStackTrace();
fail();
}
}
}

View File

@ -0,0 +1,7 @@
import java.util.Vector;
class TypedVector{
public void method(Vector<String> v) {
}
}

View File

@ -0,0 +1,41 @@
package bytecode.types;
import static org.junit.Assert.*;
import java.lang.reflect.Method;
import java.util.Stack;
import java.util.Vector;
import org.junit.Test;
import bytecode.BytecodeTest;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
public class TypedVectorTest extends BytecodeTest{
@Override
protected void init() {
testName = "TypedVector";
rootDirectory = System.getProperty("user.dir")+"/test/bytecode/types/";
}
@Test
public void test() {
try{
Class cls = getClassToTest();
Object obj = cls.newInstance();
Vector<String> stringVector = new Vector<String>();
Class[] params = new Class[1];
params[0] = stringVector.getClass();
Method method = cls.getDeclaredMethod("method", params);
method.invoke(obj, stringVector);
assertTrue(true);
}catch(Exception e){
Logger.getLogger("SingleClassTester").error(e.toString(), Section.CODEGEN);
fail();
}
}
}

View File

@ -1,16 +0,0 @@
class Test{
void methode(){
var;
var.methode();
var.methode();
}
}
class Klasse1 {
void methode(){
}
}
class Klasse2 {
void methode(){
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,58 +0,0 @@
package unify;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import org.junit.Test;
import plugindevelopment.TypeInsertTester;
import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.core.MyCompilerAPI;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.LoggerConfiguration;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.parser.JavaParser.yyException;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet;
public class UnifyFilter {
public final static String rootDirectory = System.getProperty("user.dir")+"/test/unify/";
private final String testFile = "UnifyFilter.jav";
@Test
public void test(){
MyCompilerAPI compiler = MyCompiler.getAPI(new LoggerConfiguration().setOutput(Section.UNIFY, System.out));
try {
compiler.parse(new File(this.rootDirectory+testFile));
Menge<TypeinferenceResultSet> ergebnis = compiler.typeReconstruction();
//Nichts weiter unternehmen. Nur die Ausgabe des Unifikationsalgorithmus anzeigen.
String log = Logger.getWholeLog();
//System.out.println(log);
writeLogFile(log);
} catch (Exception e){
e.printStackTrace();
}
}
private void writeLogFile(String log){
try {
PrintWriter writer = new PrintWriter(rootDirectory+testFile+".log", "UTF-8");
writer.write(log);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

304
test/unify/UnifyTest.java Normal file
View File

@ -0,0 +1,304 @@
package unify;
import junit.framework.Assert;
import org.junit.Test;
import de.dhbwstuttgart.syntaxtree.factory.UnifyPairMengenBuilder;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.factory.Unify_FC_TTO_Builder;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.Pair.PairOperator;
import de.dhbwstuttgart.typeinference.unify.Unify;
public class UnifyTest {
@Test
public void unifyTestSimpleTypes() {
// Init Factories and Builders
UnifyTypeFactory typeFactory = new UnifyTypeFactory();
Unify_FC_TTO_Builder fcBuilder = new Unify_FC_TTO_Builder();
UnifyPairMengenBuilder assumptionBuilder = new UnifyPairMengenBuilder();
UnifyPairMengenBuilder resultBuilder = new UnifyPairMengenBuilder();
/*
* Test a <. Boolean
*/
// Init Types
RefType boolT = typeFactory.GetSimpleType("java.lang.Boolean");
TypePlaceholder aTph = typeFactory.GetTypePlaceholder("a");
// Expected Result
resultBuilder.clear();
resultBuilder.addPair(aTph, boolT, PairOperator.Equal);
resultBuilder.addPair(aTph, typeFactory.GetExtendsType(boolT),
PairOperator.Equal);
Menge<Menge<Pair>> expectedResult = resultBuilder.getNestedPairMenge();
// Actual Result
assumptionBuilder.clear();
assumptionBuilder.addPair(aTph, boolT);
Menge<Menge<Pair>> actualResult = Unify.unify(
assumptionBuilder.getPairMenge(), fcBuilder.Get_FC_TTO());
// System.out.println(expectedResult);
// System.out.println(actualResult);
Assert.assertTrue(mengeEquals(expectedResult, actualResult));
/*
* Test b <. a, a <. Boolean
*/
// Init Types
boolT = typeFactory.GetSimpleType("java.lang.Boolean");
aTph = typeFactory.GetTypePlaceholder("a");
TypePlaceholder bTph = typeFactory.GetTypePlaceholder("b");
// Expected Result
resultBuilder.clear();
resultBuilder.addPair(aTph, boolT, PairOperator.Equal);
resultBuilder.addPair(aTph, typeFactory.GetExtendsType(boolT),
PairOperator.Equal);
resultBuilder.addPair(bTph, boolT, PairOperator.Equal);
resultBuilder.addPair(bTph, typeFactory.GetExtendsType(boolT),
PairOperator.Equal);
expectedResult = resultBuilder.getNestedPairMenge();
// Actual Result
assumptionBuilder.clear();
assumptionBuilder.addPair(bTph, aTph);
assumptionBuilder.addPair(aTph, boolT);
actualResult = Unify.unify(assumptionBuilder.getPairMenge(),
fcBuilder.Get_FC_TTO());
// System.out.println(expectedResult);
// System.out.println(actualResult);
// NOTE: Elemente im actualResult sind nicht unique
// Assert.assertTrue(mengeEquals(expectedResult, actualResult));
/*
* Test b <. a, a <. b
*/
aTph = typeFactory.GetTypePlaceholder("a");
bTph = typeFactory.GetTypePlaceholder("b");
// Expected Result
resultBuilder.clear();
resultBuilder.addPair(bTph, aTph);
resultBuilder.addPair(aTph, bTph);
Menge<Pair> buffer = resultBuilder.getPairMenge();
expectedResult = new Menge<Menge<Pair>>();
expectedResult.add(buffer);
// Actual Result
assumptionBuilder.clear();
assumptionBuilder.addPair(bTph, aTph);
assumptionBuilder.addPair(aTph, bTph);
actualResult = Unify.unify(assumptionBuilder.getPairMenge(),
fcBuilder.Get_FC_TTO());
// System.out.println(expectedResult);
// System.out.println(actualResult);
Assert.assertTrue(mengeEquals(expectedResult, actualResult));
/*
* Test Integer <. a, a <. Boolean
*/
RefType intT = typeFactory.GetSimpleType("java.lang.Integer");
boolT = typeFactory.GetSimpleType("java.lang.Boolean");
aTph = typeFactory.GetTypePlaceholder("a");
bTph = typeFactory.GetTypePlaceholder("b");
// Expected Result
resultBuilder.clear();
expectedResult = resultBuilder.getNestedPairMenge();
// Actual Result
assumptionBuilder.clear();
assumptionBuilder.addPair(intT, aTph);
assumptionBuilder.addPair(aTph, boolT);
actualResult = Unify.unify(assumptionBuilder.getPairMenge(),
fcBuilder.Get_FC_TTO());
// System.out.println(expectedResult);
// System.out.println(actualResult);
Assert.assertTrue(mengeEquals(expectedResult, actualResult));
}
@Test
public void unifyTestGenerics() {
// Init Factories and Builders
UnifyTypeFactory typeFactory = new UnifyTypeFactory();
Unify_FC_TTO_Builder fcBuilder = new Unify_FC_TTO_Builder();
UnifyPairMengenBuilder assumptionBuilder = new UnifyPairMengenBuilder();
UnifyPairMengenBuilder resultBuilder = new UnifyPairMengenBuilder();
/*
* Test a <. MyClass<T, F>
*/
TypePlaceholder aTph = typeFactory.GetTypePlaceholder("a");
RefType myType = typeFactory.GetSimpleType("MyClass",
typeFactory.GetTypePlaceholder("T"),
typeFactory.GetTypePlaceholder("F"));
// Expected Result
resultBuilder.clear();
resultBuilder.addPair(aTph, myType, PairOperator.Equal);
resultBuilder.addPair(aTph, typeFactory.GetExtendsType(myType));
Menge<Menge<Pair>> expectedResult = resultBuilder.getNestedPairMenge();
// Actual Result
assumptionBuilder.clear();
assumptionBuilder.addPair(aTph, myType);
Menge<Menge<Pair>> actualResult = Unify.unify(
assumptionBuilder.getPairMenge(), fcBuilder.Get_FC_TTO());
// System.out.println(expectedResult);
// System.out.println(actualResult);
Assert.assertTrue(mengeEquals(expectedResult, actualResult));
/*
* Test List<List<T>> <. List<T>
*/
TypePlaceholder tTph = typeFactory.GetTypePlaceholder("T");
RefType list = typeFactory.GetSimpleType("List", tTph);
RefType listlist = typeFactory.GetSimpleType("List", list);
// Expected Result
resultBuilder.clear();
resultBuilder.addPair(typeFactory.GetExtendsType(list), tTph,
PairOperator.Equal);
expectedResult = resultBuilder.getNestedPairMenge();
// Actual Result
assumptionBuilder.clear();
assumptionBuilder.addPair(listlist, list);
actualResult = Unify.unify(assumptionBuilder.getPairMenge(),
fcBuilder.Get_FC_TTO());
System.out.println(expectedResult);
System.out.println(actualResult);
Assert.assertTrue(mengeEquals(expectedResult, actualResult));
/*
* Test List<T> <. List<List<T>>
*/
}
@Test
public void unifyTestInheritance() {
// Init Factories and Builders
UnifyTypeFactory typeFactory = new UnifyTypeFactory();
Unify_FC_TTO_Builder fcBuilder = new Unify_FC_TTO_Builder();
UnifyPairMengenBuilder assumptionBuilder = new UnifyPairMengenBuilder();
UnifyPairMengenBuilder resultBuilder = new UnifyPairMengenBuilder();
// Init Types
RefType tBool = typeFactory.GetSimpleType("java.lang.Boolean");
RefType tString = typeFactory.GetSimpleType("java.lang.String");
RefType tInt = typeFactory.GetSimpleType("java.lang.Integer");
TypePlaceholder tphA = typeFactory.GetTypePlaceholder("a");
// Build inheritance hierachy
// Bool <. String <. Int
fcBuilder.AddInheritance(tBool, tString);
fcBuilder.AddInheritance(tString, tInt);
// Build Assumptions
assumptionBuilder.addPair(tphA, tString);
// Build expected result
resultBuilder.addPair(tphA, tBool, PairOperator.Equal);
resultBuilder.addPair(tphA, typeFactory.GetExtendsType(tBool),
PairOperator.Equal);
resultBuilder.addPair(tphA, tString, PairOperator.Equal);
resultBuilder.addPair(tphA, typeFactory.GetExtendsType(tString),
PairOperator.Equal);
// Assert
Menge<Menge<Pair>> actualResult = Unify.unify(
assumptionBuilder.getPairMenge(), fcBuilder.Get_FC_TTO());
// System.out.println(actualResult);
// System.out.println("-------------------");
// System.out.println(resultBuilder.getNestedPairMenge());
Assert.assertTrue(mengeEquals(resultBuilder.getNestedPairMenge(),
actualResult));
}
@Test
public void unifyTestWildcards() {
}
private static boolean mengeEquals(Menge<Menge<Pair>> m1,
Menge<Menge<Pair>> m2) {
if (m1.size() != m2.size())
return false;
return containsAll(m1, m2) && containsAll(m2, m1);
}
private static boolean containsAll(Menge<Menge<Pair>> m1,
Menge<Menge<Pair>> m2) {
for (Menge<Pair> elem : m2)
if (!contains(m1, elem))
return false;
return true;
}
private static boolean contains(Menge<Menge<Pair>> m1, Menge<Pair> m2) {
for (Menge<Pair> elem : m1)
if (mengePairEquals(elem, m2))
return true;
return false;
}
private static boolean mengePairEquals(Menge<Pair> m1, Menge<Pair> m2) {
if (m1.size() != m2.size())
return false;
return containsAllPair(m1, m2) && containsAllPair(m2, m1);
}
private static boolean containsAllPair(Menge<Pair> m1, Menge<Pair> m2) {
for (Pair elem : m1)
if (contains(m2, elem))
return true;
return false;
}
private static boolean contains(Menge<Pair> m, Pair p) {
for (Pair elem : m)
if (pairEquals(elem, p))
return true;
return false;
}
private static boolean pairEquals(Pair p1, Pair p2) {
return (p1.TA1.equals(p2.TA1) && p1.TA2.equals(p2.TA2))
|| (p1.TA1.equals(p2.TA2) && p1.TA2.equals(p2.TA1));
}
}