Programowanie w parze z kompilatorem Roslyn
Programowanie w parach jest znane z paradygmatu programowania ekstremalnego. Jego zadaniem jest podniesienie jakości kodu poprzez połączenie dwóch programistów, gdzie jeden pisze kod a drugi obserwuje poczynania kolegi i doradza. W założeniu takie podejście ma zmniejszyć ilość błędów, poprawić czytelność kodu oraz paradoksalnie dla niektórych, dostarczyć szybciej rozwiązanie. Ciężko jednak przekonać biznes, że dwóch programistów pracujących razem nad jednym zadaniem dostarczy więcej w krótszym czasie, ponieważ w krótszym czasie generuje większe koszty niż zysk z takiego przedsięwzięcia.
Piotr Czech. Konsultant w firmie VLOG, gdzie wspiera rozwój oprogramowania u klientów. Budował systemy oparte o RODO oraz mobilne systemy telemetryczne zbierające i przetwarzający dane o kierowcach w celu obniżenia ubezpieczeń, między zadaniami na poprawianie bugów. Entuzjasta podejść architektonicznych w systemach oraz budowania wydajnych rozwiązań opartych o platformę .NET poprzez eksplorację nowych technik oraz uczenie innych… i gonienie ich, jeśli nie przykładają się do kodu.
Sytuacja zmienia się diametralnie patrząc przez pryzmat wielu lat tworzenia i utrzymywania danego systemu, gdzie koszty utrzymania przerastają koszty wytworzenia.
Jednak jeśli nie jesteśmy w stanie wprowadzić tej techniki to możemy wykorzystać substytut, który pozwoli utrzymać kod na minimalnym (akceptowalnym) poziomie, który sami zdefiniujemy. W tym celu wykorzystamy analizatory kodu.
Spis treści
Analizator kodu
Jego zadaniem jest statyczna analiza kodu, oznacza to:
- sprawdzenie poprawności składni
- sprawdzenie jakości kodu i przyjętych standardów
- znalezienie luk bezpieczeństwa lub problemów wydajnościowych
- wykonanie auto refactoringu i proponowanie rozwiązań
Języki silnie typowane takie jak C# czy Java posiadają w sobie podstawowe rozwiązania, które sprawdzają kod przed kompilacją.
Jednak, gdy mówimy o projektach, w których mamy setki solucji potrzebujemy rozwiązania, które będzie dbać o więcej niż tylko czy kod się uruchomi, dlatego m.in .NET’cie wprowadzono nowy typ kompilatora — Roslyn.
Analiza na poziomie kompilatora — Roslyn
Roslyn jest kompilatorem i dba o to jak kod zostanie wygenerowany, sam w sobie posiada wiele sztuczek, dzięki którym nasz kod wynikowy jest bardziej wydajny. Kod źródłowy można znaleźć pod tym linkiem, analizuje składnie, semantykę, przepływ danych przez co jesteśmy w stanie zbudować własne poprawki dla kodu, gdzie deweloperowi ukażą się jako sugestie podczas pisania rozwiązania.
To co jest najważniejsze w tym wszystkim, razem z kompilatorem został dostarczony zestaw reguł, dzięki którym jesteśmy w stanie wymuszać określone standardy np. reguła CA2000 wymaga, aby po skończeniu używania klasy użyć metody dispose, jeśli implementuje interfejs IDisposable, aby nie pojawił się wyciek pamięci.
StyleCop, ponieważ tutaj o nim mowa pozwala na wymuszanie określonych standardów kodu i jest jednym z wielu rozwiązań na tym polu. Jego implementacje dla Roslyna znajduje się pod nazwą StyleCopAnalyzers, czyli wbudowany w kompilator zestaw reguł czyt. analizator.
Niektóre reguły pozwalają na szybki refactoring (autofix), więc rozwiązania pokroju Resharpera poza własnymi regułami układania kodu i wprowadzania poprawek jest w stanie skorzystać z analizatorów i rozszerzyć swoje działanie o dodatkowe mechanizmy, tak jak na obrazku powyżej.
Budowanie paczki z regułami
Analizatory w .NET’cie można zainstalować na poziomie rozszerzenia (VSIX) lub paczki (nugeta). Drugi sposób oraz wiedza, że możemy zbudować własny analizator pozwala zbudować nam (agregować) różne analizatory w jedną paczkę oraz stworzyć własne zasady co do reguł.
Dzięki temu przy wdrożeniu nowego analizatora mamy we wszystkich projektach te same reguły bez potrzeby załączania dodatkowych plików do każdego projektu np. settings.stylecop.
Aby zbudować swój własny analizator będziemy potrzebować rozszerzenia do Visual Studio, które instalujemy poprzez Visual Studio Installer:
Posiadając to rozszerzenie możemy wybrać między trzema rodzajami projektów. W naszym wypadku wybierzemy wersję drugą, w której jesteśmy w stanie zbudować własne reguły oraz szybkie poprawki kodu.
Projekt jest zbudowany w oparciu o .NET Standard, więc jest kompatybilny ze wszystkimi rozwiązaniami oferowanymi w ekosystemie .NET.
W naszym wypadku ograniczymy się do zbudowania biblioteki z regułami, pomijając szybkie poprawki.
Teoretycznie jest to pusty projekt. Analizatory znajdują się wśród referencji. Reguły, które one definiują możemy nadpisać za pomocą pliku [dowolna_nazwa].ruleset, który podczas budowania projektu będzie nadpisywał domyślne reguły, dodatkowo możemy zmodyfikować StyleCop dzięki plikowi stylecop.json.
Warto przejrzeć już stworzone analizatory m.in:
1. Roslynator, AsyncFixer, Refactoring Essentials, Code Cracker — użyteczne podczas analizy i refactoringu kodu.
2. Puma Scan, Secure Code Scan — sprawdzają kod pod względem bezpieczeństwa.
3. Sharpen — rozszerzenie VSIX do eliminacji długu technologicznego i użytej w kodzie przestarzałej składni.
Po co agregować paczki?
Jednym z benefitów tworzenia pustego projektu, który posiada tylko zewnętrzne referencje jest przeciwdziałanie długowi technologicznemu. Łatwiej jest zrobić upgrade dla 20 systemów, który posiada tylko jedną paczkę z 50 zależnościami niż dla każdego projektu robić to osobno.
Kolejnym benefitem jest centralne zarządzanie zależnościami, ponieważ patrząc przez pryzmat moje firmy, gdzie osoby pracują nad podniesieniem wersji projektów i tworzeniem wewnętrznych paczek w tym wypadku są w stanie ujednolicić wersje dla wszystkich systemów za jednym zamachem.
Rozszerzenia do Visual Studio Code
Powyższy przykład z Roslyn’em bazował jedynie na ekosystemie .NET, jednak VS Code pozwala nam zintegrować wiele różnych środowisk programistycznych i rozszerzyć ich możliwości o dodatkowe funkcjonalności.
Polecane rozszerzenia:
1. Prettier — rozszerzenie do formatowania kodu według standardów dla danego języka
2. TSLint — analizator kodu do TypeScripta
3. Angular Essentials — all-in-one, paczka agregująca wszystkie rozszerzenia, które przydadzą się przy pracy z Angularem
4. EditorConfig for VS Code — rozszerzenie, która dba o jednolity styl kodowania wszystkich programistów w zespole poprzez narzucenie z góry określony standardów i reguł.
Podsumowanie
Przykładowy projekt z analizatorami znajdziesz na moim githubie: xeinaemm. W kolejnej części opiszę budowanie własnych mechanizmów do poprawek kodu, z których będą mogli korzystać deweloperzy. A tymczasem, do następnego!
Zdjęcie główne artykułu pochodzi z unsplash.com.