Intelligente Code Completion in Java-IDEs

Code Completion – wie Auto-Vervollständigung das Entwickeln erleichtert
Kommentare

Ob Wortvorschläge in E-Mail-Clients, Textverarbeitung oder Suchmaschinen: Das Konzept der automatischen (Code-)Vervollständigung (engl. Code Completion) hat sich nicht nur in Entwicklerkreisen durchgesetzt. Doch Code Completion kann mehr als dem Entwickler nur dann und wann etwas Tipparbeit ersparen; ein modernes Code-Completion-System wie Eclipse Code Recommenders erleichtert darüber hinaus das Erlernen neuer APIs und lässt Neulinge vom Wissensschatz ihres Teams oder gar der weltweiten Entwicklercommunity profitieren.

Spätestens mit Microsofts IntelliSense, das 1996 in die Visual-Basic-Entwicklungsumgebung Einzug hielt, hat die Idee der automatischen Codevervollständigung endgültig den Sprung von der Theorie in die Praxis geschafft. In den späten 80er Jahren noch Gegenstand universitärer Forschung, wurde Code Completion nun zum unverzichtbaren Helferlein tausender Entwickler und verbreitete sich unter dem quasi-universellen Tastenkürzel CTRL+SPACE rasch von einer IDE zur nächsten. So ist es wenig verwunderlich, dass alle modernen Entwicklungsumgebungen im Java-Umfeld (Eclipse, IntelliJ IDEA, NetBeans) über Code Completion in ähnlicher Form verfügen. Statt mühsam Methoden- und Funktionsnamen aus dem Gedächtnis oder der (hoffentlich vorhandenen) API-Dokumentation hervorzukramen, bekommt man sie nun in einem praktischen Menü präsentiert; man muss die richtige Funktion oder Methode nur noch auswählen…

Abb.1

Abb.2

Abb.3

Abb. 1 bis 3: Code Completion in Eclipse, IntelliJ IDEA und NetBeans

Den Wald vor lauter Bäumen…

Doch die jeweils für das aktuelle Problem passende Methode auszuwählen ist oftmals leichter gesagt als getan; selbst ein scheinbar einfaches Konzept wie ein Widget für textuelle Benutzereingaben manifestiert sich in einer Vielzahl von Methoden – von denen die allermeisten im Kontext des Problems irrelevant sind.

Abb. 4: Die 187 Methoden (und 3 Felder) von „Text“, einem typischen GUI-Widget

In solch einer Situation verbringt der Entwickler – vor allem, wenn ihm das API noch nicht so geläufig ist – viel Zeit damit, Schritt für Schritt durch die Liste der Vorschläge zu gehen und anhand von Methodennamen und -parametern abzuwägen, welche der Methoden wohl die richtige ist. Im besten Fall verfügen die aufgelisteten Alternativen zwar noch über API-Dokumentation (im Java-Umfeld meist JavaDoc), die von der IDE in Form eines Tooltips dargeboten wird und bei der Entscheidungsfindung hilft. Aber auch das Überfliegen dieser Dokumentation kostet wertvolle Zeit. Und so ist es nicht sehr verwunderlich, dass ein Entwickler im Angesicht eines unbekannten API im Schnitt 25 Sekunden benötigt, sich für eine der Methoden zu entscheiden. Mehr noch: Trotz einer manchmal gar mehrminütigen Bedenkzeit gelingt es Entwicklern nicht immer, aus der Vielzahl an Alternativen die in ihrem Fall optimale zu wählen; die Folge sind weitere Verzögerungen und Code, der umständlicher ist als er sein müsste. In jedem Fall aber wird der Entwickler aus dem „Flow“ gerissen; er weiß, was zur Lösung seines Problems prinzipiell zu tun ist, doch muss immer wieder innehalten, um mühsam herauszufinden, wie er diese Lösung mittels des verwendeten API kommunizieren muss.
In der Vergangenheit haben IDEs meist versucht, die von der Code Completion vorgeschlagene Menge an Methoden durch Heuristiken zu ordnen. Mittels mehr oder minder komplizierter Verfahren wurden dabei einzelne Methoden im Code-Completion-Dialog einige Listenplätze hinauf- oder hinabbefördert. Am grundsätzlichen Problem hat sich jedoch nichts geändert; die Sortierung ist zuallererst eine alphabetische, die hier und da um einige syntaktische Kriterien ergänzt wurde. Solche rein syntaktischen Ansätze greifen zwangsweise zu kurz. So macht es zum Beispiel einen großen Unterschied, ob ein Text-Widget innerhalb der createDialogArea(…)-Methode eines Dialogs benutzt wird oder aber innerhalb von okPressed(); im ersten Fall wird das Widget offensichtlich initialisiert werden müssen, während man im zweiten Fall sicherlich eher daran interessiert ist, etwaige Eingaben auszulesen. Diese Semantik ist aber nur für Menschen offensichtlich; syntaktisch unterscheiden sich die Methodensignaturen von createDialogArea(…) und okPressed() nämlich kaum.

Während es für einen menschlichen Entwickler ein Leichtes ist, die implizite Semantik einer Methode wie okPressed() zu erfassen (nämlich „Der Benutzer hat seine Eingaben getätigt und den Dialog mit OK bestätigt“), tun sich Computer damit schwer. Doch glücklicherweise ist das „Verstehen” der Semantik von okPressed() auch gar nicht nötig, um intelligente Vorschläge in der Code Completion zu machen; es reicht völlig aus, das Wissen menschlicher Entwickler abzuschöpfen. Dies ist der Grundgedanke hinter Eclipse Code Recommenders. Die Tatsache, dass die Methode getText() häufig innerhalb von okPressed(), aber nur selten innerhalb von createDialogArea(…) Verwendung findet, lässt sich nämlich durchaus aus vorhandenem Quellcode ablesen – nur eben gerade nicht aus dem Dialog, über dessen Quellcode der Entwickler gerade in seiner IDE brütet.

[ header = Wer A sagt, muss sollte auch B sagen ]

Wer A sagt, muss sollte auch B sagen

Eclipse Code Recommenders analysiert daher bereits existierenden Code, um aus diesem mittels Data Mining häufige Benutzungsmuster abzuleiten. Glücklicherweise existieren heutzutage umfangreiche Repositories wie GitHub oder Maven Central, die der Allgemeinheit unzählige Open-Source-Projekte zugänglich machen. Und genau dieses Wissensschatzes bedient sich auch Code Recommenders; für jedes API werden all jene Projekte analysiert, die diese benutzen. Ein [ctrl]flow genannter Data-Mining-Prozess extrahiert daraus spezielle Modelle, die Auskunft darüber geben, wie man die fraglichen APIs typischerweise benutzt. Diese Modelle werden in der IDE von Eclipse Code Recommenders automatisch heruntergeladen und ausgewertet, wann immer der Entwickler die Code Completion benutzt; jedem Entwickler stehen in der Eclipse IDE somit automatisch alle Informationen darüber bereit, wie andere Entwickler mit den gängigen Open-Source-APIs und -Frameworks arbeiten. Für den Fall des Text-Widgets ist Code Recommenders zum Beispiel in der Lage, vorherzusagen, mit welcher Wahrscheinlichkeit sich der Entwickler im aktuellen Kontext für eine Methode interessiert.

 Abb.5

Abb.6

Abb. 5 und 6: Intelligente Code Completion in „Dialog.createDialogArea(…)“ bzw. „okPressed()“

Informationen, die in diese Vorhersage einfließen, sind zum Beispiel die Methode, die aktuell implementiert wird (createDialogArea(…) bzw. okPressed()) oder die Herkunft des Objekts, auf dem eine Methode aufgerufen werden soll. So spielt es nämlich häufig eine große Rolle, ob ein Objekt als Parameter übergeben oder aber frisch erzeugt wurde. Des Weiteren berücksichtigt Code Recommenders noch, welche anderen Methoden bereits auf dem Objekt aufgerufen wurden. Diese Informationen können dabei nicht nur zur Vorhersage des nächsten Aufrufs dienen, sondern auch dazu, ganze Aufruffolgen zu Codetemplates zu synthetisieren. Dieses Verfahren nennt sich Adaptive Template Completion und ermöglicht es Entwicklern, die häufigen Benutzungsmuster einer Klasse schnell zu erfassen.

Abb.7

Abb. 7: Adaptive Template Completion für ein frisch erzeugtes „Text“-Widget

Intelligente Code Completion, ob für einzelne Aufrufe oder gar ganze Templates, erleichtert es somit, auch bei unbekannten APIs den „Flow“ während des Programmierens aufrechtzuerhalten; der Entwickler muss seine Arbeit viel seltener dafür unterbrechen, die Dokumentation oder die Suchmaschine seiner Wahl zu befragen, um herauszufinden, wie er ein konkretes API zu benutzen hat. Intelligente Code Completion ist aber nur ein Schritt auf dem Weg zu mehr Produktivität. Aus den im existierenden Code präsenten Mustern lassen sich noch weitere Informationen ableiten, die die API-Dokumentation ergänzen können. Während die Unterstützung durch intelligente Code Completion erst relativ spät greift – nämlich dann, wenn der Entwickler bereits Code geschrieben hat – unterstützt ihn die auf Basis der Modelle erstellte erweiterte Dokumentation (Extended Documentation, Extdoc) schon früher. So kann sich der Entwickler zum Beispiel vorab darüber informieren, welche Methoden oder Methodenkombinationen beim Erweitern der Klasse Dialog typischerweise zu überschreiben sind.

Abb.8

Abb. 8: Extdoc statt JavaDoc am Beispiel der Klasse „Dialog“

Alle oben beschriebenen Features sind mitsamt der dazugehörigen Modelle bereits Teil von Eclipse Code Recommenders und damit auch ein fester Bestandteil der gängigsten Downloadpakete der Eclipse IDE (Eclipse for Java/RCP/DSL Developers). Modelle für Eclipse Code Recommenders müssen jedoch nicht auf Methodenaufrufe oder Überschreibungsbeziehungen beschränkt sein; Code Recommenders ist vielmehr ein komplettes Framework, mit dem es leicht möglich ist, Modelle und damit intelligente Code Completion bzw. erweiterte Dokumentation auch für andere Arten von Benutzungsmustern zur Verfügung zu stellen. So sind Modelle, die zu verwendende Annotationen oder Methodenparameter vorschlagen, nicht nur denkbar, sondern befinden sich zum Teil auch schon in der Erprobung, d. h. im Incubator-Stadium. Bereits jetzt stellt das Eclipse-Code-Recommenders-Projekt im Rahmen des jährlichen Release Trains der Eclipse IDE eine stetig wachsende Zahl von Modellen für gängige Open-Source-Bibliotheken und -Frameworks bereit, die in den kommenden Monaten mit der Erschließung weiterer Software-Repositories noch anwachsen wird. Für nicht frei verfügbaren Code gibt es darüber hinaus die Möglichkeit, mithilfe der [ctrl]flow-Tools Data Mining auf dem eigenen, nicht öffentlichen Repository zu betreiben und die resultierenden Modelle an die eigenen Entwickler zu verteilen.

[ header = Auf dem Weg zur IDE 2.0 ]

Auf dem Weg zur IDE 2.0

Die oben erwähnten Software-Repositories sind aber nicht die einzige Quelle, aus der sich Benutzungsmuster ableiten lassen. Eine weitere ist der Quellcode, wie er in der IDE eines jeden Entwicklers vorliegt: Mit jeder Methode, die ein Entwickler in der IDE auswählt, macht dieser nämlich implizit eine Aussage darüber, dass die gewählte Methode im aktuellen Kontext genau die richtige ist; andernfalls hätte er sie ja nicht ausgewählt. Und dies ist genau die Form von Aussagen, auf die das Data Mining der [ctrl]flow-Tools spezialisiert ist. Was liegt also näher, als das (implizite) Wissen dort anzuzapfen, wo es entsteht: in der IDE des Entwicklers selbst? Übertragen auf tausende Entwickler, erhält man damit effektiv ein Code-Completion-System, das der Vervollständigung von Suchbegriffen in Suchmaschinen wie Google oder Bing ähnelt; jede Interaktion mit dem Benutzer liefert dem System Feedback, das es künftig intelligentere Vorschläge machen lässt. Dieser Ansatz überträgt somit Kernideen des Web 2.0 (Crowd Sourcing, Collective Intelligence) auf den Bereich der Code-Completion-Systeme und schafft damit eine intelligente IDE 2.0.

Eine erste Implementierung dieser Idee wird momentan von der Firma Codetrails entwickelt und basiert auf der ursprünglich durch den Texteditor Emacs populär gemachten so genannten Hippie Completion (in Emacs: Hippie Expand). Je häufiger ein Wort bzw. eine Methode im umgebenen Dokument verwendet wird, desto wichtiger erscheint es der Vervollständigung. Crowd Sourcing dehnt den Begriff der Umgebung nun auf die Gemeinschaft aller Entwickler aus, die ebenfalls die fragliche Klasse benutzen. Die klassische Hippie Completion wird hierbei um eine Woodstock genannte Datenbank ergänzt, die sich aus dem Feedback der Entwicklergemeinschaft speist.

Abb.9

Abb. 9: Woodstock = Hippie Completion + Crowd Sourcing

Wie bei Suchmaschinen dürfen sowohl Datenschutz als auch Schutz des geistigen Eigentums bei einer IDE 2.0 ebenfalls nicht zu kurz kommen. Schließlich werden (kleinste) Teile des eigenen Quellcodes in die Cloud übertragen. Doch beiden Bedenken lässt sich im Bereich der Code Completion leicht begegnen. Zum einen benötigt eine intelligente Code Completion nur wenige Informationen über den Kontext, in dem ein Methodenaufruf getätigt wurde, um eine hohe Treffergenauigkeit zu erzielen und beherzigt somit den Grundsatz der Datensparsamkeit. Zum anderen obliegt dem Entwickler die volle Kontrolle darüber, für welche Methoden überhaupt Informationen übertragen werden. Somit können zum Beispiel Informationen über die Verwendung gängiger Open-Source-Bibliotheken mit anderen Entwicklern weltweit geteilt werden, während Informationen über den eigenen, proprietären Quellcode den Entwicklerrechner nie verlassen.

Abb.10

Abb. 10: Kontrolliertes Crowd Sourcing: die Sharing Preferences

Und schließlich gibt es, wie bei Eclipse Code Recommenders auch, die Möglichkeit, den Dienst nicht öffentlich zu betreiben und die Daten nur mit den eigenen Entwicklern zu teilen.

Über den Tellerrand hinaus

Während intelligente Code Completion sicherlich als die Kernkompetenz von Eclipse Code Recommenders angesehen werden kann, bietet das Projekt auch eine solide Basis für weitere Innovationen im Bereich intelligenter, datengetriebener Unterstützung sowohl für einzelne Entwickler als auch für große Teams. So liefern die im Rahmen des Data Mining gefundenen Benutzungsmuster den Designern eines API zum Beispiel wertvolle Hinweise darüber, wie ihr API tatsächlich benutzt wird und wo die Erwartungen der Designer und der Nutzer auseinander laufen. So hilft Code Recommenders nicht nur direkt beim Erlernen eines API, sondern kann auch dafür sorgen, dass sich deren Erlernbarkeit langfristig verbessert  Ebenso lässt sich aus den erhobenen Daten ableiten, wer im Team der Experte für ein gewisses API ist, denn selbst mit intelligenter Code Completion ist es manchmal nötig, einen Kollegen zu fragen. Diese Kontaktinformation kann dann zum Beispiel die automatisch generierte Dokumentation ergänzen. Eine solche Kombination von automatisch generierter, erweiterter Dokumentation und Crowd Sourcing erscheint besonders vielversprechend. So wäre es einem Entwickler zum Beispiel möglich, die Dokumentation direkt in der IDE zu annotieren oder auch mit einer Bewertung zu versehen.

Fazit

Eine intelligentes Code-Completion-System wie Eclipse Code Recommenders hebt eine einfache Idee aus den achtziger Jahren, nämlich die der automatischen Codevervollständigung, auf eine neue Stufe: Nicht länger ist die IDE darauf beschränkt, dem Entwickler mitzuteilen, was er alles tun könnte; sie zeigt ihm darüber hinaus, was andere Entwickler in einer ähnlichen Situation getan haben. Durch die Empfehlungen von Code Recommenders verbreitet sich das Wissen um die korrekte Benutzung neuer APIs nicht nur schneller im Team, sondern – mittels Crowd Sourcing – auch in der weltweiten Entwicklergemeinde. Umgekehrt können sich die Designer eines API nun erstmals einen Überblick darüber verschaffen, wie ihre APIs denn nun wirklich benutzt werden. Eine IDE 2.0 schafft es somit, Feedbackzyklen wesentlich zu verkürzen – ohne dass der Programmierer aus seinem „Flow“ gerissen wird.

Eclipse Code Recommenders: Eine kurze Historie

Eclipse Code Recommenders ist das Ergebnis fünfjähriger Forschung zu intelligenter Code Completion an der TU Darmstadt. Seit 2011 ist Eclipse Code Recommenders ein Open-Source-Projekt unter dem Dach der Eclipse Foundation und wird dort seit 2012 im Rahmen des jährlichen Release Trains zusammen mit deren Java-IDE ausgeliefert. So hat Code Recommenders erst kürzlich wieder pünktlich Einzug in das 2013er Release (Codename Kepler) der Eclipse-Plattform gefunden. Ebenfalls im Jahr 2013 gründete sich die Firma Codetrails, die sowohl die Entwicklung von Eclipse Code Recommenders sponsert als auch dieses mit dem [ctrl]flow-Server und den Crowd Recommendation Tools fit für den Unternehmenseinsatz macht.

 

 

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -