Руководство по Ada (Ada 2022)
8.3 Видимость
Правила видимости, приведённые ниже, определяют, какие объявления видимы и непосредственно видны в каждой точке программы. Правила видимости применяются к явным и неявным объявлениям.
Статическая семантика
Объявление считается непосредственно видимым в тех местах, где имя, состоящее только из идентификатора или символа оператора, достаточно для обозначения объявления; то есть, для обозначения объявления не требуется использование нотации выбранного компонента или специального контекста (например, предшествующего => в именованном ассоциации). Объявление считается видимым там, где оно непосредственно видно, а также в других местах, где некоторое имя (например, выбранный компонент) может обозначать объявление.
Категория синтаксиса direct_name используется для обозначения контекстов, где требуется непосредственная видимость. Категория синтаксиса selector_name используется для обозначения контекстов, где требуется видимость, но не непосредственная видимость.
Существует два вида непосредственной видимости: непосредственная видимость и видимость с помощью директивы use. Объявление непосредственно видно в месте, если оно непосредственно видно, потому что место находится в его непосредственной области видимости. Объявление видимо с помощью директивы use, если оно непосредственно видно благодаря директиве use_clause (см. 8.4). Оба условия могут применяться.
Объявление может быть скрыто, либо от непосредственной видимости, либо от всей видимости, в определённых частях своей области видимости. Где скрыто от всей видимости, оно вообще не видно (ни с помощью direct_name, ни с помощью selector_name). Где скрыто от непосредственной видимости, теряется только непосредственная видимость; видимость с помощью selector_name всё ещё возможна.
Два или более объявления перегружены, если у всех одинаковое определяющее имя, и существует место, где все они непосредственно видны.
Объявления вызываемых сущностей (включая литералы перечислений) перегружаемы, что означает, что перегрузка разрешена для них.
Два объявления являются омографами, если у них одинаковое определяющее имя, и, если оба перегружаемы, их профили совместимы по типу. Внутреннее объявление скрывает любой внешний омограф от непосредственной видимости.
Два омографа обычно не допускаются непосредственно в пределах той же области объявления, если один не заменяет другой (см. Правила законности ниже). Единственные объявления, которые заменяемы, — это неявные объявления предопределённых операторов и унаследованных примитивных подпрограмм. Объявление заменяет другой омограф, который появляется непосредственно в пределах той же области объявления в следующих случаях:
- Объявление, которое не заменяемо, заменяет объявление, которое заменяемо, независимо от того, какое объявление появляется первым;
- Неявное объявление унаследованного оператора заменяет предопределённый оператор;
- Неявное объявление унаследованной подпрограммы заменяет предыдущее неявное объявление унаследованной подпрограммы.
- Если два или более омографа объявляются неявно в одном месте:
Если хотя бы одно из них — подпрограмма, которая не является ни пустой процедурой, ни абстрактной подпрограммой и не требует замены (см. 3.9.3), то они заменяют те, которые являются пустыми процедурами, абстрактными подпрограммами или требуют замены. Если остаётся более одного такого омографа, который не заменён таким образом, то все они скрыты от всей видимости.
В противном случае (все являются пустыми процедурами, абстрактными подпрограммами или требуют замены), любая пустая процедура заменяет все абстрактные подпрограммы и все подпрограммы, которые требуют замены; если остаётся более одного такого омографа, который не заменён таким образом, то, если профили оставшихся омографов полностью совместимы друг с другом, выбирается один произвольно; если нет, то все они скрыты от всей видимости.
- Для неявного объявления примитивной подпрограммы в обобщённом блоке существует копия этого объявления в экземпляре. Однако для каждого типа, объявленного в видимой части экземпляра, неявно объявляется новый набор примитивных подпрограмм. Эти новые объявления появляются непосредственно после объявления типа и заменяют скопированные. Копированные могут вызываться только изнутри экземпляра; новые могут вызываться только извне экземпляра, хотя для помеченных типов тело нового может быть выполнено вызовом старого.
Объявление видно в своей области видимости, за исключением случаев, когда оно скрыто от всей видимости следующим образом:
- Заменённое объявление скрыто от всей видимости в области видимости заменяющего объявления.
- Объявление скрыто от всей видимости до конца объявления, за исключением:
Для типа записи или расширения записи объявление скрыто от всей видимости только до ключевого слова record;
Для объявления пакета, обобщённого пакета, тела подпрограммы или объявления функции выражения объявление скрыто от всей видимости только до ключевого слова is объявления;
Для объявления задачи или защищённого объявления объявление скрыто от всей видимости только до ключевого слова with объявления, если оно есть, или ключевого слова is объявления, если with отсутствует.
- Если завершение объявления является объявлением, то в области видимости завершения первое объявление скрыто от всей видимости. Аналогично, спецификация дискриминанта или спецификация параметра скрыта в области видимости соответствующей спецификации дискриминанта или спецификации параметра соответствующего завершения или соответствующей инструкции accept.
- Объявление блока библиотеки (включая объявление переименования блока библиотеки) скрыто от всей видимости в местах за пределами его области объявления, которые не находятся в области видимости директивы nonlimited_with, которая его упоминает. Ограниченное представление блока библиотеки скрыто от всей видимости в местах, которые не находятся в области видимости директивы limited_with, которая его упоминает; кроме того, ограниченное представление скрыто от всей видимости в области объявления пакета, а также в области видимости любой директивы nonlimited_with, которая упоминает пакет. Где объявление ограниченного представления пакета видно, любое имя, обозначающее пакет, обозначает ограниченное представление, включая те, которые предоставляются переименованием пакета.
- Для каждого объявления или переименования обобщённого блока как потомка некоторого родительского обобщённого пакета существует соответствующее вложенное объявление в каждом экземпляре родителя. Такое вложенное объявление скрыто от всей видимости, кроме мест, которые находятся в области видимости директивы with, которая упоминает потомка.
Объявление с определяющим идентификатором или определяющим символом оператора непосредственно видно (и, следовательно, непосредственно видно) в своей непосредственной области видимости, за исключением случаев, когда оно скрыто от непосредственной видимости следующим образом:
- Объявление скрыто от непосредственной видимости в непосредственной области видимости омографа объявления, если омограф находится во внутренней области объявления;
- Объявление также скрыто от непосредственной видимости, где скрыто от всей видимости.
Атрибут или спецификация аспекта видим повсюду в своей области видимости.
Правила разрешения имён
direct_name должен разрешить обозначение непосредственно видимого объявления, определяющее имя которого такое же, как и direct_name. selector_name должен разрешить обозначение видимого объявления, определяющее имя которого такое же, как и selector_name.
END_OF_DOCUMENT_MARKER Эти правила видимости и прямой видимости не применяются в context_clause, parent_unit_name или pragma, которые появляются на месте compilation_unit. Для этих контекстов см. правила в 10.1.6, «Правила видимости на уровне среды».
Правила допустимости
Непереопределяемое объявление недопустимо, если существует омоним, появляющийся непосредственно в той же области объявления, который виден в месте объявления и не скрыт от всей видимости непереопределяемым объявлением. Кроме того, расширение типа недопустимо, если где-либо в его непосредственной области оно имеет два видимых компонента с одинаковым именем. Аналогично, context_clause для единицы компиляции недопустим, если он упоминает (в with_clause) некоторую библиотечную единицу, и существует омоним библиотечной единицы, видимый в месте единицы компиляции, и омоним, и упомянутая библиотечная единица объявлены непосредственно в той же области объявления. Эти правила также применяются к операциям диспетчеризации, объявленным в видимой части экземпляра генерической единицы. Однако они не применяются к другим перегружаемым объявлениям в экземпляре; такие объявления могут иметь профили, соответствующие типу, в экземпляре, при условии, что соответствующие объявления в генерике не были соответствующими типу.
ПРИМЕЧАНИЕ 1 Видимость для единиц компиляции вытекает из определения среды в 10.1.4, за исключением того, что необходимо применить with_clause для получения видимости к library_unit_declaration или library_unit_renaming_declaration.
ПРИМЕЧАНИЕ 2 В дополнение к правилам видимости, приведенным выше, значение появления direct_name или selector_name в заданном месте текста может зависеть от правил перегрузки (см. 8.6).
ПРИМЕЧАНИЕ 3 Не все контексты, где identifier, character_literal или operator_symbol разрешены, требуют видимости соответствующего объявления. Контексты, где видимость не требуется, определяются с помощью одной из этих трех синтаксических категорий непосредственно в синтаксическом правиле, а не с использованием direct_name или selector_name.