JavaPatternMatching/src/de/dhbwstuttgart/core/MyCompiler.java

874 lines
35 KiB
Java
Raw Normal View History

2013-10-18 11:33:46 +00:00
// ino.module.MyCompiler.8569.package
2014-09-02 08:33:54 +00:00
package de.dhbwstuttgart.core;
2013-10-18 11:33:46 +00:00
// ino.end
// ino.module.MyCompiler.8569.import
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import de.dhbwstuttgart.typeinference.Menge;
2014-10-09 10:01:16 +00:00
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.LoggerConfiguration;
2014-11-04 12:47:05 +00:00
import de.dhbwstuttgart.logger.Section;
2014-09-04 14:35:44 +00:00
import de.dhbwstuttgart.myexception.CTypeReconstructionException;
import de.dhbwstuttgart.myexception.JVMCodeException;
import de.dhbwstuttgart.parser.JavaParser;
import de.dhbwstuttgart.parser.Scanner;
import de.dhbwstuttgart.parser.JavaParser.yyException;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.ClassBody;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.ImportDeclarations;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList;
2014-09-04 14:35:44 +00:00
import de.dhbwstuttgart.syntaxtree.SourceFile;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.syntaxtree.misc.DeclId;
import de.dhbwstuttgart.syntaxtree.misc.UsedId;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.IMatchable;
import de.dhbwstuttgart.syntaxtree.type.ITypeContainer;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ByteCodeResult;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.typeinference.FunNInterface;
2015-07-08 15:46:54 +00:00
import de.dhbwstuttgart.typeinference.FunVoidNInterface;
2014-09-08 13:12:47 +00:00
import de.dhbwstuttgart.typeinference.Pair;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.typeinference.exceptions.ParserError;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
2013-10-18 11:33:46 +00:00
// 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
// 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");
2013-10-18 11:33:46 +00:00
// ino.end
// ino.attribute.inferencelog.21268.declaration
protected static Logger inferencelog = Logger.getLogger(MyCompiler.class.getName());
2013-10-18 11:33:46 +00:00
// ino.end
// ino.attribute.parserlog.21271.declaration
//protected static Logger parserlog = Logger.getLogger("parser");
2013-10-18 11:33:46 +00:00
// ino.end
// ino.attribute.OutputDir.21274.declaration
protected String OutputDir = "";
// ino.end
// ino.attribute.m_AbstractSyntaxTree.21280.decldescription type=javadoc
/**
* Der abstrake Syntaxbaum
* <br/>Autor: ¯Â¿Â½rg ¯Â¿Â½uerle
2013-10-18 11:33:46 +00:00
*/
// ino.end
// ino.attribute.m_AbstractSyntaxTree.21280.declaration
private Menge<SourceFile> m_AbstractSyntaxTree = new Menge<SourceFile>();
2013-10-18 11:33:46 +00:00
// 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
2013-10-18 11:33:46 +00:00
*/
// ino.end
// ino.method.MyCompiler.21283.definition
private MyCompiler()
// ino.end
// ino.method.MyCompiler.21283.body
{
this.init();
}
// ino.end
// ino.method.getAPI.21286.defdescription type=javadoc
/**
* Author: rg ¤uerle<br/>
* Stellt eine neue Instanz der CompilerAPI zur Verf�gung.
2013-10-18 11:33:46 +00:00
* Diese Methode sollte von der IDE aus aufgerufen werden,
* um eine Quellcode-Datei zu kompilieren.
* @return Die Compiler-API
*/
// ino.end
// ino.method.getAPI.21286.definition
public static MyCompilerAPI getAPI(LoggerConfiguration loggerConfig)
2013-10-18 11:33:46 +00:00
// ino.end
// ino.method.getAPI.21286.body
{
Logger.setStandardConfiguration(loggerConfig);
return new MyCompiler();
2013-10-18 11:33:46 +00:00
}
// ino.end
public Menge<Pair> testPair = null;
2013-10-18 11:33:46 +00:00
// 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
2013-10-18 11:33:46 +00:00
* 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
2014-11-04 12:47:05 +00:00
2013-10-18 11:33:46 +00:00
// ino.end
// ino.method.wandleGeneric2RefType.21289.definition
public static void wandleGeneric2RefType(Menge<Type> Parameter, Menge<Class> KlassenVektor )
2013-10-18 11:33:46 +00:00
// 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: f�r GenericTypeVar existiert eine gleichnamige Klasse
2013-10-18 11:33:46 +00:00
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 f�r GenericTypeVar eine deklarierte Klasse
2013-10-18 11:33:46 +00:00
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 )
{
2014-09-02 16:49:19 +00:00
RefType RNeu = new RefType( TempParameter.getName().toString(), null,TempParameter.getOffset());
2013-10-18 11:33:46 +00:00
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)" );
2013-10-18 11:33:46 +00:00
//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
2014-11-04 12:47:05 +00:00
*/
2013-10-18 11:33:46 +00:00
// 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
* <code>NewTVar(jclass)</code> (siehe Algorithmus 5.17 TRProg, Martin Pl�micke)
2013-10-18 11:33:46 +00:00
* aufgerufen.
* <br/>Author: ¯Â¿Â½rg ¯Â¿Â½uerle
2013-10-18 11:33:46 +00:00
* @param reader
* @throws IOException
* @throws JavaParser.yyException
*/
// ino.end
// ino.method.parse.21292.definition
private void parse_backup(Reader reader)
2013-10-18 11:33:46 +00:00
throws IOException, JavaParser.yyException
// ino.end
// ino.method.parse.21292.body
{
/*
2013-10-18 11:33:46 +00:00
parserlog.info("#########################################");
parserlog.info("# Parsen - START #");
parserlog.info("#########################################\n");
//////////////////////////////////////
// Alte Daten l�schen:
2013-10-18 11:33:46 +00:00
//////////////////////////////////////
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: f�r TypePlaceholder existiert eine gleichnamige Klasse
2013-10-18 11:33:46 +00:00
// 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();
2013-10-18 11:33:46 +00:00
// 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;
2014-02-11 01:47:39 +00:00
mycompiler.myclass.Field tempFieldDecl = null;
2013-10-18 11:33:46 +00:00
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);
2013-10-18 11:33:46 +00:00
parserlog.debug( "------------------------------------");
// Schleife �ber alle fielddeclarations
tempMengeFieldDecl = tempKlassBody.getFields();
for( int k = 0; k < tempMengeFieldDecl.size(); k++ )
2013-10-18 11:33:46 +00:00
{
tempFieldDecl = tempMengeFieldDecl.elementAt(k);
2013-10-18 11:33:46 +00:00
if( tempFieldDecl instanceof Constructor )
{
2014-02-11 01:47:39 +00:00
//parserlog.debug("T->Konstruktor: " + ((DeclId)tempFieldDecl.get_Name().elementAt(0)).get_Name() + " - ReturnType: " + tempFieldDecl.getTypeName());
2013-10-18 11:33:46 +00:00
// pr�fen, ob Construktorname == Klassenname - falls nein: Construktor in Methode umwandeln !!!
2013-10-18 11:33:46 +00:00
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
2013-10-18 11:33:46 +00:00
// R�ckgabetyp = Objekt der Klasse 'TypePlaceholder'
2013-10-18 11:33:46 +00:00
// #JB# 31.03.2005
// ###########################################################
Methode.setReturnType(TypePlaceholder.fresh(Methode));
2013-10-18 11:33:46 +00:00
//Methode.setReturnType( new TypePlaceholder("###NEU###") );
// ###########################################################
// Element an der Position k durch neues ersetzen!
tempMengeFieldDecl.setElementAt( Methode, k );
2013-10-18 11:33:46 +00:00
}
}
if( tempFieldDecl instanceof Method && !(tempFieldDecl instanceof Constructor) )
{
2014-02-11 01:47:39 +00:00
//parserlog.debug("T->Methode: " + ((DeclId)tempFieldDecl.get_Name().elementAt(0)).get_Name() + " - ReturnType: " + tempFieldDecl.getTypeName());
2013-10-18 11:33:46 +00:00
}
2014-02-11 01:47:39 +00:00
2013-10-18 11:33:46 +00:00
}
// Debugg-Infos
parserlog.debug("");
parserlog.debug("T->NEUE Felddeklarationen f�r die Klasse:" + strKlasse);
2013-10-18 11:33:46 +00:00
parserlog.debug( "-----------------------------------------");
for( int k = 0; k < tempMengeFieldDecl.size(); k++ )
2013-10-18 11:33:46 +00:00
{
tempFieldDecl = tempMengeFieldDecl.elementAt(k);
2013-10-18 11:33:46 +00:00
//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;
2013-10-18 11:33:46 +00:00
FormalParameter tempFP;
Method tempMethod;
Type tempReturn;
Type tempType;
for( int k = 0; k < tempMengeFieldDecl.size(); k++ )
2013-10-18 11:33:46 +00:00
{
tempFieldDecl = tempMengeFieldDecl.elementAt(k);
2013-10-18 11:33:46 +00:00
tempMethod = null;
if( tempFieldDecl instanceof Method )
{
tempMethod = (Method)tempFieldDecl;
tempReturn = tempMethod.getReturnType();
// Funktionen ohne definierten R�ckgabetyp suchen!!!
2013-10-18 11:33:46 +00:00
if( tempReturn instanceof TypePlaceholder )
{
// Methode mit nicht-definiertem R�ckgabetyp gefunden!
2013-10-18 11:33:46 +00:00
// #JB# 31.03.2005
// ###########################################################
// Wird bereits �ber fresh() gemacht!!
2013-10-18 11:33:46 +00:00
//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!!
2013-10-18 11:33:46 +00:00
//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");
*/
2013-10-18 11:33:46 +00:00
} // end Methode parse()
// ino.end
/////////////////////////////////////////////////////////////////////////////////////////////////
// Implementierte API-Methoden:
/////////////////////////////////////////////////////////////////////////////////////////////////
// ino.method.init.21295.defdescription type=javadoc
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
2013-10-18 11:33:46 +00:00
* Initialisiert den Compiler
*/
// ino.end
// ino.method.init.21295.definition
public void init()
// ino.end
// ino.method.init.21295.body
{
TypePlaceholder.deleteRegistry();
// Log4J fuer die Ausgabe vorbereiten
//DOMConfigurator.configure("log4j.xml");
}
// ino.end
// ino.method.parse.21298.defdescription type=javadoc
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
2013-10-18 11:33:46 +00:00
* Ruft die Parse-Methode.
* @param file Die Quellcode-Datei
* @throws FileNotFoundException Wenn die Quellcode-Datei nicht existiert.
* @throws IOException Wenn was schief ¯Â¿Â½uft.
2013-10-18 11:33:46 +00:00
* @throws JavaParser.yyException Wenn ein Fehler beim Parsen auftritt.
*/
// ino.end
// ino.method.parse.21298.definition
2014-03-14 15:34:25 +00:00
public SourceFile parse(File file)
2013-10-18 11:33:46 +00:00
throws FileNotFoundException, IOException, JavaParser.yyException
// ino.end
// ino.method.parse.21298.body
{
FileReader fr = new FileReader(file);
2014-03-14 15:34:25 +00:00
SourceFile ret = this.parse2SyntaxTree(fr);
this.m_AbstractSyntaxTree.add(ret);
2013-10-18 11:33:46 +00:00
fr.close();
2014-03-14 15:34:25 +00:00
return ret;
2013-10-18 11:33:46 +00:00
}
// ino.end
2013-10-18 11:33:46 +00:00
// ino.method.typeReconstruction.21304.defdescription type=javadoc
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
2013-10-18 11:33:46 +00:00
* Ruft den Typrekonstruktionsalgorithmus auf.
* @return Die Menge aller ¯Â¿Â½glichen Typkombinationen
2013-10-18 11:33:46 +00:00
* @throws NullPointerException Wenn noch kein abstrakter Syntaxbaum vorhanden
* ist. @throws CTypeReconstructionException Wenn ein Fehler bei der
* Typrekonstruktion auftritt.
*/
// ino.end
// ino.method.typeReconstruction.21304.definition
public Menge<TypeinferenceResultSet> typeReconstruction()
2013-10-18 11:33:46 +00:00
throws NullPointerException, CTypeReconstructionException
// ino.end
// ino.method.typeReconstruction.21304.body
{
if(m_AbstractSyntaxTree==null){
throw new NullPointerException("Es wurde noch kein Abstrakter Syntaxbaum erstellt!");
}
2014-11-04 12:47:05 +00:00
inferencelog.info("##########################################", Section.TYPEINFERENCE);
inferencelog.info("# TypeReconstruction-Algorithmus - START #", Section.TYPEINFERENCE);
inferencelog.info("##########################################\n", Section.TYPEINFERENCE);
2014-02-11 01:47:39 +00:00
TypeAssumptions globalAssumptions = makeFunNAssumptions();
Menge<TypeinferenceResultSet> result = new Menge<TypeinferenceResultSet>();
for(SourceFile srcFile : m_AbstractSyntaxTree){
result.addAll(srcFile.typeReconstruction(globalAssumptions));
}
2014-02-11 01:47:39 +00:00
2014-11-04 12:47:05 +00:00
inferencelog.info("#########################################", Section.TYPEINFERENCE);
inferencelog.info("# TypeReconstruction-Algorithmus - ENDE #", Section.TYPEINFERENCE);
inferencelog.info("#########################################\n", Section.TYPEINFERENCE);
2013-10-18 11:33:46 +00:00
return result;
}
// ino.end
/**
* Erstellt die FunN-Assumptions
* Fun0-FunN (momentan ¼r N = 6)
* @return
*/
private TypeAssumptions makeFunNAssumptions(){
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());
}
2015-07-08 15:46:54 +00:00
for(int i = 0; i<6; i++){
FunVoidNInterface funN = new FunVoidNInterface(i);
ret.add(funN.getPublicFieldAssumptions());
}
return ret;
}
2013-10-18 11:33:46 +00:00
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
* Generiert den Bytecode und das Class-File ¯Â¿Â½r den Syntaxbaum.
2013-10-18 11:33:46 +00:00
* @throws NullPointerException Wenn noch kein abstrakter Syntaxbaum vorhanden
* ist.
2014-09-02 16:49:19 +00:00
@Override
public Menge<ClassFile> codeGeneration(ResultSet result)
2013-10-18 11:33:46 +00:00
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));
}
2013-10-18 11:33:46 +00:00
codegenlog.info("Codegenerierung beendet!");
return ret;
2014-09-02 16:49:19 +00:00
}*/
2013-10-18 11:33:46 +00:00
// ino.method.main.21313.defdescription type=javadoc
/**
* Die Main-Funktion, �ber die der Compiler auch per Konsole gestartet
2013-10-18 11:33:46 +00:00
* 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
{
MyCompilerAPI compiler = MyCompiler.getAPI(new LoggerConfiguration());
2013-10-18 11:33:46 +00:00
// Hier koennten ggf. Aenderungen der Ausgabeeinstellungen
// (Debuginfos) vorgenommen werden -> LOG4J
try {
compiler.parse(new File(args[0]));
} catch (FileNotFoundException e) {
System.err.println("Die Datei \""+args[0]+"\" konnte nicht gefunden werden.");
System.exit(0);
} catch (IOException e) {
System.err.println("Fehler beim Parsen:");
System.err.println(e);
System.exit(0);
} catch (yyException e) {
System.err.println("Fehler beim Parsen:");
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
{
char c = dir.charAt(dir.length()-1);
if (c != '/' & c != '\\') dir = dir + "/";
OutputDir = dir;
// Verzeichnis(se) ggf. anlegen
File f = new File(dir);
f.mkdirs();
}
// ino.end
// ino.method.getOutputDir.21319.definition
public String getOutputDir()
// ino.end
// ino.method.getOutputDir.21319.body
{
return OutputDir;
}
// ino.end
2014-09-03 14:15:04 +00:00
/*
2013-10-18 11:33:46 +00:00
// 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)){
2014-09-02 16:49:19 +00:00
ret=(impDecl.getQualifiedName().toString());
2013-10-18 11:33:46 +00:00
break;
}
}
return ret;
}
// ino.end
2014-09-03 14:15:04 +00:00
*/
2013-10-18 11:33:46 +00:00
// 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;
2013-10-18 11:33:46 +00:00
* @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
2014-09-03 14:15:04 +00:00
2013-10-18 11:33:46 +00:00
// ino.end
// ino.method.makeRefTypesFullyQualified.21325.definition
public static void makeRefTypesFullyQualified(Menge<Type> containedTypes, ImportDeclarations declarations)
2013-10-18 11:33:46 +00:00
// 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
2013-10-18 11:33:46 +00:00
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
2014-09-03 14:15:04 +00:00
*/
2013-10-18 11:33:46 +00:00
/**
* @author Arne ¼dtke
2013-10-18 11:33:46 +00:00
* Ersetzt alle GTVs durch TPHs mit gleichem Namen. Arbeitet Rekursiv.
* ACHTUNG: BACKDOOR CREATE!!! Nur ¼r Testzwecke verwenden.
2013-10-18 11:33:46 +00:00
* @param T - Typ, bei welchem die GTVs ersetzt werden sollen.
*/
public static Type makeGenericTypeVars2TypePlaceHolders(Type T)
{
if(T instanceof RefType)
{
RefType refT = (RefType)T;
if(refT.get_ParaList() != null)
{
Menge<Type> paras = refT.get_ParaList();
2013-10-18 11:33:46 +00:00
for(int i = 0; i<paras.size();i++)
{
Type tt = paras.elementAt(i);
if(tt instanceof GenericTypeVar)
{
GenericTypeVar gtv = (GenericTypeVar)tt;
2014-09-02 16:49:19 +00:00
paras.set(i,TypePlaceholder.backdoorCreate(gtv.getName().toString()));
2013-10-18 11:33:46 +00:00
}
else
{
makeGenericTypeVars2TypePlaceHolders(tt);
}
}
}
}
else if(T instanceof IMatchable)
{
Type TT = ((IMatchable)T).getMatchType();
makeGenericTypeVars2TypePlaceHolders(TT);
}
return T;
}
/**
* Parst den Inhalt einer Datei zu einem Syntaxbaum.
*/
2014-04-15 12:56:20 +00:00
private SourceFile parse2SyntaxTree(Reader fileContent) throws ParserError{
//StringReader reader = new StringReader(fileContent);
//////////////////////////////////////
// Scanner und Parser erzeugen:
//////////////////////////////////////
Scanner scanner = new Scanner(fileContent);
JavaParser parser = new JavaParser();
//////////////////////////////////////
// Parsen ==> Ergebnis: srcFile
//////////////////////////////////////
SourceFile srcFile = null;
try {
srcFile = (SourceFile) parser.yyparse( scanner );
} catch (IOException | yyException e) {
e.printStackTrace();
2014-04-15 12:56:20 +00:00
if(e instanceof yyException)throw new ParserError((yyException)e);
}
//////////////////////////////////////
// Postprocessing:
//////////////////////////////////////
srcFile.parserPostProcessing(null); //Muss mit null aufgerufen werden.
//Fertig:
return srcFile;
}
/**
* Diese Funktion nimmt einen Menge von Dateinamen. Alle diese Dateien werden zu einem SyntaxBaum geparst.
2013-10-18 11:33:46 +00:00
*/
public void parse(Menge<String> filenames) throws ParserError {
for(String filename : filenames){
StringBuffer fileData = new StringBuffer();
BufferedReader reader;
try {
reader = new BufferedReader(
new FileReader(filename));
} catch (FileNotFoundException e) {
2014-04-15 12:56:20 +00:00
throw new DebugException("Die Datei "+ filename+" konnte nicht gelesen werden.");
}
char[] buf = new char[1024];
int numRead=0;
try {
while((numRead=reader.read(buf)) != -1){
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
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...
}
/*
2013-10-18 11:33:46 +00:00
String gesamterSrc = "";
//Hier werden alle übergebenen Dateinamen abgearbeitet:
2013-10-18 11:33:46 +00:00
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...
2013-10-18 11:33:46 +00:00
} catch (Exception e) {
e.printStackTrace();
throw new TypinferenzException("Die übergebenen Dateien konnten nicht zum Parsen eingelesen werden.");
2013-10-18 11:33:46 +00:00
}
}
try {
// und anschließend zum Parsen übergeben.
2013-10-18 11:33:46 +00:00
this.parse(gesamterSrc.toString());
} catch (Exception e) {
e.printStackTrace();
//throw new TypinferenzException("Fehler beim Parsen");
}
*/
2013-10-18 11:33:46 +00:00
}
@Override
public SourceFile parse(String sourceCode) {
SourceFile ret = this.parse2SyntaxTree(new StringReader(sourceCode));
this.m_AbstractSyntaxTree.add(ret);
return ret;
}
@Override
public Menge<Menge<ByteCodeResult>> generateBytecode(TypeinferenceResultSet typeinferenceResult) {
2015-08-27 11:36:14 +00:00
//SourceFile parsedFile = this.m_AbstractSyntaxTree.firstElement();
//Class parsedClass = parsedFile.KlassenVektor.firstElement();
Menge<Menge<ByteCodeResult>> ret = new Menge<>();
2015-08-27 11:36:14 +00:00
for(SourceFile sf : this.m_AbstractSyntaxTree){
ret.addAll(sf.generateBytecode(typeinferenceResult));
}
2015-08-27 11:36:14 +00:00
return ret;
}
2013-10-18 11:33:46 +00:00
}
// ino.end