Поиск вызовов удалённых процедур в 1С: платформа с ключом нашла 64 из 69, скрипт 63
Разработка - Инструментарий разработчика
Файлы
ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.
Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний
Оформите подписку на компанию для решения рабочих задач
Оформить подписку и скачать решение со скидкойВы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.
-ThinClient -Server -ExternalConnection) нашла 13 висячих вызовов из 69. Все 13 были либо вызовами без имени модуля внутри своего модуля, либо вызовами удалённого модуля целиком. Обращения вида Модуль.Метод( к удалённому, переименованному или неэкспортному методу она пропустила./CheckModules с добавленным ключом -ExtendedModulesCheck нашёл 64 из 69 и ни одного ложного срабатывания на чистой выгрузке. Проверка стала дольше: медиана 26,0 с против 16,6 с./CheckModules и /CheckConfig и скрипт danglers.py на поиске вызовов несуществующих методов общих модулей.Для поиска вызовов, оставшихся после удаления или переименования процедуры общего модуля, достаточно одного дополнительного ключа платформы. Скрипт нужен там, где нет базы и лицензии для платформы, и там, где методы вызываются через строки.
- Ключи хука
-ThinClient -Server -ExternalConnectionне ловят обращенияМодуль.Метод(к несуществующему методу. - Ключ
-ExtendedModulesCheckловит их и пишет «Возможно ошибочный метод». - Строки платформа не разбирает: вызовы через
ВыполнитьиВычислитьона пропустила. Скрипт находит их, если строка сМодуль.Методпередаётся вВыполнить,Вычислитьили фоновое задание. Склеенные имена и лишние параметры не нашёл никто. - Первая версия скрипта на чистой УТ 11.5 дала 1 910 ложных находок. После исправлений находок 4, и все они настоящие.
- Скрипт сравнивает выгрузку со своей прежней версией и подсказывает вероятное новое имя.
Главная мысль: результат проверки зависит от набора ключей, поэтому перед выводом «платформа этого не ловит» стоит перебрать ключи.
Для кого: разработчики и сопровождающие конфигураций 1С, которые удаляют и переименовывают процедуры общих модулей и хотят узнать об оставшихся вызовах до релиза.
- Стенд
- Что считается висячим вызовом
- Что нашла платформа с ключами хука
- Что меняет ключ -ExtendedModulesCheck
- Сколько стоит ключ
- Чего не нашла платформа с ключом
- Скрипт danglers.py
- Сколько скрипт находит и сколько ошибается
- Прогон на УТ 11.5
- Как я бы собрала проверку
- Что проверить у себя
- Ограничения замера и чего скрипт не делает
- Файл к статье
- Итог
- Ссылки по теме
Разработчик удаляет из общего модуля устаревшую процедуру или переименовывает её. Сам модуль компилируется, а вызов остаётся в форме документа, которую давно никто не открывал. Ошибка выйдет у пользователя после обновления. Я проверила на «Нано-УТ 2.0», что из таких висячих вызовов находит платформа и где нужен отдельный скрипт.
Стенд
| Условие | Значение |
|---|---|
| Платформа | 1С:Предприятие 8.3.27.2130 x86, пакетный запуск Конфигуратора |
| Исходники | «Нано-УТ 2.0»: 81 BSL и 212 XML, 16 общих модулей, 45 экспортных методов, 195 обращений вида Модуль.Метод( |
| Скрипт | Python 3.12.10, только стандартная библиотека |
| Компьютер | Windows 11 Pro, Intel Core i5-2400, 7,9 ГБ ОЗУ, SATA SSD; рабочая машина с открытыми приложениями |
| Порядок | Правка копии выгрузки; для платформы новая файловая база, загрузка из файлов, три проверки; один прогон на правку |
| Дата | 24.10.2026 |
Исходное дерево взято из базового коммита стенда, правки сделаны в копии вне каталога OneDrive. Конфигурация небольшая. Времена и счётчики ниже относятся к ней и не переносятся на УТ или ERP.
Что считается висячим вызовом
Висячим я называю обращение к методу общего модуля, которого после правки нет в виде, доступном этому вызову: процедуру удалили, переименовали, сняли с неё Экспорт или удалили модуль целиком. Вызов остаётся в тексте, а платформа сообщит об этом сама только при определённом наборе ключей.
Для 15 правок я записала истинное число таких вызовов. Для правок существующего кода (01, 03, 04, 05, 06, 14) считала через grep -o по исходной выгрузке: сколько раз в ней встречается СостояниеУчета.Ключ(, ПечатьСервер.Сформировать( и так далее. Для добавленных проб (08-11, 15) число известно по построению. В правке 02 я сначала записала 1. Три вызова Списать без имени модуля внутри самого ТоварыУчет увидела только по журналу платформы и исправила истину на 4, поэтому для этой правки число не было заведено заранее. Сами правки лежат в cases.py архива.
| № | Правка | Истина |
|---|---|---|
| 01 | Удалена функция ЦеныСервер.ЦенаНаДату |
1 |
| 02 | Удалена ТоварыУчет.Списать: один вызов из другого модуля и три вызова без имени модуля внутри самого модуля |
4 |
| 03 | ПечатьСервер.Сформировать переименована в Собрать (вызовы из десяти форм) |
10 |
| 04 | У ФормыСервер.Справка снят Экспорт (вызовы из четырнадцати форм) |
14 |
| 05 | Удалена СостояниеУчета.Ключ |
21 |
| 06 | Модуль ПечатьСервер удалён целиком, скрипт запущен без --old |
10 |
| 07 | То же, скрипт запущен с --old |
10 |
| 08 | В форму и модуль объекта добавлены три вызова несуществующих методов, один с переносом строки после точки | 3 |
| 09 | Вызовы через Выполнить, Вычислить и строку с именем метода |
3 |
| 10 | Имя метода собрано склейкой строк | 1 |
| 11 | Ловушки: комментарий, текст сообщения, локальная переменная с именем модуля, вызов через структуру, регистр букв, строка с продолжением | 0 |
| 12 | Расширение вызывает удалённую ТоварыУчет.Списать, выгрузка расширения передана скрипту |
2 |
| 13 | То же, выгрузка расширения не передана | 2 |
| 14 | Вызов неэкспортной процедуры из другого модуля | 1 |
| 15 | Существующая ЦеныСервер.ЦенаНаДату вызвана с пятью параметрами вместо трёх |
1 |
Правки 07, 12 и 13 повторяют платформенные варианты других правок или требуют расширения, поэтому на платформе я их не запускала. Расширение 12-13 проверено только скриптом.
Добавленные пробные вызовы выглядят так:
Что нашла платформа с ключами хука
В хуке git из моей предыдущей статьи проверка шла командой /CheckModules -ThinClient -Server -ExternalConnection. Эти же ключи я оставила для первой колонки. Перед правками на чистой выгрузке все три проверки дали код 0 и ни одного замечания.
На правках 01, 03, 04, 05, 08, 09, 10, 14 и 15 код возврата проверки оказался 0. Платформа вызова удалённого, переименованного или неэкспортного метода через имя модуля не заметила: «Синтаксических ошибок не обнаружено!». Этот результат согласуется с прошлым опытом: вызов ТоварыУчет.НетТакойПроцедуры() тоже прошёл.
Код 101 пришёл на правках 02 и 06. На правке 02 платформа показала три вызова Списать без имени модуля внутри самого ТоварыУчет: шесть сообщений, потому что проверка идёт в двух контекстах. На правке 06 при удалённом модуле она назвала десять обращений из форм: «Переменная не определена (ПечатьСервер)». Вызов ТоварыУчет.Списать из ВозвратыУчет в правке 02 остался незамеченным.
Выжимка из журналов:
| Правка | Сообщение платформы | Проверка |
|---|---|---|
| 02 | Процедура или функция с указанным именем не определена (Списать), три места в ТоварыУчет | как в хуке |
| 06 | Переменная не определена (ПечатьСервер), десять форм | как в хуке |
| 01, 03, 04, 05, 08, 09, 10, 14, 15 | Нет сообщений, код 0 | как в хуке |
Это выжимка из evidence/platform-run.txt и platform-run2.txt, не вывод консоли целиком.
Что меняет ключ -ExtendedModulesCheck
Затем я добавила ключ -ExtendedModulesCheck в тот же /CheckModules. Команда для файловой базы:
Платформа начала сообщать «Возможно ошибочный метод» с именем модуля и методом. На правке 01 журнал содержит одну строку: ОбщийМодуль.ДокументыСервис.Модуль Возможно ошибочный метод: "ЦенаНаДату". Номера строки в сообщении нет, указаны модуль и имя метода. Для правки 05 пришло 21 сообщение, по числу вызовов, с разбивкой по модулям: ТоварыУчет 5, ЗаказыУчет 8, ВозвратыУчет 5, ДеньгиУчет 2, ЦеныУчет 1.
Третью проверку, /CheckConfig с ключами -ExtendedModulesCheck -IncorrectReferences -HandlersExistence -UnreferenceProcedures, я запускала для сравнения. Вызовы она нашла так же, как расширенный /CheckModules. Сверх этого она сообщала «Не обнаружено ссылок на процедуру» про мои пробные процедуры и про ФормыСервер.Справка после снятия Экспорт. Эти сообщения в итоговый счёт я не включала.
Сводка по 12 правкам платформы (журналы platform-run.txt и platform-run2.txt; сводка собрана скриптом compare.py и лежит в evidence/comparison.txt):
| № | Истина | Платформа как в хуке | Платформа с ключом | Скрипт | Скрипт с прежней выгрузкой |
|---|---|---|---|---|---|
| 01 | 1 | 0 | 1 | 1 | 1 |
| 02 | 4 | 3 | 4 | 1 | 1 |
| 03 | 10 | 0 | 10 | 10 | 10 |
| 04 | 14 | 0 | 14 | 14 | 14 |
| 05 | 21 | 0 | 21 | 21 | 21 |
| 06 | 10 | 10 | 10 | 0 | 10 |
| 08 | 3 | 0 | 3 | 3 | 3 |
| 09 | 3 | 0 | 0 | 2 | 2 |
| 10 | 1 | 0 | 0 | 0 | 0 |
| 11 | 0 | 0 | 0 | 0 | 0 |
| 14 | 1 | 0 | 1 | 1 | 1 |
| 15 | 1 | 0 | 0 | 0 | 0 |
| Итого | 69 | 13 | 64 | 53 | 63 |
Платформа с ключом на чистой выгрузке молчала. Ложных срабатываний в этих правках не было ни у неё, ни у скрипта. Скрипт с прежней выгрузкой и платформа с ключом находят почти поровну, 63 и 64, но на разных правках: платформа видит вызовы без имени модуля (02), скрипт - строки (09). Вместе они находят 66 из 69.
Колонка «Скрипт» относится к исправленной версии от 25.10.2026. Первая версия на этих же правках нашла 54 и дала 2 ложных (evidence/cases-v1.txt): она проверяла все строки подряд и засчитывала голое имя в правке 09. Почему её пришлось исправить, сказано ниже в разделе про УТ 11.5.
Сколько стоит ключ
Времена взяты из журналов опыта: 15 созданий базы, 14 успешных загрузок выгрузки и по 14 запусков каждой из трёх проверок.
| Стадия | Запусков | Минимум, с | Медиана, с | Максимум, с |
|---|---|---|---|---|
| Создание базы | 15 | 6,4 | 9,5 | 13,8 |
| Загрузка выгрузки | 14 | 17,9 | 32,9 | 55,5 |
/CheckModules как в хуке |
14 | 12,1 | 16,6 | 27,7 |
/CheckModules с -ExtendedModulesCheck |
14 | 15,5 | 26,0 | 33,2 |
/CheckConfig расширенная |
14 | 17,7 | 26,4 | 37,8 |
Сумма медиан для цепочки «создать базу, загрузить, проверить с ключом» равна 68,4 с, а для создания, загрузки и всех трёх проверок на одну правку 111,4 с (evidence/platform-timing.txt). Разница медиан расширенной и обычной проверки модулей 9,4 с. Часть запусков шла одновременно с моими тестами других задач, поэтому разброс широк: загрузка занимает от 17,9 до 55,5 с. Это времена одного компьютера на небольшой конфигурации, по ним нельзя оценивать крупные решения.
Чего не нашла платформа с ключом
Три группы правок остались без замечаний, хотя вызовы там настоящие.
Вызовы через строки (правка 09) платформа не разбирает: Выполнить("ЦеныСервер.НетТакой4()") проверка не трогает. Имя, склеенное из частей (правка 10), невозможно проверить статически, и ни платформа, ни скрипт его не нашли. Лишние параметры при вызове существующего метода (правка 15) тоже прошли: платформа не сообщила ничего ни в одном из режимов.
Это согласуется с самим принципом статической проверки. Вычислить строку до запуска нельзя, а число параметров платформа в этих режимах не сверила: на правке 15 обе проверки модулей ответили «Синтаксических ошибок не обнаружено!».
Скрипт danglers.py
Скрипт нужен для трёх задач: быстрая проверка без платформы, поиск обращений через строки и сравнение с прежней версией выгрузки. Работает он так.
- В каталоге
CommonModulesчитаетExt/Module.bslкаждого модуля и запоминает процедуры и функции, в том числеАсинх: имя, наличиеЭкспорт, число параметров. - Убирает из текста комментарии и содержимое строковых литералов, сохраняя номера строк.
- Во всех
.bslвыгрузки ищетИмя.Метод(, гдеИмясовпадает с общим модулем. Если метода в модуле нет, сообщаетнет_метода; если он безЭкспорта–не_экспортный. Имя, которое в этом файле занято переменной, параметром, реквизитом или табличной частью объекта или реквизитом формы, общим модулем не считается. - Строки, которые передаются в
Выполнить,Вычислить,ФоновыеЗадания.Выполнить,ВыполнитьМетодКонфигурацииили в длительные операции, проверяет так же: ищет в нихИмя.Метод(или строку, целиком равнуюИмя.Метод. Находки получают видчерез_строку. С ключом--strings allпроверяются все строки, как в первой версии скрипта. - С ключом
--oldсравнивает экспортные методы с прежней выгрузкой: показывает удалённые и подсказывает вероятное новое имя по схожести и числу параметров. Вызовы модуля, которого уже нет, получают видмодуль_удалён. - С ключом
--extпроверяет выгрузку расширения: оно может вызывать методы основной конфигурации.
Запуск:
Код возврата 1 означает, что находки есть, 2 – ошибку запуска. Этого достаточно, чтобы поставить скрипт шагом в CI или pre-commit.
Вывод на правке 03 с --old (выжимка из evidence/demo-03-rename.txt):
| Строка вывода | Смысл |
|---|---|
| удалён экспортный метод: ПечатьСервер.Сформировать (возможное переименование: Собрать) | подсказка по сравнению с прежней выгрузкой |
| нет_метода: ...ЗаказКлиента/Forms/ФормаОбъекта/Ext/Form/Module.bsl:21 ПечатьСервер.Сформировать | одно из десяти обращений из форм |
Вывод на правке 09 (выжимка из evidence/demo-09-strings.txt):
| Вид | Место | Вызов | Примечание |
|---|---|---|---|
| через_строку | ПродажаТовара/Ext/ObjectModule.bsl:23 | ЦеныСервер.НетТакой4 | метода нет |
| через_строку | ПродажаТовара/Ext/ObjectModule.bsl:24 | СкладСервер.НетТакой5 | метода нет |
Третья строка, Имя = "СкладСервер.НетТакой6", только кладёт имя в переменную. Её скрипт показывает с --strings all: по умолчанию проверяются строки, которые сразу уходят на исполнение.
Сколько скрипт находит и сколько ошибается
Все 15 правок прогнаны через скрипт (evidence/cases.txt). Ожидания для первой версии я записала до её первого запуска. Для исправленной версии ожидания правок 09 и 11 изменены после прогона на УТ 11.5, остальные 13 правок дали прежний результат.
| Показатель | Значение |
|---|---|
| Настоящих висячих вызовов во всех 15 правках | 83 |
| Найдено верно | 66 |
| Пропущено | 17 |
| Лишних срабатываний | 0 |
| Точность на стенде, 66 из 66 находок | 100% |
| Полнота, 66 из 83 | 80% |
Пропуски объясняются так. Три вызова без имени модуля внутри своего модуля (правка 02): скрипт ищет только форму Модуль.Метод(, для них нужна платформа. Десять вызовов удалённого модуля в правке 06 без --old: сам скрипт не знает, что модуль был. С --old (правка 07) находятся все десять. Голое имя в переменной в правке 09, склеенное имя в правке 10, вызов при отсутствии выгрузки расширения в правке 13 и лишние параметры в правке 15 – по одному.
В первой версии ложные срабатывания давали ловушки правки 11: текст сообщения "Вызовите ТоварыУчет.НетТакого() вручную" и локальная переменная ЦеныСервер = Новый Структура с вызовом ЦеныСервер.Вставить(...). Теперь строка из Сообщить не проверяется, имя, занятое переменной, модулем не считается, и правка 11 проходит без находок. Комментарий, вызов через поле структуры, регистр букв и строка с продолжением | ошибок не давали и раньше.
Время запуска: 10 запусков подряд на выгрузке стенда заняли от 0,37 до 0,45 с, медиана 0,38 с вместе с запуском интерпретатора (evidence/timing.txt).
Прогон на УТ 11.5
Ловушки стенда придумала я сама, поэтому скрипт я запустила ещё на чистой выгрузке «Управление торговлей» 11.5.22.77: 12 290 модулей BSL, 2 711 общих модулей, около 300 тысяч обращений Модуль.Метод(. В типовой конфигурации висячих вызовов почти нет, и каждая находка здесь проверяет сам скрипт.
Первая версия скрипта, та, что лежала в архиве, дала 1 910 находок за 9 мин 59 с. Среди проверенных настоящих не оказалось:
| Находок | Причина |
|---|---|
| 280 | не разбирались Асинх Процедура и Асинх Функция, вызовы таких методов выглядели висячими |
| 6 | строка-комментарий с кавычками внутри многострочного текста запроса сбивала разбор, и процедуры ниже по модулю терялись |
| 33 | имя модуля совпадало с табличной частью или переменной, например Пользователи.Количество() в модуле справочника ГруппыДоступа |
| 1 591 | строки с именами подсистем и ключами параметров, например ОбщегоНазначения.ПодсистемаСуществует("ЭлектронноеВзаимодействие.ОбменСКонтрагентами") |
Исправленная версия на той же выгрузке дала 4 находки за 5 мин 23 с (evidence/ut-11.5-run.txt). Все четыре - обращения через строки к методам, которых в указанных модулях нет:
| Модуль и строка | Обращение |
|---|---|
| РаспознаваниеДокументовСлужебныйВызовСервера, 166 | ФоновыеЗадания.Выполнить("РаспознаваниеДокументов.ОтправитьВложенияИзПочтыНаРаспознавание", ...) |
| РаспознаваниеДокументовСлужебныйВызовСервера, 201 | ФоновыеЗадания.Выполнить("РаспознаваниеДокументов.ОтправитьФайлыИзКаталогаНаРаспознавание", ...) |
| ОбщегоНазначенияБТС, 1161 | Выполнить("СтандартныеПодсистемыПовтИсп.ПараметрыПрограммныхСобытий()") |
| ОбщегоНазначенияБТС, 1181 | Вычислить("ОбщегоНазначения.ОбработчикиСлужебногоСобытия(Событие)") |
В общем модуле РаспознаваниеДокументов этой выгрузки методов ОтправитьВложенияИзПочтыНаРаспознавание и ОтправитьФайлыИзКаталогаНаРаспознавание нет, а фоновые задания обращаются именно к ним. Платформа такие вызовы не проверяет даже с ключом: имя метода передано строкой. Оба обращения в ОбщегоНазначенияБТС защищены: первое стоит внутри Попытка, второе выполняется только когда ПоддерживаютсяПрограммныеСобытия() вернула Истина.
Как я бы собрала проверку
Два инструмента закрывают разные места, и вместе они дают больше каждого по отдельности.
| Задача | Чем закрывать |
|---|---|
Обращения Модуль.Метод( к несуществующему методу и снятый Экспорт |
-ExtendedModulesCheck или скрипт |
| Вызовы без имени модуля внутри модуля, удалённый модуль | /CheckModules с любым набором ключей |
Строки с Модуль.Метод, переданные в Выполнить, Вычислить или фоновое задание |
только скрипт |
| Быстрая проверка на каждый коммит или в CI без платформы | только скрипт |
| Склеенные имена, лишние параметры | ничего из проверенного |
Для хука git, где важна скорость, я оставила бы скрипт первым шагом, а полную проверку с ключом вынесла бы на сервер. На стенде скрипт добавит к коммиту меньше секунды, а серверная цепочка «создать базу, загрузить, проверить с ключом» займёт около 68 с. На конфигурации размера УТ 11.5 скрипт работает около 5 минут, и там его место в CI рядом с серверной проверкой.
Что проверить у себя
Порядок для рабочей конфигурации. Начинать лучше с копии базы.
- Выгрузите конфигурацию в файлы:
1cv8.exe DESIGNER /F C:\base\ib /DumpConfigToFiles C:\dump. Выгрузка должна быть полной, сConfiguration.xml. - Запустите
python -X utf8 danglers.py --src C:/dump. Если находок нет, код возврата 0. Находки видачерез_строкув фоновых заданиях проверьте первыми: платформа их не видит. - После планируемого удаления или переименования запустите скрипт с
--oldи прежней выгрузкой: он покажет удалённые экспортные методы и вероятные новые имена. - На копии базы выполните
/CheckModulesс вашими ключами и добавьте-ExtendedModulesCheck. Сравните число замечаний с прогоном без ключа: разница покажет, сколько межмодульных обращений платформа раньше пропускала. - Если в проекте есть расширения, передайте скрипту их выгрузки через
--ext. В этом опыте расширение проверено только скриптом.
Ограничения замера и чего скрипт не делает
Опыт ограничен и не доказывает ничего сверх таблиц.
- Платформа проверена на одной конфигурации из 16 общих модулей. Скрипт дополнительно прогнан на чистой УТ 11.5.22.77; ERP и конфигурации с расширениями в опыт не входили.
- Одна версия платформы, 8.3.27.2130 x86. Контексты компиляции только
-ThinClient -Server -ExternalConnection. - Расширения проверены только скриптом на условном примере из одного модуля. На платформе расширение не загружалось.
- Обработчики форм, заданные в XML формы, скрипт не проверяет. Число параметров вызова тоже.
- Скрипт разбирает текст регулярными выражениями и не строит дерево программы.
- Число настоящих вызовов в каждой правке записывала я, она же автор скрипта и правок. Числа описывают 15 заведённых мной правок. О частоте таких ошибок в реальных проектах они ничего не говорят.
- Первый прогон правки 06 не загрузился: после удаления папки модуля в
Configuration.xmlосталась ссылка на него, платформа сообщила, что файл объекта не существует. Я исправила правку и повторила 06 и 11 (platform-run2.txt). Первоначальная версия правки 11 содержала обращение к несуществующей переменной, это тоже исправлено в cases.py.
Файл к статье
В архиве dangling-refs-16-3-companion.zip лежат: danglers.py, README.md с запуском и пределами, cases.py с заведёнными правками, run_cases.py, test_danglers.py, platform_check.py для опыта на платформе, compare.py, выгрузка «Нано-УТ 2.0» (stand/src) и журналы запусков в evidence, среди них прогон на УТ 11.5 (ut-11.5-run.txt) и журналы первой версии скрипта (*-v1.txt). После распаковки без платформы проверка выполняется командами:
Тест проходит 22 проверки: четыре на разбор текста, две на чистую выгрузку, 15 по одной на правку и одна на режим --strings all. Опыт на платформе повторяется командой platform_check.py с новым каталогом --work; одна правка занимает по медианам журнала около 111 с.
Итог
Платформа находит висячие вызовы общих модулей, если дать ей ключ -ExtendedModulesCheck: на 12 правках она нашла 64 из 69, и стоило это около 9 с сверх обычной проверки модулей. Ключи хука -ThinClient -Server -ExternalConnection нашли 13. Скрипт на Python нашёл 53 вызова, с прежней выгрузкой 63, без ложных срабатываний, и добавил обращения через строки, подсказку о переименовании и проверку расширения. Вызовы без имени модуля он не видит. На чистой УТ 11.5 исправленный скрипт дал 4 находки, все настоящие; первая версия там же дала 1 910 ложных, и этот прогон показал её ошибки. Склеенные имена и число параметров остались без проверки в обоих инструментах.
Ссылки по теме
Вступайте в нашу телеграмм-группу Инфостарт