Справочник по Ada 2012
10.1.3 Подразделения единиц компиляции
Подразделения подобны дочерним единицам, с этими (важными) отличиями: подразделения поддерживают отдельную компиляцию только тел (не объявлений); родительская единица содержит заглушку_тела для указания существования и места каждого из своих подразделений; объявления, появляющиеся в теле родительской единицы, могут быть видимыми внутри подразделений.
Синтаксис
заглушка_тела ::= заглушка_тела_подпрограммы | заглушка_тела_пакета | заглушка_тела_задачи | заглушка_тела_защищенного_типа
заглушка_тела_подпрограммы ::=
[индикатор_переопределения]
спецификация_подпрограммы is separate
[спецификация_аспекта];
[индикатор_переопределения]
спецификация_подпрограммы is separate
[спецификация_аспекта];
заглушка_тела_защищенного_типа ::=
protected body идентификатор_определения is separate
[спецификация_аспекта];
protected body идентификатор_определения is separate
[спецификация_аспекта];
Правила легальности
Родительское тело подраздела — это тело программной единицы, обозначаемое его имя_родительской_единицы. Термин подразделение используется для обозначения подразделения и также для собственного_тела подразделения. Подразделения программной единицы включают любое подразделение, которое называет эту программную единицу своим родителем, а также любое подразделение, которое называет такое подразделение своим родителем (рекурсивно).
Родительское тело подраздела должно быть присутствовать в текущей среде и должно содержать соответствующую заглушку_тела с тем же идентификатором_определения, что и подраздел.
заглушка_тела_пакета должна быть завершением объявления_пакета или объявления_обобщенного_пакета; заглушка_тела_задачи должна быть завершением объявления задачи; заглушка_тела_защищенного_типа должна быть завершением объявления защищенного типа.
В отличие от этого, заглушка_тела_подпрограммы не обязательно должна быть завершением предыдущего объявления, в этом случае _заглушка объявляет подпрограмму. Если _заглушка является завершением, то она должна быть завершением объявления_подпрограммы или объявления_обобщенной_подпрограммы. Профиль заглушки_тела_подпрограммы, который завершает объявление, должен полностью соответствовать этому объявлению.
Подраздел, соответствующий заглушке_тела, должен быть того же типа (package_, subprogram_, task_ или protected_) что и заглушка_тела. Профиль тела_подпрограммы подраздела должен полностью соответствовать профилю соответствующей заглушки_тела.
Заглушка_тела должна появляться непосредственно в разделе_объявлений тела единицы компиляции. Это правило не применяется внутри экземпляра обобщенной единицы.
Идентификаторы определения всех заглушек_тела, которые появляются непосредственно в определенном разделе_объявлений, должны быть различны.
Правила после компиляции
Для каждой заглушки_тела должно быть подразделение, содержащее соответствующее собственное_тело.
ПРИМЕЧАНИЯ
4 Правила в 10.1.4, «Процесс компиляции» указывают, что заглушка_тела эквивалентна соответствующему собственному_телу. Это подразумевает:
Видимость внутри подраздела — это видимость, которая была бы получена в месте соответствующей заглушки_тела (в теле родительской единицы), если бы раздел_контекста подраздела был добавлен к разделу_контекста родительского тела.
Эффект вызова заглушки_тела — это вызов подраздела.
Примеры
Пакет Parent сначала записывается без подразделений:
package Parent is
procedure Inner;
end Parent;
procedure Inner;
end Parent;
with Ada.Text_IO;
package body Parent is
Variable : String := "Привет, там.";
procedure Inner is
begin
Ada.Text_IO.Put_Line(Variable);
end Inner;
end Parent;
package body Parent is
Variable : String := "Привет, там.";
procedure Inner is
begin
Ada.Text_IO.Put_Line(Variable);
end Inner;
end Parent;
Тело процедуры Inner может быть преобразовано в подразделение, переписав тело пакета следующим образом (с объявлением Parent, остающимся прежним):
package body Parent is
Variable : String := "Привет, там.";
procedure Inner is separate;
end Parent;
Variable : String := "Привет, там.";
procedure Inner is separate;
end Parent;
with Ada.Text_IO;
separate(Parent)
procedure Inner is
begin
Ada.Text_IO.Put_Line(Variable);
end Inner;
separate(Parent)
procedure Inner is
begin
Ada.Text_IO.Put_Line(Variable);
end Inner;