Справочник Ada 2005
10.1.1 Единицы компиляции — библиотечные единицы
Элемент library_item — это единица компиляции, являющаяся объявлением, телом или переименованием библиотечной единицы. Каждая библиотечная единица (кроме Standard) имеет родительскую единицу, которая является библиотечным пакетом или обобщенным библиотечным пакетом. Библиотечная единица является дочерней единицей своей родительской единицы. Корневые библиотечные единицы являются дочерними единицами предопределенного библиотечного пакета Standard.
Синтаксис
library_item ::= [private] library_unit_declaration
| library_unit_body
| [private] library_unit_renaming_declaration
| library_unit_body
| [private] library_unit_renaming_declaration
library_unit_declaration ::=
subprogram_declaration | package_declaration
| generic_declaration | generic_instantiation
subprogram_declaration | package_declaration
| generic_declaration | generic_instantiation
library_unit_renaming_declaration ::=
package_renaming_declaration
| generic_renaming_declaration
| subprogram_renaming_declaration
package_renaming_declaration
| generic_renaming_declaration
| subprogram_renaming_declaration
Индикатор overriding_indicator запрещён в subprogram_declaration, generic_instantiation или subprogram_renaming_declaration, которые объявляют библиотечную единицу.
Библиотечная единица — это программная единица, которая объявляется с помощью элемента library_item. Когда программная единица является библиотечной единицей, используется префикс «библиотека» (или «обобщенная библиотека», если обобщенная), а также для её объявления и тела, как в «процедура библиотеки», «библиотечный package_body» или «обобщенный библиотечный пакет». Термин единица компиляции используется для обозначения compilation_unit. Когда смысл понятен из контекста, этот термин также используется для обозначения library_item единицы компиляции или proper_body подмодуля (то есть единицы компиляции без context_clause и separate (parent_unit_name)).
Объявление родителя элемента library_item (и библиотечной единицы) — это объявление, обозначенное именем parent_unit_name, если таковое имеется, в имени программной единицы defining_program_unit_name элемента library_item. Если имени parent_unit_name нет, то родительским объявлением является объявление Standard, элемент library_item является корневым элементом library_item, а библиотечная единица (переименование) является корневой библиотечной единицей (переименование). Объявление и тело Standard не имеют родительского объявления.
Родительская единица элемента library_item или библиотечной единицы — это библиотечная единица, объявленная его родительским объявлением.
Дочерние единицы библиотечной единицы находятся непосредственно внутри декларативной области объявления библиотечной единицы. Предки библиотечной единицы — это сама единица, её родитель, родитель родителя и так далее. (Standard является предком каждой библиотечной единицы.) Отношение потомка является обратным отношению предка.
Объявление library_unit_declaration или library_unit_renaming_declaration является скрытым, если объявление непосредственно предшествует зарезервированному слову private; в противном случае оно общедоступное. Библиотечная единица является закрытой или открытой в соответствии с её объявлением. Открытые потомки библиотечной единицы — это сама библиотечная единица и открытые потомки её открытых дочерних единиц. Остальные её потомки — скрытые потомки.
Для каждого библиотечного package_declaration в окружении существует неявное объявление ограниченного вида этого библиотечного пакета. Ограниченный вид пакета содержит:
- Для каждого вложенного package_declaration — объявление ограниченного вида этого пакета с тем же defining_program_unit_name.
- Для каждого type_declaration в видимой части — неполный вид типа; если type_declaration помечен, то вид — помеченный неполный вид.
Ограниченный вид библиотечного package_declaration является закрытым, если этому библиотечному package_declaration непосредственно предшествует зарезервированное слово private.
Нет синтаксиса для объявления ограниченных видов пакетов, потому что они всегда неявные. Неявное объявление ограниченного вида библиотечного пакета не является объявлением библиотечной единицы (библиотечное package_declaration — есть); тем не менее, это элемент library_item. Неявное объявление ограниченного вида библиотечного пакета образует (неявную) единицу компиляции, у которой context_clause пустой.
Библиотечное package_declaration является завершением объявления его ограниченного вида.
Правила легальности
Родительская единица элемента library_item должна быть библиотечным пакетом или обобщенным библиотечным пакетом.
Если имя defining_program_unit_name данного объявления или тела имеет имя parent_unit_name, то данное объявление или тело должно быть элементом library_item. Тело программной единицы должно быть элементом library_item тогда и только тогда, когда объявление программной единицы является элементом library_item. В library_unit_renaming_declaration имя (старое) name должно обозначать элемент library_item.
Имя parent_unit_name (которое может использоваться в имени defining_program_unit_name элемента library_item и в фразе separate подмодуля subunit), и каждый из его prefixов, не должен обозначать renaming_declaration. С другой стороны, имя, обозначающее library_unit_renaming_declaration, разрешено в nonlimited_with_clause и в других местах, где разрешено имя библиотечной единицы.
END_OF_DOCUMENT_MARKER Если пакет библиотеки является экземпляром обобщённого пакета, то каждый дочерний пакет библиотеки должен быть либо самим экземпляром, либо переименованием единицы библиотеки.
Дочерний пакет обобщённой библиотеки должен быть либо самим обобщённым модулем, либо переименованием другого дочернего модуля того же обобщённого модуля. Переименование дочернего пакета обобщённого пакета должно происходить только в декларативной области обобщённого пакета.
Дочерний пакет родительского обобщённого пакета должен быть инстанцирован или переименован только в декларативной области родительского обобщённого пакета.
Для каждого дочернего элемента C некоторого родительского обобщённого пакета P существует соответствующая декларация C, вложенная непосредственно в каждый экземпляр P. В целях этого правила, если дочерний элемент C сам имеет дочерний элемент D, каждая соответствующая декларация для C имеет соответствующий дочерний элемент D. Соответствующая декларация для дочернего элемента в экземпляре видна только в области видимости with_clause, которая упоминает (оригинальный) обобщённый модуль дочернего элемента.
Подпрограмма библиотеки не должна переопределять примитивную подпрограмму.
Определяющее имя функции, являющейся единицей компиляции, не должно быть символом_оператора.
Статическая семантика
Декларация переименования подпрограммы subprogram_renaming_declaration, которая является library_unit_renaming_declaration, является переименованием-как-декларацией, а не переименованием-как-телом.
Существуют два вида зависимостей между единицами компиляции:
- Семантические зависимости (см. ниже) — это те, которые необходимы для проверки правил компиляции через границы единиц компиляции; единица компиляции зависит семантически от других единиц компиляции, необходимых для определения её законности. Правила видимости основаны на семантических зависимостях.
- Зависимости от разработки (см. 10.2) определяют порядок разработки library_itemов.
Элемент библиотеки library_item семантически зависит от своей родительской декларации. Подмодуль семантически зависит от своего родительского тела. Тело единицы библиотеки library_unit_body семантически зависит от соответствующей library_unit_declaration, если таковая имеется. Декларация ограниченного представления пакета библиотеки семантически зависит от декларации ограниченного представления своего родителя. Декларация пакета библиотеки семантически зависит от декларации его ограниченного представления. Единица компиляции семантически зависит от каждого элемента библиотеки library_item, упомянутого в with_clause единицы компиляции. Кроме того, если данная единица компиляции содержит attribute_reference типа, определённого в другой единице компиляции, то данная единица компиляции семантически зависит от другой единицы компиляции. Связь семантической зависимости является транзитивной.
Динамическая семантика
Разработка декларации ограниченного представления пакета не имеет эффекта.
ПРИМЕЧАНИЯ
1 Простая программа может состоять из одной единицы компиляции. компиляция не обязательно должна иметь какие-либо единицы компиляции; например, её текст может состоять из pragmaов.
2 designator функции библиотеки не может быть символом_оператора, но нелинейная renaming_declaration может переименовать функцию библиотеки в оператор. В рамках раздела две подпрограммы библиотеки должны иметь разные имена и, следовательно, не могут перегружать друг друга. Однако renaming_declaration разрешено определять перегруженные имена для таких подпрограмм, а локально объявленная подпрограмма разрешена для перегрузки подпрограммы библиотеки. Расширенное имя Standard.L может быть использовано для обозначения корневой единицы библиотеки L (если декларация Standard скрыта), поскольку декларации корневых единиц библиотеки находятся непосредственно в декларативной области пакета Standard.
Примеры
Примеры единиц библиотеки:
package Rational_Numbers.IO is -- публичный дочерний элемент Rational_Numbers, см. 7.1
procedure Put(R : in Rational);
procedure Get(R : out Rational);
end Rational_Numbers.IO;
procedure Put(R : in Rational);
procedure Get(R : out Rational);
end Rational_Numbers.IO;
private procedure Rational_Numbers.Reduce(R : in out Rational);
-- закрытый дочерний элемент Rational_Numbers
-- закрытый дочерний элемент Rational_Numbers
with Rational_Numbers.Reduce; -- ссылка на закрытый дочерний элемент
package body Rational_Numbers is
...
end Rational_Numbers;
package body Rational_Numbers is
...
end Rational_Numbers;
with Rational_Numbers.IO; use Rational_Numbers;
with Ada.Text_io; -- см. A.10
procedure Main is -- корневая процедура библиотеки
R : Rational;
begin
R := 5/3; -- создание рационального числа, см. 7.1
Ada.Text_IO.Put("The answer is: ");
IO.Put(R);
Ada.Text_IO.New_Line;
end Main;
with Ada.Text_io; -- см. A.10
procedure Main is -- корневая процедура библиотеки
R : Rational;
begin
R := 5/3; -- создание рационального числа, см. 7.1
Ada.Text_IO.Put("The answer is: ");
IO.Put(R);
Ada.Text_IO.New_Line;
end Main;
with Rational_Numbers.IO;
package Rational_IO renames Rational_Numbers.IO;
-- декларация переименования единицы библиотеки
package Rational_IO renames Rational_Numbers.IO;
-- декларация переименования единицы библиотеки
Каждый из перечисленных library_itemов может быть передан компилятору по отдельности.