Kodu Bir Uygulama ile Biçimlendirmek mi!? Harika!

   Microsoft “Roslyn” ile .net derleyicilerini managed hale dönüştürmek dışında bize derleyicinin dinamiklerini oldukça tutarlı API’ler ile sunmakta. Bir önceki makalemi hatırlayacak olursanız Roslyn ile kodumuzu analiz etmeye başlamıştık. Kod analizlerinde ilk yapılması gereken şey yazılan kodun söz dizim ağacını çıkartmak olmalıdır. Bu şekilde yazılan kodu her bir bileşeni programsal olarak temsil edilebilir ve işlenebilir olacaktır. Önceki makalemde size bu işlemin Roslyn söz dizim API’si ile ne kadar da kolay olduğunu göstermiştim. Bu makalemde bir adım daha ileri giderek söz dizim API’si ile elde ettiğimiz veriyi nasıl şekillendirebileceğimizi göstermek istiyorum.

   Makalemin başlığından da anlayacağınız gibi örneğim yazdığımız bir kodu yeniden biçimlendirmek üzerine olacak (bknz.: prettyprint). Büyük bir ekibin parçası iseniz daha da önemlisi benim gibi böylesi bir ekibi yönetme sorumluluğunuz varsa, yazılan kodun tek bir elden çıkmış gibi olması sizin için önemli olmalı. Bu sayede ekibe yeni katılan bir yazılımcı standartlarınıza alışması sonrasında projenin her yerindeki kodları inceleyebilir/kolayca anlayabilir. Eminim ki pek çoğunuz yaşamıştır; sizden önceki yazılım geliştiricinin yazdığı kodlar sizin alışkın olduğunuz tarzdan farklı yazılmıştır. Değişken isimleri farklı şekilde verilmiştir, hatta parantezler bile alışkın olduğunuz yerde değildir ve bunlar sizin koda ısınma sürenizi olumsuz etkileyecektir. Bu durumun önüne geçebilmek ve sirkülasyon yaşanan ekiplerde kodun tek elden çıkmış gibi görünebilmesini sağlamak için standartlara ihtiyacınız olacaktır. Şanslıyız ki Visual Studio bu konuda bize yardımcı ve kodu yeniden biçimlendiriyor; fakat bunun için yazılım geliştiricinin menüden ya da klavyeden bu işlemi tetiklemesi gerekli. Bu durumda da bazen bu basit işlem gözden kaçabilir. Bu durumda yapılabilecek en mantıklı hareket kullanıcının kodunuz TFS v.b. kaynak kod sunucunuza girmeden hemen önce bu işlemi otomatik yaptırabilmek.

   Roslyn ile birlikte kolayca ulaşabildiğimiz söz dizim ağacı bize kodu yeniden düzenlemek ve ekibin standartlarına uygun hale getirmek için bir şans vermekte. Önceki paragrafta örneklediğim ve benzeri durumlar Roslyn geliştiricilerinin de akıllarına gelmiş olacak ki bu konuda bize yardımcı olmak adına CompilationUnitSyntax sınıfı içerisinde Format genişletme fonksiyonunu sunmaktalar. Söz dizim ağacına ulaşılan bir kodun yeniden formatlanarak düzgün hale gelmesi için tek yapmanız gereken aşağıdaki gibi format fonksiyonunu çağırmak oluyor;

var sozDizimAgaci = SyntaxTree.ParseCompilationUnit(
@"using System;
 
namespace Com.
Enterprisecoding.
RoslynOrnegi 
{
public
class
MerhabaDunya 
{ 
public
static
void
Mesaj()
{ 
Console.
WriteLine
(""Enterprisecoding'den Roslyn'e Merhaba""); 
} 
}
}");
 
var duzenlenmisKod = sozDizimAgaci.Root.Format().GetFullText();

  Bu örnekteki düzensiz koda ait söz dizim ağacına ulaşılması sonrasında Format fonksiyonu çağrıldığında verilen kod aşağıdaki gibi yeniden düzenlenecektir;

using System;

namespace Com.Enterprisecoding.RoslynOrnegi
{
    public class MerhabaDunya
    {
        public static void Mesaj()
        {
            Console.WriteLine("Enterprisecoding'den Roslyn'e Merhaba");
        }
    }
}

  Harika değil mi!

  Bu noktada tabi ki akıllara şu soru takılacak; “benim ekibimde kullanılan standartlar bundan farklı, ben ne yapabilirim?” Örneğin; ekibimin standartları gereği süslü parantezler bu örnekte olduğu gibi bir alt satırda değil de aynı satırda kalmalı…

   Bu noktada tahmin edebileceğiniz gibi hazırda kullanılabilecek bir fonksiyon yok; fakat tabi ki çaresiz de değiliz. Roslyn’de söz dizim ağacı çıkartılan bir kodun yeniden yazılabilmesi için SyntaxRewriter sınıfı sunulmakta. Ziyaretçi tasarım deseninin uygulandığı bu sınıf, verdiğimiz söz dizin ağacındaki her bir simgeye uğrayarak düzenlenmiş halini bizden isteyecektir. Bu durumda bizim yapmamız gereken verilen simgenin bir açan süslü parantez olması ya da arkasından bir açan süslü parantez gelmesi durumunda boşlukları silmek olacak. Bu kadar basit…

public class KodDuzenleyici : SyntaxRewriter {
    protected override SyntaxToken VisitToken(SyntaxToken simge) {
 
        if (simge.GetNextToken().Kind == SyntaxKind.OpenBraceToken) {
            return simge.WithTrailingTrivia();
        }
        else if (simge.Kind == SyntaxKind.OpenBraceToken) {
            return simge.WithLeadingTrivia();
        }
 
        return simge;
    }
}

   Bu kod parçacığında kullandığımız WithTrailingTrivia ve WithLeadingTrivia fonksiyonları verilen simgenin sadece önündeki veya arkasındaki boşluk v.b. karakterlerle kopyalanmasını sağlayacaktır. Bu durumda da çağırılan fonksiyona göre simgenin önündeki ya da arkasındaki boşluklar otomatik olarak silinecektir. Kodumuzu aşağıdaki şekilde kullanmamız mümkün;

var duzenlenmisKod = new KodDuzenleyici().Visit(sozDizimAgaci.Root.Format()).GetFullText();

  Bu kodun çalışması sonrasında verdiğimiz string ifade içerisindeki kodumuz aşağıdaki gibi yeniden formatlanmış olacak;

using System;

namespace Com.Enterprisecoding.RoslynOrnegi{
    public class MerhabaDunya{
        public static void Mesaj(){
            Console.WriteLine("Enterprisecoding'den Roslyn'e Merhaba");
        }
    }
}

   Üstelik isterseniz bu kullanımı aşağıdaki gibi bir genişleme fonksiyonu yardımıyla daha basit bir hale getirmeniz de mümkün;

public static class EnterprisecodingSyntaxExtensions {
    public static SyntaxNode KoduBicimlendir(this SyntaxNode dugum) {
        return new KodDuzenleyici().Visit(dugum.Format());
    }
}

   Bu düzenleme sonrasında kodun kullanımı da şu şekilde olacaktır;

var duzenlenmisKod = sozDizimAgaci.Root.KoduBicimlendir().GetFullText();

Fatih Boy

Ankara'da yaşayan Fatih, bir kamu kurumunda danışman olarak çalışmaktadır. ALM süreçleri, kurumsal veri yolu sistemleri, kurumsal altyapı ve yazılım geliştirme konularında destek vermektedir. Boş zamanlarında açık kaynak kodlu projeler geliştirmeyi ve bilgisini yazdığı makalelerle paylaşmayı seven Fatih, aynı zamanda Visual C# ve Visual Studio teknolojileri konusundan Microsoft tarafından altı yıl üst üste MVP (En Değerli Profesyonel) ödülüne layık görülmüştür. İş hayatı boyunca masaüstü uygulamaları, web teknolojileri, akıllı istemciler gibi konularda Asp.Net, Php, C#, Java programlama dilleri ve MySql, MsSql ve Oracle gibi veritabanı yönetim yazılımları ile çalışmıştır. İngilizce ve Türkçe olarak yayınlanan makalelerini gerek İngilizce bloğunda, gerekse de Türkçe bloğunda bulabileceğiniz gibi web sitesinden de açık kaynak kodlu geliştirdiği yazılımlarına ulaşabilirsiniz. vCard - Twitter - Facebook - Google+

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir