BlogKontaktTagcloud

C++ Refactoring Support für Eclipse-CDT

Nur knapp 5 Tage dauert unsere Diplomarbeit noch. Inzwischen ist zumindest unser Broschürentext fertig, den ich hier exklusiv vorab publiziere. Dieser Text wird zusammen mit den Texten der anderen Diplomarbeiten des Fachbereichs Informatik der HSR in der im Januar erscheinenden Diplomarbeitsbroschüre gedruckt. Diese Broschüre erhalten dann die Eltern und andere interessierte Personen wir haben deshalb versucht den Text nicht allzu technisch werden zu lasen. Wer es also genauer wissen will muss an die Diplomarbeitsaustellung kommen.

Aufgabenstellung

Eclipse ist eine professionelle Software-Entwicklungsumgebung. Die Programmiersprache Java wird von Eclipse standardmässig unterstützt, allerdings existiert mit dem CDT (C/C++ Development Tooling) auch eine Erweiterung für die Entwicklung mit den Programmiersprachen C und C++.

Während in den Eclipse Java Development Tools (JDT) verschiedene Refactorings angeboten werden, steht für CDT erst ein automatisiertes Refactoring zur Verfügung.

Unter Refactoring versteht man eine Vorgehensweise in der Softwareentwicklung bei der die Qualität von Quellcode gesteigert wird, ohne dabei dessen Funktionalität zu verändern. Refactoring reduziert mittelfristig den Aufwand für die Fehleranalyse und für funktionale Erweiterun-gen. Refactorings sind in klar definierte Schritte aufgeteilt. Wenn diese automatisch ausgeführt werden können, erleichtert dies die Arbeit der Entwickler und ist deshalb für Entwicklungs-umgebungen ein starker Wettbewerbsvorteil.

Ziel der ArbeitExtract Method Refactoring

Es sollen verschiedene Refactorings implementiert werden um den Entwicklern ihre Alltagsarbeit zu erleichtern. Die Refactorings sollen möglichst viele Eigenschaften von C++ unterstützen, Kommentare und Makros sollen bei den Codetransformationen behandelt werden und wieder richtig zurückgeschrieben werden. Die bestehende Infrastruktur von Eclipse im Allgemeinen und CDT im Speziellen soll verwendet werden und wo nötig erweitert werden.

Lösung

Der bestehende Code des CDT wurde so erweitert, dass die Refactorings „Replace Magic Number with Symbolic Constant“, „Move Field“, „Move Method“, „Extract Subclass“ und „Extract Method“ automatisiert möglich sind.

Durch das Erweitern des Parsers und des Abstract-Syntax-Tree war es uns möglich auch von Eclipse CDT nicht behandelte Codestellen zu parsen und korrekt zu erkennen. Durch diese Erweiterung der bestehenden Infrastruktur können nun auch Kommentare und Makros erkannt und während der Durchführung des Refactorings korrekt behandelt werden.

Damit der Code aus dem Abstract-Syntax-Tree wieder in Quellcode umgewandelt werden kann, wurde ein Codegenerator implementiert.

Um die Refactorings effizient zu testen, wurde das Testingframework JUnit so erweitert, dass die Testdefinitionen aus einer Datei gelesen werden können. Um die Testdefinitionen möglichst einfach zu bearbeiten, wurde ein kleiner Editor für Eclipse entwickelt. Mit CruiseControl wurde die von uns angepasste Version von Eclipse CDT bei jeder Änderung getestet und für sieben verschiedene Plattformen übersetzt.

Ähnliche Beiträge:
Diplomarbeitsausstellung an der HSR
Diplomarbeiten an der HSR
Ruby on Rails Coding Weekend
ROFL Prog 1
I dit it!
Comments (6)  Permalink

Fertig!

Wie schon angekündigt haben wir am Freitag, wie andere auch (z.B. die oder die), unsere Semesterarbeit abgegeben. Für Interessierte hier schon mal vorab unser Abstract, sobald die Abstracts aller Arbeiten online sind, werde ich sicher nochmals darüber schreiben. Die Qualität der Arbeiten waren in diesem Semester (mit den obligaten Ausnahmen), meiner Meinung nach, einiges höher als im letzten.
Ähnliche Beiträge:
Mein erster Patch
Generische Decorator in Java mit Reflection
Developing Eclipse CDT
PHP 6 is coming
Akregator Konqueror Plugin & Patch
Comments (0)  Permalink

Mein erster Patch

Ich bin gar nicht dazu gekommen zu schreiben das mein erster Patch für ein Open Source Projekt angenommen wurde. Auch wenn es sich dabei nur um ein einziges Break handelt bin ich sehr stolz. Die weiteren Patches werden ja bald folgen.
Ähnliche Beiträge:
Fertig!
Generische Decorator in Java mit Reflection
Developing Eclipse CDT
PHP 6 is coming
Akregator Konqueror Plugin & Patch
Comments (0)  Permalink

Generische Decorator in Java mit Reflection

In unserer Eclipse CDT Semesterarbeit geht es zügig voran. Emanuel schreibt eine Erweiterung für den Abstract Syntax Tree um Kommentare zu speichern. Kommentare sind im AST meist nicht nötig, für Refactorings ist es aber entscheiden das Kommentare nicht einfach auf der Strecke bleiben oder gar verloren gehen.

Um die Kommentare zu Speichern hat Emanuel den Knoten mit der Kommentarinformationen „dekoriert“ und dazu das Decoratorpattern verwendet. Dazu hat er das Interface des entsprechende Knotens implementiert und für die Funktionen des ursprünglichen Knotens einfach einen Wrapper geschrieben der auf die Methoden des „echten“ Knoten zugreift. Dies ist das übliche Vorgehen bei einer solchen Problemstellung. Das kann bei vielen Knoten schnell in einem grossen Programmieraufwand enden. Da wir uns entschieden die Kommentare nur in zwei Knoten zu speichern hielt sich der Aufwand dazu in Grenzen. Trotzdem bemerkten wir auch in diesem Fall dass das Ganze auch sehr fehleranfällig ist. In unserem Dekorator hatte sich trotz kleines Umfanges bereits ein Fehler versteckt, den wir zum Glück beim durchsehen des Codes noch fanden.

Der Vorschlag unseres Professors war nun das Problem generischer mit Reflection zu lösen wie das auch in Ruby oder Smalltalk gehen soll. Eine andere Möglichkeit währe es wohl die Klassen statisch mit einem Script automatisch zu erzeugen. Wir haben letzte Woche nun versucht den Lösungsvorschlag unseres Professors zu implementieren. Dazu verwendeten wir die „dynamic proxies“-Funktionalität von Java wie sie seit Java 1.3 vorhanden ist und unter anderem auch für Java RMI verwendet wird.

Zuerst müssen wir nun eine Factory erstellen welche das Proxy-Objekt erstellt, da dies über einen gewöhnlichen Konstruktor nicht mehr möglich ist. Der Factory übergeben wir den Orginal Knoten der dekoriert werden soll. Das sieht in unserem Beispiel dann so aus:

public static Object invocationFactory(CPPASTNode node) {
CPPASTCommentedInvocationHandler handler = new CPPASTCommentedInvocationHandler(
node);

Class[] interfaces = getAllInterfaces(node);

Object o = Proxy.newProxyInstance(IASTCommentDecorator.class
.getClassLoader(), interfaces, handler);

return o;
}

Zuerst wird der Handler erzeugt der die Zugriffe die auf das Proxy-Objekt erfolgen handhabt. Auf die Funktionalität des Handlers gehe ich später in diesem Text ein. Mit der Methode „getAllInterfaces“ werden danach alle Interfaces des Knoten zurückgegeben und mit dem Interface das die Funktionalität zum Speichern von Knoten bereitstellt ergänzt. Danach wird ein Proxy-Objekt („Proxy.newProxyInstance“) für diese Elemente mit diesen Interfaces und dem Handler erstellt.

private static Class[] getAllInterfaces(CPPASTNode node) {
Class[] interfaces = node.getClass().getInterfaces();
Class[] allInterfaces = new Class[interfaces.length + 1];

for (int i = 0; i < interfaces.length; ++i) {
allInterfaces[i] = interfaces[i];
}

allInterfaces[allInterfaces.length - 1] = IASTCommentDecorator.class;
return allInterfaces;
}

Der Handler ist dann ein relativ einfaches Konstrukt welches das InvocationHandler-Interface implementiert. Welches einzig und allein die invoke Methode verlangt.

public class CPPASTCommentedInvocationHandler implements InvocationHandler 

Im Konstruktor wird der Orginalknoten gespeichert und ein Objekt der Klasse die das Speichern der Kommentare vornimmt angelegt. Die Speicherfunktionalität hätte auch im Handler selbst implementiert werden können, eine eigene Klasse löst aber die Kopplung und erhöht die Wiederverwendbarkeit des Codes.

In der invoke Methode landen nun alle Aufrufe an das Proxy-Objekt. Zuerst werden nun hier die Methoden equals und acceppt abgefangen da sie sowohl mit dem Knoten als auch mit dem Kommentar-Speicher interagieren. und deshalb direkt im Handler behandelt werden.

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {

if (method.getName().equals("equals") && args.length == 1
&& args[0].getClass().equals(Object.class)) {

return equalsMethodeCall(args[0]);
} else if (method.getName().equals("accept") && args.length == 1
&& ASTVisitor.class.isInstance(args[0]) ){

return acceptMethodeCall((ASTVisitor) args[0]);
} else {
return standardClassCalls(method, args);
}
}

In der Methode „standardClassCalls“ werden nun die übrigen Methodenaufrufe an die beiden Klassen „verteilt“. Alle Methoden die vom IASTCommentDecorator ausgehen werden an das Objekt commentExt, welches die Speicherfunktionen für die Kommentare (also das Interface IASTCommentDecorator) implementiert. Alle anderen Methoden wurden ja von den Interface des konkreten Knotens implementiert und werden deshalb auch an diesen weitergeleitet.

private Object standardClassCalls(Method method, Object[] args)
throws IllegalAccessException, InvocationTargetException {
if (method.getDeclaringClass().equals(IASTCommentDecorator.class)) {
return method.invoke(commentExt, args);
} else {
return method.invoke(node, args);
}
}

Die Implementation auf diese Weise ist sehr flexibel und elegant, auch wenn sie ein wenig schwer zu verstehen ist. Leider kann das Proxy-Objekt nur in die entsprechende Interface, und nicht in eine Knotenklasse, gecastet werden. Da in Eclipse CDT, wie vermutlich in den meisten grösseren Projekten, nicht konsequent gegen Interfaces programmiert würde funktioniert dieser Lösungsansatz bei uns leider nicht.

Ähnliche Beiträge:
Developing Eclipse CDT
Fertig!
Mein erster Patch
Generisches toString in Java mit Reflection
Named parameters in Java (bgl-style)
Comments (0)  Permalink

Developing Eclipse CDT

Meine Links auf del.icio.us haben es bereits angekündigt. Emanuel und ich haben mit unserer nächsten Semesterarbeit begonnen. Diesmal versuchen wir für und mit Peter Sommerlad "CDT AST writability for Eclipse" zu implementieren. Nun sind wir bereits in der zweiten Semester- und Projektwoche.

Diese Projekt hat Emanuel und mir definitiv gezeigt das wir noch nicht alles über Java wissen. Der Code ist kompliziert, weist viele Eigenarten auf (die teilweise die c/c++ Vergangenheit der Entwickler nicht verheimlichen können) und bietet auch aus der Javasicht einige Neuheiten. Mit folgendem Code hätte ich zu Beginn dieser Woche noch nichts anfangen könne.

public static IViewPart openDOMASTView(IEditorPart editor){
...
( (DOMAST)tempView).setContentProvider( (DOMAST)tempView).new
ViewContentProvider(((CEditor)editor).getInputFile()));
...
}

Ja genau der Code instanziert eine innere Klasse aus einem statischen Kontext. Aber so was lernt man wohl in keiner Vorlesung (oder vergisst es schneller wieder als man es gehört hat).

Inzwischen sehen ich aber bereits wieder Licht. Das Codechaos wird langsam durchschaubar, obwohl beim CDT wohl die Grundregel gilt, dass keine Funktion nur einmal existiert und Codeduplizierung zur Tagesordnung zu gehören scheint. Heute bin ich auch über den ersten Fehler im Code gestolpert und habe einen Patch dafür erstellt. Wie es mit dem Projekt weitergeht wird wohl auf meinem Blog oder in unserem Projekt-Wiki stehen.

Ähnliche Beiträge:
Generische Decorator in Java mit Reflection
Fertig!
Mein erster Patch
Named parameters in Java (bgl-style)
SCJP, now!
Comments (0)  Permalink

Diplomarbeiten an der HSR

Am Freitag wurden an der Hochschule Rapperswil die Diplomarbeiten der Informatik und Elektrotechnik ausgestellt. Das die Büroräumlichkeiten kurzerhand in Austellungsräume Umfunktioniert wurden hatte für den eint oder anderen so seine Tücken. Jedenfalls wurde, während an den meisten Plätzen bereits angestossen und die arbeiten erklährt wurden, an einigen Orten heftig gearbeitet.

Meiner Meinung nach das für die Allgemeinheit interessanteste Projekt ist der C++ Refactorer für Eclipse "Cerp C++ Eclipse Refactoring Plugin", der das CDT von Eclipse mit einigen nützlichen Refactoringmethoden erweitert. Ebenfalls interessant waren die verschlüsselungs Erweiterung für KPhone und eine CISCO VOIP Integration in Outlook. Alle Projekte findet man, in der erstmals farbigen, Diplomarbeitsbroschüre (2 MB PDF).

Ganz im allgemeinen war das Spektrum der Arbeiten wieder einmal sehr breit. Von sehr einfachen bis sehr komplexe Arbeiten war alles anzutreffen, ebenso war auch die Qualität sehr unterschiedlich. Leider waren die Plakate zu den Arbeiten meist überladen und unverständlich, ebenso waren die mündlichen Erklährungen zu den Projekten nicht immer "managementtauglich", das heisst zu lang, zu kompliziert und zu wenig gut verkauft. Das ist insbesondere deshalb schade weil dieses Jahr wieder einige Herren in Krawatten (und auch solche ohne) sich für Diplomanden sehr interessiert zeigten.

Ähnliche Beiträge:
I dit it!
C++ Refactoring Support für Eclipse-CDT
Diplomarbeitsausstellung an der HSR
Ingenieur?
Restart
Comments (2)  Permalink

Eclipse mit Erich Gamma

Heute abend habe ich die Veranstaltung "IBM und Erich Gamma präsentieren Eclipse" an der ETH Zürich besucht.

Erich Gamma hat einen kompletten Überblick über Eclipse/RCP gegeben.
Eclipse ist sowohl eine IDE, eine open source community, ein Ökosystem (Möglichkeit Produkte zu verkaufen) als auch eine Fundation.

Zuerst erklärte er Eclipse als Plattform und die betonte immer wieder die Wichtigkeit eines stabilen API's (was schon das Mantra des Moduls Advanced Pattern und Frameworks war). Eclipse erreicht dies in erster Line dadurch das es die Anzahl offener Schnittstellen möglichst klein hält.

In Eclipse ist nun alles ein Plugin, die Platform verbindet und installiert (neuerdings mit OSGi zur Laufzeit) diese nur. Die Plugins kennen ihre Abhängigkeit, definieren Erweiterungspunkte und benutzen diese auch.

In der anschliessenden Demonstration zeigte er dann wie man ein Plugin erstellt und deployt. Das Beispiel war mit einem Wahnsinns Tempo zusammengeklickt (programmieren musste er dank clever angewandten Refactorings kaum mehr). Das ganze hat neben der Genialität des Frameworks auch gezeigt das ich mit Eclipse noch einiges zu lernen habe und meine Produktivität noch massiv steigern kann.

Danach kam noch die Demonstration von RCP, bei dem er einen Taschenrechner zur mit einer zusätzlichen Operation erweiterte (auch hier hat er kein Code geschrieben, sondern nur geklaut).

Danach folgen noch einige interessante Kennzahlen und Infos zur Eclipse Entwicklung. Es ist interessant zu sehen wie konsequent die Eclipse Entwickler die XP-Rules umsetzen. Einige Infos folgten dann noch ganz am Rande, JUnit 4 wird wohl bald erscheinen und Eclipse hat seit heute (nach 5 Jahren!) endlich eine neue Homepage.

Ein sehr interessanter Abend, vielen Dank für den Tipp Alain.
Ähnliche Beiträge:
C++ Refactoring Support für Eclipse-CDT
Fertig!
Mein erster Patch
Generische Decorator in Java mit Reflection
Developing Eclipse CDT
Comments (6)  Permalink

Ward wechselt zu Eclipse

Ward Cunningham wechselt von Microsoft zur Eclipse Foundation. Eclipse wird durch den Mann der seiner Zeit immer einen Schritt voraus ist, seinen Vorsprung zu anderen IDE's und Frameworks noch ausbauen können.

Und ich bin versucht zu sagen: "Endlich mal einer der nicht zu Google geht..."

[via heise]
Ähnliche Beiträge:
Fertig!
Mein erster Patch
Generische Decorator in Java mit Reflection
Developing Eclipse CDT
Mobile App Hackathon
Comments (0)  Permalink
1-8/8