Семантическая сеть для раздельной компиляции
Интерн сейчас принес интересную идею (обсуждали предстоящую
магистерскую диссертацию).
Есть два куска кода на разных языка. Один фрагмент каким-то образом
вызывает фрагмент. Например, это может быть JS-клиент для
http-сервиса, написанного на C#.
Для того, чтобы проанализировать, как эти фрагменты кода
взаимодействуют между собой, можно построить семантическую сеть,
описывающую эти фрагменты и взаимодействие между ними.
В узлах будут какие-то сущности языков (я предложил их называть языки
А и Б соответственно). Это функции, переменные или классы. Может быть
это более крупные конструкты (серверные точки вызова, к примеру).
Ребра же в этой сети — это «использование» узлами друг друга. То
есть, когда код А вызывает endpoint, написанный на Б, то это ребро
«использования».
Почему беру слово «использовать» в кавычки?
Потому что для каждой сети необходимо это слово строго
формализовать, так как оно напрямую зависит от того, что является
узлами сети.
И тут у меня появилась интересная идея: а давайте используем эту же
схему для анализа при раздельной компиляции!
Дано
Язык А — произвольный язык, допускающий компиляцию в некоторую
бинарную форму.
Язык Б — бинарная форма представления семантики языка. По-другому,
пусть это будут артефакты компиляции. Бинарную форму в подавляющем
большинстве случаев можно представить в виде АСТ-дерева или какого-то
текста, поэтому рассуждения о языке Б считаю валидными.
После первичной компиляции можно построить сеть между языками А и Б
таким образом, что узлы будут однозначно соединены ребрами
«использования», где «использование» — это наличие скомпилированного
представления.
Получить
После модификации текста на языке А (или, в общем случае, модификации
как текста на языке А, так и артефактов на языке Б) необходимо
построить минимальный перечень узлов сети, относящихся к тексту на
языке А для восстановления корректности сети (восстановления
однозначности соединения ребрами «использования»).
Модификация текстов на языке А может быть следующих видов:
— добавлен новый узел (добавлена функция, например)
— удален существующий узел
— модифицировано тело узла (изменено тело функции без изменения
интерфейса функции)
— модифицирован интерфейс узла
Имея на руках перечень узлов сети, для которых необходимо произвести
перекомпиляцию (восстановление ребер «использования»), можно очень
существенно сократить суммарное время компиляции общей программы.