forked from JavaTX/JavaCompilerCore
863 lines
34 KiB
Java
Executable File
863 lines
34 KiB
Java
Executable File
// 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;
|
||
import java.io.FileReader;
|
||
import java.io.IOException;
|
||
import java.io.Reader;
|
||
import java.io.StringReader;
|
||
import java.util.Vector;
|
||
|
||
import de.dhbwstuttgart.logger.Logger;
|
||
import de.dhbwstuttgart.logger.Section;
|
||
import de.dhbwstuttgart.bytecode.ClassFile;
|
||
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;
|
||
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;
|
||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||
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.FunNInterface;
|
||
import de.dhbwstuttgart.typeinference.Pair;
|
||
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;
|
||
|
||
|
||
|
||
// 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");
|
||
// 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
|
||
|
||
|
||
// ino.attribute.m_AbstractSyntaxTree.21280.decldescription type=javadoc
|
||
/**
|
||
* Der abstrake Syntaxbaum
|
||
* <br/>Autor: J<>rg B<>uerle
|
||
*/
|
||
// ino.end
|
||
// ino.attribute.m_AbstractSyntaxTree.21280.declaration
|
||
private Vector<SourceFile> m_AbstractSyntaxTree = new Vector<SourceFile>();
|
||
// ino.end
|
||
|
||
// ino.method.MyCompiler.21283.defdescription type=javadoc
|
||
/**
|
||
* Author: J<>rg B<>uerle<br/>
|
||
* Der private Konstruktor. Es soll von au<61>en kein Compiler angelegt werden
|
||
* k<>nnen, sondern nur eine API zur Verf<72>gung gestellt werden.
|
||
* @param logger Konfiguration f<>r Debug Ausgabe TODO
|
||
*/
|
||
// 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: J<>rg B<>uerle<br/>
|
||
* Stellt eine neue Instanz der CompilerAPI zur Verf<72>gung.
|
||
* 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()
|
||
// ino.end
|
||
// ino.method.getAPI.21286.body
|
||
{
|
||
return new MyCompiler();
|
||
}
|
||
// ino.end
|
||
|
||
public Vector<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<65>t.
|
||
* Beim Parsen werden n<>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(Vector<Type> Parameter, Vector<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: f<>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 f<>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
|
||
* <code>NewTVar(jclass)</code> (siehe Algorithmus 5.17 TRProg, Martin Pl<50>micke)
|
||
* aufgerufen.
|
||
* <br/>Author: J<>rg B<>uerle
|
||
* @param reader
|
||
* @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 l<>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: f<>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
|
||
// Vector 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;
|
||
Vector<mycompiler.myclass.Field> tempVectorFieldDecl;
|
||
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 <20>ber alle fielddeclarations
|
||
tempVectorFieldDecl = tempKlassBody.getFields();
|
||
for( int k = 0; k < tempVectorFieldDecl.size(); k++ )
|
||
{
|
||
tempFieldDecl = tempVectorFieldDecl.elementAt(k);
|
||
if( tempFieldDecl instanceof Constructor )
|
||
{
|
||
//parserlog.debug("T->Konstruktor: " + ((DeclId)tempFieldDecl.get_Name().elementAt(0)).get_Name() + " - ReturnType: " + tempFieldDecl.getTypeName());
|
||
|
||
// pr<70>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.setDeclIdVector( Konstruktor.getDeclIdVector() );
|
||
// types_in_parameterlist wird wohl erst sp<73>ter und intern gef<65>llt
|
||
|
||
// R<>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!
|
||
tempVectorFieldDecl.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());
|
||
}
|
||
|
||
}
|
||
|
||
// Debugg-Infos
|
||
parserlog.debug("");
|
||
parserlog.debug("T->NEUE Felddeklarationen f<>r die Klasse:" + strKlasse);
|
||
parserlog.debug( "-----------------------------------------");
|
||
for( int k = 0; k < tempVectorFieldDecl.size(); k++ )
|
||
{
|
||
tempFieldDecl = tempVectorFieldDecl.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;
|
||
Vector<FormalParameter> tempVFktPara;
|
||
FormalParameter tempFP;
|
||
Method tempMethod;
|
||
Type tempReturn;
|
||
Type tempType;
|
||
for( int k = 0; k < tempVectorFieldDecl.size(); k++ )
|
||
{
|
||
tempFieldDecl = tempVectorFieldDecl.elementAt(k);
|
||
tempMethod = null;
|
||
|
||
if( tempFieldDecl instanceof Method )
|
||
{
|
||
tempMethod = (Method)tempFieldDecl;
|
||
tempReturn = tempMethod.getReturnType();
|
||
|
||
// Funktionen ohne definierten R<>ckgabetyp suchen!!!
|
||
if( tempReturn instanceof TypePlaceholder )
|
||
{
|
||
// Methode mit nicht-definiertem R<>ckgabetyp gefunden!
|
||
|
||
// #JB# 31.03.2005
|
||
// ###########################################################
|
||
// Wird bereits <20>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 <20>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: J<>rg B<>uerle<br/>
|
||
* 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: J<>rg B<>uerle<br/>
|
||
* Ruft die Parse-Methode.
|
||
* @param file Die Quellcode-Datei
|
||
* @throws FileNotFoundException Wenn die Quellcode-Datei nicht existiert.
|
||
* @throws IOException Wenn was schief l<>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
|
||
{
|
||
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: J<>rg B<>uerle<br/>
|
||
* Ruft den Typrekonstruktionsalgorithmus auf.
|
||
* @return Die Menge aller m<>glichen Typkombinationen
|
||
* @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 Vector<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!");
|
||
}
|
||
inferencelog.info("##########################################", Section.TYPEINFERENCE);
|
||
inferencelog.info("# TypeReconstruction-Algorithmus - START #", Section.TYPEINFERENCE);
|
||
inferencelog.info("##########################################\n", Section.TYPEINFERENCE);
|
||
|
||
TypeAssumptions globalAssumptions = makeFunNAssumptions();
|
||
Vector<TypeinferenceResultSet> result = new Vector<TypeinferenceResultSet>();
|
||
for(SourceFile srcFile : m_AbstractSyntaxTree){
|
||
result.addAll(srcFile.typeReconstruction(globalAssumptions));
|
||
|
||
}
|
||
|
||
inferencelog.info("#########################################", Section.TYPEINFERENCE);
|
||
inferencelog.info("# TypeReconstruction-Algorithmus - ENDE #", Section.TYPEINFERENCE);
|
||
inferencelog.info("#########################################\n", Section.TYPEINFERENCE);
|
||
|
||
return result;
|
||
}
|
||
// ino.end
|
||
|
||
/**
|
||
* Erstellt die FunN-Assumptions
|
||
* Fun0-FunN (momentan f<>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());
|
||
}
|
||
|
||
|
||
return ret;
|
||
}
|
||
|
||
/**
|
||
* Author: J<>rg B<>uerle<br/>
|
||
* Generiert den Bytecode und das Class-File f<>r den Syntaxbaum.
|
||
* @throws NullPointerException Wenn noch kein abstrakter Syntaxbaum vorhanden
|
||
* ist.
|
||
|
||
@Override
|
||
public Vector<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 ...");
|
||
|
||
Vector<ClassFile> ret = new Vector<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, <20>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
|
||
{
|
||
MyCompilerAPI compiler = MyCompiler.getAPI();
|
||
|
||
// 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
|
||
/*
|
||
// 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 Vector x; => java.util.Vector 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(Vector<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<61>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 L<>dtke
|
||
* Ersetzt alle GTVs durch TPHs mit gleichem Namen. Arbeitet Rekursiv.
|
||
* ACHTUNG: BACKDOOR CREATE!!! Nur f<>r Testzwecke verwenden.
|
||
* @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)
|
||
{
|
||
Vector<Type> paras = refT.get_ParaList();
|
||
for(int i = 0; i<paras.size();i++)
|
||
{
|
||
Type tt = paras.elementAt(i);
|
||
if(tt instanceof GenericTypeVar)
|
||
{
|
||
GenericTypeVar gtv = (GenericTypeVar)tt;
|
||
paras.set(i,TypePlaceholder.backdoorCreate(gtv.getName().toString()));
|
||
}
|
||
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.
|
||
*/
|
||
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();
|
||
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 Vector von Dateinamen. Alle diese Dateien werden zu einem SyntaxBaum geparst.
|
||
*/
|
||
public void parse(Vector<String> filenames) throws ParserError {
|
||
|
||
for(String filename : filenames){
|
||
StringBuffer fileData = new StringBuffer();
|
||
BufferedReader reader;
|
||
try {
|
||
reader = new BufferedReader(
|
||
new FileReader(filename));
|
||
} catch (FileNotFoundException e) {
|
||
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<6E>ngen...
|
||
|
||
}
|
||
/*
|
||
String gesamterSrc = "";
|
||
//Hier werden alle <20>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<6E>ngen...
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
throw new TypinferenzException("Die <20>bergebenen Dateien konnten nicht zum Parsen eingelesen werden.");
|
||
}
|
||
}
|
||
|
||
try {
|
||
// und anschlie<69>end zum Parsen <20>bergeben.
|
||
this.parse(gesamterSrc.toString());
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
//throw new TypinferenzException("Fehler beim Parsen");
|
||
}
|
||
|
||
*/
|
||
}
|
||
|
||
@Override
|
||
public SourceFile parse(String sourceCode) {
|
||
SourceFile ret = this.parse2SyntaxTree(new StringReader(sourceCode));
|
||
this.m_AbstractSyntaxTree.add(ret);
|
||
return ret;
|
||
}
|
||
|
||
@Override
|
||
public Vector<ClassFile> codeGeneration(ResultSet result)
|
||
throws NullPointerException, JVMCodeException {
|
||
// TODO Auto-generated method stub
|
||
return null;
|
||
}
|
||
}
|
||
// ino.end
|