Repository navigation
v0.4.0
BREAKING
lspбез--modeтеперь работает в режимеauto: при наличии корня проекта
подключается к общему backend, раньше — прямой stdio. Для редактора это значит,
что несколько окон одного проекта делят один backend.mcp --modeдля workspace-профиля по умолчаниюbroker, раньшеstdio. Для
MCP-клиентов это значит общий демон вместо отдельного процесса на клиента.[diagnostics] ordinaryAppSupportбез значения берётся из<DefaultRunMode>
основной конфигурации, раньше — значение по умолчанию.
Added
- config:
[source].exclude_globs— глоб-шаблоны файлов и каталогов, исключаемых из
проекта (служебные каталоги инструментов на любой глубине, сгенерированные файлы
рядом с исходниками). Шаблоны относительно каталога конфига, действуют там же, где
[source].exclude: LSP, CLI и MCP. Без ключа поведение прежнее. - metadata: модуль обычной формы читает необязательное описание диалога
Ext/Form/Form.json— элементы, реквизиты формы и привязанные процедуры, которые
иначе заперты в двоичномExt/Form.bin. С ним процедуры, привязанные к событиям
формы, элементов и кнопок, не считаются неиспользуемыми, а реквизиты формы —
локальными переменными. Читается любая версия формата от 1 (новые версии только
добавляют поля); файл с недопустимой версией, неразбираемый или старшеForm.bin
не читается. Формат:docs/configuration/ordinary-form-sidecar.md. - config: ключ
extendsвbsl-analyzer.toml— наследование общего файла
настроек. Родитель (путь абсолютный или от каталога файла) читается первым,
дочерний файл накладывается поверх: таблицы сливаются рекурсивно, скаляры и
массивы заменяются. Цепочки разрешены, цикл и отсутствующий или битый родитель
— ошибка загрузки с путём файла; относительные пути из родителя разрешаются от
каталога проекта. LSP и MCP следят за файлами цепочки и перечитывают
конфигурацию при их правке. В.bsl-analyzer.jsonключ отвергается. - diagnostics:
MissingFormEventHandler— обработчик, назначенный вForm.xml
управляемой формы (событие формы, событие элемента, действие команды), которого
нет в модуле формы. Модуль при этом компилируется, и раньше это видела только
проверка конфигурации с флажком «Существование назначенных обработчиков»
(«Отсутствует обработчик»). Имя сравнивается без учёта регистра; обычные формы и
формы, заимствованные расширением, не проверяются. Critical, тип Error, включено
по умолчанию. - diagnostics: новое правило
UnresolvedMetadataPath(ошибка, включено по умолчанию) —
строковый литерал первым аргументомТип,ПредопределенноеЗначение,ОткрытьФорму,
ПолучитьФорму,ОткрытьФормуМодально(и английских имён) называет объект
метаданных, которого нет в конфигурации, или предопределённое значение, которого нет
у перечисления, справочника или плана. Проверка — та же, что у обращения кодом
(Справочники.X,Перечисления.X.Y); имя формы, общие формы, внешние обработки,
вычисляемые строки, модули без видимой конфигурации, значения объектов без
прочитанных предопределённых элементов и заимствованных объектов без видимой
основной конфигурации не проверяются. - hir-ty: чтение через менеджер перечисления, справочника, плана видов
характеристик, плана счетов или плана видов расчёта проверяется по метаданным:
Перечисления.X.<Значение>, которого нет среди значений перечисления, и
Справочники.X.<Имя>, которого нет среди предопределённых элементов (вложенные в
группы — тоже), даютUnresolvedField— так же, как расширенная проверка
конфигуратора даёт «Возможно ошибочное свойство». Объект без прочитанных
предопределённых элементов (нетExt/Predefined.xml) и заимствованный расширением
объект без видимой основной конфигурации не проверяются; методы менеджера и
обращение по индексу не затронуты. - diagnostics: в модуле обычной формы с описанием диалога (
Ext/Form/Form.json)
ЭлементыФормы.Имяразрешается в элемент формы, а обращение к элементу, которого
в диалоге нет, даётUnresolvedField— если модуль не добавляет элементы сам, не
передаётЭтаФорма/ЭлементыФормынаружу и не исполняет код из строки
(Выполнить,Вычислить). Без сайдкара ничего не меняется.
Changed
- diagnostics:
UnresolvedMetadataPathпроверяет и строки-имена типов конструктора
Новый ОписаниеТипов(...)(первый, второй и третий аргумент, каждое имя списка через
запятую) теми же правилами, что иТип(...). Кроме того, вТипиОписаниеТипов
сообщается имя набора типов без имени объекта (ДокументСсылка,СправочникСсылка,
CatalogRef,ЛюбаяСсылка): платформа его не принимает («Тип не определен» /
«Недопустимое значение параметра»).ОтчетОбъектбез имени — самостоятельный тип на
сервере и не сообщается. - config:
[diagnostics] ordinaryAppSupport, если он не задан, берётся из
<DefaultRunMode>основной конфигурации:OrdinaryApplication—true, иначе
(и без основной конфигурации) —false. Явное значение по-прежнему главнее.
Это же значение теперь получает модель сред исполнения
(EnvOptions::ordinary_app_support), которую раньше включал только
ТолстыйКлиентОбычноеПриложениев[features].checked_environments, — правила
диагностик и модель сред больше не расходятся. Действует в LSP,analyze,
check-config(показывает источник значения) и в настройках диагностик
MCP-сервера; правкаConfiguration.xmlподхватывается без перезапуска (в MCP —
настройками диагностик). - diagnostics: модули объекта, менеджера, набора записей и менеджера значения в
конфигурации с<DefaultRunMode>ManagedApplicationилиAutoпроверяются и
относительно толстого клиента управляемого приложения — платформа компилирует их
там. Клиент судится как в клиент-серверном варианте:ModuleAccessibility
сообщает об обращении к общему модулю только с флагом «Сервер» (без «Вызов
сервера» и «Клиент (управляемое приложение)») и о вызове&НаСервере-метода
своего модуля из кода без директивы. В конфигурации обычного приложения и без
основной конфигурации толстый клиент управляемого приложения не добавляется.
Вызов&НаСервере-метода своего модуля из кода без директивы сообщается и для
толстого клиента обычного приложения, когда он проверяется. - diagnostics: внешнее соединение, если оно включено в
[features].checked_environments, судится как в клиент-серверном варианте.
ModuleAccessibilityбольше не сообщает о вызове общего модуля с флагом «Вызов
сервера» из внешнего соединения (платформа его там видит) и сообщает о вызове
&НаСервере- или&НаСервереБезКонтекста-метода модуля объекта, менеджера,
набора записей и менеджера значения из кода без директивы (платформа: «Процедура
или функция с указанным именем не определена»). Тело такого метода проверяется
только относительно сервера. По умолчанию внешнее соединение не проверяется, и
проверка прежняя. - diagnostics: быстрое исправление
UnusedParameters«Удалить неиспользуемый
параметр»: параметр уходит из объявления, а аргумент на его позиции — из каждого
вызова метода в модуле (имя сравнивается без учёта регистра, вызовы через
ЭтотОбъект./ЭтаФорма.тоже правятся, пропущенный аргумент и запятые
учитываются). Не предлагается дляЭкспорт-метода, в модуле сВыполнить/
Вычислитьили сОписаниеОповещения/УстановитьДействие, имя обработчика
которого не один строковый литерал, когда имя метода встречается в строке модуля или в теле расширения,
когда имя читается не вызовом, когда имя параметра ещё встречается в методе (в любой
ветке препроцессора, в строке) и когда вызов передаёт на этой позиции не литерал и
не простое имя — выбросить вызов функции или чтение поля значит потерять его эффект.
Исправление ручное, вsource.fixAllне входит.
Fixed
-
mcp: клиент, перешедший с
server/discoverнаinitialize, снова получает инструменты.
Так поступает Claude Code, если на discover нет ответа ~3 с. Это бывает на холодном
кэше справки, когда сервер собирает индекс около 12 с. rmcp 3.1.4 оставляла соединение
в inline-lifecycle, иtools/listбез_metaполучал-32602. Теперьrmcp3.6.0,
минимум 3.5.1, где это исправлено (modelcontextprotocol/rust-sdk#1248). Вместо
устаревшего в этих версияхmodel::ServerInfoиспользуетсяServerConfig. -
diagnostics:
UnusedParametersбольше не сообщает о параметрах обработчика операции
веб-сервиса и обработчика получения сообщения сервиса интеграции: их сигнатуру задаёт
описание сервиса, как у обработчика HTTP-сервиса. -
parser:
#КонецЕсливложенной директивы больше не закрывает охватывающую область
модуля. Это случалось в двух местах: директива внутри выражения (Если Ложь/
#Если … Тогда/Или …/#КонецЕсли/Тогда) — восстановление после ошибки
съедало её#Еслив одиночку; и блок, накрывающий веткуИначеЕслиоператора
Если, — блок кончался наИначеЕсли, а его#Иначе/#КонецЕслидоставались
внешней области. Методы после такого места выпадали из
#Если Не ТонкийКлиент И Не ВебКлиент … Тогда, иUnavailableInEnvironmentи
ModuleAccessibilityпроверяли их во всех окружениях модуля. Теперь восстановление
оставляет#Еслиправилам операторов, а пересечённый блок помнится открытым до своего
#КонецЕсли. Сообщения об ошибке разбора на этих конструкциях остаются (кроме
ложного «неожиданного#КонецЕсли» и каскада за ним). -
parser: условная группа
#Если … #КонецЕсли, разрывающая конструкцию, больше не
даёт ложную ошибку разбора и каскад за ней (функция, принятая за процедуру,
«возврат значения из процедуры»). Платформа выбирает строки ветки до разбора, поэтому
группа может стоять внутри выражения, междуЕслииТогдаили дать каждой ветке
свой заголовок при общем теле и общемКонецЕсли. Такая группа читается одним
вариантом: ветка, условие которой истинно при всех определённых символах, — код,
заголовок, директивы и прочие ветки — непрозрачные узлыPRE_TORN_IF_PART.
Группа, каждая ветка которой держит целые операторы, разбирается как прежде.
Дерево условий (ConditionalTree) получает узел на такую группу, и проверки
окружения видят условие прочитанной ветки. Переразбор метода внутри условной группы
отказывает, если старый или новый текст метода не держит целых конструкций. -
diagnostics: флаг общего модуля «Клиент (обычное приложение)»
(ClientOrdinaryApplication) теперь всегда входит в среды модуля, а не только при
включённой поддержке обычного приложения. Раньше модуль, отмеченный только этим
флагом, получал пустое множество сред («неизвестно»), иModuleAccessibility
молчал, когда к нему обращались из модуля обычной формы, открываемой в толстом
клиенте управляемого приложения, или из клиентского и серверного кода управляемой
формы. Платформа в этих средах такой модуль не компилирует («Переменная не
определена»). Проверяется ли сам толстый клиент обычного приложения, по-прежнему
решаетchecked_environments. -
diagnostics: модуль обычной формы больше не проверяется относительно толстого
клиента управляемого приложения, если в основной конфигурации выключено свойство
«Использовать обычные формы в управляемом приложении»
(UseOrdinaryFormInManagedApplication): платформа его там не компилирует, а
ModuleAccessibilityиUnavailableInEnvironmentсообщали о недоступности в
этой среде. При включённом свойстве проверка прежняя; без основной конфигурации
по-прежнему учитываются оба толстых клиента. Свойство перечитывается при правке
Configuration.xml. -
diagnostics:
MismatchedArgCountбольше не судит вызовы, которые платформа
принимает. Ветвь#Если, которую не компилирует ни одно окружение модуля
(#Если Сервер И Не Сервер Тогда— подсказка типов для редактора, клиентская
ветвь серверного модуля), и метод, объявленный в такой ветви уровня модуля,
аргументов не проверяют — там уже молчатUnresolvedBareCallи проверка
минимальной версии; ветвь с нераспознанным условием и ветви модуля с
неизвестным окружением проверяются по-прежнему. Условие, истинность которого
не зависит отСервер(Сервер И Не Сервер), теперь решено и в толстом клиенте
и внешнем соединении, гдеСерверзависит от режима базы, — это же уточняет
проверки окружения (UnavailableInEnvironment,ModuleAccessibility).Новый Файл,
Новый ДокументDOMиНовый ДокументHTMLбез аргументов получили
конструктор без параметров;ЭлементDOM.ПолучитьЭлементыПоИмени(<Имя>)и
ФоновоеЗадание.ОжидатьЗавершения(<Таймаут>)— потерянные справкой параметры.
Все формы проверены компиляцией (/CheckConfig) и выполнением на 8.3.17 и 8.3.27;
конструкторы, которых у платформы нет (Новый HTTPСоединениебез аргументов),
по-прежнему сообщаются. -
diagnostics: синхронные методы
HTTPСоединение(Получить,
ОтправитьДляОбработки,Записать,Изменить,Удалить,
ПолучитьЗаголовки,ВызватьHTTPМетод) больше не отмечаются
UnavailableInEnvironmentв тонком и толстом клиенте. Справка с 8.3.21 оставляет
у них только серверные контексты, но вызов на клиенте лишь признан устаревшим:
платформа 8.3.17 и 8.3.27 выполняет его в тонком и толстом клиенте. Устаревание по-прежнему
сообщаетDeprecatedPlatformApi; веб-клиент, где нет самого типа, не затронут. -
diagnostics:
ФорматированныйДокумент.УстановитьHTML,ДокументPDF.ПреобразоватьВОттенкиСерого,
ДокументPDF.ДобавитьПодписьиЗаписьPDF.ПреобразоватьВОттенкиСерогобольше не отмечаются
UnavailableInEnvironmentв тонком клиенте, аУстановитьHTML- ещё и в толстом. Справка
не называет у них эти клиенты, но платформа (8.3.17 и 8.3.27) выполняет вызовы и там. Синхронные
методыМенеджерСистемыВзаимодействияне тронуты: в тонком клиенте их действительно нет. -
diagnostics:
CommonModuleAssignмолчит, когда имя общего модуля совпадает с
реквизитом контекста модуля — реквизитом управляемой формы или объекта:
присваивание пишет в реквизит (платформа 8.3.17/8.3.27), а не в модуль. В методе
без контекста (&НаСервереБезКонтекста,&НаКлиентеНаСервереБезКонтекста)
реквизит формы не виден, и диагностика сохраняется. -
diagnostics:
ScheduledJobHandlerне требует от обработчика предопределённого
регламентного задания отсутствия параметров, если все они необязательные:
платформа 8.3.17/8.3.27 вызывает его с пустым массивом параметров задания, и
параметр со значением по умолчанию его принимает; ошибкой остаётся только
обязательный параметр («Недостаточно фактических параметров»). -
parser: метка, совпадающая с ключевым словом (
~КонецЦикла:,Перейти ~Возврат;),
разбирается как имя метки, если слово стоит вплотную за тильдой, — и платформа
8.3.17/8.3.27 такой модуль собирает. ПреждеПерейти ~КонецЦикла;закрывал цикл
раньше времени, и модуль получал каскад ложныхParseError. -
parser:
Экспортпринимается после любого имени вПерем(Перем А Экспорт, Б Экспорт;,
Перем А Экспорт, Б;) безParseError, и экспортируется только имя, за которым
он стоит: так ведёт себя платформа 8.3.17/8.3.27 — вПерем А, Б Экспорт;
экспортирована однаБ. Подсветка объявлений следует тому же правилу. -
hir-ty: вызов без получателя в модуле объекта, менеджера или набора записей, имя
которого — и метод самого объекта, и глобальная функция платформы, разрешается в
метод объекта, как это делает платформа:ПолучитьФорму()в модуле объекта отчёта
иПолучитьДанныеВыбора(Параметры)в модуле менеджера больше не дают
MismatchedArgCountиTypeMismatchпо сигнатуре глобальной функции, а лишний
аргумент сверх сигнатуры метода по-прежнему отмечается. Исключение по справке:
ПолучитьДанныеВыборас двумя аргументами в модуле менеджера — глобальная функция. -
diagnostics:
MissedRequiredParameterбольше не судит вызовы в ветви#Если,
которую не компилирует ни одно окружение модуля (#Если Сервер И Не Сервер Тогда—
подсказка типов для редактора, клиентская ветвь серверного модуля): платформа
отбрасывает такую ветвь до компиляции, и вызов в ней ничего не передаёт. Касается
и вызовов своего модуля, и вызовов общих модулей и модулей менеджеров, в том числе
методов, объявленных в такой ветви на уровне модуля; тот же вызов в компилируемом
коде по-прежнему сообщается. Ветвь, условие которой не решается (#Если Линукс,
Серверво внешнем соединении), и ветви модуля неизвестной среды судятся, как прежде.
Проверено компиляцией (/CheckConfig) и выполнением на 8.3.17 и 8.3.27. -
diagnostics:
UnavailableInEnvironmentбольше не отмечает в тонком и веб-клиенте
члены коллекций данных формы. Табличная часть объекта в модуле формы - это
ДанныеФормыКоллекция, поэтому её методы (Добавить,НайтиСтроки,Количество,
Индекс,Удалить,Очиститьи др.) получают доступность и коллекции формы, а
НомерСтрокиеё строки (в том числеЭлементы.<Таблица>.ТекущиеДанные) -
доступностьДанныеФормыЭлементКоллекции. Реквизит формы типаТаблицаЗначений
без объявленных колонок и реквизит объекта типаТаблицаЗначений/
ДеревоЗначений(Объект.<Реквизит>) - тожеДанныеФормыКоллекция/
ДанныеФормыДерево, на клиенте и на сервере;РеквизитФормыВЗначениепо-прежнему
даётТаблицаЗначений. Метод, которого у коллекции формы нет (ВыгрузитьКолонку,
Свернуть), у такого реквизита отмечается какUnresolvedMethodCall, а
ДанныеФормыВЗначение(<реквизит>, ...)больше не даётTypeMismatch. -
diagnostics: методы
COMSafeArrayи членыРасписаниеРегламентногоЗаданиябольше не
отмечаютсяUnavailableInEnvironmentв тонком клиенте, а свойстваРасписаниеРегламентногоЗадания-
ещё и в веб-клиенте. Страницы самих типов в справке называют эти клиенты, страницы членов - нет;
платформа (8.3.17 и 8.3.27) выполняет вызовы там.ТребуетсяВыполнениев веб-клиенте, глобальные
функции модальных диалогов в веб-клиенте иНачатьУдалениеФайлов/ПолучитьОбщуюФормуна
сервере не тронуты: платформа отказывает в них при выполнении. -
platform-help: корпус справки 8.5 (8.5.1.1423, 8.5.4.1683) больше не отвергается
целиком. Архивы 8.5 сами описываютФормаКлиентскогоПриложения.РежимОткрытияОкна,
поэтому курируемое добавление свойства пропускается, когда у типа ровно одно
свойство с обоими именами, и остаётся запись архива с описанием. Совпадение
только одним именем или несколько свойств с обоими именами по-прежнему
отвергаются (github#462). -
diagnostics: успешная пересборка резидента гасит перенесённый долг сверки. Пара
«окно убытка + рубеж фактов» захватывается под тем же локом, что и перенос, и
гашение отказывает, если окно переоткрыли или рубеж обрезан переполнением, — тогда
долг выживает, чтения идут полным сканом, а доставленные после подписки правки
не теряются (github#188). -
diagnostics: устаревший снимок конфигурации больше не запускает лишнюю полную
пересборку. Отказ по поколению базлайна возвращает обязанность сканировать и
сбрасывает кэш снимка, а настоящая правка конфигурации на диске по-прежнему
вызывает пересборку (github#189). -
search: приписывание файла корню сведено к одной ролевой процедуре
(WorkspaceRoots::file_key): движок и публикатор базлайна — тонкие проекции,
третьей процедуры нет; расхождение на ссылке, ведущей вне корней, закрыто
паритет-тестами (github#278). -
search: канонизация корня — снимок поколения: ретаргет ссылки-корня
переканонизирует таблицу без сменыroot_id— строки и внешние адреса переживают
переезд, коллизии id и резервный id конфигурации разведены, а адресованные
запросы с нерезолвимой регистрацией отклоняются, не отвечая из покинутого
каталога. Таблицу корней проекта — её читаютquery,outline, резидент
диагностики и граф — строят под id, которые обслуживает поиск, так что id из
выдачиsearchпосле ретаргета принимают все инструменты (github#277). -
search: терминальный отказ инициализации индекса больше не подаётся как строка постройки:
пустой слот читается единым дискриминатором (идёт инициализация / объявленный отказ /
слот просто пуст) — вsearch statusтерминальные формулировки вместо «building» во
всех разделах, структурированное полеstateсогласовано с прозой, терминальный отказ
reference-цикла назван, а остановленный с демоном рантайм — тоже терминален
(github#212). -
search: графовый контекст записей оверлея обновляется после публикации графа:
обязательство контекстной марки решается один раз на ключ и передаётся записи (её
собственной грязной марке — точечный рефреш пересобирает запись от текущего
провайдера) независимо от того, обслуживает ли стор ключ и включена ли токен-политика;
ключ без записи и без строк стора по-прежнему ждёт исполнителя (github#234). -
diagnostics: резидент диагностик выходит из
Failedповторной попыткой (backoff 5–60 с,
BSL_MCP_DIAG_RETRY_*), причина прошлого падения видна и во время повтора; у сборки
появился таймаут (BSL_MCP_DIAG_BUILD_TIMEOUT_SECS, по умолчанию 600 с), а исход
отставленной дедлайном попытки больше не публикуется; устойчивый отказ резидентных
инструментов приходит единым структурнымerror.data(state/reason/retry_after_ms/
attempts/failed_age_ms),statusконверта согласован с состоянием — контракт 3.5
(github#226). -
mcp-server: состав проекта, заданный флагами, закреплён boot-тестом:
SharedState::workspace
на вложенных конфигурациях глубже досягаемости автопоиска строит проект через
project::at— возврат наproject_model::Project::newроняет тест (github#227). -
debug: отказ сервера отладки (HTTP не 2xx) доходит до вызывающего с текстом
descr,
а не читается как успех;setBreakpoints, отвергнутый 8.3.17 из-за
breakOnCondition, повторяется без него. Ошибкаevalвозвращает текст платформы
изexceptionStr. Предмет, остановленный доattach, находится через
getDbgAllTargetStatesи продолжается (continue/step, параметрtarget);
disconnectпродолжает остановленные предметы перед отключением (github#421).
localsиexpandбез ответа за 5 с — ошибка, а не пустой успех; имя файла
аренды отладчика не длиннее 255 байт. -
hir-ty, bsl-metadata: колонки, которые управляемая форма добавляет к таблице своего
реквизита (<AdditionalColumns table="Объект.Товары">вForm.xml), читаются и
находятся на строках этой табличной части в модуле этой формы: ложный
UnresolvedFieldнаОбъект.Товары.Добавить().<Колонка>и
Элементы.Товары.ТекущиеДанные.<Колонка>больше не выдаётся. В другие формы, в модуль
объекта и на строки других табличных частей колонки не попадают.
Full Changelog: v0.3.2...v0.4.0