Mechanizm szablonów XPAND jest moim ulubionym generatorem kodu. Jest nieprawdopodobnie wygodny i posiada wiele unikalnych cech które naprawdę ułatwiają pracę. Tematem tego wpisu (tutoriala) będą tzw. upiększacze kodu.
W generatorze XPAND domyślnie mamy dwa takie upiększacze: JavaBeautifier oraz XmlBeautifier. Jeżeli generujemy kod w jednej z obsługiwanych notacji dzięki dodaniu tych klas do procesu mamy pięknie sformatowany i czytelny kod wynikowy. Co jednak jeżeli generujemy kod JavaScript gdy budujemy aplikację webową? Cóż wynik nie jest najciekawszy. Praktycznie wygenerowanie czytelnego kodu graniczy z cudem i wymaga tworzenie naprawdę nieczytelnych szablonów które symulują częściowo formatowanie wynikowe co stanowi wyjątkowo brzydki anty-wzorzec. Koszmar którego nawet nie będę prezentował.
Dlaczego nie ma domyślnie klasy formatującej JavaScript w pakiecie XPAND? Odpowiedzią jest oczywiście nieskończona ilość generowanych notacji. Spróbujmy więc czy napisanie klasy pomocniczej dla JavaScript jest trudne.
Od czego zacząć? Myślę że powinniśmy postępować zgodnie z metodologią "Monkey see/Monkey do" zaprezentowaną kilka lat temu przez
Ericha Gammę w książce
"Contributing to Eclipse". Co kryje się pod tym tajemniczym sformułowaniem? Prosta zasada "zobacz jak robią to inni, skopiuj i dostosuj rozwiązanie do swoich potrzeb".
Zobaczmy więc jak działa klasa JavaBeautifier. Otwieramy sobie jej źródło i wszystko staje się jasne. Klasa ta implementuje interfejs
PostProcessor z metodą:
beforeWriteAndClose(FileHandle fileHandle) odpowiedzialną za formatowanie kodu. Sam proces formatowania przekazywany jest do mechanizmów JDT wykorzystując klasę:
org.eclipse.jdt.core.formatter.CodeFormatter;
Cały process wygląda mniej więcej następująco:
beforeWriteAndClose(final FileHandle fileHandle){
jeżeli rozszerzenie == 'java' to:
Document doc = new Document(fileHandle.getBuffer().toString());
TextEdit edit = getCodeFormatter().format(
CodeFormatter.K_COMPILATION_UNIT, doc.get(), 0, doc.get().length(), 0, null);
edit.apply(doc);
fileHandle.setBuffer(new StringBuffer(doc.get()));
}CodeFormatter getCodeFormatter() {
inicjacja opcji na podstawie ustawień formatowania
return ToolFactory.createCodeFormatter(options);
}Jak widać całość opiera się o gotowe mechanizmy formatujące. Ponieważ identyczne możliwości formatowania kodu zostały zaimplementowane także w WTP dla edytora JavaScript wykorzystanie tego podejścia nie wydaje się być problemem. Jak jednak znaleźć odpowiedni kod w środowisku złożonym z grubo ponad tysiąca projektów jeżeli nie wiemy gdzie mechanizmy te zostały zaimplementowane? Wykorzystamy mechanizm Plugin Spy pokazujący nam informacje o praktycznie dowolnym elemencie środowiska. Otwieramy edytor JavaScript dostarczany z pakietem WTP,
ALT+SHIFT+F1 i pojawia nam się następująca informacja:

Skoro wiemy już że edytor ten został dostarczony przez plugin WST.JSDT wgrywamy go do naszego workspace. W tym celu wykorzystujemy kreator:
Plug-in Development|Plug-ins and Fragments|Binary Project with linked content|filtr *wst.jstd i ściągamy podejrzane projekty:
org.eclipse.wst.jsdt.core
org.eclipse.wst.jsdt.core.uiPraktycznie od razu zauważamy pakiet
formatter a w nim klasę w której znajduje się identyczny kod:
org.eclipse.wst.jsdt.core.formatter.CodeFormatterApplicationWywołanie mechanizmów formatujących JSDT wymagać będzie od nas zaledwie zmiany dwóch importów z JDT na JSDT oraz identyfikatora określającego formatowaną zawartość. Postępując z wzorcem małpki kopiujemy oryginalną zawartość klasy JavaBeautifer do nowej klasy o nazwie JavaScriptBeautifier. Następnie modyfikujemy importy:
//import org.eclipse.jdt.core.ToolFactory;
//import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.wst.jsdt.core.ToolFactory;
import org.eclipse.wst.jsdt.core.formatter.CodeFormatter;sprawdzane rozszerzenie pliku oraz identyfikator:
//getCodeFormatter().format(CodeFormatter.K_COMPILATION_UNIT,..
getCodeFormatter().format(CodeFormatter.K_JAVASCRIPT_UNIT,...Klasa upiększająca kod JavaScript jest gotowa. Ostatnim elementem jest ustalenie konfiguracji w jaki sposób kod powinien się formatować. W tym celu korzystając z kreatora tworzymy właściwy dla naszych projektów sposób formatowania (najlepiej zwiększyć długość linii z 80 do 140...160 co jest moim zdaniem optymalne dla kodu generowanego)
Ustawienia te zostaną zapisane w pliku:
[workspace].metadata\.plugins\org.eclipse.core.runtime\.settings\ org.eclipse.wst.jsdt.core.prefsKopiujemy plik konfiguracyjny do naszego projektu w którym wykorzystujemy nasz formater i gotowe. Całość zabrała nam zaledwie kilka minut (napisanie tego tutoriala trochę więcej).
Mam nadzieję że komuś taka klasa się przyda. W czasach absolutnej dominacji aplikacji webowych, technologii Ajax, przeglądarki Google Chrome etc. coraz częściej generujemy kod JavaScript a nic tak nie cieszy jak kod czytelny i dobrze sformatowany :)