Large-Scale Automated Refactoring Using ClangMR (Рубрика Architecture)
В последнее время я много изучаю, как Gen AI помогает в SDLC. Но иногда надо вернуться на шаг назад и понять, а как мы жили до генеративного интеллекта и что делали для повышения эффективности рефакторинга. И если копнуть туда, то видно, что эти старые и проверенные подходы активно используются в современности для обеспечения предсказуемых результатов комбинации стохастических и детерминированных подходов. Собственно, именно так я дошел до чтения короткого whitepaper 2013 года ребят из Google. Здесь они рассказывали про крупномасштабный рефакторинг своей кодовой базы на C++, например, со старой версии стандарта на более новую. Интересно, что их масштаб кодовой базы потребовал сразу учитывать возможность распараллеливания работы, для чего они использовали Map Reduce (именно это означает MR в конце названия ClangMR). Но теперь пора перейти к основным идеям из этой статьи
Собственно, суть в том, что фреймворк ClangMR решает проблему технического долга в крупных C++ кодовых базах через семантически безопасный рефакторинг, который хорошо параллелится. Ключевыми моментами подхода является
- Использование AST (abstract syntax tree), абстрактных синтаксических деревьев. В отличие от regex-инструментов, это позволяет гораздо точнее описывать изменения ,например, легко можно различить методы с одинаковыми именами в разных классах
- Масштабируемость. Распределенная обработка через MapReduce сокращает время рефакторинга с месяцев до часов.
- Повторяемость. Поддержка инкрементных изменений, когда авторы использовали инструмент итеративно для рефакторинга десятков тысяч файлов частями
Сама реализация ClangMR основана на трех китах - Indexing (индексация): компиляция кодовой базы в AST с хранением в распределенной БД (e.g., Google's Bigtable).
- Node matching (сопоставление узлов): Разработчики определяют AST-шаблоны (например, memberExpr(hasName("OldMethod")) и коллбэки для генерации правок. Интересно, что эта часть состоит из описания паттерна для матчинга частей дерева, а также callback для применения изменений (причем callback может решить, что изменений не требуется)
- Sorce code refactorer (применение изменений): Локальное применение правок с разрешением конфликтов и автоформатированием через ClangFormat.
Эта статья и подход, описанный в ней, привели к нескольким последствиям
- Развитие Clang/LLVM: Компоненты вроде AST matcher API стали основой для Clang-Tidy и Clang refactoring engine
- Смена практик рефакторинга: Популяризация AST-подходов, повлиявшая на инструменты вроде Coccinelle для ядра Linux.
- Эволюция стандартной библиотеки: Ускоренное внедрение современных возможностей создало давление на вендоров компиляторов.
В общем, статья была очень интересной для 2013 года. Но если говорить про микс этого подхода с Gen AI, то можно посмотреть доклад ребят из Uber 2024 года "This Year in Uber’s AI-Driven Developer Productivity Revolution", в котором они рассказывали среди прочего про миграцию с Java на Kotlin, где активно использовался микс AST matcher, а также Gen AI, который помогал генерировать правила трансформации:) Подробнее можно почитать в моем обзоре этого доклада (1 и 2)
#Architecture #Leadership #Software #SoftwareDevelopment #AI #Engineering