Formatter — dastur kodini belgilangan uslub qoidalariga muvofiq avtomatik qayta joylashtiradigan vosita. U kodning ishlash mantiqini o‘zgartirmasdan bo‘sh joylar, qator uzunligi, indentatsiya, qavslar, vergullar va boshqa tashqi ko‘rinish elementlarini bir xil shaklga keltiradi.
Formatter jamoaviy loyihalarda kod uslubi bo‘yicha tortishuvlarni kamaytiradi. Dasturchi kodni turlicha yozishi mumkin, ammo formatter natijani yagona standartga keltiradi.
Formatlash vazifalari
Formatter odatda quyidagi o‘zgarishlarni bajaradi:
- indentatsiyani tekislaydi;
- operatorlar atrofidagi bo‘sh joylarni tartiblaydi;
- uzun qatorlarni bir necha qatorga bo‘ladi;
- qavs va vergullarni uslubga mos joylashtiradi;
- string yozilish usulini bir xil qiladi;
- importlar orasidagi bo‘sh qatorlarni tartiblaydi;
- keraksiz bo‘sh joylarni olib tashlaydi;
- fayl oxiriga newline qo‘shadi.
Masalan:
def add(a,b): return a+b
formatterdan keyin:
def add(a, b):
return a + b
ko‘rinishiga kelishi mumkin.
Semantikani saqlash
Formatterning asosiy tamoyili — dastur semantikasini saqlash. Kodning tashqi ko‘rinishi o‘zgaradi, ammo bajarilish natijasi o‘zgarmasligi kerak.
Biroq ayrim tillarda whitespace semantik ahamiyatga ega. Python indentatsiyani blok tuzilmasi sifatida ishlatadi. Shu sababli formatter parser orqali kod tuzilishini tushunib, faqat xavfsiz o‘zgarishlarni bajaradi.
Oddiy matn almashtirish formatter uchun yetarli emas. U ko‘pincha:
- source code’ni token yoki syntax tree’ga ajratadi;
- kod tuzilishini tahlil qiladi;
- format qoidalarini qo‘llaydi;
- yangi source code hosil qiladi.
Parser asosidagi formatter
Parser asosidagi formatter kodni Abstract Syntax Tree yoki unga yaqin tuzilma orqali tushunadi.
Afzalliklari:
- qavs va bloklarni aniq taniydi;
- commentlarni tegishli joyda saqlaydi;
- string ichidagi belgilarni kod deb qabul qilmaydi;
- murakkab ifodalarni xavfsiz qayta joylashtiradi;
- sintaktik xatoni aniqlaydi.
Kod parse qilinmasa, formatter odatda faylni o‘zgartirmaydi va xato qaytaradi.
Opinionated formatter
Ba’zi formatterlar kam konfiguratsiya bilan qat’iy uslub beradi. Bunday vosita opinionated formatter deb ataladi.
Uning maqsadi:
- barcha loyihada bir xil natija;
- konfiguratsiya bahsini kamaytirish;
- formatter versiyasi yangilanganda barqaror qoidalar;
- jamoa ichida shaxsiy uslub farqini yo‘qotish.
Masalan, qator uzunligi, trailing comma yoki qavs joylashuvi vosita tomonidan qat’iy belgilanadi.
Konfiguratsiyalanuvchi formatter
Boshqa formatterlarda quyidagilar sozlanadi:
- indent hajmi;
- tab yoki space;
- maksimal qator uzunligi;
- quote turi;
- trailing comma;
- brace style;
- import tartibi;
- ayrim qoidalarni o‘chirish.
Ko‘p konfiguratsiya loyiha uslubiga moslashadi, ammo turli repositorylarda natija farq qilishi mumkin.
Formatter va linter
Formatter kod ko‘rinishini avtomatik tuzatadi.
Linter esa:
- ehtimoliy xatolar;
- ishlatilmagan variable;
- xavfli construct;
- noto‘g‘ri naming;
- murakkablik;
- style violation
haqida ogohlantiradi.
Ba’zi linterlar ayrim style xatolarini avtomatik tuzatishi mumkin, ammo formatter va linter vazifasi to‘liq bir xil emas.
Import formatter
Importlarni tartiblash ayrim ekotizimlarda alohida vosita bilan bajariladi.
U:
guruhlarini ajratadi va alifbo bo‘yicha tartiblaydi.
Importni avtomatik o‘chirish ehtiyotkorlik talab qiladi, chunki ayrim importlar side effect uchun ishlatilishi mumkin.
IDE integratsiyasi
Formatter IDE yoki code editor ichida quyidagi holatlarda ishlashi mumkin:
- fayl saqlanganda;
- alohida buyruq bilan;
- tanlangan kod bo‘lagida;
- commitdan oldin;
- paste qilinganda;
- refactoringdan keyin.
“Format on save” kodni doim bir xil holatda saqlashga yordam beradi.
CI tekshiruvi
CI pipeline formatter natijasini tekshirishi mumkin.
Ikki asosiy rejim mavjud:
Write rejimi
Fayllarni o‘zgartiradi.
Check rejimi
Fayl standartga mos kelmasa xato qaytaradi, ammo o‘zgartirmaydi.
CI odatda check rejimidan foydalanadi. Dasturchi formatterdan lokal muhitda foydalanib, tayyor kodni commit qiladi.
Pre-commit
Pre-commit hook commit yaratilishidan oldin formatter ishlatadi.
Afzalligi — noto‘g‘ri formatlangan fayl repositoryga kirmaydi.
Kamchiligi — juda katta loyihada barcha faylni qayta formatlash commitni sekinlashtirishi mumkin. Ko‘pincha faqat o‘zgargan fayllar tekshiriladi.
Birinchi katta formatlash
Mavjud katta loyiha formatterga o‘tkazilganda minglab qator o‘zgarishi mumkin.
Bunday o‘zgarish odatda funksional o‘zgarishlardan alohida commit qilinadi. Bu:
- code review’ni yengillashtiradi;
- keyingi diffni toza saqlaydi;
git blametarixini tushunishni osonlashtiradi;- merge conflict sababini ajratadi.
Git ayrim vositalarda format-only commitni blame hisobidan chiqarish uchun maxsus konfiguratsiya bilan ishlatilishi mumkin.
Deterministik natija
Bir xil input va bir xil konfiguratsiya uchun formatter har safar bir xil output berishi kerak.
Aks holda:
- fayl doim o‘zgaradi;
- turli IDElar qarama-qarshi format beradi;
- CI va lokal muhit mos kelmaydi;
- merge conflict ko‘payadi.
Shu sababli formatter versiyasi dependency yoki toolchain ichida aniq belgilanadi.
Commentlar
Commentlar syntax tree’ning oddiy qismi bo‘lmasligi mumkin. Formatter ularni:
- tegishli node bilan bog‘laydi;
- joylashuvini saqlaydi;
- qator uzunligiga moslashtiradi;
- koddan ajratadi.
Noto‘g‘ri formatter comment ma’nosini yo‘qotishi mumkin. Yetuk vositalar commentlar uchun alohida qoidaga ega.
Formatni vaqtincha o‘chirish
Generated code, jadval ko‘rinishidagi literal yoki maxsus misolda formatter natijasi noqulay bo‘lishi mumkin.
Ko‘p formatter maxsus comment orqali ma’lum bo‘lakni o‘zgartirmaslik imkonini beradi.
Bu imkoniyat kam qo‘llanadi, aks holda yagona format maqsadi buziladi.
Idempotent formatlash
Yaxshi formatter bir marta ishlagandan keyin hosil bo‘lgan kodni qayta formatlaganda yana o‘zgartirmaydi. Bu xususiyat idempotency deb ataladi. Idempotent natija CI, editor va pre-commit orasidagi cheksiz o‘zgarishlarni oldini oladi.
Bog‘liq tushunchalar
Code style, Linter, Parser, Abstract Syntax Tree, Indentation, Pre-commit, CI, IDE, Source code