June 16, 2023

Семантическая сеть для раздельной компиляции

Интерн сейчас принес интересную идею (обсуждали предстоящую
магистерскую диссертацию).

Есть два куска кода на разных языка. Один фрагмент каким-то образом
вызывает фрагмент. Например, это может быть JS-клиент для
http-сервиса, написанного на C#.

Для того, чтобы проанализировать, как эти фрагменты кода
взаимодействуют между собой, можно построить семантическую сеть,
описывающую эти фрагменты и взаимодействие между ними.

В узлах будут какие-то сущности языков (я предложил их называть языки
А и Б соответственно). Это функции, переменные или классы. Может быть
это более крупные конструкты (серверные точки вызова, к примеру).

Ребра же в этой сети — это «использование» узлами друг друга. То
есть, когда код А вызывает endpoint, написанный на Б, то это ребро
«использования».

Почему беру слово «использовать» в кавычки?

Потому что для каждой сети необходимо это слово строго
формализовать, так как оно напрямую зависит от того, что является
узлами сети.

И тут у меня появилась интересная идея: а давайте используем эту же
схему для анализа при раздельной компиляции!

Дано

Язык А — произвольный язык, допускающий компиляцию в некоторую
бинарную форму.
Язык Б — бинарная форма представления семантики языка. По-другому,
пусть это будут артефакты компиляции. Бинарную форму в подавляющем
большинстве случаев можно представить в виде АСТ-дерева или какого-то
текста, поэтому рассуждения о языке Б считаю валидными.
После первичной компиляции можно построить сеть между языками А и Б
таким образом, что узлы будут однозначно соединены ребрами
«использования», где «использование» — это наличие скомпилированного
представления.

Получить

После модификации текста на языке А (или, в общем случае, модификации
как текста на языке А, так и артефактов на языке Б) необходимо
построить минимальный перечень узлов сети, относящихся к тексту на
языке А для восстановления корректности сети (восстановления
однозначности соединения ребрами «использования»).

Модификация текстов на языке А может быть следующих видов:

— добавлен новый узел (добавлена функция, например)
— удален существующий узел
— модифицировано тело узла (изменено тело функции без изменения
интерфейса функции)
— модифицирован интерфейс узла

Имея на руках перечень узлов сети, для которых необходимо произвести
перекомпиляцию (восстановление ребер «использования»), можно очень
существенно сократить суммарное время компиляции общей программы.

Идея, в целом, выглядит очень перспективной.

М., удачи!