flang компилятор доказывает, что программа не зациклится 0.6.2 GitHub

Имя файла теряется между разбором и «Бедой», и языковой сервер в двоичном упирается именно в этот разрыв, а не в транспорт

Языковой сервер решает, В КАКОМ БУФЕРЕ показать диагностику, по имени файла в её месте. Диагностика без имени файла показана быть не может — сервер отправляет её текстом в журнал редактора (window/logMessage), и человек не видит подчёркивания вовсе.

В реализации на flang имя файла до диагностики не доезжает, и разрыв проходит по одному объявлению. Разбор его знает: «Разобранное» несёт «путь». Диагностика его уже не знает: «Беда» (flang/self/types.flang) — это «код», «сообщение», «место», а «Место»«есть», «строка», «столбец». Между ними лежит весь слой проверки типов, который про файлы не знает ничего.

Свидетель на JavaScript эту дыру закрыл иначе и раньше: stampFile из flang/src/link.mjs — сама она в двадцать две строки проставляет имя файла В КАЖДОЕ МЕСТО разобранного дерева, и диагностика получает его через тот же объект места, ни во что не печатаясь. Просит об этом ровно один вызывающий — языковой сервер (attributeFiles: true в checkSource); flang check и flang ast не просят, и печать дерева от этого не меняется.

Что из этого следует для двоичного. flang lsp собран, отвечает настоящему клиенту и сверен с Node побайтово — на программе ИЗ ОДНОГО ФАЙЛА. На программе с использует он расходится ровно в одном месте: беда импортированного модуля уходит в журнал вместо буфера этого модуля. Правило, по которому двоичный решает, назвать ли файл, — счёт, а не догадка: файл называется тогда и только тогда, когда исходник ОДИН. Тогда всё, что нашлось, нашлось в нём.

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

Половина разрыва закрывается дёшево, и она закрыта. Эталон stampFile написан («Пометить файлом» в flang/self/bootstrap/compiler.flang — сама она в тридцать пять строк) и метит оба разбора — первый и переразбор с известными именами, как это делает свидетель в двух местах linkProgram. Живёт он в точке входа, а не в self/link.flang, нарочно: слой связывания сверяется со свидетелем побайтово на 231 программе, и лишнее поле в его выводе покраснело бы на первой же.

Этой половины хватило дополнению и наведению: они читают имя файла ПРЯМО ИЗ УЗЛА («Своё объявление», «Про чужой файл» в self/lsp.flang), а не из беды. До метки двоичный отвечал "detail":"функция из другом модуле" и sortText «2» там, где Node отвечает "функция" и «1», — то есть считал СВОЁ объявление чужим на каждом файле. Расхождение в двух полях одного элемента списка из шестисот; глазом такое не ловится.

Вторая половина стоит правки общего слоя, и потому не сделана. Довести имя до беды — значит добавить «файл» и «есть файл» в «Место». Мест сборки записи всего шесть (types.flang 2, link.flang 1, compiler.flang 3), и это дёшево. Дорого другое: «Место» строят РУКАМИ проверки побайтовой сверки — flang/test/self-link.test.mjs собирает {есть, строка, столбец} на стороне JavaScript и подаёт внутрь слоя. Правка общего слоя тянет за собой правку сверки двух реализаций, а сверка — единственное, чем эти реализации удерживаются вместе.

Чем подтверждено. Ветка work/adr-pakety, коммит 6516ea71. Сессия LSP из двенадцати сообщений (initializeinitialized → два didOpendidChangedidSavehovercompletiondefinitiondidCloseshutdownexit), поданная двоичному и flang/bin/flang-lsp.mjs: 11 исходящих сообщений, 155 956 байт, расхождений 0, коды возврата совпали (0 с прощанием, 1 без него). Та же сверка на программе с использует: 4 сообщения, расхождение 1 — то самое. Число мест сборки «Место»grep; 22 строки stampFilewc -l по flang/src/link.mjs.

Чем ограничено. «Файл один — значит беда его» верно для беды, найденной разбором, типами и завершаемостью. Про ядро доказательств это не проверялось: checkSource свидетеля его не зовёт, и в поручении сервера его тоже нет.

Связано: pulling-a-module-into-the-self-hosted-compiler-pays-for-meetings-not-size, byte-for-byte-comparison, cikl-porucheniy-prinadlezhit-hozyainu-a-ne-yazyku