Перейти до вмісту

Написала парсер, який читає справжній C‑заголовок на 7 308 рядків і перевіряє кожне місце виклику, кожну константу переліку й те, що кожен клас‑власник вказівника є final, після того як через написаний вручну заголовок‑заглушку виклики трьох вилучених функцій компілювалися, лінкувалися й аварійно завершувалися.

7,308 рядків заголовка C — прочитано, а не вгадано

Ситуація. На початку проєкту C‑інтерфейс описував написаний вручну заголовний файл з оголошеннями функцій, на які розраховував застосунок. Цей заголовний файл компілювався, застосунок компонувався, а виклики трьох функцій, яких у ядрі вже не існувало, доходили до моменту виклику й завершувалися аварійно. І компілятор, і компонувальник задовольнилися описом бібліотеки замість самої бібліотеки, тож розбіжність проявилася лише під час виконання.

Завдання. Справжній заголовний файл — 7 308 рядків і 268 оголошень — мав стати еталоном, а кожне використання оголошень із нього в коді Swift треба було звіряти з ним автоматично, а не вручну під час рев’ю.

Дія. Перевірка — це парсер, який читає справжній заголовний файл з основного репозиторію й будує множину функцій, констант переліків і типів, оголошених у ньому, а потім читає код Swift і звіряє з цією множиною кожне місце виклику та кожне посилання на константу. Виклик функції, якої немає в заголовному файлі, призводить до помилки збірки. Посилання на перейменовану константу переліку теж призводить до помилки збірки. Наразі використовуються 132 з 268 оголошень, і знати, які саме 136 не використовуються, корисно саме по собі: це точно показує, до якої частини ядра клієнт ще не дістався. Парсер також перевіряє правило, якого не може забезпечити компілятор: кожен клас Swift, що володіє вказівником на дані ядра, має бути оголошений як final. Від класу без final, який володіє вказівником, можна успадкуватися, а підклас, що перевизначає деініціалізацію або додає власне керування часом життя, змінює момент звільнення вказівника — і виникає використання після звільнення, хоча поблизу немає жодного ключового слова unsafe. Правило перевіряють за назвами класів по всьому дереву коду.

Результат. Клас дефектів, через який стався початковий збій, більше не може повторитися, бо застаріле посилання тепер спричиняє помилку збірки, а не помилку під час виконання. Обмеження в тому, що парсер розуміє оголошення в заголовному файлі, але не їхню семантику: він доводить, що функція з відповідною назвою існує, а якщо в основному репозиторії змінилося призначення функції чи правило володіння, але сигнатура лишилася тією самою, перевірка пропустить її без зауважень.

Одна частина довшого переліку — і він увесь на цьому сайті.

Кожен запис написано однаково: ситуація, завдання, що ми зробили і що змінилося.

Переглянути весь перелік