Das Projekt "Typinferenz in Java", welches im Rahmen einiger Studienarbeiten entwickelt wurde, beschäftigt sich mit der Entwicklung eines Java-Compilers, der ein integriertes Typinferenz-System besitzt.
In weit verbreiteten Hochsprachen wie C++, Pascal oder Java ist es zwingend erforderlich, den Typ einer Variablen, einer Methode oder eines Methodenparameters festzulegen. Der in diesem Projekt entwickelte Java-Compiler kann anhand von benutzten Methoden und Eigenschaften eines Objekts die Typen von Variablen rekonstruieren. Es ist also nicht zwingend erforderlich, dass der Programmierer die Typen von Variablen explizit definiert.
Der Compiler beherrscht grundlegende Java-Konstrukte wie Klassen, Interfaces, Packages, gebundene und ungebundene generische Klassen- und Methodenparameter.
Bei der Typrekonstruktion (auch Typinferenz genannt) wird die bereits erwähnte Berechnung der Typen nichtdeklarierter Variablen durchgeführt. Der Typrekonstruktionsalgorithmus besteht aus zahlreichen Unteralgorithmen.
Diese Arbeiten direkt auf den Datenstrukturen des Compilers und berechnen anhand von Schlussregeln Typannahmen für nichtdefinierte Variablen.
Um bei der Berechnung der Typen entstandenen Typannahmen zu vereinigen, wurde ein Unifikationsalgorithmus entwickelt und implementiert, welcher die konkreten Typen der nicht-typifizierten Variablen berechnen kann. Diese Typen müssen nicht eindeutig sein. Aus diesem Grund wurde eine Erweiterung für die Entwicklungsumgebung Eclipse entwickelt, welche es dem Programmierer ermöglicht, zwischen den berechneten Typen auszuwählen.
Die GUI hat die Aufgabe, den Compiler als Plugin für die Java-Entwicklungsumgebung Eclipse bereitzustellen. Ein Java-Projekt kann somit, direkt in Eclipse, mit dem Compiler mit Typinferenz kompiliert werden. Der Compiler ist in dem Plugin als jar-Archiv eingebunden und somit integraler Bestandteil und Herzstück des Plugins. Der Compiler selbst ist eine unabhängige Komponente. Der von ihm erstellte Parsebaum wird aufgegriffen und die darin enthaltenen Information entsprechend grafisch dargestellt.
Im Folgenden soll die grundsätzliche Funktionalität des Plugins anhand eines Bildes mit entsprechender Beschreibung der einzelnen Punkte erläutert werden. Das Bild beschreibt den Zustand nach erfolgreicher Kompilierung einer Klasse:
Hier steht der Java-Quelltext ohne Typangaben | ||
Über diesen Button wird der Quelltext kompiliert und die Typen rekonstruiert | ||
Übersichtsliste über alle Klassen, sowie deren Methoden und Variablen mit Angabe des berechneten Typs | ||
Durch Überfahren einer Variable mit der Maus kann der berechnete Typ per Tooltip abgerufen werden | ||
In der Konsole werden gefundene Variablen, sowie evtl. auch Fehler angezeigt |
Folgende zwei Beispiele zeigen, wie das Plugin im Fehlerfall reagiert:
Das Error-Symbol markiert eine Zeile, in der ein Fehler aufgetreten ist Es erscheint der Hinweis, das eine Klammer erwartet wird | ||
Die genaue Fehlerstelle wird rot unterstrichen |
Das Error-Symbol markiert eine Zeile, in der ein Fehler aufgetreten ist | ||
Die genaue Fehlerstelle wird rot unterstrichen |
Der Compiler berechnet unbekannte Typen anhand deren Verwendung. Es gibt jedoch Fälle, in denen die Typrekonstruktion nicht eindeutig ist. Hier ist der Anwender selbst gefordert, den gewünschten Typ über ein Kontextmenü auszuwählen. Dem Anwender werden alle Typen, die für diesen Fall in Frage kommen, in einer Auswahlliste angezeigt. Ein solches Szenario ist in folgendem Bild dargestellt:
Das Warn-Symbol markiert eine Zeile, in der eine Unklarheit besteht Hier mit dem Hinweis | ||
Die Variable, welche keinen eindeutigen Typ besitzt, wird gelb unterstrichen | ||
Über ein Kontextmenü kann der Anwender hier der Variablen einen konkreten Typ aus einer vorgegebene Auswahlliste zuordnen |
Im Teilprojekt der Bytecodegenerierung wird der abstrakte Syntaxbaum und die unifizierten Typen in Bytecode umgewandelt. Dieser Bytecode kann von jeder Java Virtual Machine auf verschiedenen Plattformen ausgeführt werden, die die Version des Bytecodes (aktuell Version 1.5) interpretieren kann. Der generierte Bytecode ist vollständig Java-konform und beinhaltet ebenfalls Signaturen, die aus den generischen Typen erstellt werden.