Analyzer

.editorconfig, warning sebagai error, dan konteks nullable.

Daftar isi

Analyzer memeriksa kode pada waktu build dan melaporkan temuannya sebagai pesan bernomor sebelum program sempat dijalankan. Topik ini membahas analyzer bawaan .NET SDK, konteks nullable beserta warning CS86xx yang dihasilkannya, pengaturan severity melalui berkas .editorconfig, serta TreatWarningsAsErrors pada csproj yang mengubah warning menjadi error. Setelah topik ini diselesaikan, kesalahan pemakaian null dan pelanggaran aturan kualitas dapat dibuat menggagalkan build, sehingga masalahnya tertangkap pada waktu kompilasi dan bukan saat program berjalan.

Analyzer bawaan .NET SDK#

Analyzer adalah komponen yang berjalan bersama kompilator C# pada waktu build, membaca struktur kode, lalu melaporkan temuannya sebagai diagnosis yang dilengkapi kode, misalnya CS8602. Kompilator C#, yaitu Roslyn, menghasilkan diagnosis berkode CS untuk kesalahan sintaks, kesalahan tipe, dan analisis nullable. Selain itu, .NET SDK membawa dua kelompok analyzer bawaan yang siap dipakai tanpa pemasangan, yaitu aturan kualitas kode berkode CA dan aturan gaya kode (code style) berkode IDE. Ketiganya menulis keluaran pada dotnet build dengan bentuk yang sama, yaitu lokasi berkas beserta barisnya, kode diagnosis, dan pesan yang menjelaskan temuannya.

KelompokContoh kodeYang diperiksa
Kompilator (CS)CS8602, CS8618aliran nilai null saat konteks nullable aktif
Aturan kualitas (CA)CA1062kesalahan desain, misalnya parameter metode publik yang tidak divalidasi
Aturan gaya (IDE)IDE0005kerapian kode, misalnya using yang tidak diperlukan

CA1062 menagih pemeriksaan parameter pada metode publik sebelum parameter itu dipakai, sedangkan IDE0005 menandai using yang tidak diperlukan. Dua aturan itu cukup mewakili kebiasaan kelompok CA dan IDE, sehingga keduanya dipakai sebagai contoh pada topik ini. Analyzer lain dapat ditambahkan lewat paket, tetapi pembahasan di sini fokus pada yang bawaan.

Setiap diagnosis memiliki tingkat keparahan atau severity. Tingkat bawaannya berbeda antar kelompok. Warning CS86xx tampil sebagai warning, sebagian besar aturan CA tidak aktif sampai dinyalakan melalui konfigurasi, dan aturan IDE umumnya tampil sebagai saran di editor. Tingkat tersebut dapat dinaikkan maupun diturunkan per aturan, dan tempat pengaturannya adalah berkas .editorconfig.

Konteks nullable dan warning kompilator#

Konteks nullable adalah mode analisis kompilator yang melacak kemungkinan nilai null pada tipe referensi. Mode ini dinyalakan dengan <Nullable>enable</Nullable> pada csproj, dan templat console bawaan .NET 10 sudah mengaktifkannya sejak awal. Dalam konteks ini, tipe string menyatakan nilai yang tidak boleh null, sedangkan string? menyatakan null yang sah. Apabila nilai yang mungkin null dipakai tanpa pemeriksaan, kompilator menampilkan warning berkode CS86xx tanpa menggagalkan build.

Program uji berikut memuat dua pola yang lazim memicu warning nullable. Property Nama pada kelas Profil bertipe string tanpa nilai awal, sehingga kelasnya dapat selesai dikonstruksi dengan property yang belum berisi apa pun. Variabel nama bertipe string? dan langsung dipanggil metode Length-nya tanpa pemeriksaan. Metode Hitung pada kelas PenghitungKata dipakai pada bagian selanjutnya untuk menguji aturan CA1062. Program ini sengaja tidak dijalankan karena dereferensinya memang bermasalah, sedangkan yang ingin diamati adalah perilaku build.

csharp Program.cs
// Program uji: memicu warning nullable dan pelanggaran aturan CA1062.
string? nama = null;
int panjang = nama.Length;
Console.WriteLine(panjang);

public class Profil
{
    public string Nama { get; set; }
}

public static class PenghitungKata
{
    public static int Hitung(string teks) => teks.Split(' ').Length;
}

Proyek console sementara dibuat di luar direktori modul, kemudian berkas Program.cs di atas menimpa berkas bawaan templat.

bash
# membuat proyek console sementara di luar direktori modul
# proyek lama dihapus lebih dahulu agar demo dapat diulang
rm -rf /tmp/cs-uji-an
dotnet new console -o /tmp/cs-uji-an 2>&1 | grep "Restore succeeded"
text Keluaran
Restore succeeded.
bash
# menimpa berkas Program.cs bawaan templat dengan program uji
cp Program.cs /tmp/cs-uji-an/

# membangun proyek, lalu memilah baris warning CS yang tampil
# baris yang sama dicetak logger dua kali, sehingga duplikatnya dihapus dan urutannya dibakukan
dotnet build /tmp/cs-uji-an --no-incremental 2>&1 | grep -oE "Program\.cs\([0-9]+,[0-9]+\): warning CS[0-9]+" | LC_ALL=C sort -u
text Keluaran
Program.cs(3,15): warning CS8602
Program.cs(8,19): warning CS8618

Keluaran menunjukkan dua warning. CS8618 pada baris 8 melaporkan property Nama yang non-nullable tetapi belum diinisialisasi ketika konstruktor selesai, dengan saran menambahkan pengubah required atau mengubah tipenya menjadi nullable. CS8602 pada baris 3 melaporkan pemanggilan anggota pada nilai yang mungkin null, karena variabel nama memang dinyatakan string?. Keduanya tidak menghentikan build, sehingga program tetap terkompilasi dan pemanggilan nama.Length baru melempar NullReferenceException saat program berjalan. Analyzer memberi kesempatan menutup jalur itu sebelum program dieksekusi.

Mengatur severity pada .editorconfig#

.editorconfig adalah berkas konfigurasi berformat INI yang dibaca editor maupun proses build. Berkas ini dicari dengan menelusuri folder berkas sumber ke atas hingga ditemukan baris root = true, sehingga satu berkas pada akar repository dapat mengatur seluruh proyek di bawahnya, sedangkan berkas pada folder yang lebih dalam menggantikan pengaturan yang lebih umum. Bagian [*.cs] menyasar seluruh berkas C#, dan di dalamnya tiap aturan dipetakan dengan sintaks dotnet_diagnostic.<kode>.severity = <nilai>.

Nilai yang sah untuk severity adalah sebagai berikut.

NilaiEfeknya
errordiagnosis ditampilkan sebagai error dan menggagalkan build
warningdiagnosis ditampilkan sebagai warning, build tetap berlanjut
suggestiondiagnosis disembunyikan dari keluaran build dan tampil sebagai saran di editor
silentanalisis tetap dijalankan, tetapi pesannya tidak ditampilkan
noneaturan dimatikan sehingga analisisnya tidak dijalankan

Berkas .editorconfig berikut mengangkat CA1062 menjadi error untuk seluruh berkas C# pada proyek yang memuatnya. Aturan ini dipilih karena pelanggarannya berbahaya saat program berjalan, yaitu parameter metode publik yang dipakai tanpa validasi sehingga NullReferenceException dapat muncul dari metode yang tidak memvalidasinya.

ini .editorconfig
root = true

# aturan CA1062 diangkat menjadi error untuk seluruh berkas C#
[*.cs]
dotnet_diagnostic.CA1062.severity = error

Setelah berkas tersebut disalin ke proyek uji, build berikutnya langsung berhenti.

bash
# menyalin .editorconfig ke dalam proyek uji
cp .editorconfig /tmp/cs-uji-an/

# membangun ulang, lalu memilah baris error yang tampil
dotnet build /tmp/cs-uji-an --no-incremental 2>&1 | grep -oE "Program\.cs\([0-9]+,[0-9]+\): error (CS|CA)[0-9]+" | LC_ALL=C sort -u
text Keluaran
Program.cs(13,46): error CA1062

Baris pada keluaran meminta parameter teks divalidasi sebelum dipakai, misalnya dengan melempar ArgumentNullException bila nilainya null. Warning CS8602 dan CS8618 masih tampil pada keluaran penuh karena tingkatnya belum diubah, tetapi keluaran di atas sengaja dipilah agar baris errornya terlihat jelas. Satu aturan saja sudah cukup mengubah build yang selalu berhasil menjadi build yang menolak kode berbahaya.

Warning sebagai error dengan TreatWarningsAsErrors#

Menetapkan aturan satu per satu pada .editorconfig tepat untuk aturan tertentu yang ingin dipertegas. Kebutuhan sebaliknya juga lazim, yaitu menyatakan bahwa proyek ini tidak menerima warning apa pun. Caranya adalah properti <TreatWarningsAsErrors>true</TreatWarningsAsErrors> pada csproj, yang menyuruh build memperlakukan setiap warning sebagai error sehingga build gagal bila masih ada yang tersisa.

xml Contoh: PropertyGroup dengan TreatWarningsAsErrors
<PropertyGroup>
  <OutputType>Exe</OutputType>
  <TargetFramework>net10.0</TargetFramework>
  <ImplicitUsings>enable</ImplicitUsings>
  <Nullable>enable</Nullable>
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

Berkas proyek cs-uji-an.csproj ditulis ulang dengan properti tersebut, lalu build dijalankan ulang.

bash
# menulis ulang berkas proyek dengan TreatWarningsAsErrors
cat > /tmp/cs-uji-an/cs-uji-an.csproj <<'EOF'
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  </PropertyGroup>

</Project>
EOF

# membangun ulang, lalu memilah baris error yang tampil
dotnet build /tmp/cs-uji-an --no-incremental 2>&1 | grep -oE "Program\.cs\([0-9]+,[0-9]+\): error (CS|CA)[0-9]+" | LC_ALL=C sort -u
text Keluaran
Program.cs(13,46): error CA1062
Program.cs(3,15): error CS8602
Program.cs(8,19): error CS8618

Kini tiga error muncul sekaligus. CS8602 dan CS8618 naik derajat menjadi error karena TreatWarningsAsErrors, sedangkan CA1062 memang sudah berlevel error sejak .editorconfig. Kompilasi digagalkan, sehingga tidak ada program yang dihasilkan dan pelanggaran itu harus diperbaiki lebih dahulu. Pola seperti ini dipakai sebagai gerbang kualitas pada CI, yaitu build yang menolak perubahan kode yang menambah warning baru. Setelah latihan selesai, proyek sementara dihapus.

bash
# menghapus proyek sementara setelah latihan selesai
rm -rf /tmp/cs-uji-an

Kesalahan umum#

  • Menganggap konteks nullable menjamin program bebas NullReferenceException. Analisisnya bersifat statis dan hanya melaporkan jalur yang mungkin bermasalah, sedangkan nilai dari metode eksternal, deserialisasi, atau proyek lain tetap bisa null tanpa terdeteksi. Warning tetap perlu ditindak dengan pemeriksaan nyata, bukan sekadar ditandai ! agar senyap.
  • Menyalahkan .editorconfig yang tidak terbaca. Aturan yang ditulis pada berkas .editorconfig di luar jalur folder berkas sumber tidak pernah ditemukan, sehingga build terlihat mengabaikan pengaturan. Letakkan berkasnya pada folder proyek atau folder leluhurnya, dan pastikan baris root = true berada pada berkas yang paling atas.
  • Mengaktifkan TreatWarningsAsErrors pada kode yang menumpuk warning. Seluruh warning lama berubah menjadi error sekaligus, sehingga build gagal dengan daftar yang sulit ditindak. Bersihkan warning yang ada lebih dahulu, atau naikkan tingkatnya per aturan pada .editorconfig, lalu aktifkan properti ini setelah daftarnya kosong.

Ringkasan#

  • Analyzer bawaan .NET SDK bekerja pada waktu build: kompilator Roslyn menghasilkan diagnosis CS, aturan kualitas membawa kode CA, dan aturan gaya membawa kode IDE.
  • Konteks nullable yang diaktifkan lewat <Nullable>enable</Nullable> melaporkan pemakaian nilai yang mungkin null sebagai warning CS86xx, misalnya CS8618 dan CS8602.
  • Berkas .editorconfig memetakan tingkat tiap aturan melalui dotnet_diagnostic.<kode>.severity dengan nilai error, warning, suggestion, silent, dan none.
  • Properti <TreatWarningsAsErrors>true</TreatWarningsAsErrors> mengubah seluruh warning menjadi error sehingga build menjadi gerbang yang menolak kode yang melanggar aturan.

Referensi#