Skip to content

fix(hir-ty): вызов на менеджере значения константы разрешается в экспорт её ValueManagerModule - #426

Merged
itrous merged 6 commits into
itrous:developfrom
flamber-dev:pr/vmm-call-resolution-v2
Oct 15, 2026
Merged

itrous merged 6 commits into
itrous:developfrom
flamber-dev:pr/vmm-call-resolution-v2

Conversation

@flamber-dev

Copy link
Copy Markdown
Contributor

Продолжение #319 (влит): после него ValueManagerModule.bsl константы индексируется как её модуль объекта, и экспорт этого модуля находится по имени. Но вызов СНАРУЖИ - через Константы.<Имя>.СоздатьМенеджерЗначения() - до этого модуля по-прежнему не доходит. Эта правка закрывает вторую половину сценария.

Проблема

На develop (4467ba9a) Константы.<Имя>.СоздатьМенеджерЗначения() типизируется голым фантомом PlatformObject("КонстантаМенеджерЗначения") - имени константы в типе нет. resolve_user_call знает только MetadataRef объектов и ObjectManager, поэтому на таком получателе:

  • переход к определению с места вызова - None;
  • поиск ссылок от объявления экспорта находит только само объявление;
  • опечатка СоздатьМенеджерЗначения().НетТакогоМетода() не даёт UnresolvedMethodCall, как и вызов неэкспортной процедуры модуля (платформа такой вызов отвергает).
// Константы/Константа1/Ext/ValueManagerModule.bsl
Процедура Метод1(Параметр1) Экспорт
КонецПроцедуры

// Общий модуль
Процедура Прогон(Параметр1) Экспорт
    Константы.Константа1.СоздатьМенеджерЗначения().Метод1(Параметр1); // переход к определению: ничего
    МенеджерЗначения = Константы.Константа1.СоздатьМенеджерЗначения();
    МенеджерЗначения.НетТакогоМетода();                                // находки нет
КонецПроцедуры

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

Исправление

Новый вид MetadataKind::ConstantValueManager (КонстантаМенеджерЗначения.<Имя>), по образцу ExternalDataProcessorObject:

  • map_generic_metadata_return_type: возврат КонстантаМенеджерЗначения у менеджера константы даёт MetadataRef(ConstantValueManager, <Имя>);
  • object_kind_to_mdo отдаёт MdoType::Constant: пользовательские методы ищутся в слоте объекта константы, куда fix(hir-def): модуль менеджера значения константы индексируется как её модуль объекта #319 кладёт ValueManagerModule. Правило экспорта, порядок «сначала пользовательский метод, потом платформа» и диагностика MethodNotExport - общие с объектами, ничего отдельного;
  • platform_prefix = ConstantValueManager: методы и свойства платформы берутся из того же префикса корпуса, что уже использует неявный получатель самого модуля менеджера значения (CONSTANT_VALUE_MANAGER_PREFIX в infer.rs);
  • имя получателя в диагностике - КонстантаМенеджерЗначения.<Имя>, а не Константы.<Имя> (это менеджер);
  • мост подтипов: параметр, документированный общим КонстантаМенеджерЗначения, принимает конкретный менеджер значения, как СправочникОбъект принимает объект справочника.

Что не меняется:

  • Константы.<Имя>.Метод() по-прежнему не доходит до модуля менеджера значения и даёт тот же UnresolvedMethodCall;
  • константа БЕЗ ValueManagerModule судится как справочник без модуля объекта: поверхность - только платформа, неизвестное имя сообщается. Так кодовая база уже поступает со всеми объектами без модуля (контроль на Справочник1 в том же тесте), отдельное правило для констант создало бы расхождение;
  • иерархия вызовов строится по синтаксическому графу вызовов, который типизированные получатели не опускает вообще - вызов экспорта модуля объекта справочника через СоздатьЭлемент() в иерархии тоже не виден. Вызов на менеджере значения теперь стоит там же, где вызов на объекте справочника; тест это фиксирует.

Доказательство

crates/ide/tests/value_manager_calls.rs, 9 тестов на фикстуре bsl-metadata/fixtures/designer (СтрокаКонст с модулем менеджера значения, ЧислоКонст без него, Справочник1). Два из них - контрольные и проходят на обеих сторонах: the_manager_spelling_stays_unresolved (написание через менеджер не меняется) и platform_members_of_the_value_manager_stay_platform_members (платформенные члены не затеняются модулем и не сообщаются).

develop (4467ba9a), добавлен только файл теста:

   Compiling ide v0.3.2 (...\wt-dev\crates\ide)
     Running tests\value_manager_calls.rs (...)
running 9 tests
test references_from_the_declaration_include_both_call_spellings ... FAILED
test goto_definition_through_a_local_variable_reaches_the_value_manager_export ... FAILED
test goto_definition_from_the_call_result_reaches_the_value_manager_export ... FAILED
test call_hierarchy_treats_the_value_manager_call_like_a_catalog_object_call ... FAILED
test the_manager_spelling_stays_unresolved ... ok
test a_constant_without_a_value_manager_module_is_judged_like_a_catalog_without_an_object_module ... FAILED
test an_absent_method_on_the_value_manager_is_reported ... FAILED
test a_non_exported_value_manager_procedure_does_not_resolve_from_outside ... FAILED
test platform_members_of_the_value_manager_stay_platform_members ... ok

thread 'references_from_the_declaration_include_both_call_spellings' panicked at crates\ide\tests\value_manager_calls.rs:188:5:
  left: [(FileId(0), "Метод1")]
 right: [(FileId(0), "Метод1"), (FileId(1), "Метод1"), (FileId(1), "Метод1")]

thread 'goto_definition_through_a_local_variable_reaches_the_value_manager_export' panicked at crates\ide\tests\value_manager_calls.rs:161:10:
the call names the value-manager export

thread 'goto_definition_from_the_call_result_reaches_the_value_manager_export' panicked at crates\ide\tests\value_manager_calls.rs:150:10:
the call names the value-manager export

thread 'call_hierarchy_treats_the_value_manager_call_like_a_catalog_object_call' panicked at crates\ide\tests\value_manager_calls.rs:223:5:
  left: None
 right: Some(FileId(0))

thread 'a_constant_without_a_value_manager_module_is_judged_like_a_catalog_without_an_object_module' panicked at crates\ide\tests\value_manager_calls.rs:359:5:
  left: [("UnresolvedMethodCall", "Справочники.Справочник1.СоздатьЭлемент().НетВСправочнике")]
 right: [("UnresolvedMethodCall", "Справочники.Справочник1.СоздатьЭлемент().НетВСправочнике"), ("UnresolvedMethodCall", "Константы.ЧислоКонст.СоздатьМенеджерЗначения().НетВКонстанте")]

thread 'an_absent_method_on_the_value_manager_is_reported' panicked at crates\ide\tests\value_manager_calls.rs:255:5:
  left: []
 right: [("UnresolvedMethodCall", "Константы.СтрокаКонст.СоздатьМенеджерЗначения().НетТакогоМетода"), ("UnresolvedMethodCall", "МенеджерЗначения.ИТакогоНет")]

thread 'a_non_exported_value_manager_procedure_does_not_resolve_from_outside' panicked at crates\ide\tests\value_manager_calls.rs:290:5:
  left: []
 right: [("UnresolvedMethodCall", "Константы.СтрокаКонст.СоздатьМенеджерЗначения().Внутренняя")]

test result: FAILED. 2 passed; 7 failed; 0 ignored; 0 measured; 0 filtered out

ветка:

running 9 tests
test goto_definition_from_the_call_result_reaches_the_value_manager_export ... ok
test goto_definition_through_a_local_variable_reaches_the_value_manager_export ... ok
test references_from_the_declaration_include_both_call_spellings ... ok
test call_hierarchy_treats_the_value_manager_call_like_a_catalog_object_call ... ok
test a_constant_without_a_value_manager_module_is_judged_like_a_catalog_without_an_object_module ... ok
test an_absent_method_on_the_value_manager_is_reported ... ok
test the_manager_spelling_stays_unresolved ... ok
test a_non_exported_value_manager_procedure_does_not_resolve_from_outside ... ok
test platform_members_of_the_value_manager_stay_platform_members ... ok
test result: ok. 9 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

Мост подтипов - hir-ty subtype::tests::constant_value_manager_assignable_to_its_generic_name. С вырезанной веткой моста:

test subtype::tests::constant_value_manager_assignable_to_its_generic_name ... FAILED
thread 'subtype::tests::constant_value_manager_assignable_to_its_generic_name' panicked at crates\hir-ty\src\subtype.rs:993:9:
assertion failed: is_assignable(&db, value_manager, generic)

С ней - ok.

Проверка

  • cargo test --no-fail-fast -p bsl-types -p hir-def -p hir-ty -p hir -p ide -p ide-db -p ide-diagnostics на develop и на ветке: списки упавших совпадают (одни и те же 27 тестов на обеих сторонах, падают на develop и без этой правки - фон прогона под Windows), на ветке на 10 прошедших больше (9 новых тестов ide и тест моста подтипов). Новых падений нет.
  • cargo fmt --all -- --check: чисто.
  • cargo clippy --workspace --all-targets (собирает все крейты, включая те, что сопоставляют MetadataKind исчерпывающе): набор предупреждений совпадает с develop (два предупреждения в mcp-server, существующие на develop).

Вне рамок

  • Вызов через менеджер Константы.<Имя>.Метод() - его платформа не разрешает, поведение не меняется.
  • Иерархия вызовов для типизированных получателей вообще (объект справочника, менеджер значения) - отдельная задача графа вызовов.
  • Вывод типа значения МенеджерЗначения.Значение из типа константы этой правкой не затрагивается.

🤖 Generated with Claude Code

…ValueManagerModule

`Константы.<Имя>.СоздатьМенеджерЗначения()` returned the bare platform phantom
`КонстантаМенеджерЗначения`, which names no constant: the user-call cascade knew
nothing to look up, so go-to-definition, references and the unresolved-call
verdict all stopped at the receiver.

The value manager is now `MetadataRef(ConstantValueManager, <Имя>)`. Its user
methods come from the constant's object slot, where the module index files the
ValueManagerModule; its platform members from the `ConstantValueManager.` corpus
prefix; a diagnostic names it `КонстантаМенеджерЗначения.<Имя>`; a parameter
documented with the generic `КонстантаМенеджерЗначения` still accepts it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@itrous

itrous commented Oct 15, 2026

Copy link
Copy Markdown
Owner

🤖 Начата автоматическая приёмка — этот pull request взят в работу ИИ-агентом:
изменения переносятся на актуальную целевую ветку, проходят независимое ревью
и соответствующие тесты, очевидные замечания правятся по ходу. Обновления появятся
в этом треде; merge возможен только после завершения проверки.

Елишев Кирилл and others added 5 commits October 15, 2026 19:36
…fields of its value manager

The field lookup kept its own copy of the object-kind table and missed
ConstantValueManager, so a valid read or write of a value-manager module
export variable was reported as UnresolvedField. Reuse the table that
method resolution already uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the constant

`mdo_type_of_kind` had no arm for `ConstantValueManager`, so the type of
`Константы.<Имя>.СоздатьМенеджерЗначения()` navigated nowhere although the
constant's XML is there to reach.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@itrous
itrous merged commit 4501837 into itrous:develop Oct 15, 2026
4 checks passed
@itrous

itrous commented Oct 15, 2026

Copy link
Copy Markdown
Owner

🤖 Автоматическая приёмка завершена: изменения приняты, PR влит коммитом 4501837.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants