Spec-Zone.ru › Ada 2022
Руководство по Ada (Ada 2022)

10.1.2 Определения контекста — операторы with

Оператор context_clause используется для указания library_itemов, имена которых необходимы внутри единицы компиляции.

Синтаксис

context_clause ::= {context_item}
context_item ::= with_clause | use_clause
with_clause ::= limited_with_clause | nonlimited_with_clause
limited_with_clause ::= limited [private] with library_unit_name {, library_unit_name};
nonlimited_with_clause ::= [private] with library_unit_name {, library_unit_name};

Правила разрешения имен

Область видимости оператора with_clause, который появляется в library_unit_declaration или library_unit_renaming_declaration, охватывает всю декларативную область объявления, включая все дочерние элементы и подблоки. Область видимости оператора with_clause в теле состоит из тела, включая все подблоки.
library_item (и соответствующая единица библиотеки) называется в with_clause, если она обозначена именем library_unit_name в with_clause. library_item (и соответствующая единица библиотеки) упоминается в with_clause, если она названа в with_clause или обозначается префиксом в with_clause.
За пределами собственной декларативной области объявление или переименование единицы библиотеки могут быть видны только в области видимости with_clause, которая её упоминает. Видимость объявления или переименования единицы библиотеки в противном случае следует из её размещения в окружении.

Правила законности

Если with_clause данной compilation_unit упоминает закрытый дочерний элемент некоторой единицы библиотеки, то данная compilation_unit должна быть одной из:
  • объявлением, телом или подблоком закрытого потомка этой единицы библиотеки;
  • телом или подблоком публичного потомка этой единицы библиотеки, но не телом подпрограммы, действующим как объявление подпрограммы (см. 10.1.4); или
  • объявлением публичного потомка этой единицы библиотеки, в этом случае with_clause должен содержать зарезервированное слово private.
Имя, обозначающее library_item (или соответствующее объявление для дочернего элемента обобщённого внутри экземпляра — см. 10.1.1), если оно видно только благодаря упоминанию в одном или нескольких with_clauseов единицы U, которые включают зарезервированное слово private, должно появляться только внутри:
  • частной части;
  • тела публичного потомка U, но не в subprogram_specification тела подпрограммы, являющейся публичным потомком U;
  • закрытого потомка U или его тела; или
  • псевдонима внутри оператора контекста.
Элемент библиотеки, упомянутый в limited_with_clause, должен быть неявным объявлением ограниченного вида библиотечного пакета, а не объявлением подпрограммы, обобщённого элемента, экземпляра обобщённого элемента или переименования.
Оператор limited_with_clause не должен появляться в library_unit_body, subunit или library_unit_renaming_declaration.
Оператор limited_with_clause, который называет библиотечный пакет, не должен появляться:
  • в операторе контекста для явного объявления названного библиотечного пакета или любого его потомка;
  • в операторе контекста для library_item, который находится в области видимости оператора nonlimited_with_clause, который упоминает тот же библиотечный пакет; или
  • в операторе контекста для library_item, который находится в области видимости оператора use_clause, который называет сущность, объявленную в декларативной области библиотечного пакета.
ПРИМЕЧАНИЕ Элемент библиотеки, упомянутый в операторе nonlimited_with_clause единицы компиляции, виден внутри единицы компиляции и поэтому действует как обычное объявление. Таким образом, внутри единицы компиляции, которая упоминает его объявление, имя библиотечного пакета может быть указано в операторах use_clause, может использоваться для построения расширенных имён, библиотечная подпрограмма может быть вызвана, а экземпляры библиотечной обобщённой единицы могут быть объявлены. Если дочерний элемент родительского обобщённого пакета упоминается в nonlimited_with_clause, то соответствующее объявление, вложенное в каждый видимый экземпляр, видно внутри единицы компиляции. Аналогично, library_item, упомянутый в limited_with_clause единицы компиляции, виден внутри единицы компиляции и, таким образом, может быть использован для построения расширенных имён.

Примеры

Примеры использования операторов with, limited with и private with:
package Office is
end Office;
with Ada.Strings.Unbounded;
package Office.Locations is
type Location is new Ada.Strings.Unbounded.Unbounded_String;
end Office.Locations;
limited with Office.Departments; -- типы неполны
private with Office.Locations; -- только виден в частной части
package Office.Employees is
type Employee is private;
function Dept_Of(Emp : Employee) return access Departments.Department;
procedure Assign_Dept(Emp : in out Employee;
Dept : access Departments.Department);
...
private
type
Employee is
record

Dept : access Departments.Department;
Loc : Locations.Location;
...
end record;
end Office.Employees;
limited with Office.Employees;
package Office.Departments is
type Department is ...;
function Manager_Of(Dept : Department) return access Employees.Employee;
procedure Assign_Manager(Dept : in out Department;
Mgr : access Employees.Employee);
...
end Office.Departments;
END_OF_DOCUMENT_MARKER
Можно использовать ограничение для поддержки взаимозависимых абстракций, разделенных по нескольким пакетам. В этом случае сотрудник назначается в отдел, а отдел имеет руководителя, который также является сотрудником. Если ограничение со служебным словом private появляется в одном модуле библиотеки и упоминает второй модуль, оно предоставляет видимость второму модулю, но ограничивает эту видимость частной частью и телом первого модуля. Компилятор проверяет, что второй модуль не используется в видимой части первого модуля.


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API