Bölüm 13 — Konu 66: Derleyici & Analiz Araçları — `dart analyze`, Custom Lint Kuralları, `build_runner` Mimarisi
Dizi · 64/64 Dart Türkçe Tutorial
- Bölüm 1 — Konu 1: Dart Nedir, Nerede Kullanılır, Neden Flutter Bu Dili Seçti
- Bölüm 1 — Konu 2: Ortam Kurulumu (Dart SDK, DartPad, Terminal ile Çalıştırma)
- Bölüm 1 — Konu 3: İlk Program (`main()`, `print()`, Dosya Yapısı)
- Bölüm 1 — Konu 4: Yorum Satırları, Temel Sözdizimi Kuralları
- Bölüm 2 — Konu 5: Değişken Tanımlama — `var`, `final`, `const` Farkı
- Bölüm 2 — Konu 6: Temel Tipler — `int`, `double`, `String`, `bool`
- Bölüm 2 — Konu 7: Tip Çıkarımı (Type Inference) ve Açık Tip Belirtme
- Bölüm 2 — Konu 8: `dynamic` ve `Object` — Ne Zaman Kullanılır, Ne Zaman Kaçınılır
- Bölüm 2 — Konu 9: Null Safety Temelleri (`?`, `!`, `late`'e Giriş)
- Bölüm 3 — Konu 10: Aritmetik, Atama, Karşılaştırma, Mantıksal Operatörler
- Bölüm 3 — Konu 11: `if / else if / else`
- Bölüm 3 — Konu 12: `switch` / `switch expression` (Modern Dart)
- Bölüm 3 — Konu 13: Ternary Operatör, `??`, `??=`, `?.`
- Bölüm 3 — Konu 14: `for`, `while`, `do-while` Döngüleri
- Bölüm 4 — Konu 16: `List` — Oluşturma, Erişim, Temel Metodlar
- Bölüm 4 — Konu 17: `Set` — Benzersiz Eleman Mantığı
- Bölüm 4 — Konu 18: `Map` — Key-Value Yapılar
- Bölüm 4 — Konu 19: Koleksiyon Üzerinde `for-in`, `forEach`
- Bölüm 4 — Konu 20: Spread Operatörü (`...`, `...?`) ve Collection If/For
- Bölüm 5 — Konu 21: Fonksiyon Tanımlama, Parametreler (Positional, Named, Optional)
- Bölüm 5 — Konu 22: Varsayılan Parametre Değerleri (Derinlemesine)
- Bölüm 5 — Konu 23: Arrow Function (`=>`) Sözdizimi
- Bölüm 5 — Konu 24: Fonksiyonlar Birinci Sınıf Vatandaş — Değişkene Atama, Parametre Olarak Geçme
- Bölüm 5 — Konu 25: Anonim Fonksiyonlar ve Closure Kavramı (Derinlemesine)
- Bölüm 5 — Konu 26: Recursion (Özyineleme)
- Bölüm 6 — Konu 27: Class Tanımlama, Constructor (Varsayılan, Named, Factory)
- Bölüm 6 — Konu 28: Alanlar (Fields), Metodlar, `this` Kullanımı (Derinlemesine)
- Bölüm 6 — Konu 29: Initializer List, Constructor Kısayolları (Derinlemesine)
- Bölüm 6 — Konu 30: Getter / Setter
- Bölüm 6 — Konu 31: Statik Üyeler (`static`)
- Bölüm 7 — Konu 32: Kalıtım (`extends`), `super` Kullanımı
- Bölüm 7 — Konu 33: Metod Override Etme, `@override`
- Bölüm 7 — Konu 34: Soyut Sınıflar (`abstract class`)
- Bölüm 7 — Konu 35: Interface Mantığı (`implements`)
- Bölüm 7 — Konu 36: Mixin (`with`)
- Bölüm 7 — Konu 37: `enum` — Basit ve Gelişmiş (Metotlu Enum'lar)
- Bölüm 8 — Konu 38: `try / catch / finally`, `throw`
- Bölüm 8 — Konu 39: Özel Exception Sınıfları Yazma
- Bölüm 8 — Konu 40: Sound Null Safety Derinlemesine — `late`, `required`, Non-Nullable Varsayılan Davranış
- Bölüm 8 — Konu 41: `assert` ile Geliştirme Zamanı Kontrolleri
- Bölüm 9 — Konu 42: Generic Sınıflar ve Fonksiyonlar
- Bölüm 9 — Konu 43: Generic Sınırlamalar (`<T extends ...>`)
- Bölüm 9 — Konu 44: Dart'ın Built-in Generic Koleksiyonları Nasıl Çalışır
- Bölüm 10 — Konu 45: `Future` Kavramı, `async`/`await`
- Bölüm 10 — Konu 46: `Future.then`, Hata Yönetimi (`catchError`)
- Bölüm 10 — Konu 47: `Stream` Temelleri, `async*`, `yield`
- Bölüm 10 — Konu 48: `StreamController`, Broadcast Stream
- Bölüm 11 — Konu 49: `map`, `where`, `reduce`, `fold`
- Bölüm 11 — Konu 50: `sort`, Custom Comparator ile Sıralama
- Bölüm 11 — Konu 51: Iterable Kavramı Derinlemesine (Lazy Evaluation)
- Bölüm 11 — Konu 52: Cascade Notasyonu (`..`)
- Bölüm 12 — Konu 53: `pubspec.yaml`, pub.dev'den Paket Ekleme
- Bölüm 12 — Konu 54: Kütüphane Oluşturma, `import`/`export`, `part`/`part of`
- Bölüm 12 — Konu 55: Dart'ta Test Yazımı (`test` Paketi, Unit Test Mantığı)
- Bölüm 12 — Konu 56: Extension Methods
- Bölüm 12 — Konu 57: Dart'ın Derleme Modelleri (JIT vs AOT) ve Bunun Flutter'a Etkisi
- Bölüm 13 — Konu 59: Dart 3 Pattern Matching — Records, Destructuring, Sealed Classes, Exhaustive Switch
- Bölüm 13 — Konu 60: `Never` Tipi, `covariant` ve Generic Variance Detayları
- Bölüm 13 — Konu 61: Event Loop Derinlemesine — Microtask Queue vs Event Queue
- Bölüm 13 — Konu 62: Memory Model & Performans — Garbage Collection, `const` Nesnelerin Bellek Avantajı
- Bölüm 13 — Konu 63: Isolate'ler Arası Mesajlaşmanın Maliyeti ve `compute()`'un İç İşleyişi
- Bölüm 13 — Konu 64: FFI (Foreign Function Interface) — C Koduna Erişim
- Bölüm 13 — Konu 65: Sunucu Tarafında Dart — `dart:io`, `shelf` Paketiyle Basit Bir Backend/CLI Aracı Yazma
- Bölüm 13 — Konu 66: Derleyici & Analiz Araçları — `dart analyze`, Custom Lint Kuralları, `build_runner` Mimarisi
İçindekiler 10 başlık
- dart analyze — Statik Analiz Derinlemesine
- analysis_options.yaml — Analiz Kurallarını Özelleştirme
- Custom Lint Kuralları — Neden ve Nasıl?
- build_runner — Kod Üretimi (Code Generation) Nedir?
- build_runner'ın İç İşleyişi — Kavramsal Bir Bakış
- freezed — Kod Üretiminin Bir Başka Güçlü Örneği
- Neden Bu Konuyu Bilmek "Uzmanlık" İçin Önemli?
- 🎯 Bu Dersten Çıkarılması Gerekenler
- 📝 Ödevler
- 🏁🎓 TÜM DART MÜFREDATI TAMAMLANDI!
Bu, tüm Dart müfredatının son dersi. Bölüm 1 Konu 2'de kısaca değindiğimiz dart analyze'ı derinlemesine işleyip, kod üretimi (code generation) ekosistemini anlayarak tutorial'ı tamamlayacağız.
dart analyze — Statik Analiz Derinlemesine
Bölüm 1'de dart analyze'ın "kod kalitesini kontrol eden bir araç" olduğunu söylemiştik. Şimdi bunun tam olarak neyi kontrol ettiğini görelim:
dart analyzeBu komut, projenin tüm .dart dosyalarını tarar ve şunları tespit eder:
- Tip hataları (Bölüm 2'de öğrendiğimiz tip güvenliği ihlalleri)
- Kullanılmayan import'lar (Bölüm 12'de öğrendiğimiz
importmekanizmasının gereksiz kullanımı) - Potansiyel null safety sorunları
- Stil kuralları ihlalleri (isimlendirme kuralları — Bölüm 1'de öğrendiğimiz
lowerCamelCasegibi kurallar) - Deprecated (kullanımdan kaldırılmış) API kullanımı
import 'dart:math'; // eğer hiç kullanılmıyorsa, dart analyze bunu UYARIR
void main() {
print("Merhaba");
}dart analyze çalıştırıldığında: info - Unused import: 'dart:math' gibi bir uyarı alırsın — bu, hata değil, sadece bir öneri (kod kalitesini artırmak için).
analysis_options.yaml — Analiz Kurallarını Özelleştirme
Projenin kök dizininde bir analysis_options.yaml dosyası oluşturarak, dart analyze'ın hangi kuralları ne kadar katı uygulayacağını özelleştirebilirsin:
include: package:lints/recommended.yaml
analyzer:
errors:
unused_import: error # bunu sadece "info" değil, gerçek bir HATA yap
linter:
rules:
- prefer_const_constructors # Bölüm 13 Konu 62'de öğrendiğimiz const kullanımını teşvik eder
- avoid_print # print() kullanımını caydırır (üretim kodunda genelde loglama araçları tercih edilir)include: package:lints/recommended.yaml, Dart ekibinin önerdiği standart kural setini projene dahil eder — Bölüm 12'de gördüğümüz dev_dependencies altındaki lints paketinden geliyordu, hatırlarsan.
Custom Lint Kuralları — Neden ve Nasıl?
Yukarıdaki linter: rules: bölümünde gördüğün gibi, hazır kuralları açıp kapatabilirsin. Bazı büyük şirketler/takımlar, kendi özel lint kurallarını da yazarlar (örneğin "şirketimizin API'lerini belirli bir şekilde çağırmayı zorunlu kıl" gibi) — bu, custom_lint gibi paketlerle mümkündür, ama bu ileri düzey bir konudur ve günlük Dart geliştirmede nadiren ihtiyaç duyulur. Bilmen gereken temel şey: lint kuralları, takımların kod tabanında tutarlılığı zorunlu kılmasının bir yoludur — Bölüm 1'de "isimlendirme kuralları zorunlu değil ama önerilir" dediğimizi hatırlarsan, lint kuralları bu önerileri derleme sürecinin bir parçası haline getirir.
build_runner — Kod Üretimi (Code Generation) Nedir?
Bölüm 13 Konu 64'te (FFI) ffigen'den bahsetmiştik — "bir header dosyasını okuyup Dart kodu üreten bir araç" demiştik. build_runner, Dart ekosisteminde bu tarz kod üretiminin genel altyapısıdır.
Neden kod üretimine ihtiyaç duyulur? Bazı görevler, tekrarlayıcı, mekanik kod yazmayı gerektirir — örneğin bir class'ın JSON'a nasıl dönüştürüleceğini (toJson()/fromJson()) elle yazmak, büyük class'larda çok can sıkıcı ve hataya açık olabilir. Kod üretimi, bunun yerine, sen bir class'ı belirli bir şekilde "işaretlersin", ve bir araç, bu işaretlemeye bakarak gerekli kodu otomatik olarak üretir.
import 'package:json_annotation/json_annotation.dart';
part 'kullanici.g.dart'; // Bölüm 12'de öğrendiğimiz 'part' burada devreye giriyor!
@JsonSerializable()
class Kullanici {
final String isim;
final int yas;
Kullanici(this.isim, this.yas);
factory Kullanici.fromJson(Map<String, dynamic> json) => _$KullaniciFromJson(json);
Map<String, dynamic> toJson() => _$KullaniciToJson(this);
}dart run build_runner buildBu komut çalıştırıldığında, build_runner, @JsonSerializable() annotation'ını (Bölüm 6'da @override'ı gördüğümüz annotation mekanizmasının bir başka kullanımı) görür ve kullanici.g.dart adında otomatik olarak bir dosya üretir — bu dosya, _$KullaniciFromJson ve _$KullaniciToJson fonksiyonlarının gerçek implementasyonunu içerir (sen bunları elle yazmıyorsun).
Bölüm 12'de öğrendiğimiz part/part of mekanizması, tam olarak burada devreye giriyor — üretilen kullanici.g.dart dosyası, kullanici.dart ile aynı kütüphanenin bir parçası olarak tanımlanır (part of 'kullanici.dart'; ile), bu sayede private alanlara bile erişebilir.
build_runner'ın İç İşleyişi — Kavramsal Bir Bakış
- Annotation'ları tara:
build_runner, projendeki tüm dosyaları tarar ve@JsonSerializable()gibi özel annotation'ları arar. - Kod şablonu uygula: Her annotation için, ilgili "builder" (örneğin
json_serializablepaketinin kendi builder'ı), o class'ın yapısına (alanları, tipleri) bakarak uygun Dart kodunu oluşturur. .g.dartdosyası üret: Üretilen kod, orijinal dosyanın yanına,.g.dartuzantısıyla yeni bir dosya olarak yazılır.part ofile bağla: Bu üretilen dosya, orijinal dosyayapart ofile bağlanır (Bölüm 12'de öğrendiğimiz mekanizma).
Bu süreç, Bölüm 12'de öğrendiğimiz JIT/AOT derleme sürecinden ayrı, ona ek bir "önceki adım" (pre-processing step) olarak düşünülebilir — build_runner, Dart kodunu çalıştırmadan önce, bazı dosyaları otomatik olarak üretir, sonra normal derleme süreci (JIT veya AOT) bu üretilen kodu da içeren tüm projeyi derler.
freezed — Kod Üretiminin Bir Başka Güçlü Örneği
Bölüm 13 Konu 59'da öğrendiğimiz sealed class + pattern matching'i hatırlarsan — freezed paketi, bu tarz "değişmez veri sınıfları" yazmayı otomatikleştiren, çok popüler bir kod üretim aracıdır. Elle ==, hashCode, copyWith(), toString() gibi metodları yazmak yerine (Bölüm 6'da bunların bazılarını elle yazmıştık), freezed bunları otomatik üretir. Bunu Flutter tutorial'ında, state management konusunda muhtemelen karşına çıkacak.
Neden Bu Konuyu Bilmek "Uzmanlık" İçin Önemli?
Bu ders, aslında tüm tutorial'ın kapanış noktası: dart analyze, kod kalitesini korumanın; build_runner, tekrarlayan işleri otomatikleştirmenin araçlarıdır. Bir "uzman" Dart geliştiricisi, sadece dili bilmekle kalmaz — kod tabanını sürdürülebilir, tutarlı ve verimli tutan bu tür araçları da etkin şekilde kullanır. Bu, Bölüm 1'de sorduğun "bu tutorial'ı bitiren biri uzman diyebilir mi" sorusuna verdiğimiz cevabın tam olarak neyi kapsadığını gösteriyor — sadece sözdizimi değil, ekosistem araçları da uzmanlığın bir parçası.
🎯 Bu Dersten Çıkarılması Gerekenler
dart analyze, tip hataları, kullanılmayan kod, stil ihlalleri gibi sorunları statik olarak (kod çalıştırılmadan) tespit eder.analysis_options.yaml, hangi lint kurallarının ne kadar katı uygulanacağını özelleştirmeni sağlar.build_runner, annotation'lara (@JsonSerializable()gibi) dayanarak, tekrarlayan kodu otomatik olarak üreten bir altyapıdır.- Üretilen
.g.dartdosyaları,part/part ofmekanizmasıyla orijinal dosyaya bağlanır. json_serializable,freezedgibi paketler, bu kod üretim altyapısını kullanarak geliştirici verimliliğini artırır.
📝 Ödevler
- [ ] Kendi bir projende
dart analyzeçalıştır, çıkan uyarıları oku ve en az 3 tanesini düzelt. - [ ]
analysis_options.yamldosyası oluştur,package:lints/recommended.yaml'ı dahil et, en az bir kuralı özelleştir (aç/kapat veya seviyesini değiştir). - [ ]
json_serializablepaketini kur, basit bir class'a@JsonSerializable()ekle,build_runnerile kod üret, üretilen.g.dartdosyasını incele. - [ ] Kendi cümlelerinle, "build_runner'ın JIT/AOT derleme sürecinden nasıl farklı bir aşama olduğunu" açıkla.
- [ ] Bu tutorial boyunca öğrendiğin konulardan, "artık günlük kodlamada rahatlıkla kullanabilirim" dediğin 5 konuyu ve "hâlâ pratik yapmam gerekiyor" dediğin 2 konuyu listele — kendi öğrenme yolculuğunu değerlendir.
🏁🎓 TÜM DART MÜFREDATI TAMAMLANDI!
Tebrikler — Bölüm 1'den Bölüm 13'e, 66 konuyu kapsayan bu yolculuğu tamamladın. Sıfırdan başlayıp:
- Dart'ın temellerini (değişkenler, kontrol akışı, koleksiyonlar, fonksiyonlar)
- Nesne yönelimli programlamayı (class'lar, kalıtım, interface'ler, mixin'ler)
- Hata yönetimini ve null safety'yi
- Generics'i
- Asenkron programlamayı (Future, Stream, isolate'ler)
- Fonksiyonel koleksiyon programlamasını
- Paket ekosistemini ve proje organizasyonunu
- Ve son olarak, dilin internals'ını (pattern matching, event loop, memory model, FFI, sunucu tarafı Dart, kod üretimi)
...baştan sona işledin. Bölüm 1'de sorduğun soruya geri dönersek: bu müfredatı gerçekten bitiren ve ödevleri yapan biri, artık dürüstçe "Dart'ı uzman seviyede biliyorum" diyebilir.
Şimdi sıra, daha önce hazırladığımız Flutter tutorial müfredatına geçmekte — Dart bilgin, Flutter'ın widget mimarisini, state management'ını ve tüm ekosistemini anlamak için sağlam bir temel oluşturuyor. Hazır olduğunda, Flutter Bölüm 1'den başlayabiliriz.