Eclipse Photon 2018-09 für PHP – endlich gute Content Assist Performance

Ende August war ich auf die "R"-Version von Eclipse Photon umgestiegen. Der Start der IDE erwies sich zwar als elend langsam; aber immerhin erschien mir das Zusammenspiel mit GTK3 gegenüber Eclipse Oxygen deutlich verbessert. Auch eine Java10-Runtime-Umgebung ließ sich gut verwenden.

Etwas hat mich jedoch zunehmend bei der Arbeit behindert:
Bei großen PHP-Projekten erwies sich die Content-Assist-Funktion [CA] des PHP Editors als bodenlos langsam. Wenn man den Heap beobachtete, so wechselte der während des Wartens auf eine CA-Antwort ständig die Größe. Gegenüber den in Eclipse ablaufenden Hintergrundsprozessen (Neu-Indizierung vieler Files? Update diverser Oberflächenelemente? ...) kam die CA-Funktionalität offenbar erst mit geringer Priorität zum Tragen. Das war völlig irregulär. Mal erhielt man eine Anwtort zu einer lokalen Variable sofort; mal musste man 5- 6 Sekunden warten. Die Meldung "Computing proposals ...." ging mir zunehmend auf den Zeiger. Wer will beim Tippen schon 5 Sek warten, bis der erste Vorschlag kommt? Leider hat keine der angebotenen Optionen unter "Preferences >> PHP >> Editor >> Content Assist" viel geholfen. Auch nicht zur "asynchron Code Completion". Ich war kurz davor, wieder auf Oxygen zurück zu gehen.

Heute habe ich heute aber die neue "September-Version von Eclipse ( "eclipse-php-2018-09-linux-gtk-x86_64.tar.gz" ) installiert, Updates der "webkit2"-Bibliotheken unter Opensuse vorgenommen und auch die "~/.eclipse"-Eintragungen neu erstellen lassen.

Und siehe da: Die Performance der CA-Funktionalität im PHP-Editor ist nun wieder so wie in alten Zeiten. nach nun 6 Stunden Arbeit kann ich sagen: Das Programmieren mit PHP und Eclipse macht wieder Freude ....

Eclipse PDT – Code Assist in PHP 5.4 Traits

Traits sind eine feine Sache, wenn man horizontales Design in PHP Projekten angemessen unterstützen will.
Siehe z.B.: http://www.kingcrunch.de/blog/2011/08/01/php5-4-traits-aka-horizontal-reuse/
Ich setze Traits z.Z. selbst verstärkt in Kundenprojekten ein. Ein kleines praktisches Problemchen, über das ich in Eclipse PDT dabei gestolpert bin, ist die Frage des Code Assists bzw. der Code Completion bei der Code-Erstellung innerhalb von Methoden (Funktionsblöcken) eines Traits.

In den Code-Blöcken der Methoden eines Traits kommt ja oft der $this-Operator mit Referenzen auf Methoden, Variablen und ggf. weitere (z.B. injizierte) Objekte der Zielobjekte bzw. Zielklassen des Traits zum Einsatz. Die Zielklassen eines Traits - also die Klassen, in die der Trait eingebunden und die Trait-Funktionen genutzt werden sollen - beinhalten ja typischerweise bereits Referenzen auf eigene Methoden und ggf. auch weitere Objekte (mit zugehörigen Klassen-Variablen und Methoden). Diese referenzierten Methoden und auch Objekte müssen im Trait u.U. angesprochen werden.

Bei der entwicklungstechnischen Bearbeitung der Zielklassen selbst unterstützt einen PDT umfangreich mit Code Assisting auch für weitere referenzierte Objekte und Klassen, wenn

  • diejenigen Member-Variablen, denen die intern referenzierten Objekte zugeordnet werden, z.B. per "phpDocumentor Tag"-Anweisung mit einem Hint hinsichtlich der Klassenzugehörigkeit versehen wurden
  • und/oder innerhalb der Methoden-Codes ein entsprechendes Type Hinting vorgenommen wurde.

Siehe hierzu:
PHP Type Hinting with Eclipse
PHP Code Content Assists und Inline Type Hinting in Eclipse

Nun möchte man gerne bei der Trait-Entwicklung

  • für die Methoden und Variablen der Zielklassen des Traits selbst
  • wie auch für Objekte und deren Klassen, die innerhalb der Zielklasse referenziert werden,

Code Assisting erhalten, wenn man diese in einer Trait-Methode ansprechen und nutzen will.

Natürlich kann die PDT-Engine bei der Bearbeitung eines Traits aber nicht wissen, für welche Ziel-Klassen das Trait zum Einsatz kommen wird. Mit welchem Klassentypus (einer Vererbungshierarchie) der $this-Operator innerhalb des Traits assoziiert sein wird, ist daher ohne weitere Hilfe unklar. Damit hängen auch alle über $this referenzierten internen Objekte in der Luft. Code Assist innerhalb eines Traits beschränkt sich daher ohne weiteres Zutun des Entwicklers nur auf genau die Variablen und Funktionen/Methoden, die im Trait selbst definiert wurden.

In dem Falle, dass die Ziel-Klassen des Traits alle von einer (gemeinsamen) Klasse abgeleitet wurden, kann man aber mehr erreichen.

Diese Situation entspricht z.B. der, dass man für bestimmte Objekt-Typen über eine Vererbungshierarchie einen Satz von Funktionalitäten bereitgestellt hat. Nun sollen entsprechende Objekte in einer unterschiedlichen Gruppen von Applikationen zum Einsatz kommen, in denen die Basis-Funktionalitäten in gruppen- und applikationsspezifischer Weise überschrieben und ergänzt werden sollen. Diese Änderungen/Ergänzungen seien applikationsspezifisch und nicht strukturell bedingt und mögen daher keinen Grund für eine Erweiterung der Klassenhierarchie selbst darstellen.
Dann kann man in PHP sein Ziel auf breiter Front pro Gruppe durch Integration von gruppenspezifischen Traits erreichen.

Beispiel: Eine Veererbungshierarchie stelle ein allgemeines Spektrum an Funktionalitäten für Template-Control-Objekte zur Verfügung. In unserem zu realisierenden Anwendungsspektrum sollen diese Funktionalitäten für definierte Applikationsgruppen spezifisch - innerhalb einer Applikatonsgruppe jedoch immer in gleicher Weise - kombiniert werden. Traits lösen dieses Problem auf einfache und elegante Weise.

Innerhalb des Traits möchte man nun Code-Assisting für die Variablen der gemeinsamen Basisklassen erhalten. Nennen wir die potentiellen Zielklassen mal "Class_CTRL_1", "Class_CTRL_2", ... und gehen wir davon aus, dass alle diese Klassen von einer gemeinsamen Parent-Klasse "Class_Basis_CTRL" abgeleitet sein sollen.

Der kleine aber wirkungsvolle Trick, um volles Code Assist zu bekommen, besteht nun darin, am Kopf einer Trait-Methode $this auf eine interne Variable abzubilden und dabei ein Typ-Hinting einzusetzen:

/* @var $myself Class_Basis_CTRL */
$myself = $this;

Danach arbeitet man in der Entwicklung der Trait-Methoden-Codes anstelle von $this mit $myself weiter und erhält dadurch kompletten Zugriff auf alle Variablen und Methoden von "Class_Basis_Ctrl" im Rahmen des PDT Code Assists. Und weiter auch auf referenzierte Objektklassen, wenn die für die zugehörigen Variablen in der Zielklasse bereits Type Hinting eingesetzt wurde. Das macht wirklich Spaß und Laune ...

Viel Spaß künftig bei der effizienten Entwicklung von Traits unter PHP5.4 mit Eclipse !

PHP Code Content Assists und Inline Type Hinting in Eclipse

Vor ein paar Jahren war ich sehr happy, als ich entdeckte, dass Eclipse mit dem PHP Pluging (PDT) etliche Möglichkeiten im Bereich des PHP Content Assistings bietet. So nutze ich die Möglichkeiten des Type Hintings mittels "phpDocumentor tags" ausgiebig oberhalb der Deklaration von Class Member Variablen oder bei der Definition von Funktionen (frei oder als Objekt-Methoden). Es ist einfach schön, bequem und sehr effizient, wenn "Ctrl-Space" das Tippen von neuem Code in einem PHP-Projekt mit passenden Vorschlägen aufgrund der Definition von Klassen etc. in anderen Dateien unterstützt. Fast magisch !

Was ich bisher nicht hinbekommen hatte, war das Type Hinting und "Content Assisting" zu Variablen im PHP-Code, die im Rahmen einer dynamischen Namensgebung über die Nutzung der Funktion "call_user_func" als Objekt einer Klasse instanziiert werden. Das braucht man z.B., wenn man das Singleton-Pattern benutzt und das Singleton-Objekt entweder erstmalig instanziiert werden muss oder aber die Referenz auf das ggf. schon existierende Singleton-Objekt geholt werden soll - soweit es bereits woanders instanziiert wurde.

Aber auch das geht unter Eclipse PDT mit sog. "Inline Type Hinting". Ein Beispiel:

	$get_instance ="getInstance"; 
	$Class_SS_Run_Data_Name = "Class_SS_Run_Data";
	$ay_SS_Run_Data		= array($Class_SS_Run_Data_Name, $get_instance);

	/* @var $SS_Run_Data Class_SS_Run_Data */		
	$SS_Run_Data = call_user_func($ay_SS_Run_Data);
	unset($ay_SS_Run_Data); 		

getInstance ist hier eine statische Methode, die gemäß des Singleton Patterns entweder das Objekt instanziiert oder die Referenz auf das Singleton Objekt aus einer statischen Variablen ermittelt.

Wichtig ist hier aber die Kommentar-Zeile und ihr Aufbau. Die Klasse "Class_SS_Run_Data" ist in einer anderen Datei definiert, deren Source Pfad natürlich im Bereich des BUILD Path des PHP-Projektes liegen muss.

Tippe ich nun später "$SS_Run_Data->" im Code erhalte ich je nach Einstellungen des Content Assistings umgehend oder spätestens über Ctrl-Space eine Vorschlagsliste zu Variablen oder Methoden der Klasse. Super !

Gelernt habe ich das nach Lesen eines Artikels von Norm McGarry, der sich mal die Mühe gemacht hat, die verschiedenen Arten des "Type Hintings" für "Content Assist"-Zwecke unter Eclipse PDT zusammenzustellen. Siehe:
PHP Type Hinting with Eclipse

Herzlichen Dank an Norm McGarry!