
# Typinferenz

## Generische Variablen
### GTVs in Constraints
* GTVs können in Constraints auf 2 Arten auftauchen.
	* Als GTZ und als TPH
* In folgenden Fällen als TPH:
	* Die Generische Variable ist nicht in dem Bereich definiert, in dem sie benutzt wird.
	* Es kann auch vorkommen, dass die Generische Variable in der gleichen Klasse definiert wurde, aber für eine andere Methode gilt.
	
* In folgenden Fällen als GTV:
	* Die Generische Variable ist für den Bereich definiert, in dem der Constraint generiert wird.
	* In der selben Methode oder der selben Klasse. Dies lässt sich überprüfen, indem man die Klasse in welcher die GTV deklariert wurde mit der Klasse in welcher deren Typ benutzt wird vergleicht.
	* Ist die GTV als Klassenparameter definiert und aus der selben Klasse wird darauf zugegriffen.
	* Die GTV ist in einer Methode oder FieldDeclaration definiert, aber nicht dem selben wie darauf zugegriffen wird.

## ResultSet

* Spezifisch für jedes SourceFile (nicht für jede Klasse)
* mehrere ResultSets pro Klasse
* 

* Enthält:
	* constraintPairs
	* unifiedConstraints

## TypeInsertSet
* Stellt die Typeinsetzung für eine der generierten Lösungen dar
* Setzt alle Typen und generischen Variablen ein, welche zu dieser Lösung gehören
	
### Einsetzen von Generischen Variablen
Die einzusetzenden Generischen Variablen werden erst beim Einsetzen eines Typs generiert.

* Ablauf:
	* 1. Alle TypePlaceholder im einzusetzenden Typ ermitteln.
	* 2. Alle Constraints die mit diesen TPHs zusammenhängen ermitteln (Das kann möglicherweise wegfallen)
	* 3. Alle TPHs, aus Schritt 1 und 2 zusammenfügen.
	* 4. Kontrollieren, welche TPHs in dem InsertKontext noch nicht bekannt sind. 
	* 5. Alle Unbekannten TPHs herausfiltern (von den Pairs nur TA2)
	* 6. Alle unbekannten TPHs + Pairs als GenericTypeInsertPoint deklarieren.

## Lambda Ausdrücke und FunN
### Erstellen der Typconstraints für einen Lambda Ausdruck
* Return-Type des Lambda Ausdrucks: retT
* Parameter Typen: pT1 ... pTN
* Für jeden Typ einen TPH generieren
	* für Return Typ: TPH R
	* für Parameter Typen: TPH P1 ... TPH PN
* Es gilt:
	* TPH R < retT
	* pTN < TPH PN

## Ablauf Typinferenz:

1. Parsen
	* (Parser postProcessing)
2. Typinferenz
	* Anfangspunkt SourceFile
	* löst geparste Typen zu richtigen Typen auf (RefTypes, GenericVar)
	* setzt TPHs ein
	* bildet Constraints, welche in ResultSet gesammelt werden. ResultSet wird durch Syntaxbaum gereicht.
	* Assumptions generieren
		* Wird im Syntaxbaum für jeden Knoten ausgeführt und die Assumptions für darunterliegende Knoten gebildet
		* 
3. Unifizierung
	* wird im SourceFile aufgerufen
	* unifiziert Constraints aller im SourceFile vorkommenden Klassen
	
4. Erstellen von TypeInsertSet
	* Durchlaufen des Syntaxbaumes
	* Jeder Knoten erstellt TypeInsertSets anhand des ResultSets.
	* Bei Knoten, welche Generische Variablen beinhalten können werden GenericTypeInsertPoints erstellt
			
5. Einsetzen eines TypeInsertSet (optional)
	1. Auf allen TypeInsertPoints die getUnresolvedTPHs-Methoden aufrufen
	2. Alle Abhängigkeiten dieser 
	
